@aztec/bb-prover 0.47.0 → 0.48.0
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/bb/execute.d.ts +9 -0
- package/dest/bb/execute.d.ts.map +1 -1
- package/dest/bb/execute.js +36 -1
- package/dest/instrumentation.d.ts +5 -5
- package/dest/instrumentation.d.ts.map +1 -1
- package/dest/instrumentation.js +25 -21
- package/dest/prover/bb_private_kernel_prover.d.ts.map +1 -1
- package/dest/prover/bb_private_kernel_prover.js +3 -6
- package/dest/prover/bb_prover.d.ts +2 -2
- package/dest/prover/bb_prover.d.ts.map +1 -1
- package/dest/prover/bb_prover.js +13 -23
- package/dest/test/test_circuit_prover.d.ts +6 -2
- package/dest/test/test_circuit_prover.d.ts.map +1 -1
- package/dest/test/test_circuit_prover.js +26 -8
- package/dest/verifier/bb_verifier.d.ts.map +1 -1
- package/dest/verifier/bb_verifier.js +40 -13
- package/package.json +7 -7
- package/src/bb/execute.ts +40 -0
- package/src/instrumentation.ts +28 -23
- package/src/prover/bb_private_kernel_prover.ts +3 -4
- package/src/prover/bb_prover.ts +16 -25
- package/src/test/test_circuit_prover.ts +25 -12
- package/src/verifier/bb_verifier.ts +44 -12
package/src/bb/execute.ts
CHANGED
|
@@ -621,6 +621,46 @@ export async function verifyAvmProof(
|
|
|
621
621
|
return await verifyProofInternal(pathToBB, proofFullPath, verificationKeyPath, 'avm_verify', log);
|
|
622
622
|
}
|
|
623
623
|
|
|
624
|
+
/**
|
|
625
|
+
* Verifies a ClientIvcProof
|
|
626
|
+
* TODO(#7370) The verification keys should be supplied separately
|
|
627
|
+
* @param pathToBB - The full path to the bb binary
|
|
628
|
+
* @param targetPath - The path to the folder with the proof, accumulator, and verification keys
|
|
629
|
+
* @param log - A logging function
|
|
630
|
+
* @returns An object containing a result indication and duration taken
|
|
631
|
+
*/
|
|
632
|
+
export async function verifyClientIvcProof(
|
|
633
|
+
pathToBB: string,
|
|
634
|
+
targetPath: string,
|
|
635
|
+
log: LogFn,
|
|
636
|
+
): Promise<BBFailure | BBSuccess> {
|
|
637
|
+
const binaryPresent = await fs
|
|
638
|
+
.access(pathToBB, fs.constants.R_OK)
|
|
639
|
+
.then(_ => true)
|
|
640
|
+
.catch(_ => false);
|
|
641
|
+
if (!binaryPresent) {
|
|
642
|
+
return { status: BB_RESULT.FAILURE, reason: `Failed to find bb binary at ${pathToBB}` };
|
|
643
|
+
}
|
|
644
|
+
|
|
645
|
+
try {
|
|
646
|
+
const args = ['-o', targetPath];
|
|
647
|
+
const timer = new Timer();
|
|
648
|
+
const command = 'verify_client_ivc';
|
|
649
|
+
const result = await executeBB(pathToBB, command, args, log);
|
|
650
|
+
const duration = timer.ms();
|
|
651
|
+
if (result.status == BB_RESULT.SUCCESS) {
|
|
652
|
+
return { status: BB_RESULT.SUCCESS, durationMs: duration };
|
|
653
|
+
}
|
|
654
|
+
// Not a great error message here but it is difficult to decipher what comes from bb
|
|
655
|
+
return {
|
|
656
|
+
status: BB_RESULT.FAILURE,
|
|
657
|
+
reason: `Failed to verify proof. Exit code ${result.exitCode}. Signal ${result.signal}.`,
|
|
658
|
+
};
|
|
659
|
+
} catch (error) {
|
|
660
|
+
return { status: BB_RESULT.FAILURE, reason: `${error}` };
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
|
|
624
664
|
/**
|
|
625
665
|
* Used for verifying proofs with BB
|
|
626
666
|
* @param pathToBB - The full path to the bb binary
|
package/src/instrumentation.ts
CHANGED
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
type TelemetryClient,
|
|
9
9
|
type Tracer,
|
|
10
10
|
ValueType,
|
|
11
|
+
millisecondBuckets,
|
|
11
12
|
} from '@aztec/telemetry-client';
|
|
12
13
|
|
|
13
14
|
/**
|
|
@@ -15,8 +16,8 @@ import {
|
|
|
15
16
|
*/
|
|
16
17
|
export class ProverInstrumentation {
|
|
17
18
|
private simulationDuration: Histogram;
|
|
18
|
-
private witGenDuration:
|
|
19
|
-
private provingDuration:
|
|
19
|
+
private witGenDuration: Histogram;
|
|
20
|
+
private provingDuration: Histogram;
|
|
20
21
|
|
|
21
22
|
private witGenInputSize: Gauge;
|
|
22
23
|
private witGenOutputSize: Gauge;
|
|
@@ -33,25 +34,29 @@ export class ProverInstrumentation {
|
|
|
33
34
|
|
|
34
35
|
this.simulationDuration = meter.createHistogram(Metrics.CIRCUIT_SIMULATION_DURATION, {
|
|
35
36
|
description: 'Records how long it takes to simulate a circuit',
|
|
36
|
-
unit: '
|
|
37
|
-
valueType: ValueType.
|
|
37
|
+
unit: 'ms',
|
|
38
|
+
valueType: ValueType.INT,
|
|
38
39
|
advice: {
|
|
39
|
-
explicitBucketBoundaries:
|
|
40
|
+
explicitBucketBoundaries: millisecondBuckets(1), // 10ms -> ~327s
|
|
40
41
|
},
|
|
41
42
|
});
|
|
42
43
|
|
|
43
|
-
this.witGenDuration = meter.
|
|
44
|
+
this.witGenDuration = meter.createHistogram(Metrics.CIRCUIT_WITNESS_GEN_DURATION, {
|
|
44
45
|
description: 'Records how long it takes to generate the partial witness for a circuit',
|
|
45
|
-
unit: '
|
|
46
|
-
valueType: ValueType.
|
|
46
|
+
unit: 'ms',
|
|
47
|
+
valueType: ValueType.INT,
|
|
48
|
+
advice: {
|
|
49
|
+
explicitBucketBoundaries: millisecondBuckets(1),
|
|
50
|
+
},
|
|
47
51
|
});
|
|
48
52
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
this.provingDuration = meter.createGauge(Metrics.CIRCUIT_PROVING_DURATION, {
|
|
52
|
-
unit: 's',
|
|
53
|
+
this.provingDuration = meter.createHistogram(Metrics.CIRCUIT_PROVING_DURATION, {
|
|
54
|
+
unit: 'ms',
|
|
53
55
|
description: 'Records how long it takes to prove a circuit',
|
|
54
|
-
valueType: ValueType.
|
|
56
|
+
valueType: ValueType.INT,
|
|
57
|
+
advice: {
|
|
58
|
+
explicitBucketBoundaries: millisecondBuckets(2), // 100ms -> 54 minutes
|
|
59
|
+
},
|
|
55
60
|
});
|
|
56
61
|
|
|
57
62
|
this.witGenInputSize = meter.createGauge(Metrics.CIRCUIT_WITNESS_GEN_INPUT_SIZE, {
|
|
@@ -87,15 +92,15 @@ export class ProverInstrumentation {
|
|
|
87
92
|
* Records the duration of a circuit operation.
|
|
88
93
|
* @param metric - The metric to record
|
|
89
94
|
* @param circuitName - The name of the circuit
|
|
90
|
-
* @param
|
|
95
|
+
* @param timerOrMS - The duration
|
|
91
96
|
*/
|
|
92
97
|
recordDuration(
|
|
93
98
|
metric: 'simulationDuration' | 'witGenDuration' | 'provingDuration',
|
|
94
|
-
circuitName: CircuitName,
|
|
95
|
-
|
|
99
|
+
circuitName: CircuitName | 'tubeCircuit',
|
|
100
|
+
timerOrMS: Timer | number,
|
|
96
101
|
) {
|
|
97
|
-
const
|
|
98
|
-
this[metric].record(
|
|
102
|
+
const ms = typeof timerOrMS === 'number' ? timerOrMS : timerOrMS.ms();
|
|
103
|
+
this[metric].record(Math.ceil(ms), {
|
|
99
104
|
[Attributes.PROTOCOL_CIRCUIT_NAME]: circuitName,
|
|
100
105
|
[Attributes.PROTOCOL_CIRCUIT_TYPE]: 'server',
|
|
101
106
|
});
|
|
@@ -105,11 +110,11 @@ export class ProverInstrumentation {
|
|
|
105
110
|
* Records the duration of an AVM circuit operation.
|
|
106
111
|
* @param metric - The metric to record
|
|
107
112
|
* @param appCircuitName - The name of the function circuit (should be a `contract:function` string)
|
|
108
|
-
* @param
|
|
113
|
+
* @param timerOrMS - The duration
|
|
109
114
|
*/
|
|
110
|
-
recordAvmDuration(metric: 'witGenDuration' | 'provingDuration', appCircuitName: string,
|
|
111
|
-
const
|
|
112
|
-
this[metric].record(
|
|
115
|
+
recordAvmDuration(metric: 'witGenDuration' | 'provingDuration', appCircuitName: string, timerOrMS: Timer | number) {
|
|
116
|
+
const ms = typeof timerOrMS === 'number' ? timerOrMS : timerOrMS.s();
|
|
117
|
+
this[metric].record(Math.ceil(ms), {
|
|
113
118
|
[Attributes.APP_CIRCUIT_NAME]: appCircuitName,
|
|
114
119
|
});
|
|
115
120
|
}
|
|
@@ -122,7 +127,7 @@ export class ProverInstrumentation {
|
|
|
122
127
|
*/
|
|
123
128
|
recordSize(
|
|
124
129
|
metric: 'witGenInputSize' | 'witGenOutputSize' | 'proofSize' | 'circuitSize' | 'circuitPublicInputCount',
|
|
125
|
-
circuitName: CircuitName,
|
|
130
|
+
circuitName: CircuitName | 'tubeCircuit',
|
|
126
131
|
size: number,
|
|
127
132
|
) {
|
|
128
133
|
this[metric].record(Math.ceil(size), {
|
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
} from '@aztec/circuit-types';
|
|
6
6
|
import { type CircuitSimulationStats, type CircuitWitnessGenerationStats } from '@aztec/circuit-types/stats';
|
|
7
7
|
import {
|
|
8
|
+
AGGREGATION_OBJECT_LENGTH,
|
|
8
9
|
ClientIvcProof,
|
|
9
10
|
Fr,
|
|
10
11
|
type PrivateCircuitPublicInputs,
|
|
@@ -350,10 +351,8 @@ export class BBNativePrivateKernelProver implements PrivateKernelProver {
|
|
|
350
351
|
]);
|
|
351
352
|
const json = JSON.parse(proofString);
|
|
352
353
|
const fields = json.map(Fr.fromString);
|
|
353
|
-
const numPublicInputs = vkData.numPublicInputs;
|
|
354
|
-
|
|
355
|
-
// TODO(https://github.com/AztecProtocol/barretenberg/issues/1044): Reinstate aggregation
|
|
356
|
-
// circuitType === 'App' ? vkData.numPublicInputs : vkData.numPublicInputs - AGGREGATION_OBJECT_LENGTH;
|
|
354
|
+
const numPublicInputs = vkData.numPublicInputs - AGGREGATION_OBJECT_LENGTH;
|
|
355
|
+
|
|
357
356
|
const fieldsWithoutPublicInputs = fields.slice(numPublicInputs);
|
|
358
357
|
this.log.info(
|
|
359
358
|
`Circuit type: ${circuitType}, complete proof length: ${fields.length}, without public inputs: ${fieldsWithoutPublicInputs.length}, num public inputs: ${numPublicInputs}, circuit size: ${vkData.circuitSize}, is recursive: ${vkData.isRecursive}, raw length: ${binaryProof.length}`,
|
package/src/prover/bb_prover.ts
CHANGED
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
} from '@aztec/circuit-types';
|
|
10
10
|
import { type CircuitProvingStats, type CircuitWitnessGenerationStats } from '@aztec/circuit-types/stats';
|
|
11
11
|
import {
|
|
12
|
+
AGGREGATION_OBJECT_LENGTH,
|
|
12
13
|
type AvmCircuitInputs,
|
|
13
14
|
type BaseOrMergeRollupPublicInputs,
|
|
14
15
|
type BaseParityInputs,
|
|
@@ -30,7 +31,7 @@ import {
|
|
|
30
31
|
type RootRollupInputs,
|
|
31
32
|
type RootRollupPublicInputs,
|
|
32
33
|
TUBE_PROOF_LENGTH,
|
|
33
|
-
TubeInputs,
|
|
34
|
+
type TubeInputs,
|
|
34
35
|
type VerificationKeyAsFields,
|
|
35
36
|
type VerificationKeyData,
|
|
36
37
|
makeRecursiveProofFromBinary,
|
|
@@ -225,16 +226,6 @@ export class BBNativeRollupProver implements ServerCircuitProver {
|
|
|
225
226
|
kernelRequest.inputs.previousKernel.vk,
|
|
226
227
|
);
|
|
227
228
|
|
|
228
|
-
// PUBLIC KERNEL: kernel request should be nonempty at start of public kernel proving but it is not
|
|
229
|
-
// TODO(#7369): We should properly enqueue the tube in the public kernel lifetime
|
|
230
|
-
if (!kernelRequest.inputs.previousKernel.clientIvcProof.isEmpty()) {
|
|
231
|
-
const { tubeVK, tubeProof } = await this.getTubeProof(
|
|
232
|
-
new TubeInputs(kernelRequest.inputs.previousKernel.clientIvcProof),
|
|
233
|
-
);
|
|
234
|
-
kernelRequest.inputs.previousKernel.vk = tubeVK;
|
|
235
|
-
kernelRequest.inputs.previousKernel.proof = tubeProof;
|
|
236
|
-
}
|
|
237
|
-
|
|
238
229
|
await this.verifyWithKey(
|
|
239
230
|
kernelRequest.inputs.previousKernel.vk,
|
|
240
231
|
kernelRequest.inputs.previousKernel.proof.binaryProof,
|
|
@@ -288,9 +279,7 @@ export class BBNativeRollupProver implements ServerCircuitProver {
|
|
|
288
279
|
): Promise<PublicInputsAndRecursiveProof<BaseOrMergeRollupPublicInputs>> {
|
|
289
280
|
// We may need to convert the recursive proof into fields format
|
|
290
281
|
logger.debug(`kernel Data proof: ${baseRollupInput.kernelData.proof}`);
|
|
291
|
-
logger.
|
|
292
|
-
logger.info(`Number of public inputs in baseRollupInput: ${baseRollupInput.kernelData.vk.numPublicInputs}`);
|
|
293
|
-
logger.info(`Number of public inputs ${baseRollupInput.kernelData.publicInputs}`);
|
|
282
|
+
logger.debug(`Number of public inputs in baseRollupInput: ${baseRollupInput.kernelData.vk.numPublicInputs}`);
|
|
294
283
|
baseRollupInput.kernelData.proof = await this.ensureValidProof(
|
|
295
284
|
baseRollupInput.kernelData.proof,
|
|
296
285
|
'BaseRollupArtifact',
|
|
@@ -476,7 +465,7 @@ export class BBNativeRollupProver implements ServerCircuitProver {
|
|
|
476
465
|
this.instrumentation.recordSize('witGenInputSize', circuitName, input.toBuffer().length);
|
|
477
466
|
this.instrumentation.recordSize('witGenOutputSize', circuitName, output.toBuffer().length);
|
|
478
467
|
|
|
479
|
-
logger.
|
|
468
|
+
logger.info(`Generated witness`, {
|
|
480
469
|
circuitName,
|
|
481
470
|
duration: timer.ms(),
|
|
482
471
|
inputSize: input.toBuffer().length,
|
|
@@ -530,7 +519,7 @@ export class BBNativeRollupProver implements ServerCircuitProver {
|
|
|
530
519
|
const proof = new Proof(rawProof, vkData.numPublicInputs);
|
|
531
520
|
const circuitName = mapProtocolArtifactNameToCircuitName(circuitType);
|
|
532
521
|
|
|
533
|
-
this.instrumentation.recordDuration('provingDuration', circuitName, provingResult.durationMs
|
|
522
|
+
this.instrumentation.recordDuration('provingDuration', circuitName, provingResult.durationMs);
|
|
534
523
|
this.instrumentation.recordSize('proofSize', circuitName, proof.buffer.length);
|
|
535
524
|
this.instrumentation.recordSize('circuitPublicInputCount', circuitName, vkData.numPublicInputs);
|
|
536
525
|
this.instrumentation.recordSize('circuitSize', circuitName, vkData.circuitSize);
|
|
@@ -633,6 +622,12 @@ export class BBNativeRollupProver implements ServerCircuitProver {
|
|
|
633
622
|
// Read the proof as fields
|
|
634
623
|
const tubeVK = await extractVkData(provingResult.vkPath!);
|
|
635
624
|
const tubeProof = await this.readTubeProofAsFields(provingResult.proofPath!, tubeVK, TUBE_PROOF_LENGTH);
|
|
625
|
+
|
|
626
|
+
this.instrumentation.recordDuration('provingDuration', 'tubeCircuit', provingResult.durationMs);
|
|
627
|
+
this.instrumentation.recordSize('proofSize', 'tubeCircuit', tubeProof.binaryProof.buffer.length);
|
|
628
|
+
this.instrumentation.recordSize('circuitPublicInputCount', 'tubeCircuit', tubeVK.numPublicInputs);
|
|
629
|
+
this.instrumentation.recordSize('circuitSize', 'tubeCircuit', tubeVK.circuitSize);
|
|
630
|
+
|
|
636
631
|
// Sanity check the tube proof (can be removed later)
|
|
637
632
|
await this.verifyWithKey(tubeVK, tubeProof.binaryProof);
|
|
638
633
|
|
|
@@ -680,7 +675,7 @@ export class BBNativeRollupProver implements ServerCircuitProver {
|
|
|
680
675
|
const proof = await this.readProofAsFields(provingResult.proofPath!, circuitType, proofLength);
|
|
681
676
|
|
|
682
677
|
const circuitName = mapProtocolArtifactNameToCircuitName(circuitType);
|
|
683
|
-
this.instrumentation.recordDuration('provingDuration', circuitName, provingResult.durationMs
|
|
678
|
+
this.instrumentation.recordDuration('provingDuration', circuitName, provingResult.durationMs);
|
|
684
679
|
this.instrumentation.recordSize('proofSize', circuitName, proof.binaryProof.buffer.length);
|
|
685
680
|
this.instrumentation.recordSize('circuitPublicInputCount', circuitName, vkData.numPublicInputs);
|
|
686
681
|
this.instrumentation.recordSize('circuitSize', circuitName, vkData.circuitSize);
|
|
@@ -787,8 +782,7 @@ export class BBNativeRollupProver implements ServerCircuitProver {
|
|
|
787
782
|
}
|
|
788
783
|
|
|
789
784
|
const operation = async (bbWorkingDirectory: string) => {
|
|
790
|
-
|
|
791
|
-
const numPublicInputs = vk.numPublicInputs; // - AGGREGATION_OBJECT_LENGTH;
|
|
785
|
+
const numPublicInputs = vk.numPublicInputs - AGGREGATION_OBJECT_LENGTH;
|
|
792
786
|
const proofFullFilename = path.join(bbWorkingDirectory, PROOF_FILENAME);
|
|
793
787
|
const vkFullFilename = path.join(bbWorkingDirectory, VK_FILENAME);
|
|
794
788
|
|
|
@@ -900,11 +894,8 @@ export class BBNativeRollupProver implements ServerCircuitProver {
|
|
|
900
894
|
if (!vkData) {
|
|
901
895
|
throw new Error(`Invalid verification key for ${circuitType}`);
|
|
902
896
|
}
|
|
903
|
-
const numPublicInputs = vkData.numPublicInputs;
|
|
904
|
-
|
|
905
|
-
// const numPublicInputs = CIRCUITS_WITHOUT_AGGREGATION.has(circuitType)
|
|
906
|
-
// ? vkData.numPublicInputs
|
|
907
|
-
// : vkData.numPublicInputs - AGGREGATION_OBJECT_LENGTH;
|
|
897
|
+
const numPublicInputs = vkData.numPublicInputs - AGGREGATION_OBJECT_LENGTH;
|
|
898
|
+
|
|
908
899
|
const fieldsWithoutPublicInputs = json
|
|
909
900
|
.slice(0, 3)
|
|
910
901
|
.map(Fr.fromString)
|
|
@@ -949,7 +940,7 @@ export class BBNativeRollupProver implements ServerCircuitProver {
|
|
|
949
940
|
|
|
950
941
|
const json = JSON.parse(proofString);
|
|
951
942
|
|
|
952
|
-
const numPublicInputs = vkData.numPublicInputs;
|
|
943
|
+
const numPublicInputs = vkData.numPublicInputs - AGGREGATION_OBJECT_LENGTH;
|
|
953
944
|
if (numPublicInputs === 0) {
|
|
954
945
|
throw new Error(`Tube proof should have public inputs (e.g. the number of public inputs from PrivateKernelTail)`);
|
|
955
946
|
}
|
|
@@ -33,6 +33,7 @@ import {
|
|
|
33
33
|
makeRecursiveProof,
|
|
34
34
|
} from '@aztec/circuits.js';
|
|
35
35
|
import { createDebugLogger } from '@aztec/foundation/log';
|
|
36
|
+
import { sleep } from '@aztec/foundation/sleep';
|
|
36
37
|
import { Timer } from '@aztec/foundation/timer';
|
|
37
38
|
import {
|
|
38
39
|
ProtocolCircuitVkIndexes,
|
|
@@ -70,11 +71,12 @@ import { mapPublicKernelToCircuitName } from '../stats.js';
|
|
|
70
71
|
export class TestCircuitProver implements ServerCircuitProver {
|
|
71
72
|
private wasmSimulator = new WASMSimulator();
|
|
72
73
|
private instrumentation: ProverInstrumentation;
|
|
74
|
+
private logger = createDebugLogger('aztec:test-prover');
|
|
73
75
|
|
|
74
76
|
constructor(
|
|
75
77
|
telemetry: TelemetryClient,
|
|
76
78
|
private simulationProvider?: SimulationProvider,
|
|
77
|
-
private
|
|
79
|
+
private opts: { proverTestDelayMs: number } = { proverTestDelayMs: 0 },
|
|
78
80
|
) {
|
|
79
81
|
this.instrumentation = new ProverInstrumentation(telemetry, 'TestCircuitProver');
|
|
80
82
|
}
|
|
@@ -103,7 +105,7 @@ export class TestCircuitProver implements ServerCircuitProver {
|
|
|
103
105
|
SimulatedServerCircuitArtifacts.PrivateKernelEmptyArtifact,
|
|
104
106
|
);
|
|
105
107
|
const result = convertSimulatedPrivateKernelEmptyOutputsFromWitnessMap(witness);
|
|
106
|
-
|
|
108
|
+
await this.delay();
|
|
107
109
|
return makePublicInputsAndRecursiveProof(
|
|
108
110
|
result,
|
|
109
111
|
makeRecursiveProof(NESTED_RECURSIVE_PROOF_LENGTH),
|
|
@@ -131,7 +133,7 @@ export class TestCircuitProver implements ServerCircuitProver {
|
|
|
131
133
|
SimulatedServerCircuitArtifacts.PrivateKernelEmptyArtifact,
|
|
132
134
|
);
|
|
133
135
|
const result = convertPrivateKernelEmptyOutputsFromWitnessMap(witness);
|
|
134
|
-
|
|
136
|
+
await this.delay();
|
|
135
137
|
return makePublicInputsAndRecursiveProof(
|
|
136
138
|
result,
|
|
137
139
|
makeRecursiveProof(NESTED_RECURSIVE_PROOF_LENGTH),
|
|
@@ -172,7 +174,7 @@ export class TestCircuitProver implements ServerCircuitProver {
|
|
|
172
174
|
result.toBuffer().length,
|
|
173
175
|
this.logger,
|
|
174
176
|
);
|
|
175
|
-
|
|
177
|
+
await this.delay();
|
|
176
178
|
return Promise.resolve(rootParityInput);
|
|
177
179
|
}
|
|
178
180
|
|
|
@@ -211,7 +213,7 @@ export class TestCircuitProver implements ServerCircuitProver {
|
|
|
211
213
|
result.toBuffer().length,
|
|
212
214
|
this.logger,
|
|
213
215
|
);
|
|
214
|
-
|
|
216
|
+
await this.delay();
|
|
215
217
|
return Promise.resolve(rootParityInput);
|
|
216
218
|
}
|
|
217
219
|
|
|
@@ -243,6 +245,7 @@ export class TestCircuitProver implements ServerCircuitProver {
|
|
|
243
245
|
result.toBuffer().length,
|
|
244
246
|
this.logger,
|
|
245
247
|
);
|
|
248
|
+
await this.delay();
|
|
246
249
|
return makePublicInputsAndRecursiveProof(
|
|
247
250
|
result,
|
|
248
251
|
makeRecursiveProof(NESTED_RECURSIVE_PROOF_LENGTH),
|
|
@@ -250,13 +253,14 @@ export class TestCircuitProver implements ServerCircuitProver {
|
|
|
250
253
|
);
|
|
251
254
|
}
|
|
252
255
|
|
|
253
|
-
public getTubeProof(
|
|
256
|
+
public async getTubeProof(
|
|
254
257
|
_tubeInput: TubeInputs,
|
|
255
258
|
): Promise<{ tubeVK: VerificationKeyData; tubeProof: RecursiveProof<typeof TUBE_PROOF_LENGTH> }> {
|
|
256
|
-
|
|
259
|
+
await this.delay();
|
|
260
|
+
return {
|
|
257
261
|
tubeVK: VerificationKeyData.makeFake(),
|
|
258
262
|
tubeProof: makeEmptyRecursiveProof(TUBE_PROOF_LENGTH),
|
|
259
|
-
}
|
|
263
|
+
};
|
|
260
264
|
}
|
|
261
265
|
|
|
262
266
|
/**
|
|
@@ -287,6 +291,7 @@ export class TestCircuitProver implements ServerCircuitProver {
|
|
|
287
291
|
result.toBuffer().length,
|
|
288
292
|
this.logger,
|
|
289
293
|
);
|
|
294
|
+
await this.delay();
|
|
290
295
|
return makePublicInputsAndRecursiveProof(
|
|
291
296
|
result,
|
|
292
297
|
makeEmptyRecursiveProof(NESTED_RECURSIVE_PROOF_LENGTH),
|
|
@@ -322,6 +327,7 @@ export class TestCircuitProver implements ServerCircuitProver {
|
|
|
322
327
|
result.toBuffer().length,
|
|
323
328
|
this.logger,
|
|
324
329
|
);
|
|
330
|
+
await this.delay();
|
|
325
331
|
return makePublicInputsAndRecursiveProof(
|
|
326
332
|
result,
|
|
327
333
|
makeEmptyRecursiveProof(NESTED_RECURSIVE_PROOF_LENGTH),
|
|
@@ -355,7 +361,7 @@ export class TestCircuitProver implements ServerCircuitProver {
|
|
|
355
361
|
result.toBuffer().length,
|
|
356
362
|
this.logger,
|
|
357
363
|
);
|
|
358
|
-
|
|
364
|
+
await this.delay();
|
|
359
365
|
return makePublicInputsAndRecursiveProof(
|
|
360
366
|
result,
|
|
361
367
|
makeEmptyRecursiveProof(NESTED_RECURSIVE_PROOF_LENGTH),
|
|
@@ -384,7 +390,7 @@ export class TestCircuitProver implements ServerCircuitProver {
|
|
|
384
390
|
result.toBuffer().length,
|
|
385
391
|
this.logger,
|
|
386
392
|
);
|
|
387
|
-
|
|
393
|
+
await this.delay();
|
|
388
394
|
return makePublicInputsAndRecursiveProof(
|
|
389
395
|
result,
|
|
390
396
|
makeEmptyRecursiveProof(NESTED_RECURSIVE_PROOF_LENGTH),
|
|
@@ -392,11 +398,18 @@ export class TestCircuitProver implements ServerCircuitProver {
|
|
|
392
398
|
);
|
|
393
399
|
}
|
|
394
400
|
|
|
395
|
-
getAvmProof(_inputs: AvmCircuitInputs): Promise<ProofAndVerificationKey> {
|
|
401
|
+
public async getAvmProof(_inputs: AvmCircuitInputs): Promise<ProofAndVerificationKey> {
|
|
396
402
|
// We can't simulate the AVM because we don't have enough context to do so (e.g., DBs).
|
|
397
403
|
// We just return an empty proof and VK data.
|
|
398
404
|
this.logger.debug('Skipping AVM simulation in TestCircuitProver.');
|
|
399
|
-
|
|
405
|
+
await this.delay();
|
|
406
|
+
return { proof: makeEmptyProof(), verificationKey: VerificationKeyData.makeFake() };
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
private async delay(): Promise<void> {
|
|
410
|
+
if (this.opts.proverTestDelayMs > 0) {
|
|
411
|
+
await sleep(this.opts.proverTestDelayMs);
|
|
412
|
+
}
|
|
400
413
|
}
|
|
401
414
|
|
|
402
415
|
// Not implemented for test circuits
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type ClientProtocolCircuitVerifier, Tx } from '@aztec/circuit-types';
|
|
2
|
+
import { type CircuitVerificationStats } from '@aztec/circuit-types/stats';
|
|
2
3
|
import { type Proof, type VerificationKeyData } from '@aztec/circuits.js';
|
|
3
4
|
import { runInDirectory } from '@aztec/foundation/fs';
|
|
4
5
|
import { type DebugLogger, type LogFn, createDebugLogger } from '@aztec/foundation/log';
|
|
@@ -17,9 +18,11 @@ import {
|
|
|
17
18
|
VK_FILENAME,
|
|
18
19
|
generateContractForCircuit,
|
|
19
20
|
generateKeyForNoirCircuit,
|
|
21
|
+
verifyClientIvcProof,
|
|
20
22
|
verifyProof,
|
|
21
23
|
} from '../bb/execute.js';
|
|
22
24
|
import { type BBConfig } from '../config.js';
|
|
25
|
+
import { mapProtocolArtifactNameToCircuitName } from '../stats.js';
|
|
23
26
|
import { extractVkData } from '../verification_key/verification_key_data.js';
|
|
24
27
|
|
|
25
28
|
export class BBCircuitVerifier implements ClientProtocolCircuitVerifier {
|
|
@@ -106,7 +109,12 @@ export class BBCircuitVerifier implements ClientProtocolCircuitVerifier {
|
|
|
106
109
|
throw new Error(errorMessage);
|
|
107
110
|
}
|
|
108
111
|
|
|
109
|
-
this.logger.debug(`${circuit} verification successful
|
|
112
|
+
this.logger.debug(`${circuit} verification successful`, {
|
|
113
|
+
circuitName: mapProtocolArtifactNameToCircuitName(circuit),
|
|
114
|
+
duration: result.durationMs,
|
|
115
|
+
eventName: 'circuit-verification',
|
|
116
|
+
proofType: 'ultra-honk',
|
|
117
|
+
} satisfies CircuitVerificationStats);
|
|
110
118
|
};
|
|
111
119
|
await runInDirectory(this.config.bbWorkingDirectory, operation);
|
|
112
120
|
}
|
|
@@ -128,19 +136,43 @@ export class BBCircuitVerifier implements ClientProtocolCircuitVerifier {
|
|
|
128
136
|
return fs.readFile(result.contractPath!, 'utf-8');
|
|
129
137
|
}
|
|
130
138
|
|
|
131
|
-
verifyProof(tx: Tx): Promise<boolean> {
|
|
132
|
-
const expectedCircuit: ClientProtocolArtifact = tx.data.forPublic
|
|
133
|
-
? 'PrivateKernelTailToPublicArtifact'
|
|
134
|
-
: 'PrivateKernelTailArtifact';
|
|
135
|
-
|
|
139
|
+
public async verifyProof(tx: Tx): Promise<boolean> {
|
|
136
140
|
try {
|
|
137
|
-
// TODO(
|
|
138
|
-
//
|
|
139
|
-
//
|
|
140
|
-
|
|
141
|
+
// TODO(#7370) The verification keys should be supplied separately and based on the expectedCircuit
|
|
142
|
+
// rather than read from the tx object itself. We also need the vks for the translator and ecc, which
|
|
143
|
+
// are not being saved along the other vks yet. Reuse the 'verifyProofForCircuit' method above once
|
|
144
|
+
// we have all the verification keys available.
|
|
145
|
+
const expectedCircuit: ClientProtocolArtifact = tx.data.forPublic
|
|
146
|
+
? 'PrivateKernelTailToPublicArtifact'
|
|
147
|
+
: 'PrivateKernelTailArtifact';
|
|
148
|
+
const circuit = 'ClientIVC';
|
|
149
|
+
|
|
150
|
+
// Block below is almost copy-pasted from verifyProofForCircuit
|
|
151
|
+
const operation = async (bbWorkingDirectory: string) => {
|
|
152
|
+
const logFunction = (message: string) => {
|
|
153
|
+
this.logger.debug(`${circuit} BB out - ${message}`);
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
await tx.clientIvcProof.writeToOutputDirectory(bbWorkingDirectory);
|
|
157
|
+
const result = await verifyClientIvcProof(this.config.bbBinaryPath, bbWorkingDirectory, logFunction);
|
|
158
|
+
|
|
159
|
+
if (result.status === BB_RESULT.FAILURE) {
|
|
160
|
+
const errorMessage = `Failed to verify ${circuit} proof!`;
|
|
161
|
+
throw new Error(errorMessage);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
this.logger.debug(`${circuit} verification successful`, {
|
|
165
|
+
circuitName: mapProtocolArtifactNameToCircuitName(expectedCircuit),
|
|
166
|
+
duration: result.durationMs,
|
|
167
|
+
eventName: 'circuit-verification',
|
|
168
|
+
proofType: 'client-ivc',
|
|
169
|
+
} satisfies CircuitVerificationStats);
|
|
170
|
+
};
|
|
171
|
+
await runInDirectory(this.config.bbWorkingDirectory, operation);
|
|
172
|
+
return true;
|
|
141
173
|
} catch (err) {
|
|
142
|
-
this.logger.warn(`Failed to verify
|
|
143
|
-
return
|
|
174
|
+
this.logger.warn(`Failed to verify ClientIVC proof for tx ${Tx.getHash(tx)}: ${String(err)}`);
|
|
175
|
+
return false;
|
|
144
176
|
}
|
|
145
177
|
}
|
|
146
178
|
}
|