@aztec/bb-prover 1.2.1 → 2.0.0-nightly.20250814
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 +7 -7
- package/dest/avm_proving_tests/avm_proving_tester.d.ts.map +1 -1
- package/dest/avm_proving_tests/avm_proving_tester.js +99 -13
- package/dest/prover/proof_utils.d.ts.map +1 -1
- package/dest/prover/proof_utils.js +2 -2
- package/dest/prover/server/bb_prover.d.ts.map +1 -1
- package/dest/prover/server/bb_prover.js +3 -2
- package/dest/stats.js +5 -5
- package/dest/verifier/bb_verifier.d.ts.map +1 -1
- package/dest/verifier/bb_verifier.js +5 -12
- package/package.json +16 -16
- package/src/avm_proving_tests/avm_proving_tester.ts +134 -10
- package/src/prover/proof_utils.ts +4 -1
- package/src/prover/server/bb_prover.ts +4 -1
- package/src/stats.ts +5 -5
- package/src/verifier/bb_verifier.ts +6 -15
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { PublicTxSimulationTester, SimpleContractDataSource, type TestEnqueuedCall, type TestPrivateInsertions } from '@aztec/simulator/public/fixtures';
|
|
1
|
+
import { PublicTxSimulationTester, SimpleContractDataSource, type TestEnqueuedCall, type TestExecutorMetrics, type TestPrivateInsertions } from '@aztec/simulator/public/fixtures';
|
|
2
2
|
import { type AvmCircuitInputs, AvmCircuitPublicInputs } from '@aztec/stdlib/avm';
|
|
3
3
|
import { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
4
4
|
import type { MerkleTreeWriteOperations } from '@aztec/stdlib/interfaces/server';
|
|
@@ -7,12 +7,12 @@ import { type BBResult, type BBSuccess } from '../bb/execute.js';
|
|
|
7
7
|
export declare class AvmProvingTester extends PublicTxSimulationTester {
|
|
8
8
|
private bbWorkingDirectory;
|
|
9
9
|
private checkCircuitOnly;
|
|
10
|
-
constructor(bbWorkingDirectory: string, checkCircuitOnly: boolean, contractDataSource: SimpleContractDataSource, merkleTrees: MerkleTreeWriteOperations, globals?: GlobalVariables);
|
|
11
|
-
static new(checkCircuitOnly?: boolean, globals?: GlobalVariables): Promise<AvmProvingTester>;
|
|
12
|
-
prove(avmCircuitInputs: AvmCircuitInputs): Promise<BBResult>;
|
|
10
|
+
constructor(bbWorkingDirectory: string, checkCircuitOnly: boolean, contractDataSource: SimpleContractDataSource, merkleTrees: MerkleTreeWriteOperations, globals?: GlobalVariables, metrics?: TestExecutorMetrics);
|
|
11
|
+
static new(checkCircuitOnly?: boolean, globals?: GlobalVariables, metrics?: TestExecutorMetrics): Promise<AvmProvingTester>;
|
|
12
|
+
prove(avmCircuitInputs: AvmCircuitInputs, txLabel?: string): Promise<BBResult>;
|
|
13
13
|
verify(proofRes: BBSuccess, publicInputs: AvmCircuitPublicInputs): Promise<BBResult>;
|
|
14
|
-
proveVerify(avmCircuitInputs: AvmCircuitInputs): Promise<void>;
|
|
15
|
-
simProveVerify(sender: AztecAddress, setupCalls: TestEnqueuedCall[], appCalls: TestEnqueuedCall[], teardownCall: TestEnqueuedCall | undefined, expectRevert: boolean | undefined, feePayer?: AztecAddress, privateInsertions?: TestPrivateInsertions): Promise<void>;
|
|
16
|
-
simProveVerifyAppLogic(appCall: TestEnqueuedCall, expectRevert?: boolean): Promise<void>;
|
|
14
|
+
proveVerify(avmCircuitInputs: AvmCircuitInputs, txLabel?: string): Promise<void>;
|
|
15
|
+
simProveVerify(sender: AztecAddress, setupCalls: TestEnqueuedCall[], appCalls: TestEnqueuedCall[], teardownCall: TestEnqueuedCall | undefined, expectRevert: boolean | undefined, feePayer?: AztecAddress, privateInsertions?: TestPrivateInsertions, txLabel?: string): Promise<void>;
|
|
16
|
+
simProveVerifyAppLogic(appCall: TestEnqueuedCall, expectRevert?: boolean, txLabel?: string): Promise<void>;
|
|
17
17
|
}
|
|
18
18
|
//# sourceMappingURL=avm_proving_tester.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"avm_proving_tester.d.ts","sourceRoot":"","sources":["../../src/avm_proving_tests/avm_proving_tester.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"avm_proving_tester.d.ts","sourceRoot":"","sources":["../../src/avm_proving_tests/avm_proving_tester.ts"],"names":[],"mappings":"AACA,OAAO,EACL,wBAAwB,EACxB,wBAAwB,EACxB,KAAK,gBAAgB,EACrB,KAAK,mBAAmB,EACxB,KAAK,qBAAqB,EAC3B,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EAAE,KAAK,gBAAgB,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAClF,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC3D,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,iCAAiC,CAAC;AACjF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAOxD,OAAO,EACL,KAAK,QAAQ,EACb,KAAK,SAAS,EAKf,MAAM,kBAAkB,CAAC;AA+D1B,qBAAa,gBAAiB,SAAQ,wBAAwB;IAE1D,OAAO,CAAC,kBAAkB;IAC1B,OAAO,CAAC,gBAAgB;gBADhB,kBAAkB,EAAE,MAAM,EAC1B,gBAAgB,EAAE,OAAO,EACjC,kBAAkB,EAAE,wBAAwB,EAC5C,WAAW,EAAE,yBAAyB,EACtC,OAAO,CAAC,EAAE,eAAe,EACzB,OAAO,CAAC,EAAE,mBAAmB;WAKlB,GAAG,CAAC,gBAAgB,GAAE,OAAe,EAAE,OAAO,CAAC,EAAE,eAAe,EAAE,OAAO,CAAC,EAAE,mBAAmB;IAetG,KAAK,CAAC,gBAAgB,EAAE,gBAAgB,EAAE,OAAO,GAAE,MAAsB,GAAG,OAAO,CAAC,QAAQ,CAAC;IAuD7F,MAAM,CAAC,QAAQ,EAAE,SAAS,EAAE,YAAY,EAAE,sBAAsB,GAAG,OAAO,CAAC,QAAQ,CAAC;IAiB7E,WAAW,CAAC,gBAAgB,EAAE,gBAAgB,EAAE,OAAO,GAAE,MAAsB;IAQ/E,cAAc,CACzB,MAAM,EAAE,YAAY,EACpB,UAAU,EAAE,gBAAgB,EAAE,EAC9B,QAAQ,EAAE,gBAAgB,EAAE,EAC5B,YAAY,EAAE,gBAAgB,GAAG,SAAS,EAC1C,YAAY,EAAE,OAAO,GAAG,SAAS,EACjC,QAAQ,eAAS,EACjB,iBAAiB,CAAC,EAAE,qBAAqB,EACzC,OAAO,GAAE,MAAsB;IAiBpB,sBAAsB,CACjC,OAAO,EAAE,gBAAgB,EACzB,YAAY,CAAC,EAAE,OAAO,EACtB,OAAO,GAAE,MAAsB;CAalC"}
|
|
@@ -6,25 +6,111 @@ import { tmpdir } from 'node:os';
|
|
|
6
6
|
import path from 'path';
|
|
7
7
|
import { BB_RESULT, VK_FILENAME, generateAvmProof, verifyAvmProof } from '../bb/execute.js';
|
|
8
8
|
const BB_PATH = path.resolve('../../barretenberg/cpp/build/bin/bb');
|
|
9
|
+
// An InterceptingLogger that records all log messages and forwards them to a wrapped logger.
|
|
10
|
+
class InterceptingLogger {
|
|
11
|
+
logs = [];
|
|
12
|
+
level;
|
|
13
|
+
module;
|
|
14
|
+
logger;
|
|
15
|
+
constructor(logger){
|
|
16
|
+
this.logger = logger;
|
|
17
|
+
this.level = logger.level;
|
|
18
|
+
this.module = logger.module;
|
|
19
|
+
}
|
|
20
|
+
isLevelEnabled(level) {
|
|
21
|
+
return this.logger.isLevelEnabled(level);
|
|
22
|
+
}
|
|
23
|
+
createChild(_childModule) {
|
|
24
|
+
throw new Error('Not implemented');
|
|
25
|
+
}
|
|
26
|
+
intercept(level, msg, ...args) {
|
|
27
|
+
this.logs.push(...msg.split('\n'));
|
|
28
|
+
// Forward to the wrapped logger
|
|
29
|
+
this.logger[level](msg, ...args);
|
|
30
|
+
}
|
|
31
|
+
// Log methods for each level
|
|
32
|
+
silent(msg, ...args) {
|
|
33
|
+
this.intercept('silent', msg, ...args);
|
|
34
|
+
}
|
|
35
|
+
fatal(msg, ...args) {
|
|
36
|
+
this.intercept('fatal', msg, ...args);
|
|
37
|
+
}
|
|
38
|
+
warn(msg, ...args) {
|
|
39
|
+
this.intercept('warn', msg, ...args);
|
|
40
|
+
}
|
|
41
|
+
info(msg, ...args) {
|
|
42
|
+
this.intercept('info', msg, ...args);
|
|
43
|
+
}
|
|
44
|
+
verbose(msg, ...args) {
|
|
45
|
+
this.intercept('verbose', msg, ...args);
|
|
46
|
+
}
|
|
47
|
+
debug(msg, ...args) {
|
|
48
|
+
this.intercept('debug', msg, ...args);
|
|
49
|
+
}
|
|
50
|
+
trace(msg, ...args) {
|
|
51
|
+
this.intercept('trace', msg, ...args);
|
|
52
|
+
}
|
|
53
|
+
// Error log function can be string or Error
|
|
54
|
+
error(err, ...args) {
|
|
55
|
+
const msg = typeof err === 'string' ? err : err.message;
|
|
56
|
+
this.logs.push(msg);
|
|
57
|
+
this.logger.error(msg, err, ...args);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
9
60
|
export class AvmProvingTester extends PublicTxSimulationTester {
|
|
10
61
|
bbWorkingDirectory;
|
|
11
62
|
checkCircuitOnly;
|
|
12
|
-
constructor(bbWorkingDirectory, checkCircuitOnly, contractDataSource, merkleTrees, globals){
|
|
13
|
-
super(merkleTrees, contractDataSource, globals), this.bbWorkingDirectory = bbWorkingDirectory, this.checkCircuitOnly = checkCircuitOnly;
|
|
63
|
+
constructor(bbWorkingDirectory, checkCircuitOnly, contractDataSource, merkleTrees, globals, metrics){
|
|
64
|
+
super(merkleTrees, contractDataSource, globals, metrics), this.bbWorkingDirectory = bbWorkingDirectory, this.checkCircuitOnly = checkCircuitOnly;
|
|
14
65
|
}
|
|
15
|
-
static async new(checkCircuitOnly = false, globals) {
|
|
66
|
+
static async new(checkCircuitOnly = false, globals, metrics) {
|
|
16
67
|
const bbWorkingDirectory = await fs.mkdtemp(path.join(tmpdir(), 'bb-'));
|
|
17
68
|
const contractDataSource = new SimpleContractDataSource();
|
|
18
69
|
const merkleTrees = await (await NativeWorldStateService.tmp()).fork();
|
|
19
|
-
return new AvmProvingTester(bbWorkingDirectory, checkCircuitOnly, contractDataSource, merkleTrees, globals);
|
|
70
|
+
return new AvmProvingTester(bbWorkingDirectory, checkCircuitOnly, contractDataSource, merkleTrees, globals, metrics);
|
|
20
71
|
}
|
|
21
|
-
async prove(avmCircuitInputs) {
|
|
72
|
+
async prove(avmCircuitInputs, txLabel = 'unlabeledTx') {
|
|
73
|
+
const interceptingLogger = new InterceptingLogger(this.logger);
|
|
22
74
|
// Then we prove.
|
|
23
|
-
const proofRes = await generateAvmProof(BB_PATH, this.bbWorkingDirectory, avmCircuitInputs,
|
|
75
|
+
const proofRes = await generateAvmProof(BB_PATH, this.bbWorkingDirectory, avmCircuitInputs, interceptingLogger, this.checkCircuitOnly);
|
|
24
76
|
if (proofRes.status === BB_RESULT.FAILURE) {
|
|
25
77
|
this.logger.error(`Proof generation failed: ${proofRes.reason}`);
|
|
26
78
|
}
|
|
27
79
|
expect(proofRes.status).toEqual(BB_RESULT.SUCCESS);
|
|
80
|
+
// Parse the logs into a structured format.
|
|
81
|
+
const logs = interceptingLogger.logs;
|
|
82
|
+
// const traceSizes: { name: string; size: number }[] = [];
|
|
83
|
+
// logs.forEach(log => {
|
|
84
|
+
// const match = log.match(/\b(\w+): (\d+) \(~2/);
|
|
85
|
+
// if (match) {
|
|
86
|
+
// traceSizes.push({
|
|
87
|
+
// name: match[1],
|
|
88
|
+
// size: parseInt(match[2]),
|
|
89
|
+
// });
|
|
90
|
+
// }
|
|
91
|
+
// });
|
|
92
|
+
const times = {};
|
|
93
|
+
logs.forEach((log)=>{
|
|
94
|
+
const match = log.match(/\b([\w/]+)_ms: (\d+)/);
|
|
95
|
+
if (match) {
|
|
96
|
+
times[match[1]] = parseInt(match[2]);
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
// Hack to make labels match.
|
|
100
|
+
const txLabelWithCount = `${txLabel}/${this.txCount - 1}`;
|
|
101
|
+
// I need to cast because TS doesnt realize metrics is protected not private.
|
|
102
|
+
this.metrics?.recordProverMetrics(txLabelWithCount, {
|
|
103
|
+
proverSimulationStepMs: times['simulation/all'],
|
|
104
|
+
proverProvingStepMs: times['proving/all'],
|
|
105
|
+
proverTraceGenerationStepMs: times['tracegen/all'],
|
|
106
|
+
traceGenerationInteractionsMs: times['tracegen/interactions'],
|
|
107
|
+
traceGenerationTracesMs: times['tracegen/traces'],
|
|
108
|
+
provingSumcheckMs: times['prove/sumcheck'],
|
|
109
|
+
provingPcsMs: times['prove/pcs_rounds'],
|
|
110
|
+
provingLogDerivativeInverseMs: times['prove/log_derivative_inverse_round'],
|
|
111
|
+
provingLogDerivativeInverseCommitmentsMs: times['prove/log_derivative_inverse_commitments_round'],
|
|
112
|
+
provingWireCommitmentsMs: times['prove/wire_commitments_round']
|
|
113
|
+
});
|
|
28
114
|
return proofRes;
|
|
29
115
|
}
|
|
30
116
|
async verify(proofRes, publicInputs) {
|
|
@@ -35,21 +121,21 @@ export class AvmProvingTester extends PublicTxSimulationTester {
|
|
|
35
121
|
}
|
|
36
122
|
return await verifyAvmProof(BB_PATH, this.bbWorkingDirectory, proofRes.proofPath, publicInputs, path.join(proofRes.vkDirectoryPath, VK_FILENAME), this.logger);
|
|
37
123
|
}
|
|
38
|
-
async proveVerify(avmCircuitInputs) {
|
|
39
|
-
const provingRes = await this.prove(avmCircuitInputs);
|
|
124
|
+
async proveVerify(avmCircuitInputs, txLabel = 'unlabeledTx') {
|
|
125
|
+
const provingRes = await this.prove(avmCircuitInputs, txLabel);
|
|
40
126
|
expect(provingRes.status).toEqual(BB_RESULT.SUCCESS);
|
|
41
127
|
const verificationRes = await this.verify(provingRes, avmCircuitInputs.publicInputs);
|
|
42
128
|
expect(verificationRes.status).toBe(BB_RESULT.SUCCESS);
|
|
43
129
|
}
|
|
44
|
-
async simProveVerify(sender, setupCalls, appCalls, teardownCall, expectRevert, feePayer = sender, privateInsertions) {
|
|
45
|
-
const simRes = await this.simulateTx(sender, setupCalls, appCalls, teardownCall, feePayer, privateInsertions);
|
|
130
|
+
async simProveVerify(sender, setupCalls, appCalls, teardownCall, expectRevert, feePayer = sender, privateInsertions, txLabel = 'unlabeledTx') {
|
|
131
|
+
const simRes = await this.simulateTx(sender, setupCalls, appCalls, teardownCall, feePayer, privateInsertions, txLabel);
|
|
46
132
|
expect(simRes.revertCode.isOK()).toBe(expectRevert ? false : true);
|
|
47
133
|
const avmCircuitInputs = simRes.avmProvingRequest.inputs;
|
|
48
|
-
await this.proveVerify(avmCircuitInputs);
|
|
134
|
+
await this.proveVerify(avmCircuitInputs, txLabel);
|
|
49
135
|
}
|
|
50
|
-
async simProveVerifyAppLogic(appCall, expectRevert) {
|
|
136
|
+
async simProveVerifyAppLogic(appCall, expectRevert, txLabel = 'unlabeledTx') {
|
|
51
137
|
await this.simProveVerify(/*sender=*/ AztecAddress.fromNumber(42), /*setupCalls=*/ [], [
|
|
52
138
|
appCall
|
|
53
|
-
], undefined, expectRevert);
|
|
139
|
+
], undefined, expectRevert, /*feePayer=*/ undefined, /*privateInsertions=*/ undefined, txLabel);
|
|
54
140
|
}
|
|
55
141
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"proof_utils.d.ts","sourceRoot":"","sources":["../../src/prover/proof_utils.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"proof_utils.d.ts","sourceRoot":"","sources":["../../src/prover/proof_utils.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,cAAc,EAAS,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC7E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAa7D;;;;;GAKG;AACH,wBAAsB,qCAAqC,CAAC,SAAS,EAAE,MAAM,2BAG5E;AAED;;;;;GAKG;AACH,wBAAsB,oCAAoC,CAAC,cAAc,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,iBAG3G;AAED,wBAAsB,iBAAiB,CAAC,YAAY,SAAS,MAAM,EACjE,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,mBAAmB,EAC3B,WAAW,EAAE,YAAY,EACzB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,cAAc,CAAC,YAAY,CAAC,CAAC,CA4CvC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { IPA_CLAIM_SIZE, NESTED_RECURSIVE_PROOF_LENGTH, NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH, PAIRING_POINTS_SIZE } from '@aztec/constants';
|
|
1
|
+
import { IPA_CLAIM_SIZE, NESTED_RECURSIVE_PROOF_LENGTH, NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH, PAIRING_POINTS_SIZE, ULTRA_KECCAK_PROOF_LENGTH } from '@aztec/constants';
|
|
2
2
|
import { Fr } from '@aztec/foundation/fields';
|
|
3
3
|
import { ClientIvcProof, Proof, RecursiveProof } from '@aztec/stdlib/proofs';
|
|
4
4
|
import assert from 'assert';
|
|
@@ -36,7 +36,7 @@ export async function readProofAsFields(filePath, vkData, proofLength, logger) {
|
|
|
36
36
|
]);
|
|
37
37
|
const json = JSON.parse(proofString);
|
|
38
38
|
let numPublicInputs = vkData.numPublicInputs - PAIRING_POINTS_SIZE;
|
|
39
|
-
assert(proofLength == NESTED_RECURSIVE_PROOF_LENGTH || proofLength == NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH, `Proof length must be one of the expected proof lengths, received ${proofLength}`);
|
|
39
|
+
assert(proofLength == NESTED_RECURSIVE_PROOF_LENGTH || proofLength == NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH || proofLength == ULTRA_KECCAK_PROOF_LENGTH, `Proof length must be one of the expected proof lengths, received ${proofLength}`);
|
|
40
40
|
if (proofLength == NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH) {
|
|
41
41
|
numPublicInputs -= IPA_CLAIM_SIZE;
|
|
42
42
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bb_prover.d.ts","sourceRoot":"","sources":["../../../src/prover/server/bb_prover.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,oCAAoC,EACpC,6BAA6B,EAC7B,yCAAyC,EAEzC,sBAAsB,EACtB,iBAAiB,
|
|
1
|
+
{"version":3,"file":"bb_prover.d.ts","sourceRoot":"","sources":["../../../src/prover/server/bb_prover.ts"],"names":[],"mappings":"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"}
|
|
@@ -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 { AVM_V2_PROOF_LENGTH_IN_FIELDS_PADDED, NESTED_RECURSIVE_PROOF_LENGTH, NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH, PAIRING_POINTS_SIZE, RECURSIVE_PROOF_LENGTH, TUBE_PROOF_LENGTH } from '@aztec/constants';
|
|
7
|
+
import { AVM_V2_PROOF_LENGTH_IN_FIELDS_PADDED, NESTED_RECURSIVE_PROOF_LENGTH, NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH, PAIRING_POINTS_SIZE, RECURSIVE_PROOF_LENGTH, TUBE_PROOF_LENGTH, ULTRA_KECCAK_PROOF_LENGTH } from '@aztec/constants';
|
|
8
8
|
import { Fr } from '@aztec/foundation/fields';
|
|
9
9
|
import { runInDirectory } from '@aztec/foundation/fs';
|
|
10
10
|
import { createLogger } from '@aztec/foundation/log';
|
|
@@ -212,7 +212,8 @@ const SERVER_CIRCUIT_RECURSIVE = true;
|
|
|
212
212
|
const operation = async (bbWorkingDirectory)=>{
|
|
213
213
|
const { provingResult, circuitOutput: output } = await this.generateProofWithBB(input, circuitType, convertInput, convertOutput, bbWorkingDirectory);
|
|
214
214
|
const vkData = this.getVerificationKeyDataForCircuit(circuitType);
|
|
215
|
-
const
|
|
215
|
+
const PROOF_LENGTH = circuitType == 'RootRollupArtifact' ? ULTRA_KECCAK_PROOF_LENGTH : RECURSIVE_PROOF_LENGTH;
|
|
216
|
+
const proof = await readProofAsFields(provingResult.proofPath, vkData, PROOF_LENGTH, logger);
|
|
216
217
|
const circuitName = mapProtocolArtifactNameToCircuitName(circuitType);
|
|
217
218
|
this.instrumentation.recordDuration('provingDuration', circuitName, provingResult.durationMs);
|
|
218
219
|
this.instrumentation.recordSize('proofSize', circuitName, proof.binaryProof.buffer.length);
|
package/dest/stats.js
CHANGED
|
@@ -23,17 +23,17 @@ export function mapProtocolArtifactNameToCircuitName(artifact) {
|
|
|
23
23
|
case 'RootRollupArtifact':
|
|
24
24
|
return 'root-rollup';
|
|
25
25
|
case 'PrivateKernelInitArtifact':
|
|
26
|
-
return '
|
|
26
|
+
return 'ClientIVC';
|
|
27
27
|
case 'PrivateKernelInnerArtifact':
|
|
28
|
-
return '
|
|
28
|
+
return 'ClientIVC';
|
|
29
29
|
case 'PrivateKernelTailArtifact':
|
|
30
|
-
return '
|
|
30
|
+
return 'ClientIVC';
|
|
31
31
|
case 'PrivateKernelTailToPublicArtifact':
|
|
32
|
-
return '
|
|
32
|
+
return 'ClientIVC';
|
|
33
33
|
default:
|
|
34
34
|
{
|
|
35
35
|
if (artifact.startsWith('PrivateKernelReset')) {
|
|
36
|
-
return '
|
|
36
|
+
return 'ClientIVC';
|
|
37
37
|
}
|
|
38
38
|
throw new Error(`Unknown circuit type: ${artifact}`);
|
|
39
39
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bb_verifier.d.ts","sourceRoot":"","sources":["../../src/verifier/bb_verifier.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,MAAM,EAAgB,MAAM,uBAAuB,CAAC;AAGlE,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"bb_verifier.d.ts","sourceRoot":"","sources":["../../src/verifier/bb_verifier.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,MAAM,EAAgB,MAAM,uBAAuB,CAAC;AAGlE,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,2CAA2C,CAAC;AACxF,OAAO,KAAK,EAAE,6BAA6B,EAAE,0BAA0B,EAAE,MAAM,iCAAiC,CAAC;AACjH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAElD,OAAO,EAAE,EAAE,EAAE,MAAM,kBAAkB,CAAC;AACtC,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAc7D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAQ7C,eAAO,MAAM,oBAAoB,QAA0D,CAAC;AAC5F,eAAO,MAAM,mBAAmB,QAAyD,CAAC;AAE1F,qBAAa,iBAAkB,YAAW,6BAA6B;IAEnE,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,MAAM;IAFhB,OAAO;IAKA,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;WAIR,GAAG,CAAC,MAAM,EAAE,QAAQ,EAAE,MAAM,SAAqC;IAK9E,sBAAsB,CAAC,WAAW,EAAE,sBAAsB,GAAG,mBAAmB;IAQ1E,qBAAqB,CAAC,OAAO,EAAE,sBAAsB,EAAE,KAAK,EAAE,KAAK;IAqCnE,WAAW,CAAC,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,0BAA0B,CAAC;CAwCtE"}
|
|
@@ -2,7 +2,6 @@ import { runInDirectory } from '@aztec/foundation/fs';
|
|
|
2
2
|
import { createLogger } from '@aztec/foundation/log';
|
|
3
3
|
import { Timer } from '@aztec/foundation/timer';
|
|
4
4
|
import { ServerCircuitVks } from '@aztec/noir-protocol-circuits-types/server/vks';
|
|
5
|
-
import { Tx } from '@aztec/stdlib/tx';
|
|
6
5
|
import { promises as fs } from 'fs';
|
|
7
6
|
import * as path from 'path';
|
|
8
7
|
import { fileURLToPath } from 'url';
|
|
@@ -66,27 +65,21 @@ export class BBCircuitVerifier {
|
|
|
66
65
|
try {
|
|
67
66
|
const totalTimer = new Timer();
|
|
68
67
|
let verificationDuration = 0;
|
|
69
|
-
// TODO(#7370) The verification keys should be supplied separately and based on the expectedCircuit
|
|
70
|
-
// rather than read from the tx object itself. We also need the vks for the translator and ecc, which
|
|
71
|
-
// are not being saved along the other vks yet. Reuse the 'verifyProofForCircuit' method above once
|
|
72
|
-
// we have all the verification keys available.
|
|
73
|
-
const expectedCircuit = tx.data.forPublic ? 'PrivateKernelTailToPublicArtifact' : 'PrivateKernelTailArtifact';
|
|
74
|
-
const circuit = 'ClientIVC';
|
|
75
68
|
// Block below is almost copy-pasted from verifyProofForCircuit
|
|
76
69
|
const operation = async (bbWorkingDirectory)=>{
|
|
77
70
|
const logFunction = (message)=>{
|
|
78
|
-
this.logger.debug(
|
|
71
|
+
this.logger.debug(`ClientIVC BB out - ${message}`);
|
|
79
72
|
};
|
|
80
73
|
await writeClientIVCProofToOutputDirectory(tx.clientIvcProof, bbWorkingDirectory);
|
|
81
74
|
const timer = new Timer();
|
|
82
75
|
const result = await verifyClientIvcProof(this.config.bbBinaryPath, bbWorkingDirectory.concat('/proof'), tx.data.forPublic ? PUBLIC_TAIL_CIVC_VK : PRIVATE_TAIL_CIVC_VK, logFunction, this.config.bbIVCConcurrency);
|
|
83
76
|
verificationDuration = timer.ms();
|
|
84
77
|
if (result.status === BB_RESULT.FAILURE) {
|
|
85
|
-
const errorMessage = `Failed to verify
|
|
78
|
+
const errorMessage = `Failed to verify ClientIVC proof!`;
|
|
86
79
|
throw new Error(errorMessage);
|
|
87
80
|
}
|
|
88
|
-
this.logger.debug(
|
|
89
|
-
circuitName:
|
|
81
|
+
this.logger.debug(`ClientIVC verification successful`, {
|
|
82
|
+
circuitName: 'ClientIVC',
|
|
90
83
|
duration: result.durationMs,
|
|
91
84
|
eventName: 'circuit-verification',
|
|
92
85
|
proofType: 'client-ivc'
|
|
@@ -99,7 +92,7 @@ export class BBCircuitVerifier {
|
|
|
99
92
|
totalDurationMs: totalTimer.ms()
|
|
100
93
|
};
|
|
101
94
|
} catch (err) {
|
|
102
|
-
this.logger.warn(`Failed to verify ClientIVC proof for tx ${
|
|
95
|
+
this.logger.warn(`Failed to verify ClientIVC proof for tx ${tx.getTxHash().toString()}: ${String(err)}`);
|
|
103
96
|
return {
|
|
104
97
|
valid: false,
|
|
105
98
|
durationMs: 0,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aztec/bb-prover",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0-nightly.20250814",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": "./dest/index.js",
|
|
@@ -70,27 +70,27 @@
|
|
|
70
70
|
]
|
|
71
71
|
},
|
|
72
72
|
"dependencies": {
|
|
73
|
-
"@aztec/bb.js": "
|
|
74
|
-
"@aztec/constants": "
|
|
75
|
-
"@aztec/foundation": "
|
|
76
|
-
"@aztec/noir-noirc_abi": "
|
|
77
|
-
"@aztec/noir-protocol-circuits-types": "
|
|
78
|
-
"@aztec/noir-types": "
|
|
79
|
-
"@aztec/simulator": "
|
|
80
|
-
"@aztec/stdlib": "
|
|
81
|
-
"@aztec/telemetry-client": "
|
|
82
|
-
"@aztec/world-state": "
|
|
73
|
+
"@aztec/bb.js": "2.0.0-nightly.20250814",
|
|
74
|
+
"@aztec/constants": "2.0.0-nightly.20250814",
|
|
75
|
+
"@aztec/foundation": "2.0.0-nightly.20250814",
|
|
76
|
+
"@aztec/noir-noirc_abi": "2.0.0-nightly.20250814",
|
|
77
|
+
"@aztec/noir-protocol-circuits-types": "2.0.0-nightly.20250814",
|
|
78
|
+
"@aztec/noir-types": "2.0.0-nightly.20250814",
|
|
79
|
+
"@aztec/simulator": "2.0.0-nightly.20250814",
|
|
80
|
+
"@aztec/stdlib": "2.0.0-nightly.20250814",
|
|
81
|
+
"@aztec/telemetry-client": "2.0.0-nightly.20250814",
|
|
82
|
+
"@aztec/world-state": "2.0.0-nightly.20250814",
|
|
83
83
|
"commander": "^12.1.0",
|
|
84
84
|
"pako": "^2.1.0",
|
|
85
85
|
"source-map-support": "^0.5.21",
|
|
86
86
|
"tslib": "^2.4.0"
|
|
87
87
|
},
|
|
88
88
|
"devDependencies": {
|
|
89
|
-
"@aztec/ethereum": "
|
|
90
|
-
"@aztec/kv-store": "
|
|
91
|
-
"@aztec/noir-contracts.js": "
|
|
92
|
-
"@aztec/noir-test-contracts.js": "
|
|
93
|
-
"@aztec/protocol-contracts": "
|
|
89
|
+
"@aztec/ethereum": "2.0.0-nightly.20250814",
|
|
90
|
+
"@aztec/kv-store": "2.0.0-nightly.20250814",
|
|
91
|
+
"@aztec/noir-contracts.js": "2.0.0-nightly.20250814",
|
|
92
|
+
"@aztec/noir-test-contracts.js": "2.0.0-nightly.20250814",
|
|
93
|
+
"@aztec/protocol-contracts": "2.0.0-nightly.20250814",
|
|
94
94
|
"@jest/globals": "^30.0.0",
|
|
95
95
|
"@types/jest": "^30.0.0",
|
|
96
96
|
"@types/node": "^22.15.17",
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
import type { LogFn, LogLevel, Logger } from '@aztec/foundation/log';
|
|
1
2
|
import {
|
|
2
3
|
PublicTxSimulationTester,
|
|
3
4
|
SimpleContractDataSource,
|
|
4
5
|
type TestEnqueuedCall,
|
|
6
|
+
type TestExecutorMetrics,
|
|
5
7
|
type TestPrivateInsertions,
|
|
6
8
|
} from '@aztec/simulator/public/fixtures';
|
|
7
9
|
import { type AvmCircuitInputs, AvmCircuitPublicInputs } from '@aztec/stdlib/avm';
|
|
@@ -25,6 +27,65 @@ import {
|
|
|
25
27
|
|
|
26
28
|
const BB_PATH = path.resolve('../../barretenberg/cpp/build/bin/bb');
|
|
27
29
|
|
|
30
|
+
// An InterceptingLogger that records all log messages and forwards them to a wrapped logger.
|
|
31
|
+
class InterceptingLogger implements Logger {
|
|
32
|
+
public readonly logs: string[] = [];
|
|
33
|
+
public level: LogLevel;
|
|
34
|
+
public module: string;
|
|
35
|
+
|
|
36
|
+
private logger: Logger;
|
|
37
|
+
|
|
38
|
+
constructor(logger: Logger) {
|
|
39
|
+
this.logger = logger;
|
|
40
|
+
this.level = logger.level;
|
|
41
|
+
this.module = logger.module;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
isLevelEnabled(level: LogLevel): boolean {
|
|
45
|
+
return this.logger.isLevelEnabled(level);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
createChild(_childModule: string): Logger {
|
|
49
|
+
throw new Error('Not implemented');
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
private intercept(level: LogLevel, msg: string, ...args: any[]) {
|
|
53
|
+
this.logs.push(...msg.split('\n'));
|
|
54
|
+
// Forward to the wrapped logger
|
|
55
|
+
(this.logger[level] as LogFn)(msg, ...args);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// Log methods for each level
|
|
59
|
+
silent(msg: string, ...args: any[]) {
|
|
60
|
+
this.intercept('silent', msg, ...args);
|
|
61
|
+
}
|
|
62
|
+
fatal(msg: string, ...args: any[]) {
|
|
63
|
+
this.intercept('fatal', msg, ...args);
|
|
64
|
+
}
|
|
65
|
+
warn(msg: string, ...args: any[]) {
|
|
66
|
+
this.intercept('warn', msg, ...args);
|
|
67
|
+
}
|
|
68
|
+
info(msg: string, ...args: any[]) {
|
|
69
|
+
this.intercept('info', msg, ...args);
|
|
70
|
+
}
|
|
71
|
+
verbose(msg: string, ...args: any[]) {
|
|
72
|
+
this.intercept('verbose', msg, ...args);
|
|
73
|
+
}
|
|
74
|
+
debug(msg: string, ...args: any[]) {
|
|
75
|
+
this.intercept('debug', msg, ...args);
|
|
76
|
+
}
|
|
77
|
+
trace(msg: string, ...args: any[]) {
|
|
78
|
+
this.intercept('trace', msg, ...args);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// Error log function can be string or Error
|
|
82
|
+
error(err: Error | string, ...args: any[]) {
|
|
83
|
+
const msg = typeof err === 'string' ? err : err.message;
|
|
84
|
+
this.logs.push(msg);
|
|
85
|
+
this.logger.error(msg, err, ...args);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
28
89
|
export class AvmProvingTester extends PublicTxSimulationTester {
|
|
29
90
|
constructor(
|
|
30
91
|
private bbWorkingDirectory: string,
|
|
@@ -32,31 +93,78 @@ export class AvmProvingTester extends PublicTxSimulationTester {
|
|
|
32
93
|
contractDataSource: SimpleContractDataSource,
|
|
33
94
|
merkleTrees: MerkleTreeWriteOperations,
|
|
34
95
|
globals?: GlobalVariables,
|
|
96
|
+
metrics?: TestExecutorMetrics,
|
|
35
97
|
) {
|
|
36
|
-
super(merkleTrees, contractDataSource, globals);
|
|
98
|
+
super(merkleTrees, contractDataSource, globals, metrics);
|
|
37
99
|
}
|
|
38
100
|
|
|
39
|
-
static async new(checkCircuitOnly: boolean = false, globals?: GlobalVariables) {
|
|
101
|
+
static async new(checkCircuitOnly: boolean = false, globals?: GlobalVariables, metrics?: TestExecutorMetrics) {
|
|
40
102
|
const bbWorkingDirectory = await fs.mkdtemp(path.join(tmpdir(), 'bb-'));
|
|
41
103
|
|
|
42
104
|
const contractDataSource = new SimpleContractDataSource();
|
|
43
105
|
const merkleTrees = await (await NativeWorldStateService.tmp()).fork();
|
|
44
|
-
return new AvmProvingTester(
|
|
106
|
+
return new AvmProvingTester(
|
|
107
|
+
bbWorkingDirectory,
|
|
108
|
+
checkCircuitOnly,
|
|
109
|
+
contractDataSource,
|
|
110
|
+
merkleTrees,
|
|
111
|
+
globals,
|
|
112
|
+
metrics,
|
|
113
|
+
);
|
|
45
114
|
}
|
|
46
115
|
|
|
47
|
-
async prove(avmCircuitInputs: AvmCircuitInputs): Promise<BBResult> {
|
|
116
|
+
async prove(avmCircuitInputs: AvmCircuitInputs, txLabel: string = 'unlabeledTx'): Promise<BBResult> {
|
|
117
|
+
const interceptingLogger = new InterceptingLogger(this.logger);
|
|
118
|
+
|
|
48
119
|
// Then we prove.
|
|
49
120
|
const proofRes = await generateAvmProof(
|
|
50
121
|
BB_PATH,
|
|
51
122
|
this.bbWorkingDirectory,
|
|
52
123
|
avmCircuitInputs,
|
|
53
|
-
|
|
124
|
+
interceptingLogger,
|
|
54
125
|
this.checkCircuitOnly,
|
|
55
126
|
);
|
|
56
127
|
if (proofRes.status === BB_RESULT.FAILURE) {
|
|
57
128
|
this.logger.error(`Proof generation failed: ${proofRes.reason}`);
|
|
58
129
|
}
|
|
59
130
|
expect(proofRes.status).toEqual(BB_RESULT.SUCCESS);
|
|
131
|
+
|
|
132
|
+
// Parse the logs into a structured format.
|
|
133
|
+
const logs = interceptingLogger.logs;
|
|
134
|
+
// const traceSizes: { name: string; size: number }[] = [];
|
|
135
|
+
// logs.forEach(log => {
|
|
136
|
+
// const match = log.match(/\b(\w+): (\d+) \(~2/);
|
|
137
|
+
// if (match) {
|
|
138
|
+
// traceSizes.push({
|
|
139
|
+
// name: match[1],
|
|
140
|
+
// size: parseInt(match[2]),
|
|
141
|
+
// });
|
|
142
|
+
// }
|
|
143
|
+
// });
|
|
144
|
+
const times: { [key: string]: number } = {};
|
|
145
|
+
logs.forEach(log => {
|
|
146
|
+
const match = log.match(/\b([\w/]+)_ms: (\d+)/);
|
|
147
|
+
if (match) {
|
|
148
|
+
times[match[1]] = parseInt(match[2]);
|
|
149
|
+
}
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
// Hack to make labels match.
|
|
153
|
+
const txLabelWithCount = `${txLabel}/${this.txCount - 1}`;
|
|
154
|
+
// I need to cast because TS doesnt realize metrics is protected not private.
|
|
155
|
+
(this as any).metrics?.recordProverMetrics(txLabelWithCount, {
|
|
156
|
+
proverSimulationStepMs: times['simulation/all'],
|
|
157
|
+
proverProvingStepMs: times['proving/all'],
|
|
158
|
+
proverTraceGenerationStepMs: times['tracegen/all'],
|
|
159
|
+
traceGenerationInteractionsMs: times['tracegen/interactions'],
|
|
160
|
+
traceGenerationTracesMs: times['tracegen/traces'],
|
|
161
|
+
provingSumcheckMs: times['prove/sumcheck'],
|
|
162
|
+
provingPcsMs: times['prove/pcs_rounds'],
|
|
163
|
+
provingLogDerivativeInverseMs: times['prove/log_derivative_inverse_round'],
|
|
164
|
+
provingLogDerivativeInverseCommitmentsMs: times['prove/log_derivative_inverse_commitments_round'],
|
|
165
|
+
provingWireCommitmentsMs: times['prove/wire_commitments_round'],
|
|
166
|
+
});
|
|
167
|
+
|
|
60
168
|
return proofRes as BBSuccess;
|
|
61
169
|
}
|
|
62
170
|
|
|
@@ -77,8 +185,8 @@ export class AvmProvingTester extends PublicTxSimulationTester {
|
|
|
77
185
|
);
|
|
78
186
|
}
|
|
79
187
|
|
|
80
|
-
public async proveVerify(avmCircuitInputs: AvmCircuitInputs) {
|
|
81
|
-
const provingRes = await this.prove(avmCircuitInputs);
|
|
188
|
+
public async proveVerify(avmCircuitInputs: AvmCircuitInputs, txLabel: string = 'unlabeledTx') {
|
|
189
|
+
const provingRes = await this.prove(avmCircuitInputs, txLabel);
|
|
82
190
|
expect(provingRes.status).toEqual(BB_RESULT.SUCCESS);
|
|
83
191
|
|
|
84
192
|
const verificationRes = await this.verify(provingRes as BBSuccess, avmCircuitInputs.publicInputs);
|
|
@@ -93,21 +201,37 @@ export class AvmProvingTester extends PublicTxSimulationTester {
|
|
|
93
201
|
expectRevert: boolean | undefined,
|
|
94
202
|
feePayer = sender,
|
|
95
203
|
privateInsertions?: TestPrivateInsertions,
|
|
204
|
+
txLabel: string = 'unlabeledTx',
|
|
96
205
|
) {
|
|
97
|
-
const simRes = await this.simulateTx(
|
|
206
|
+
const simRes = await this.simulateTx(
|
|
207
|
+
sender,
|
|
208
|
+
setupCalls,
|
|
209
|
+
appCalls,
|
|
210
|
+
teardownCall,
|
|
211
|
+
feePayer,
|
|
212
|
+
privateInsertions,
|
|
213
|
+
txLabel,
|
|
214
|
+
);
|
|
98
215
|
expect(simRes.revertCode.isOK()).toBe(expectRevert ? false : true);
|
|
99
216
|
|
|
100
217
|
const avmCircuitInputs = simRes.avmProvingRequest.inputs;
|
|
101
|
-
await this.proveVerify(avmCircuitInputs);
|
|
218
|
+
await this.proveVerify(avmCircuitInputs, txLabel);
|
|
102
219
|
}
|
|
103
220
|
|
|
104
|
-
public async simProveVerifyAppLogic(
|
|
221
|
+
public async simProveVerifyAppLogic(
|
|
222
|
+
appCall: TestEnqueuedCall,
|
|
223
|
+
expectRevert?: boolean,
|
|
224
|
+
txLabel: string = 'unlabeledTx',
|
|
225
|
+
) {
|
|
105
226
|
await this.simProveVerify(
|
|
106
227
|
/*sender=*/ AztecAddress.fromNumber(42),
|
|
107
228
|
/*setupCalls=*/ [],
|
|
108
229
|
[appCall],
|
|
109
230
|
undefined,
|
|
110
231
|
expectRevert,
|
|
232
|
+
/*feePayer=*/ undefined,
|
|
233
|
+
/*privateInsertions=*/ undefined,
|
|
234
|
+
txLabel,
|
|
111
235
|
);
|
|
112
236
|
}
|
|
113
237
|
}
|
|
@@ -3,6 +3,7 @@ import {
|
|
|
3
3
|
NESTED_RECURSIVE_PROOF_LENGTH,
|
|
4
4
|
NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH,
|
|
5
5
|
PAIRING_POINTS_SIZE,
|
|
6
|
+
ULTRA_KECCAK_PROOF_LENGTH,
|
|
6
7
|
} from '@aztec/constants';
|
|
7
8
|
import { Fr } from '@aztec/foundation/fields';
|
|
8
9
|
import type { Logger } from '@aztec/foundation/log';
|
|
@@ -62,7 +63,9 @@ export async function readProofAsFields<PROOF_LENGTH extends number>(
|
|
|
62
63
|
|
|
63
64
|
let numPublicInputs = vkData.numPublicInputs - PAIRING_POINTS_SIZE;
|
|
64
65
|
assert(
|
|
65
|
-
proofLength == NESTED_RECURSIVE_PROOF_LENGTH ||
|
|
66
|
+
proofLength == NESTED_RECURSIVE_PROOF_LENGTH ||
|
|
67
|
+
proofLength == NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH ||
|
|
68
|
+
proofLength == ULTRA_KECCAK_PROOF_LENGTH,
|
|
66
69
|
`Proof length must be one of the expected proof lengths, received ${proofLength}`,
|
|
67
70
|
);
|
|
68
71
|
if (proofLength == NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH) {
|
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
PAIRING_POINTS_SIZE,
|
|
6
6
|
RECURSIVE_PROOF_LENGTH,
|
|
7
7
|
TUBE_PROOF_LENGTH,
|
|
8
|
+
ULTRA_KECCAK_PROOF_LENGTH,
|
|
8
9
|
} from '@aztec/constants';
|
|
9
10
|
import { Fr } from '@aztec/foundation/fields';
|
|
10
11
|
import { runInDirectory } from '@aztec/foundation/fs';
|
|
@@ -501,7 +502,9 @@ export class BBNativeRollupProver implements ServerCircuitProver {
|
|
|
501
502
|
bbWorkingDirectory,
|
|
502
503
|
);
|
|
503
504
|
const vkData = this.getVerificationKeyDataForCircuit(circuitType);
|
|
504
|
-
|
|
505
|
+
|
|
506
|
+
const PROOF_LENGTH = circuitType == 'RootRollupArtifact' ? ULTRA_KECCAK_PROOF_LENGTH : RECURSIVE_PROOF_LENGTH;
|
|
507
|
+
const proof = await readProofAsFields(provingResult.proofPath!, vkData, PROOF_LENGTH, logger);
|
|
505
508
|
|
|
506
509
|
const circuitName = mapProtocolArtifactNameToCircuitName(circuitType);
|
|
507
510
|
|
package/src/stats.ts
CHANGED
|
@@ -26,16 +26,16 @@ export function mapProtocolArtifactNameToCircuitName(artifact: ProtocolArtifact)
|
|
|
26
26
|
case 'RootRollupArtifact':
|
|
27
27
|
return 'root-rollup';
|
|
28
28
|
case 'PrivateKernelInitArtifact':
|
|
29
|
-
return '
|
|
29
|
+
return 'ClientIVC';
|
|
30
30
|
case 'PrivateKernelInnerArtifact':
|
|
31
|
-
return '
|
|
31
|
+
return 'ClientIVC';
|
|
32
32
|
case 'PrivateKernelTailArtifact':
|
|
33
|
-
return '
|
|
33
|
+
return 'ClientIVC';
|
|
34
34
|
case 'PrivateKernelTailToPublicArtifact':
|
|
35
|
-
return '
|
|
35
|
+
return 'ClientIVC';
|
|
36
36
|
default: {
|
|
37
37
|
if (artifact.startsWith('PrivateKernelReset')) {
|
|
38
|
-
return '
|
|
38
|
+
return 'ClientIVC';
|
|
39
39
|
}
|
|
40
40
|
throw new Error(`Unknown circuit type: ${artifact}`);
|
|
41
41
|
}
|
|
@@ -2,7 +2,7 @@ import { runInDirectory } from '@aztec/foundation/fs';
|
|
|
2
2
|
import { type Logger, createLogger } from '@aztec/foundation/log';
|
|
3
3
|
import { Timer } from '@aztec/foundation/timer';
|
|
4
4
|
import { ServerCircuitVks } from '@aztec/noir-protocol-circuits-types/server/vks';
|
|
5
|
-
import type {
|
|
5
|
+
import type { ServerProtocolArtifact } from '@aztec/noir-protocol-circuits-types/types';
|
|
6
6
|
import type { ClientProtocolCircuitVerifier, IVCProofVerificationResult } from '@aztec/stdlib/interfaces/server';
|
|
7
7
|
import type { Proof } from '@aztec/stdlib/proofs';
|
|
8
8
|
import type { CircuitVerificationStats } from '@aztec/stdlib/stats';
|
|
@@ -96,19 +96,10 @@ export class BBCircuitVerifier implements ClientProtocolCircuitVerifier {
|
|
|
96
96
|
try {
|
|
97
97
|
const totalTimer = new Timer();
|
|
98
98
|
let verificationDuration = 0;
|
|
99
|
-
// TODO(#7370) The verification keys should be supplied separately and based on the expectedCircuit
|
|
100
|
-
// rather than read from the tx object itself. We also need the vks for the translator and ecc, which
|
|
101
|
-
// are not being saved along the other vks yet. Reuse the 'verifyProofForCircuit' method above once
|
|
102
|
-
// we have all the verification keys available.
|
|
103
|
-
const expectedCircuit: ClientProtocolArtifact = tx.data.forPublic
|
|
104
|
-
? 'PrivateKernelTailToPublicArtifact'
|
|
105
|
-
: 'PrivateKernelTailArtifact';
|
|
106
|
-
const circuit = 'ClientIVC';
|
|
107
|
-
|
|
108
99
|
// Block below is almost copy-pasted from verifyProofForCircuit
|
|
109
100
|
const operation = async (bbWorkingDirectory: string) => {
|
|
110
101
|
const logFunction = (message: string) => {
|
|
111
|
-
this.logger.debug(
|
|
102
|
+
this.logger.debug(`ClientIVC BB out - ${message}`);
|
|
112
103
|
};
|
|
113
104
|
|
|
114
105
|
await writeClientIVCProofToOutputDirectory(tx.clientIvcProof, bbWorkingDirectory);
|
|
@@ -123,12 +114,12 @@ export class BBCircuitVerifier implements ClientProtocolCircuitVerifier {
|
|
|
123
114
|
verificationDuration = timer.ms();
|
|
124
115
|
|
|
125
116
|
if (result.status === BB_RESULT.FAILURE) {
|
|
126
|
-
const errorMessage = `Failed to verify
|
|
117
|
+
const errorMessage = `Failed to verify ClientIVC proof!`;
|
|
127
118
|
throw new Error(errorMessage);
|
|
128
119
|
}
|
|
129
120
|
|
|
130
|
-
this.logger.debug(
|
|
131
|
-
circuitName:
|
|
121
|
+
this.logger.debug(`ClientIVC verification successful`, {
|
|
122
|
+
circuitName: 'ClientIVC',
|
|
132
123
|
duration: result.durationMs,
|
|
133
124
|
eventName: 'circuit-verification',
|
|
134
125
|
proofType: 'client-ivc',
|
|
@@ -137,7 +128,7 @@ export class BBCircuitVerifier implements ClientProtocolCircuitVerifier {
|
|
|
137
128
|
await runInDirectory(this.config.bbWorkingDirectory, operation, this.config.bbSkipCleanup, this.logger);
|
|
138
129
|
return { valid: true, durationMs: verificationDuration, totalDurationMs: totalTimer.ms() };
|
|
139
130
|
} catch (err) {
|
|
140
|
-
this.logger.warn(`Failed to verify ClientIVC proof for tx ${
|
|
131
|
+
this.logger.warn(`Failed to verify ClientIVC proof for tx ${tx.getTxHash().toString()}: ${String(err)}`);
|
|
141
132
|
return { valid: false, durationMs: 0, totalDurationMs: 0 };
|
|
142
133
|
}
|
|
143
134
|
}
|