@aztec/bb-prover 0.87.2 → 0.87.3-nightly.20250528
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dest/avm_proving_tests/avm_proving_tester.d.ts +3 -10
- package/dest/avm_proving_tests/avm_proving_tester.d.ts.map +1 -1
- package/dest/avm_proving_tests/avm_proving_tester.js +18 -62
- package/dest/bb/execute.d.ts +5 -24
- package/dest/bb/execute.d.ts.map +1 -1
- package/dest/bb/execute.js +31 -106
- package/dest/prover/server/bb_prover.d.ts +5 -5
- package/dest/prover/server/bb_prover.d.ts.map +1 -1
- package/dest/prover/server/bb_prover.js +22 -13
- package/dest/test/test_circuit_prover.d.ts +2 -2
- package/dest/test/test_circuit_prover.d.ts.map +1 -1
- package/dest/test/test_circuit_prover.js +2 -2
- package/dest/verification_key/verification_key_data.d.ts +6 -0
- package/dest/verification_key/verification_key_data.d.ts.map +1 -1
- package/dest/verification_key/verification_key_data.js +16 -16
- package/package.json +18 -16
- package/src/avm_proving_tests/avm_proving_tester.ts +30 -87
- package/src/bb/execute.ts +37 -125
- package/src/prover/server/bb_prover.ts +48 -30
- package/src/test/test_circuit_prover.ts +7 -5
- package/src/verification_key/verification_key_data.ts +20 -13
|
@@ -4,7 +4,7 @@ function _ts_decorate(decorators, target, key, desc) {
|
|
|
4
4
|
else for(var i = decorators.length - 1; i >= 0; i--)if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
5
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
6
|
}
|
|
7
|
-
import {
|
|
7
|
+
import { AVM_V2_PROOF_LENGTH_IN_FIELDS_PADDED, AVM_V2_VERIFICATION_KEY_LENGTH_IN_FIELDS_PADDED, NESTED_RECURSIVE_PROOF_LENGTH, NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH, RECURSIVE_PROOF_LENGTH, TUBE_PROOF_LENGTH } from '@aztec/constants';
|
|
8
8
|
import { createLogger } from '@aztec/foundation/log';
|
|
9
9
|
import { sleep } from '@aztec/foundation/sleep';
|
|
10
10
|
import { Timer } from '@aztec/foundation/timer';
|
|
@@ -105,7 +105,7 @@ import { PROOF_DELAY_MS, WITGEN_DELAY_MS } from './delay_values.js';
|
|
|
105
105
|
// We can't simulate the AVM because we don't have enough context to do so (e.g., DBs).
|
|
106
106
|
// We just return an empty proof and VK data.
|
|
107
107
|
this.logger.debug('Skipping AVM simulation in TestCircuitProver.');
|
|
108
|
-
return this.applyDelay(ProvingRequestType.PUBLIC_VM, ()=>makeProofAndVerificationKey(makeEmptyRecursiveProof(
|
|
108
|
+
return this.applyDelay(ProvingRequestType.PUBLIC_VM, ()=>makeProofAndVerificationKey(makeEmptyRecursiveProof(AVM_V2_PROOF_LENGTH_IN_FIELDS_PADDED), VerificationKeyData.makeFake(AVM_V2_VERIFICATION_KEY_LENGTH_IN_FIELDS_PADDED)));
|
|
109
109
|
}
|
|
110
110
|
async applyDelay(type, fn) {
|
|
111
111
|
const timer = new Timer();
|
|
@@ -5,5 +5,11 @@ import { VerificationKeyData } from '@aztec/stdlib/vks';
|
|
|
5
5
|
* @returns The verification key data
|
|
6
6
|
*/
|
|
7
7
|
export declare function extractVkData(vkDirectoryPath: string): Promise<VerificationKeyData>;
|
|
8
|
+
/**
|
|
9
|
+
* Reads the verification key data stored in a binary file at the specified directory location and parses into a VerificationKeyData.
|
|
10
|
+
* We do not assume any JSON file available but only the binary version, contrary to the above extractVkData() method.
|
|
11
|
+
* @param vkDirectoryPath - The directory containing the verification key binary data file.
|
|
12
|
+
* @returns The verification key data
|
|
13
|
+
*/
|
|
8
14
|
export declare function extractAvmVkData(vkDirectoryPath: string): Promise<VerificationKeyData>;
|
|
9
15
|
//# sourceMappingURL=verification_key_data.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"verification_key_data.d.ts","sourceRoot":"","sources":["../../src/verification_key/verification_key_data.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"verification_key_data.d.ts","sourceRoot":"","sources":["../../src/verification_key/verification_key_data.ts"],"names":[],"mappings":"AAIA,OAAO,EAA2B,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAQjF;;;;GAIG;AACH,wBAAsB,aAAa,CAAC,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAWzF;AAED;;;;;GAKG;AACH,wBAAsB,gBAAgB,CAAC,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAe5F"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { AVM_V2_VERIFICATION_KEY_LENGTH_IN_FIELDS_PADDED } from '@aztec/constants';
|
|
2
2
|
import { Fr } from '@aztec/foundation/fields';
|
|
3
|
+
import { BufferReader } from '@aztec/foundation/serialize';
|
|
3
4
|
import { hashVK } from '@aztec/stdlib/hash';
|
|
4
5
|
import { VerificationKeyAsFields, VerificationKeyData } from '@aztec/stdlib/vks';
|
|
5
6
|
import { strict as assert } from 'assert';
|
|
@@ -24,21 +25,20 @@ import { VK_FIELDS_FILENAME, VK_FILENAME } from '../bb/execute.js';
|
|
|
24
25
|
const vkAsFields = new VerificationKeyAsFields(fields, vkHash);
|
|
25
26
|
return new VerificationKeyData(vkAsFields, rawBinary);
|
|
26
27
|
}
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
const
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
const vkAsFields = new VerificationKeyAsFields(fields, vkHash);
|
|
28
|
+
/**
|
|
29
|
+
* Reads the verification key data stored in a binary file at the specified directory location and parses into a VerificationKeyData.
|
|
30
|
+
* We do not assume any JSON file available but only the binary version, contrary to the above extractVkData() method.
|
|
31
|
+
* @param vkDirectoryPath - The directory containing the verification key binary data file.
|
|
32
|
+
* @returns The verification key data
|
|
33
|
+
*/ export async function extractAvmVkData(vkDirectoryPath) {
|
|
34
|
+
const rawBinary = await fs.readFile(path.join(vkDirectoryPath, VK_FILENAME));
|
|
35
|
+
const numFields = rawBinary.length / Fr.SIZE_IN_BYTES;
|
|
36
|
+
assert(numFields <= AVM_V2_VERIFICATION_KEY_LENGTH_IN_FIELDS_PADDED, 'Invalid AVM verification key length');
|
|
37
|
+
const reader = BufferReader.asReader(rawBinary);
|
|
38
|
+
const fieldsArray = reader.readArray(numFields, Fr);
|
|
39
|
+
const fieldsArrayPadded = fieldsArray.concat(Array(AVM_V2_VERIFICATION_KEY_LENGTH_IN_FIELDS_PADDED - fieldsArray.length).fill(new Fr(0)));
|
|
40
|
+
// Currently, we do not need the vk hash for the AVM as we are not adding in the vk tree.
|
|
41
|
+
const vkAsFields = new VerificationKeyAsFields(fieldsArrayPadded, new Fr(0));
|
|
42
42
|
const vk = new VerificationKeyData(vkAsFields, rawBinary);
|
|
43
43
|
return vk;
|
|
44
44
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aztec/bb-prover",
|
|
3
|
-
"version": "0.87.
|
|
3
|
+
"version": "0.87.3-nightly.20250528",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": "./dest/index.js",
|
|
@@ -66,30 +66,32 @@
|
|
|
66
66
|
]
|
|
67
67
|
},
|
|
68
68
|
"dependencies": {
|
|
69
|
-
"@aztec/bb.js": "0.87.
|
|
70
|
-
"@aztec/constants": "0.87.
|
|
71
|
-
"@aztec/foundation": "0.87.
|
|
72
|
-
"@aztec/noir-noirc_abi": "0.87.
|
|
73
|
-
"@aztec/noir-protocol-circuits-types": "0.87.
|
|
74
|
-
"@aztec/noir-types": "0.87.
|
|
75
|
-
"@aztec/simulator": "0.87.
|
|
76
|
-
"@aztec/stdlib": "0.87.
|
|
77
|
-
"@aztec/telemetry-client": "0.87.
|
|
78
|
-
"@aztec/world-state": "0.87.
|
|
69
|
+
"@aztec/bb.js": "0.87.3-nightly.20250528",
|
|
70
|
+
"@aztec/constants": "0.87.3-nightly.20250528",
|
|
71
|
+
"@aztec/foundation": "0.87.3-nightly.20250528",
|
|
72
|
+
"@aztec/noir-noirc_abi": "0.87.3-nightly.20250528",
|
|
73
|
+
"@aztec/noir-protocol-circuits-types": "0.87.3-nightly.20250528",
|
|
74
|
+
"@aztec/noir-types": "0.87.3-nightly.20250528",
|
|
75
|
+
"@aztec/simulator": "0.87.3-nightly.20250528",
|
|
76
|
+
"@aztec/stdlib": "0.87.3-nightly.20250528",
|
|
77
|
+
"@aztec/telemetry-client": "0.87.3-nightly.20250528",
|
|
78
|
+
"@aztec/world-state": "0.87.3-nightly.20250528",
|
|
79
79
|
"commander": "^12.1.0",
|
|
80
80
|
"pako": "^2.1.0",
|
|
81
|
+
"pidusage": "^4.0.1",
|
|
81
82
|
"source-map-support": "^0.5.21",
|
|
82
83
|
"tslib": "^2.4.0"
|
|
83
84
|
},
|
|
84
85
|
"devDependencies": {
|
|
85
|
-
"@aztec/ethereum": "0.87.
|
|
86
|
-
"@aztec/kv-store": "0.87.
|
|
87
|
-
"@aztec/noir-contracts.js": "0.87.
|
|
88
|
-
"@aztec/noir-test-contracts.js": "0.87.
|
|
89
|
-
"@aztec/protocol-contracts": "0.87.
|
|
86
|
+
"@aztec/ethereum": "0.87.3-nightly.20250528",
|
|
87
|
+
"@aztec/kv-store": "0.87.3-nightly.20250528",
|
|
88
|
+
"@aztec/noir-contracts.js": "0.87.3-nightly.20250528",
|
|
89
|
+
"@aztec/noir-test-contracts.js": "0.87.3-nightly.20250528",
|
|
90
|
+
"@aztec/protocol-contracts": "0.87.3-nightly.20250528",
|
|
90
91
|
"@jest/globals": "^29.5.0",
|
|
91
92
|
"@types/jest": "^29.5.0",
|
|
92
93
|
"@types/node": "^22.15.17",
|
|
94
|
+
"@types/pidusage": "^2.0.5",
|
|
93
95
|
"@types/source-map-support": "^0.5.10",
|
|
94
96
|
"jest": "^29.5.0",
|
|
95
97
|
"jest-mock-extended": "^3.0.3",
|
|
@@ -7,7 +7,6 @@ import { type AvmCircuitInputs, AvmCircuitPublicInputs } from '@aztec/stdlib/avm
|
|
|
7
7
|
import { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
8
8
|
import type { MerkleTreeWriteOperations } from '@aztec/stdlib/interfaces/server';
|
|
9
9
|
import type { GlobalVariables } from '@aztec/stdlib/tx';
|
|
10
|
-
import { VerificationKeyData } from '@aztec/stdlib/vks';
|
|
11
10
|
import { NativeWorldStateService } from '@aztec/world-state';
|
|
12
11
|
|
|
13
12
|
import fs from 'node:fs/promises';
|
|
@@ -18,12 +17,10 @@ import {
|
|
|
18
17
|
type BBResult,
|
|
19
18
|
type BBSuccess,
|
|
20
19
|
BB_RESULT,
|
|
20
|
+
VK_FILENAME,
|
|
21
21
|
generateAvmProof,
|
|
22
|
-
generateAvmProofV2,
|
|
23
22
|
verifyAvmProof,
|
|
24
|
-
verifyAvmProofV2,
|
|
25
23
|
} from '../bb/execute.js';
|
|
26
|
-
import { extractAvmVkData } from '../verification_key/verification_key_data.js';
|
|
27
24
|
|
|
28
25
|
const BB_PATH = path.resolve('../../barretenberg/cpp/build/bin/bb');
|
|
29
26
|
|
|
@@ -31,20 +28,19 @@ export class AvmProvingTester extends PublicTxSimulationTester {
|
|
|
31
28
|
constructor(
|
|
32
29
|
private bbWorkingDirectory: string,
|
|
33
30
|
private checkCircuitOnly: boolean,
|
|
34
|
-
merkleTree: MerkleTreeWriteOperations,
|
|
35
31
|
contractDataSource: SimpleContractDataSource,
|
|
32
|
+
merkleTrees: MerkleTreeWriteOperations,
|
|
36
33
|
globals?: GlobalVariables,
|
|
37
34
|
) {
|
|
38
|
-
super(
|
|
35
|
+
super(merkleTrees, contractDataSource, globals);
|
|
39
36
|
}
|
|
40
37
|
|
|
41
|
-
// overriding parent class' create is a pain, so we use a different nam
|
|
42
38
|
static async new(checkCircuitOnly: boolean = false, globals?: GlobalVariables) {
|
|
43
39
|
const bbWorkingDirectory = await fs.mkdtemp(path.join(tmpdir(), 'bb-'));
|
|
44
40
|
|
|
45
41
|
const contractDataSource = new SimpleContractDataSource();
|
|
46
42
|
const merkleTrees = await (await NativeWorldStateService.tmp()).fork();
|
|
47
|
-
return new AvmProvingTester(bbWorkingDirectory, checkCircuitOnly,
|
|
43
|
+
return new AvmProvingTester(bbWorkingDirectory, checkCircuitOnly, contractDataSource, merkleTrees, globals);
|
|
48
44
|
}
|
|
49
45
|
|
|
50
46
|
async prove(avmCircuitInputs: AvmCircuitInputs): Promise<BBResult> {
|
|
@@ -59,95 +55,36 @@ export class AvmProvingTester extends PublicTxSimulationTester {
|
|
|
59
55
|
if (proofRes.status === BB_RESULT.FAILURE) {
|
|
60
56
|
this.logger.error(`Proof generation failed: ${proofRes.reason}`);
|
|
61
57
|
}
|
|
62
|
-
|
|
58
|
+
expect(proofRes.status).toEqual(BB_RESULT.SUCCESS);
|
|
59
|
+
return proofRes as BBSuccess;
|
|
63
60
|
}
|
|
64
61
|
|
|
65
|
-
async verify(proofRes: BBSuccess): Promise<BBResult> {
|
|
62
|
+
async verify(proofRes: BBSuccess, publicInputs: AvmCircuitPublicInputs): Promise<BBResult> {
|
|
66
63
|
if (this.checkCircuitOnly) {
|
|
67
|
-
// Skip verification if we
|
|
68
|
-
// Check-circuit
|
|
64
|
+
// Skip verification if we are only checking the circuit.
|
|
65
|
+
// Check-circuit does not generate a proof to verify.
|
|
69
66
|
return proofRes;
|
|
70
67
|
}
|
|
71
|
-
// Then we test VK extraction and serialization.
|
|
72
|
-
const succeededRes = proofRes as BBSuccess;
|
|
73
|
-
const vkData = await extractAvmVkData(succeededRes.vkPath!);
|
|
74
|
-
VerificationKeyData.fromBuffer(vkData.toBuffer());
|
|
75
|
-
|
|
76
|
-
// Then we verify.
|
|
77
|
-
const rawVkPath = path.join(succeededRes.vkPath!, 'vk');
|
|
78
|
-
return await verifyAvmProof(BB_PATH, succeededRes.proofPath!, rawVkPath, this.logger);
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
public async simProveVerify(
|
|
82
|
-
sender: AztecAddress,
|
|
83
|
-
setupCalls: TestEnqueuedCall[],
|
|
84
|
-
appCalls: TestEnqueuedCall[],
|
|
85
|
-
teardownCall: TestEnqueuedCall | undefined,
|
|
86
|
-
expectRevert: boolean | undefined,
|
|
87
|
-
feePayer = sender,
|
|
88
|
-
) {
|
|
89
|
-
const simRes = await this.simulateTx(sender, setupCalls, appCalls, teardownCall, feePayer);
|
|
90
|
-
expect(simRes.revertCode.isOK()).toBe(expectRevert ? false : true);
|
|
91
|
-
const avmCircuitInputs = simRes.avmProvingRequest.inputs;
|
|
92
|
-
const provingRes = await this.prove(avmCircuitInputs);
|
|
93
|
-
expect(provingRes.status).toEqual(BB_RESULT.SUCCESS);
|
|
94
|
-
const verificationRes = await this.verify(provingRes as BBSuccess);
|
|
95
|
-
expect(verificationRes.status).toBe(BB_RESULT.SUCCESS);
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
public async simProveVerifyAppLogic(appCall: TestEnqueuedCall, expectRevert?: boolean) {
|
|
99
|
-
const simRes = await this.simulateTx(/*sender=*/ AztecAddress.fromNumber(42), /*setupCalls=*/ [], [appCall]);
|
|
100
|
-
expect(simRes.revertCode.isOK()).toBe(expectRevert ? false : true);
|
|
101
|
-
|
|
102
|
-
const avmCircuitInputs = simRes.avmProvingRequest.inputs;
|
|
103
|
-
const provingRes = await this.prove(avmCircuitInputs);
|
|
104
|
-
expect(provingRes.status).toEqual(BB_RESULT.SUCCESS);
|
|
105
|
-
|
|
106
|
-
const verificationRes = await this.verify(provingRes as BBSuccess);
|
|
107
|
-
expect(verificationRes.status).toBe(BB_RESULT.SUCCESS);
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
export class AvmProvingTesterV2 extends PublicTxSimulationTester {
|
|
112
|
-
constructor(
|
|
113
|
-
private bbWorkingDirectory: string,
|
|
114
|
-
contractDataSource: SimpleContractDataSource,
|
|
115
|
-
merkleTrees: MerkleTreeWriteOperations,
|
|
116
|
-
globals?: GlobalVariables,
|
|
117
|
-
) {
|
|
118
|
-
super(merkleTrees, contractDataSource, globals);
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
static async new(globals?: GlobalVariables) {
|
|
122
|
-
const bbWorkingDirectory = await fs.mkdtemp(path.join(tmpdir(), 'bb-'));
|
|
123
|
-
|
|
124
|
-
const contractDataSource = new SimpleContractDataSource();
|
|
125
|
-
const merkleTrees = await (await NativeWorldStateService.tmp()).fork();
|
|
126
|
-
return new AvmProvingTesterV2(bbWorkingDirectory, contractDataSource, merkleTrees, globals);
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
async proveV2(avmCircuitInputs: AvmCircuitInputs): Promise<BBResult> {
|
|
130
|
-
// Then we prove.
|
|
131
|
-
const proofRes = await generateAvmProofV2(BB_PATH, this.bbWorkingDirectory, avmCircuitInputs, this.logger);
|
|
132
|
-
if (proofRes.status === BB_RESULT.FAILURE) {
|
|
133
|
-
this.logger.error(`Proof generation failed: ${proofRes.reason}`);
|
|
134
|
-
}
|
|
135
|
-
expect(proofRes.status).toEqual(BB_RESULT.SUCCESS);
|
|
136
|
-
return proofRes as BBSuccess;
|
|
137
|
-
}
|
|
138
68
|
|
|
139
|
-
|
|
140
|
-
return await verifyAvmProofV2(
|
|
69
|
+
return await verifyAvmProof(
|
|
141
70
|
BB_PATH,
|
|
142
71
|
this.bbWorkingDirectory,
|
|
143
72
|
proofRes.proofPath!,
|
|
144
73
|
publicInputs,
|
|
145
|
-
proofRes.
|
|
74
|
+
path.join(proofRes.vkDirectoryPath!, VK_FILENAME),
|
|
146
75
|
this.logger,
|
|
147
76
|
);
|
|
148
77
|
}
|
|
149
78
|
|
|
150
|
-
public async
|
|
79
|
+
public async proveVerify(avmCircuitInputs: AvmCircuitInputs) {
|
|
80
|
+
const provingRes = await this.prove(avmCircuitInputs);
|
|
81
|
+
expect(provingRes.status).toEqual(BB_RESULT.SUCCESS);
|
|
82
|
+
|
|
83
|
+
const verificationRes = await this.verify(provingRes as BBSuccess, avmCircuitInputs.publicInputs);
|
|
84
|
+
expect(verificationRes.status).toBe(BB_RESULT.SUCCESS);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
public async simProveVerify(
|
|
151
88
|
sender: AztecAddress,
|
|
152
89
|
setupCalls: TestEnqueuedCall[],
|
|
153
90
|
appCalls: TestEnqueuedCall[],
|
|
@@ -159,10 +96,16 @@ export class AvmProvingTesterV2 extends PublicTxSimulationTester {
|
|
|
159
96
|
expect(simRes.revertCode.isOK()).toBe(expectRevert ? false : true);
|
|
160
97
|
|
|
161
98
|
const avmCircuitInputs = simRes.avmProvingRequest.inputs;
|
|
162
|
-
|
|
163
|
-
|
|
99
|
+
await this.proveVerify(avmCircuitInputs);
|
|
100
|
+
}
|
|
164
101
|
|
|
165
|
-
|
|
166
|
-
|
|
102
|
+
public async simProveVerifyAppLogic(appCall: TestEnqueuedCall, expectRevert?: boolean) {
|
|
103
|
+
await this.simProveVerify(
|
|
104
|
+
/*sender=*/ AztecAddress.fromNumber(42),
|
|
105
|
+
/*setupCalls=*/ [],
|
|
106
|
+
[appCall],
|
|
107
|
+
undefined,
|
|
108
|
+
expectRevert,
|
|
109
|
+
);
|
|
167
110
|
}
|
|
168
111
|
}
|
package/src/bb/execute.ts
CHANGED
|
@@ -6,6 +6,7 @@ import type { AvmCircuitInputs, AvmCircuitPublicInputs } from '@aztec/stdlib/avm
|
|
|
6
6
|
import * as proc from 'child_process';
|
|
7
7
|
import { promises as fs } from 'fs';
|
|
8
8
|
import { basename, dirname, join } from 'path';
|
|
9
|
+
import pidusage from 'pidusage';
|
|
9
10
|
|
|
10
11
|
import type { UltraHonkFlavor } from '../honk.js';
|
|
11
12
|
|
|
@@ -32,7 +33,7 @@ export type BBSuccess = {
|
|
|
32
33
|
/** Full path of the public key. */
|
|
33
34
|
pkPath?: string;
|
|
34
35
|
/** Base directory for the VKs (raw, fields). */
|
|
35
|
-
|
|
36
|
+
vkDirectoryPath?: string;
|
|
36
37
|
/** Full path of the proof. */
|
|
37
38
|
proofPath?: string;
|
|
38
39
|
/** Full path of the contract. */
|
|
@@ -49,8 +50,6 @@ export type BBFailure = {
|
|
|
49
50
|
|
|
50
51
|
export type BBResult = BBSuccess | BBFailure;
|
|
51
52
|
|
|
52
|
-
export type VerificationFunction = typeof verifyProof | typeof verifyAvmProof;
|
|
53
|
-
|
|
54
53
|
type BBExecResult = {
|
|
55
54
|
status: BB_RESULT;
|
|
56
55
|
exitCode: number;
|
|
@@ -97,11 +96,23 @@ export function executeBB(
|
|
|
97
96
|
|
|
98
97
|
bb.stdout.on('data', data => {
|
|
99
98
|
const message = data.toString('utf-8').replace(/\n$/, '');
|
|
100
|
-
|
|
99
|
+
pidusage(bb.pid!, (err, stats) => {
|
|
100
|
+
if (err) {
|
|
101
|
+
logger(message);
|
|
102
|
+
} else {
|
|
103
|
+
logger(`${message} (mem: ${(stats.memory / 1024 / 1024).toFixed(2)}MiB)`);
|
|
104
|
+
}
|
|
105
|
+
});
|
|
101
106
|
});
|
|
102
107
|
bb.stderr.on('data', data => {
|
|
103
108
|
const message = data.toString('utf-8').replace(/\n$/, '');
|
|
104
|
-
|
|
109
|
+
pidusage(bb.pid!, (err, stats) => {
|
|
110
|
+
if (err) {
|
|
111
|
+
logger(message);
|
|
112
|
+
} else {
|
|
113
|
+
logger(`${message} (mem: ${(stats.memory / 1024 / 1024).toFixed(2)}MiB)`);
|
|
114
|
+
}
|
|
115
|
+
});
|
|
105
116
|
});
|
|
106
117
|
bb.on('close', (exitCode: number, signal?: string) => {
|
|
107
118
|
if (timeoutId) {
|
|
@@ -162,7 +173,7 @@ export async function executeBbClientIvcProof(
|
|
|
162
173
|
durationMs,
|
|
163
174
|
proofPath: `${outputPath}`,
|
|
164
175
|
pkPath: undefined,
|
|
165
|
-
|
|
176
|
+
vkDirectoryPath: `${outputPath}`,
|
|
166
177
|
};
|
|
167
178
|
}
|
|
168
179
|
// Not a great error message here but it is difficult to decipher what comes from bb
|
|
@@ -266,7 +277,7 @@ export async function generateProof(
|
|
|
266
277
|
durationMs: duration,
|
|
267
278
|
proofPath: `${outputPath}`,
|
|
268
279
|
pkPath: undefined,
|
|
269
|
-
|
|
280
|
+
vkDirectoryPath: `${outputPath}`,
|
|
270
281
|
};
|
|
271
282
|
}
|
|
272
283
|
// Not a great error message here but it is difficult to decipher what comes from bb
|
|
@@ -334,7 +345,7 @@ export async function generateTubeProof(
|
|
|
334
345
|
durationMs,
|
|
335
346
|
proofPath: outputPath,
|
|
336
347
|
pkPath: undefined,
|
|
337
|
-
|
|
348
|
+
vkDirectoryPath: outputPath,
|
|
338
349
|
};
|
|
339
350
|
}
|
|
340
351
|
// Not a great error message here but it is difficult to decipher what comes from bb
|
|
@@ -354,14 +365,16 @@ export async function generateTubeProof(
|
|
|
354
365
|
* @param pathToBB - The full path to the bb binary
|
|
355
366
|
* @param workingDirectory - A working directory for use by bb
|
|
356
367
|
* @param input - The inputs for the public function to be proven
|
|
357
|
-
* @param
|
|
368
|
+
* @param logger - A logging function
|
|
369
|
+
* @param checkCircuitOnly - A boolean to toggle a "check-circuit only" operation instead of proving.
|
|
358
370
|
* @returns An object containing a result indication, the location of the proof and the duration taken
|
|
359
371
|
*/
|
|
360
|
-
export async function
|
|
372
|
+
export async function generateAvmProof(
|
|
361
373
|
pathToBB: string,
|
|
362
374
|
workingDirectory: string,
|
|
363
375
|
input: AvmCircuitInputs,
|
|
364
376
|
logger: Logger,
|
|
377
|
+
checkCircuitOnly: boolean = false,
|
|
365
378
|
): Promise<BBFailure | BBSuccess> {
|
|
366
379
|
// Check that the working directory exists
|
|
367
380
|
try {
|
|
@@ -401,99 +414,12 @@ export async function generateAvmProofV2(
|
|
|
401
414
|
args.push(loggingArg);
|
|
402
415
|
}
|
|
403
416
|
const timer = new Timer();
|
|
404
|
-
const logFunction = (message: string) => {
|
|
405
|
-
logger.verbose(`AvmCircuit (prove) BB out - ${message}`);
|
|
406
|
-
};
|
|
407
|
-
const result = await executeBB(pathToBB, 'avm2_prove', args, logFunction);
|
|
408
|
-
const duration = timer.ms();
|
|
409
|
-
|
|
410
|
-
if (result.status == BB_RESULT.SUCCESS) {
|
|
411
|
-
return {
|
|
412
|
-
status: BB_RESULT.SUCCESS,
|
|
413
|
-
durationMs: duration,
|
|
414
|
-
proofPath: join(outputPath, PROOF_FILENAME),
|
|
415
|
-
pkPath: undefined,
|
|
416
|
-
vkPath: join(outputPath, VK_FILENAME),
|
|
417
|
-
};
|
|
418
|
-
}
|
|
419
|
-
// Not a great error message here but it is difficult to decipher what comes from bb
|
|
420
|
-
return {
|
|
421
|
-
status: BB_RESULT.FAILURE,
|
|
422
|
-
reason: `Failed to generate proof. Exit code ${result.exitCode}. Signal ${result.signal}.`,
|
|
423
|
-
retry: !!result.signal,
|
|
424
|
-
};
|
|
425
|
-
} catch (error) {
|
|
426
|
-
return { status: BB_RESULT.FAILURE, reason: `${error}` };
|
|
427
|
-
}
|
|
428
|
-
}
|
|
429
|
-
|
|
430
|
-
/**
|
|
431
|
-
* Used for generating AVM proofs (or doing check-circuit).
|
|
432
|
-
* It is assumed that the working directory is a temporary and/or random directory used solely for generating this proof.
|
|
433
|
-
* @param pathToBB - The full path to the bb binary
|
|
434
|
-
* @param workingDirectory - A working directory for use by bb
|
|
435
|
-
* @param bytecode - The AVM bytecode for the public function to be proven (expected to be decompressed)
|
|
436
|
-
* @param log - A logging function
|
|
437
|
-
* @returns An object containing a result indication, the location of the proof and the duration taken
|
|
438
|
-
*/
|
|
439
|
-
export async function generateAvmProof(
|
|
440
|
-
pathToBB: string,
|
|
441
|
-
workingDirectory: string,
|
|
442
|
-
_input: AvmCircuitInputs,
|
|
443
|
-
logger: Logger,
|
|
444
|
-
checkCircuitOnly: boolean = false,
|
|
445
|
-
): Promise<BBFailure | BBSuccess> {
|
|
446
|
-
// Check that the working directory exists
|
|
447
|
-
try {
|
|
448
|
-
await fs.access(workingDirectory);
|
|
449
|
-
} catch {
|
|
450
|
-
return { status: BB_RESULT.FAILURE, reason: `Working directory ${workingDirectory} does not exist` };
|
|
451
|
-
}
|
|
452
417
|
|
|
453
|
-
|
|
454
|
-
const publicInputsPath = join(workingDirectory, AVM_PUBLIC_INPUTS_FILENAME);
|
|
455
|
-
|
|
456
|
-
// The proof is written to e.g. /workingDirectory/proof
|
|
457
|
-
const outputPath = workingDirectory;
|
|
458
|
-
|
|
459
|
-
const filePresent = async (file: string) =>
|
|
460
|
-
await fs
|
|
461
|
-
.access(file, fs.constants.R_OK)
|
|
462
|
-
.then(_ => true)
|
|
463
|
-
.catch(_ => false);
|
|
464
|
-
|
|
465
|
-
const binaryPresent = await filePresent(pathToBB);
|
|
466
|
-
if (!binaryPresent) {
|
|
467
|
-
return { status: BB_RESULT.FAILURE, reason: `Failed to find bb binary at ${pathToBB}` };
|
|
468
|
-
}
|
|
469
|
-
|
|
470
|
-
try {
|
|
471
|
-
// Write the inputs to the working directory.
|
|
472
|
-
|
|
473
|
-
// WARNING: Not writing the inputs since VM1 is disabled!
|
|
474
|
-
// await fs.writeFile(publicInputsPath, input.publicInputs.toBuffer());
|
|
475
|
-
// if (!(await filePresent(publicInputsPath))) {
|
|
476
|
-
// return { status: BB_RESULT.FAILURE, reason: `Could not write publicInputs at ${publicInputsPath}` };
|
|
477
|
-
// }
|
|
478
|
-
|
|
479
|
-
// await fs.writeFile(avmHintsPath, input.avmHints.toBuffer());
|
|
480
|
-
// if (!(await filePresent(avmHintsPath))) {
|
|
481
|
-
// return { status: BB_RESULT.FAILURE, reason: `Could not write avmHints at ${avmHintsPath}` };
|
|
482
|
-
// }
|
|
483
|
-
|
|
484
|
-
const args = ['--avm-public-inputs', publicInputsPath, '-o', outputPath];
|
|
485
|
-
const loggingArg =
|
|
486
|
-
logger.level === 'debug' || logger.level === 'trace' ? '-d' : logger.level === 'verbose' ? '-v' : '';
|
|
487
|
-
if (loggingArg !== '') {
|
|
488
|
-
args.push(loggingArg);
|
|
489
|
-
}
|
|
490
|
-
|
|
491
|
-
const timer = new Timer();
|
|
492
|
-
const cmd = checkCircuitOnly ? 'check_circuit' : 'prove';
|
|
418
|
+
const cmd = checkCircuitOnly ? 'avm_check_circuit' : 'avm_prove';
|
|
493
419
|
const logFunction = (message: string) => {
|
|
494
420
|
logger.verbose(`AvmCircuit (${cmd}) BB out - ${message}`);
|
|
495
421
|
};
|
|
496
|
-
const result = await executeBB(pathToBB,
|
|
422
|
+
const result = await executeBB(pathToBB, cmd, args, logFunction);
|
|
497
423
|
const duration = timer.ms();
|
|
498
424
|
|
|
499
425
|
if (result.status == BB_RESULT.SUCCESS) {
|
|
@@ -502,7 +428,7 @@ export async function generateAvmProof(
|
|
|
502
428
|
durationMs: duration,
|
|
503
429
|
proofPath: join(outputPath, PROOF_FILENAME),
|
|
504
430
|
pkPath: undefined,
|
|
505
|
-
|
|
431
|
+
vkDirectoryPath: outputPath,
|
|
506
432
|
};
|
|
507
433
|
}
|
|
508
434
|
// Not a great error message here but it is difficult to decipher what comes from bb
|
|
@@ -541,24 +467,7 @@ export async function verifyProof(
|
|
|
541
467
|
);
|
|
542
468
|
}
|
|
543
469
|
|
|
544
|
-
/**
|
|
545
|
-
* Used for verifying proofs of the AVM
|
|
546
|
-
* @param pathToBB - The full path to the bb binary
|
|
547
|
-
* @param proofFullPath - The full path to the proof to be verified
|
|
548
|
-
* @param verificationKeyPath - The full path to the circuit verification key
|
|
549
|
-
* @param log - A logging function
|
|
550
|
-
* @returns An object containing a result indication and duration taken
|
|
551
|
-
*/
|
|
552
470
|
export async function verifyAvmProof(
|
|
553
|
-
pathToBB: string,
|
|
554
|
-
proofFullPath: string,
|
|
555
|
-
verificationKeyPath: string,
|
|
556
|
-
logger: Logger,
|
|
557
|
-
): Promise<BBFailure | BBSuccess> {
|
|
558
|
-
return await verifyProofInternal(pathToBB, proofFullPath, verificationKeyPath, 'avm_verify', logger);
|
|
559
|
-
}
|
|
560
|
-
|
|
561
|
-
export async function verifyAvmProofV2(
|
|
562
471
|
pathToBB: string,
|
|
563
472
|
workingDirectory: string,
|
|
564
473
|
proofFullPath: string,
|
|
@@ -580,7 +489,7 @@ export async function verifyAvmProofV2(
|
|
|
580
489
|
return { status: BB_RESULT.FAILURE, reason: `Could not write avm inputs to ${avmInputsPath}` };
|
|
581
490
|
}
|
|
582
491
|
|
|
583
|
-
return await verifyProofInternal(pathToBB, proofFullPath, verificationKeyPath, '
|
|
492
|
+
return await verifyProofInternal(pathToBB, proofFullPath, verificationKeyPath, 'avm_verify', logger, [
|
|
584
493
|
'--avm-public-inputs',
|
|
585
494
|
avmInputsPath,
|
|
586
495
|
]);
|
|
@@ -641,7 +550,7 @@ async function verifyProofInternal(
|
|
|
641
550
|
pathToBB: string,
|
|
642
551
|
proofFullPath: string,
|
|
643
552
|
verificationKeyPath: string,
|
|
644
|
-
command: 'verify' | 'avm_verify'
|
|
553
|
+
command: 'verify' | 'avm_verify',
|
|
645
554
|
logger: Logger,
|
|
646
555
|
extraArgs: string[] = [],
|
|
647
556
|
): Promise<BBFailure | BBSuccess> {
|
|
@@ -657,24 +566,27 @@ async function verifyProofInternal(
|
|
|
657
566
|
logger.verbose(`bb-prover (verify) BB out - ${message}`);
|
|
658
567
|
};
|
|
659
568
|
|
|
660
|
-
// take proofFullPath and remove the suffix past the / to get the directory
|
|
661
|
-
const proofDir = proofFullPath.substring(0, proofFullPath.lastIndexOf('/'));
|
|
662
|
-
const publicInputsFullPath = join(proofDir, '/public_inputs');
|
|
663
|
-
|
|
664
|
-
logger.debug(`public inputs path: ${publicInputsFullPath}`);
|
|
665
569
|
try {
|
|
666
570
|
let args;
|
|
667
|
-
|
|
571
|
+
|
|
668
572
|
if (command == 'verify') {
|
|
573
|
+
// Specify the public inputs path in the case of UH verification.
|
|
574
|
+
// Take proofFullPath and remove the suffix past the / to get the directory.
|
|
575
|
+
const proofDir = proofFullPath.substring(0, proofFullPath.lastIndexOf('/'));
|
|
576
|
+
const publicInputsFullPath = join(proofDir, '/public_inputs');
|
|
577
|
+
logger.debug(`public inputs path: ${publicInputsFullPath}`);
|
|
578
|
+
|
|
669
579
|
args = ['-p', proofFullPath, '-k', verificationKeyPath, '-i', publicInputsFullPath, ...extraArgs];
|
|
670
580
|
} else {
|
|
671
581
|
args = ['-p', proofFullPath, '-k', verificationKeyPath, ...extraArgs];
|
|
672
582
|
}
|
|
583
|
+
|
|
673
584
|
const loggingArg =
|
|
674
585
|
logger.level === 'debug' || logger.level === 'trace' ? '-d' : logger.level === 'verbose' ? '-v' : '';
|
|
675
586
|
if (loggingArg !== '') {
|
|
676
587
|
args.push(loggingArg);
|
|
677
588
|
}
|
|
589
|
+
|
|
678
590
|
const timer = new Timer();
|
|
679
591
|
const result = await executeBB(pathToBB, command, args, logFunction);
|
|
680
592
|
const duration = timer.ms();
|