Skip to content

Commit 9c6cdb3

Browse files
committed
Merge branch 'feature/declare-proofs' into feature/zkprogram-qol
2 parents 35fe9de + 1a410b1 commit 9c6cdb3

File tree

9 files changed

+160
-91
lines changed

9 files changed

+160
-91
lines changed

src/lib/mina/account-update.ts

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -655,7 +655,6 @@ type LazyProof = {
655655
kind: 'lazy-proof';
656656
methodName: string;
657657
args: any[];
658-
previousProofs: Pickles.Proof[];
659658
ZkappClass: typeof SmartContract;
660659
memoized: { fields: Field[]; aux: any[] }[];
661660
blindingValue: Field;
@@ -2116,14 +2115,7 @@ async function addProof(
21162115

21172116
async function createZkappProof(
21182117
prover: Pickles.Prover,
2119-
{
2120-
methodName,
2121-
args,
2122-
previousProofs,
2123-
ZkappClass,
2124-
memoized,
2125-
blindingValue,
2126-
}: LazyProof,
2118+
{ methodName, args, ZkappClass, memoized, blindingValue }: LazyProof,
21272119
{ transaction, accountUpdate, index }: ZkappProverData
21282120
): Promise<Proof<ZkappPublicInput, Empty>> {
21292121
let publicInput = accountUpdate.toPublicInput(transaction);
@@ -2141,7 +2133,7 @@ async function createZkappProof(
21412133
blindingValue,
21422134
});
21432135
try {
2144-
return await prover(publicInputFields, MlArray.to(previousProofs));
2136+
return await prover(publicInputFields);
21452137
} catch (err) {
21462138
console.error(`Error when proving ${ZkappClass.name}.${methodName}()`);
21472139
throw err;
@@ -2151,7 +2143,7 @@ async function createZkappProof(
21512143
}
21522144
);
21532145

2154-
let maxProofsVerified = ZkappClass._maxProofsVerified!;
2146+
let maxProofsVerified = await ZkappClass.getMaxProofsVerified();
21552147
const Proof = ZkappClass.Proof();
21562148
return new Proof({
21572149
publicInput,

src/lib/mina/zkapp.ts

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,13 @@ import {
4444
import {
4545
analyzeMethod,
4646
compileProgram,
47+
computeMaxProofsVerified,
4748
Empty,
48-
getPreviousProofsForProver,
4949
MethodInterface,
5050
sortMethodArguments,
5151
VerificationKey,
5252
} from '../proof-system/zkprogram.js';
53-
import { Proof } from '../proof-system/proof.js';
53+
import { Proof, ProofClass } from '../proof-system/proof.js';
5454
import { PublicKey } from '../provable/crypto/signature.js';
5555
import {
5656
InternalStateType,
@@ -154,11 +154,6 @@ function method<K extends string, T extends SmartContract>(
154154
// FIXME: overriding a method implies pushing a separate method entry here, yielding two entries with the same name
155155
// this should only be changed once we no longer share the _methods array with the parent class (otherwise a subclass declaration messes up the parent class)
156156
ZkappClass._methods.push(methodEntry);
157-
ZkappClass._maxProofsVerified ??= 0;
158-
ZkappClass._maxProofsVerified = Math.max(
159-
ZkappClass._maxProofsVerified,
160-
methodEntry.numberOfProofs
161-
) as 0 | 1 | 2;
162157
let func = descriptor.value as AsyncFunction;
163158
descriptor.value = wrapMethod(func, ZkappClass, internalMethodEntry);
164159
}
@@ -341,8 +336,6 @@ function wrapMethod(
341336
{
342337
methodName: methodIntf.methodName,
343338
args: clonedArgs,
344-
// proofs actually don't have to be cloned
345-
previousProofs: getPreviousProofsForProver(actualArgs),
346339
ZkappClass,
347340
memoized,
348341
blindingValue,
@@ -433,7 +426,6 @@ function wrapMethod(
433426
{
434427
methodName: methodIntf.methodName,
435428
args: constantArgs,
436-
previousProofs: getPreviousProofsForProver(constantArgs),
437429
ZkappClass,
438430
memoized,
439431
blindingValue: constantBlindingValue,
@@ -593,10 +585,10 @@ class SmartContract extends SmartContractBase {
593585
rows: number;
594586
digest: string;
595587
gates: Gate[];
588+
proofs: ProofClass[];
596589
}
597590
>; // keyed by method name
598591
static _provers?: Pickles.Prover[];
599-
static _maxProofsVerified?: 0 | 1 | 2;
600592
static _verificationKey?: { data: string; hash: Field };
601593

602594
/**
@@ -644,6 +636,7 @@ class SmartContract extends SmartContractBase {
644636
forceRecompile = false,
645637
} = {}) {
646638
let methodIntfs = this._methods ?? [];
639+
let methodKeys = methodIntfs.map(({ methodName }) => methodName);
647640
let methods = methodIntfs.map(({ methodName }) => {
648641
return async (
649642
publicInput: unknown,
@@ -657,13 +650,15 @@ class SmartContract extends SmartContractBase {
657650
});
658651
// run methods once to get information that we need already at compile time
659652
let methodsMeta = await this.analyzeMethods();
660-
let gates = methodIntfs.map((intf) => methodsMeta[intf.methodName].gates);
653+
let gates = methodKeys.map((k) => methodsMeta[k].gates);
654+
let proofs = methodKeys.map((k) => methodsMeta[k].proofs);
661655
let { verificationKey, provers, verify } = await compileProgram({
662656
publicInputType: ZkappPublicInput,
663657
publicOutputType: Empty,
664658
methodIntfs,
665659
methods,
666660
gates,
661+
proofs,
667662
proofSystemTag: this,
668663
cache,
669664
forceRecompile,
@@ -689,6 +684,17 @@ class SmartContract extends SmartContractBase {
689684
return hash.toBigInt().toString(16);
690685
}
691686

687+
/**
688+
* The maximum number of proofs that are verified by any of the zkApp methods.
689+
* This is an internal parameter needed by the proof system.
690+
*/
691+
static async getMaxProofsVerified() {
692+
let methodData = await this.analyzeMethods();
693+
return computeMaxProofsVerified(
694+
Object.values(methodData).map((d) => d.proofs.length)
695+
);
696+
}
697+
692698
/**
693699
* Deploys a {@link SmartContract}.
694700
*
@@ -1189,7 +1195,7 @@ super.init();
11891195
try {
11901196
for (let methodIntf of methodIntfs) {
11911197
let accountUpdate: AccountUpdate;
1192-
let { rows, digest, gates, summary } = await analyzeMethod(
1198+
let { rows, digest, gates, summary, proofs } = await analyzeMethod(
11931199
ZkappPublicInput,
11941200
methodIntf,
11951201
async (publicInput, publicKey, tokenId, ...args) => {
@@ -1207,6 +1213,7 @@ super.init();
12071213
rows,
12081214
digest,
12091215
gates,
1216+
proofs,
12101217
};
12111218
if (printSummary) console.log(methodIntf.methodName, summary());
12121219
}

src/lib/proof-system/proof-system.unit-test.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,6 @@ it('pickles rule creation', async () => {
5454
expect(methodIntf).toEqual({
5555
methodName: 'main',
5656
args: [EmptyProof, Bool],
57-
numberOfProofs: 1,
5857
});
5958

6059
// store compiled tag
@@ -67,7 +66,8 @@ it('pickles rule creation', async () => {
6766
main as AnyFunction,
6867
{ name: 'mock' },
6968
methodIntf,
70-
[]
69+
[],
70+
[EmptyProof]
7171
);
7272

7373
await equivalentAsync(
@@ -133,7 +133,6 @@ it('pickles rule creation: nested proof', async () => {
133133
expect(methodIntf).toEqual({
134134
methodName: 'main',
135135
args: [NestedProof2],
136-
numberOfProofs: 2,
137136
});
138137

139138
// store compiled tag
@@ -146,7 +145,8 @@ it('pickles rule creation: nested proof', async () => {
146145
main as AnyFunction,
147146
{ name: 'mock' },
148147
methodIntf,
149-
[]
148+
[],
149+
[EmptyProof, EmptyProof]
150150
);
151151

152152
let dummy = await EmptyProof.dummy(Field(0), undefined, 0);

src/lib/proof-system/proof.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,15 @@ import { ProvableType } from '../provable/types/provable-intf.js';
1515
import { ZkProgramContext } from './zkprogram-context.js';
1616

1717
// public API
18-
export { ProofBase, Proof, DynamicProof };
18+
export { ProofBase, Proof, DynamicProof, ProofClass };
1919

2020
// internal API
2121
export { dummyProof, extractProofs, extractProofTypes, type ProofValue };
2222

2323
type MaxProofs = 0 | 1 | 2;
2424

25+
type ProofClass = Subclass<typeof ProofBase>;
26+
2527
class ProofBase<Input = any, Output = any> {
2628
static publicInputType: FlexibleProvablePure<any> = undefined as any;
2729
static publicOutputType: FlexibleProvablePure<any> = undefined as any;

0 commit comments

Comments
 (0)