@aztec-labs/bb-prover 6.0.0-nightly.20260829

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.
Files changed (101) hide show
  1. package/dest/avm_proving_tests/avm_proving_tester.d.ts +27 -0
  2. package/dest/avm_proving_tests/avm_proving_tester.d.ts.map +1 -0
  3. package/dest/avm_proving_tests/avm_proving_tester.js +236 -0
  4. package/dest/bb/bb_js_backend.d.ts +196 -0
  5. package/dest/bb/bb_js_backend.d.ts.map +1 -0
  6. package/dest/bb/bb_js_backend.js +385 -0
  7. package/dest/bb/bb_js_debug.d.ts +52 -0
  8. package/dest/bb/bb_js_debug.d.ts.map +1 -0
  9. package/dest/bb/bb_js_debug.js +176 -0
  10. package/dest/bb/cli.d.ts +12 -0
  11. package/dest/bb/cli.d.ts.map +1 -0
  12. package/dest/bb/cli.js +19 -0
  13. package/dest/bb/file_names.d.ts +4 -0
  14. package/dest/bb/file_names.d.ts.map +1 -0
  15. package/dest/bb/file_names.js +5 -0
  16. package/dest/bb/index.d.ts +3 -0
  17. package/dest/bb/index.d.ts.map +1 -0
  18. package/dest/bb/index.js +16 -0
  19. package/dest/config.d.ts +31 -0
  20. package/dest/config.d.ts.map +1 -0
  21. package/dest/config.js +1 -0
  22. package/dest/honk.d.ts +13 -0
  23. package/dest/honk.d.ts.map +1 -0
  24. package/dest/honk.js +20 -0
  25. package/dest/index.d.ts +10 -0
  26. package/dest/index.d.ts.map +1 -0
  27. package/dest/index.js +8 -0
  28. package/dest/instrumentation.d.ts +47 -0
  29. package/dest/instrumentation.d.ts.map +1 -0
  30. package/dest/instrumentation.js +76 -0
  31. package/dest/prover/client/bb_private_kernel_prover.d.ts +54 -0
  32. package/dest/prover/client/bb_private_kernel_prover.d.ts.map +1 -0
  33. package/dest/prover/client/bb_private_kernel_prover.js +205 -0
  34. package/dest/prover/client/bundle.d.ts +6 -0
  35. package/dest/prover/client/bundle.d.ts.map +1 -0
  36. package/dest/prover/client/bundle.js +7 -0
  37. package/dest/prover/client/lazy.d.ts +6 -0
  38. package/dest/prover/client/lazy.d.ts.map +1 -0
  39. package/dest/prover/client/lazy.js +7 -0
  40. package/dest/prover/index.d.ts +3 -0
  41. package/dest/prover/index.d.ts.map +1 -0
  42. package/dest/prover/index.js +2 -0
  43. package/dest/prover/proof_utils.d.ts +29 -0
  44. package/dest/prover/proof_utils.d.ts.map +1 -0
  45. package/dest/prover/proof_utils.js +95 -0
  46. package/dest/prover/server/bb_prover.d.ts +88 -0
  47. package/dest/prover/server/bb_prover.d.ts.map +1 -0
  48. package/dest/prover/server/bb_prover.js +823 -0
  49. package/dest/test/delay_values.d.ts +4 -0
  50. package/dest/test/delay_values.d.ts.map +1 -0
  51. package/dest/test/delay_values.js +37 -0
  52. package/dest/test/index.d.ts +4 -0
  53. package/dest/test/index.d.ts.map +1 -0
  54. package/dest/test/index.js +3 -0
  55. package/dest/test/test_circuit_prover.d.ts +64 -0
  56. package/dest/test/test_circuit_prover.d.ts.map +1 -0
  57. package/dest/test/test_circuit_prover.js +576 -0
  58. package/dest/test/test_verifier.d.ts +9 -0
  59. package/dest/test/test_verifier.d.ts.map +1 -0
  60. package/dest/test/test_verifier.js +27 -0
  61. package/dest/verification_key/verification_key_data.d.ts +8 -0
  62. package/dest/verification_key/verification_key_data.d.ts.map +1 -0
  63. package/dest/verification_key/verification_key_data.js +19 -0
  64. package/dest/verifier/batch_chonk_verifier.d.ts +57 -0
  65. package/dest/verifier/batch_chonk_verifier.d.ts.map +1 -0
  66. package/dest/verifier/batch_chonk_verifier.js +389 -0
  67. package/dest/verifier/bb_verifier.d.ts +21 -0
  68. package/dest/verifier/bb_verifier.d.ts.map +1 -0
  69. package/dest/verifier/bb_verifier.js +193 -0
  70. package/dest/verifier/index.d.ts +4 -0
  71. package/dest/verifier/index.d.ts.map +1 -0
  72. package/dest/verifier/index.js +3 -0
  73. package/dest/verifier/queued_chonk_verifier.d.ts +26 -0
  74. package/dest/verifier/queued_chonk_verifier.d.ts.map +1 -0
  75. package/dest/verifier/queued_chonk_verifier.js +102 -0
  76. package/package.json +113 -0
  77. package/src/avm_proving_tests/avm_proving_tester.ts +235 -0
  78. package/src/bb/bb_js_backend.ts +442 -0
  79. package/src/bb/bb_js_debug.ts +227 -0
  80. package/src/bb/cli.ts +31 -0
  81. package/src/bb/file_names.ts +6 -0
  82. package/src/bb/index.ts +22 -0
  83. package/src/config.ts +31 -0
  84. package/src/honk.ts +35 -0
  85. package/src/index.ts +10 -0
  86. package/src/instrumentation.ts +119 -0
  87. package/src/prover/client/bb_private_kernel_prover.ts +531 -0
  88. package/src/prover/client/bundle.ts +10 -0
  89. package/src/prover/client/lazy.ts +10 -0
  90. package/src/prover/index.ts +2 -0
  91. package/src/prover/proof_utils.ts +154 -0
  92. package/src/prover/server/bb_prover.ts +658 -0
  93. package/src/test/delay_values.ts +41 -0
  94. package/src/test/index.ts +3 -0
  95. package/src/test/test_circuit_prover.ts +424 -0
  96. package/src/test/test_verifier.ts +20 -0
  97. package/src/verification_key/verification_key_data.ts +24 -0
  98. package/src/verifier/batch_chonk_verifier.ts +420 -0
  99. package/src/verifier/bb_verifier.ts +130 -0
  100. package/src/verifier/index.ts +3 -0
  101. package/src/verifier/queued_chonk_verifier.ts +108 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/verifier/index.ts"],"names":[],"mappings":"AAAA,cAAc,2BAA2B,CAAC;AAC1C,cAAc,kBAAkB,CAAC;AACjC,cAAc,4BAA4B,CAAC"}
@@ -0,0 +1,3 @@
1
+ export * from './batch_chonk_verifier.js';
2
+ export * from './bb_verifier.js';
3
+ export * from './queued_chonk_verifier.js';
@@ -0,0 +1,26 @@
1
+ import type { ClientProtocolCircuitVerifier, IVCProofVerificationResult } from '@aztec-labs/stdlib/interfaces/server';
2
+ import type { Tx } from '@aztec-labs/stdlib/tx';
3
+ import { type TelemetryClient } from '@aztec-labs/telemetry-client';
4
+ /** Records verification timing and failure metrics for an IVC (chonk) proof verifier. */
5
+ export declare class IVCVerifierMetrics {
6
+ private ivcVerificationHistogram;
7
+ private ivcTotalVerificationHistogram;
8
+ private ivcFailureCount;
9
+ private localHistogramOk;
10
+ private localHistogramFails;
11
+ private aggDurationMetrics;
12
+ constructor(client: TelemetryClient, name?: string);
13
+ recordIVCVerification(result: IVCProofVerificationResult): void;
14
+ private aggregate;
15
+ }
16
+ export declare class QueuedIVCVerifier implements ClientProtocolCircuitVerifier {
17
+ private verifier;
18
+ private telemetry;
19
+ private logger;
20
+ private queue;
21
+ private metrics;
22
+ constructor(verifier: ClientProtocolCircuitVerifier, concurrency: number, telemetry?: TelemetryClient, logger?: import("@aztec-labs/foundation/log").Logger);
23
+ verifyProof(tx: Tx): Promise<IVCProofVerificationResult>;
24
+ stop(): Promise<void>;
25
+ }
26
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicXVldWVkX2Nob25rX3ZlcmlmaWVyLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdmVyaWZpZXIvcXVldWVkX2Nob25rX3ZlcmlmaWVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUVBLE9BQU8sS0FBSyxFQUFFLDZCQUE2QixFQUFFLDBCQUEwQixFQUFFLE1BQU0sc0NBQXNDLENBQUM7QUFDdEgsT0FBTyxLQUFLLEVBQUUsRUFBRSxFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDaEQsT0FBTyxFQU1MLEtBQUssZUFBZSxFQUlyQixNQUFNLDhCQUE4QixDQUFDO0FBR3RDLHlGQUF5RjtBQUN6RixxQkFBYSxrQkFBa0I7SUFDN0IsT0FBTyxDQUFDLHdCQUF3QixDQUFZO0lBQzVDLE9BQU8sQ0FBQyw2QkFBNkIsQ0FBWTtJQUNqRCxPQUFPLENBQUMsZUFBZSxDQUFnQjtJQUN2QyxPQUFPLENBQUMsZ0JBQWdCLENBR3JCO0lBQ0gsT0FBTyxDQUFDLG1CQUFtQixDQUd4QjtJQUVILE9BQU8sQ0FBQyxrQkFBa0IsQ0FBaUU7SUFFM0YsWUFBWSxNQUFNLEVBQUUsZUFBZSxFQUFFLElBQUksU0FBc0IsRUFrQjlEO0lBRUQscUJBQXFCLENBQUMsTUFBTSxFQUFFLDBCQUEwQixRQVN2RDtJQUVELE9BQU8sQ0FBQyxTQUFTLENBY2Y7Q0FDSDtBQUVELHFCQUFhLGlCQUFrQixZQUFXLDZCQUE2QjtJQUtuRSxPQUFPLENBQUMsUUFBUTtJQUVoQixPQUFPLENBQUMsU0FBUztJQUNqQixPQUFPLENBQUMsTUFBTTtJQVBoQixPQUFPLENBQUMsS0FBSyxDQUFjO0lBQzNCLE9BQU8sQ0FBQyxPQUFPLENBQXFCO0lBRXBDLFlBQ1UsUUFBUSxFQUFFLDZCQUE2QixFQUMvQyxXQUFXLEVBQUUsTUFBTSxFQUNYLFNBQVMsR0FBRSxlQUFzQyxFQUNqRCxNQUFNLDhDQUFrRCxFQU1qRTtJQUVZLFdBQVcsQ0FBQyxFQUFFLEVBQUUsRUFBRSxHQUFHLE9BQU8sQ0FBQywwQkFBMEIsQ0FBQyxDQUlwRTtJQUVLLElBQUksSUFBSSxPQUFPLENBQUMsSUFBSSxDQUFDLENBRzFCO0NBQ0YifQ==
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queued_chonk_verifier.d.ts","sourceRoot":"","sources":["../../src/verifier/queued_chonk_verifier.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,6BAA6B,EAAE,0BAA0B,EAAE,MAAM,sCAAsC,CAAC;AACtH,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,uBAAuB,CAAC;AAChD,OAAO,EAML,KAAK,eAAe,EAIrB,MAAM,8BAA8B,CAAC;AAGtC,yFAAyF;AACzF,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,wBAAwB,CAAY;IAC5C,OAAO,CAAC,6BAA6B,CAAY;IACjD,OAAO,CAAC,eAAe,CAAgB;IACvC,OAAO,CAAC,gBAAgB,CAGrB;IACH,OAAO,CAAC,mBAAmB,CAGxB;IAEH,OAAO,CAAC,kBAAkB,CAAiE;IAE3F,YAAY,MAAM,EAAE,eAAe,EAAE,IAAI,SAAsB,EAkB9D;IAED,qBAAqB,CAAC,MAAM,EAAE,0BAA0B,QASvD;IAED,OAAO,CAAC,SAAS,CAcf;CACH;AAED,qBAAa,iBAAkB,YAAW,6BAA6B;IAKnE,OAAO,CAAC,QAAQ;IAEhB,OAAO,CAAC,SAAS;IACjB,OAAO,CAAC,MAAM;IAPhB,OAAO,CAAC,KAAK,CAAc;IAC3B,OAAO,CAAC,OAAO,CAAqB;IAEpC,YACU,QAAQ,EAAE,6BAA6B,EAC/C,WAAW,EAAE,MAAM,EACX,SAAS,GAAE,eAAsC,EACjD,MAAM,8CAAkD,EAMjE;IAEY,WAAW,CAAC,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,0BAA0B,CAAC,CAIpE;IAEK,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAG1B;CACF"}
@@ -0,0 +1,102 @@
1
+ import { createLogger } from '@aztec-labs/foundation/log';
2
+ import { SerialQueue } from '@aztec-labs/foundation/queue';
3
+ import { Attributes, Metrics, createUpDownCounterWithDefault, getTelemetryClient } from '@aztec-labs/telemetry-client';
4
+ import { createHistogram } from 'node:perf_hooks';
5
+ /** Records verification timing and failure metrics for an IVC (chonk) proof verifier. */ export class IVCVerifierMetrics {
6
+ ivcVerificationHistogram;
7
+ ivcTotalVerificationHistogram;
8
+ ivcFailureCount;
9
+ localHistogramOk = createHistogram({
10
+ min: 1,
11
+ max: 5 * 60 * 1000
12
+ });
13
+ localHistogramFails = createHistogram({
14
+ min: 1,
15
+ max: 5 * 60 * 1000
16
+ });
17
+ aggDurationMetrics;
18
+ constructor(client, name = 'QueuedIVCVerifier'){
19
+ const meter = client.getMeter(name);
20
+ this.ivcVerificationHistogram = meter.createHistogram(Metrics.IVC_VERIFIER_TIME);
21
+ this.ivcTotalVerificationHistogram = meter.createHistogram(Metrics.IVC_VERIFIER_TOTAL_TIME);
22
+ this.ivcFailureCount = createUpDownCounterWithDefault(meter, Metrics.IVC_VERIFIER_FAILURE_COUNT);
23
+ this.aggDurationMetrics = {
24
+ avg: meter.createObservableGauge(Metrics.IVC_VERIFIER_AGG_DURATION_AVG),
25
+ max: meter.createObservableGauge(Metrics.IVC_VERIFIER_AGG_DURATION_MAX),
26
+ min: meter.createObservableGauge(Metrics.IVC_VERIFIER_AGG_DURATION_MIN),
27
+ p50: meter.createObservableGauge(Metrics.IVC_VERIFIER_AGG_DURATION_P50),
28
+ p90: meter.createObservableGauge(Metrics.IVC_VERIFIER_AGG_DURATION_P90)
29
+ };
30
+ meter.addBatchObservableCallback(this.aggregate, Object.values(this.aggDurationMetrics));
31
+ }
32
+ recordIVCVerification(result) {
33
+ this.ivcVerificationHistogram.record(Math.ceil(result.durationMs), {
34
+ [Attributes.OK]: result.valid
35
+ });
36
+ this.ivcTotalVerificationHistogram.record(Math.ceil(result.totalDurationMs), {
37
+ [Attributes.OK]: result.valid
38
+ });
39
+ if (!result.valid) {
40
+ this.ivcFailureCount.add(1);
41
+ this.localHistogramFails.record(Math.max(Math.ceil(result.durationMs), 1));
42
+ } else {
43
+ this.localHistogramOk.record(Math.max(Math.ceil(result.durationMs), 1));
44
+ }
45
+ }
46
+ aggregate = (res)=>{
47
+ for (const [histogram, ok] of [
48
+ [
49
+ this.localHistogramOk,
50
+ true
51
+ ],
52
+ [
53
+ this.localHistogramFails,
54
+ false
55
+ ]
56
+ ]){
57
+ if (histogram.count === 0) {
58
+ continue;
59
+ }
60
+ res.observe(this.aggDurationMetrics.avg, histogram.mean, {
61
+ [Attributes.OK]: ok
62
+ });
63
+ res.observe(this.aggDurationMetrics.max, histogram.max, {
64
+ [Attributes.OK]: ok
65
+ });
66
+ res.observe(this.aggDurationMetrics.min, histogram.min, {
67
+ [Attributes.OK]: ok
68
+ });
69
+ res.observe(this.aggDurationMetrics.p50, histogram.percentile(50), {
70
+ [Attributes.OK]: ok
71
+ });
72
+ res.observe(this.aggDurationMetrics.p90, histogram.percentile(90), {
73
+ [Attributes.OK]: ok
74
+ });
75
+ }
76
+ };
77
+ }
78
+ export class QueuedIVCVerifier {
79
+ verifier;
80
+ telemetry;
81
+ logger;
82
+ queue;
83
+ metrics;
84
+ constructor(verifier, concurrency, telemetry = getTelemetryClient(), logger = createLogger('bb-prover:queued_chonk_verifier')){
85
+ this.verifier = verifier;
86
+ this.telemetry = telemetry;
87
+ this.logger = logger;
88
+ this.metrics = new IVCVerifierMetrics(this.telemetry, 'QueuedIVCVerifier');
89
+ this.queue = new SerialQueue();
90
+ this.logger.info(`Starting QueuedIVCVerifier with ${concurrency} concurrent verifiers`);
91
+ this.queue.start(concurrency);
92
+ }
93
+ async verifyProof(tx) {
94
+ const result = await this.queue.put(()=>this.verifier.verifyProof(tx));
95
+ this.metrics.recordIVCVerification(result);
96
+ return result;
97
+ }
98
+ async stop() {
99
+ await this.queue.end();
100
+ await this.verifier.stop();
101
+ }
102
+ }
package/package.json ADDED
@@ -0,0 +1,113 @@
1
+ {
2
+ "name": "@aztec-labs/bb-prover",
3
+ "version": "6.0.0-nightly.20260829",
4
+ "type": "module",
5
+ "exports": {
6
+ ".": "./dest/index.js",
7
+ "./client/bundle": "./dest/prover/client/bundle.js",
8
+ "./client/lazy": "./dest/prover/client/lazy.js",
9
+ "./client": "./dest/prover/client/bb_private_kernel_prover.js",
10
+ "./verifier": "./dest/verifier/index.js",
11
+ "./test": "./dest/test/index.js",
12
+ "./config": "./dest/config.js",
13
+ "./debug": "./dest/bb/bb_js_debug.js"
14
+ },
15
+ "bin": {
16
+ "bb-cli": "./dest/bb/index.js"
17
+ },
18
+ "typedocOptions": {
19
+ "entryPoints": [
20
+ "./src/index.ts"
21
+ ],
22
+ "name": "BB Prover",
23
+ "tsconfig": "./tsconfig.json"
24
+ },
25
+ "inherits": [
26
+ "../package.common.json"
27
+ ],
28
+ "scripts": {
29
+ "build": "yarn clean && ../scripts/tsc.sh",
30
+ "build:dev": "../scripts/tsc.sh --watch",
31
+ "clean": "rm -rf ./dest .tsbuildinfo",
32
+ "bb": "node --no-warnings ./dest/bb/index.js",
33
+ "test": "NODE_NO_WARNINGS=1 node --experimental-vm-modules ../node_modules/.bin/jest --passWithNoTests --maxWorkers=${JEST_MAX_WORKERS:-8}"
34
+ },
35
+ "jest": {
36
+ "moduleNameMapper": {
37
+ "^(\\.{1,2}/.*)\\.[cm]?js$": "$1"
38
+ },
39
+ "testRegex": "./src/.*\\.test\\.(js|mjs|ts)$",
40
+ "rootDir": "./src",
41
+ "transform": {
42
+ "^.+\\.tsx?$": [
43
+ "@swc/jest",
44
+ {
45
+ "jsc": {
46
+ "parser": {
47
+ "syntax": "typescript",
48
+ "decorators": true
49
+ },
50
+ "transform": {
51
+ "decoratorVersion": "2022-03"
52
+ }
53
+ }
54
+ }
55
+ ]
56
+ },
57
+ "extensionsToTreatAsEsm": [
58
+ ".ts"
59
+ ],
60
+ "reporters": [
61
+ "default"
62
+ ],
63
+ "testTimeout": 120000,
64
+ "setupFiles": [
65
+ "../../foundation/src/jest/setup.mjs"
66
+ ],
67
+ "testEnvironment": "../../foundation/src/jest/env.mjs",
68
+ "setupFilesAfterEnv": [
69
+ "../../foundation/src/jest/setupAfterEnv.mjs"
70
+ ]
71
+ },
72
+ "dependencies": {
73
+ "@aztec-labs/constants": "6.0.0-nightly.20260829",
74
+ "@aztec-labs/foundation": "6.0.0-nightly.20260829",
75
+ "@aztec-labs/noir-protocol-circuits-types": "6.0.0-nightly.20260829",
76
+ "@aztec-labs/simulator": "6.0.0-nightly.20260829",
77
+ "@aztec-labs/stdlib": "6.0.0-nightly.20260829",
78
+ "@aztec-labs/telemetry-client": "6.0.0-nightly.20260829",
79
+ "@aztec/bb.js": "6.0.0-nightly.20260826",
80
+ "@aztec/noir-noirc_abi": "6.0.0-nightly.20260826",
81
+ "@aztec/noir-types": "6.0.0-nightly.20260826",
82
+ "commander": "^12.1.0",
83
+ "msgpackr": "^1.11.2",
84
+ "pako": "^2.1.0",
85
+ "source-map-support": "^0.5.21",
86
+ "tslib": "^2.4.0"
87
+ },
88
+ "devDependencies": {
89
+ "@aztec-labs/noir-contracts.js": "6.0.0-nightly.20260829",
90
+ "@aztec-labs/noir-test-contracts.js": "6.0.0-nightly.20260829",
91
+ "@aztec-labs/protocol-contracts": "6.0.0-nightly.20260829",
92
+ "@aztec-labs/world-state": "6.0.0-nightly.20260829",
93
+ "@jest/globals": "^30.0.0",
94
+ "@types/jest": "^30.0.0",
95
+ "@types/node": "^22.15.17",
96
+ "@types/source-map-support": "^0.5.10",
97
+ "@typescript/native-preview": "7.0.0-dev.20260113.1",
98
+ "jest": "^30.0.0",
99
+ "jest-mock-extended": "^4.0.0",
100
+ "ts-node": "^10.9.1",
101
+ "typescript": "^5.3.3",
102
+ "viem": "npm:@aztec/viem@2.38.2"
103
+ },
104
+ "files": [
105
+ "dest",
106
+ "src",
107
+ "!*.test.*"
108
+ ],
109
+ "types": "./dest/index.d.ts",
110
+ "engines": {
111
+ "node": ">=20.10"
112
+ }
113
+ }
@@ -0,0 +1,235 @@
1
+ import type { AvmStat } from '@aztec/bb.js';
2
+
3
+ import { createLogger } from '@aztec-labs/foundation/log';
4
+ import { Timer } from '@aztec-labs/foundation/timer';
5
+ import {
6
+ type MeasuredSimulatorFactory,
7
+ PublicTxSimulationTester,
8
+ SimpleContractDataSource,
9
+ type TestEnqueuedCall,
10
+ type TestExecutorMetrics,
11
+ type TestPrivateInsertions,
12
+ } from '@aztec-labs/simulator/public/fixtures';
13
+ import { AvmSimulatorPool, MeasuredPublicTxSimulator } from '@aztec-labs/simulator/server';
14
+ import type { PublicTxResult } from '@aztec-labs/simulator/server';
15
+ import { AvmCircuitInputs, AvmCircuitPublicInputs, PublicSimulatorConfig } from '@aztec-labs/stdlib/avm';
16
+ import { AztecAddress } from '@aztec-labs/stdlib/aztec-address';
17
+ import type { Gas } from '@aztec-labs/stdlib/gas';
18
+ import type { MerkleTreeWriteOperations } from '@aztec-labs/stdlib/interfaces/server';
19
+ import type { GlobalVariables } from '@aztec-labs/stdlib/tx';
20
+ import { NativeWorldStateService } from '@aztec-labs/world-state';
21
+ import path from 'path';
22
+
23
+ import { BBJsFactory } from '../bb/bb_js_backend.js';
24
+
25
+ const BB_PATH = path.resolve('../../labs-aztec-toolchain/bin/bb-avm');
26
+
27
+ // Config with collectHints enabled for proving tests
28
+ const provingConfig: PublicSimulatorConfig = PublicSimulatorConfig.from({
29
+ skipFeeEnforcement: false,
30
+ collectCallMetadata: true, // For results.
31
+ collectDebugLogs: false,
32
+ collectHints: true, // Required for proving!
33
+ collectPublicInputs: true, // Required for proving!
34
+ collectStatistics: false,
35
+ });
36
+
37
+ export class AvmProvingTester extends PublicTxSimulationTester {
38
+ private readonly bbJsFactory = new BBJsFactory(BB_PATH, {
39
+ debugDir: process.env.BB_DEBUG_OUTPUT_DIR,
40
+ logger: createLogger('bb-prover:avm-proving-tester'),
41
+ });
42
+
43
+ constructor(
44
+ private checkCircuitOnly: boolean,
45
+ contractDataSource: SimpleContractDataSource,
46
+ merkleTrees: MerkleTreeWriteOperations,
47
+ globals?: GlobalVariables,
48
+ metrics?: TestExecutorMetrics,
49
+ simulatorFactory?: MeasuredSimulatorFactory,
50
+ ) {
51
+ super(merkleTrees, contractDataSource, globals, metrics, simulatorFactory, provingConfig);
52
+ }
53
+
54
+ static async new(
55
+ worldStateService: NativeWorldStateService, // make sure to close this later
56
+ checkCircuitOnly: boolean = false,
57
+ globals?: GlobalVariables,
58
+ metrics?: TestExecutorMetrics,
59
+ ) {
60
+ const contractDataSource = new SimpleContractDataSource();
61
+ const merkleTrees = await worldStateService.fork();
62
+
63
+ const avmSimulator = await AvmSimulatorPool.spawn({ wsdbIpcPath: worldStateService.getIpcPath() });
64
+ const simulatorFactory: MeasuredSimulatorFactory = (mt, cdb, g, m, c) =>
65
+ new MeasuredPublicTxSimulator(avmSimulator, g, cdb, mt.getRevision().forkId, m, c, undefined);
66
+
67
+ const tester = new AvmProvingTester(
68
+ checkCircuitOnly,
69
+ contractDataSource,
70
+ merkleTrees,
71
+ globals,
72
+ metrics,
73
+ simulatorFactory,
74
+ );
75
+ tester.avmSimulator = avmSimulator;
76
+ return tester;
77
+ }
78
+
79
+ public override async close(): Promise<void> {
80
+ const results = await Promise.allSettled([super.close(), this.bbJsFactory.destroy()]);
81
+ const errors = results.flatMap(result => (result.status === 'rejected' ? [result.reason] : []));
82
+ if (errors.length > 0) {
83
+ throw new AggregateError(errors, `Failed to close AVM proving tester`);
84
+ }
85
+ }
86
+
87
+ /**
88
+ * Generate an AVM proof (or run check-circuit if configured). Records per-stage timings in the test metrics.
89
+ * Returns the in-memory proof fields on success; throws via jest expect() on failure.
90
+ */
91
+ async prove(avmCircuitInputs: AvmCircuitInputs, txLabel: string = 'unlabeledTx'): Promise<Uint8Array[]> {
92
+ const inputsBuffer = avmCircuitInputs.serializeWithMessagePack();
93
+
94
+ if (this.checkCircuitOnly) {
95
+ await using instance = await this.bbJsFactory.getInstance();
96
+ const { passed, stats } = await instance.checkAvmCircuit(inputsBuffer);
97
+ this.recordProverMetrics(stats, txLabel);
98
+ expect(passed).toBe(true);
99
+ return [];
100
+ }
101
+
102
+ await using instance = await this.bbJsFactory.getInstance();
103
+ const { proof, stats } = await instance.generateAvmProof(inputsBuffer);
104
+ this.recordProverMetrics(stats, txLabel);
105
+ return proof;
106
+ }
107
+
108
+ async verify(proof: Uint8Array[], publicInputs: AvmCircuitPublicInputs): Promise<void> {
109
+ if (this.checkCircuitOnly) {
110
+ // Check-circuit did not generate a proof; nothing to verify.
111
+ return;
112
+ }
113
+ const piBuffer = publicInputs.serializeWithMessagePack();
114
+ await using instance = await this.bbJsFactory.getInstance();
115
+ const { verified } = await instance.verifyAvmProof(proof, piBuffer);
116
+ expect(verified).toBe(true);
117
+ }
118
+
119
+ public async proveVerify(avmCircuitInputs: AvmCircuitInputs, txLabel: string = 'unlabeledTx') {
120
+ const proof = await this.prove(avmCircuitInputs, txLabel);
121
+ await this.verify(proof, avmCircuitInputs.publicInputs);
122
+ }
123
+
124
+ private recordProverMetrics(stats: AvmStat[], txLabel: string) {
125
+ // Build a lookup keyed on the stage name with the `_ms` suffix stripped, matching the legacy
126
+ // stdout-scraped shape. bb::avm2::Stats::time() stores keys with `_ms` appended.
127
+ const times: { [key: string]: number } = {};
128
+ for (const { name, valueMs } of stats) {
129
+ const key = name.endsWith('_ms') ? name.slice(0, -'_ms'.length) : name;
130
+ times[key] = valueMs;
131
+ }
132
+ if (Object.keys(times).length === 0) {
133
+ throw new Error('AVM response did not contain any proving-stage timings!');
134
+ }
135
+ // Hack to make labels match.
136
+ const txLabelWithCount = `${txLabel}/${this.txCount - 1}`;
137
+ // Cast because TS doesn't realize `metrics` is protected, not private on the parent class.
138
+ (this as any).metrics?.recordProverMetrics(txLabelWithCount, {
139
+ proverSimulationStepMs: times['simulation/all'],
140
+ proverProvingStepMs: times['proving/all'],
141
+ proverTraceGenerationStepMs: times['tracegen/all'],
142
+ traceGenerationInteractionsMs: times['tracegen/interactions'],
143
+ traceGenerationTracesMs: times['tracegen/traces'],
144
+ provingSumcheckMs: times['prove/sumcheck'],
145
+ provingPcsMs: times['prove/pcs_rounds'],
146
+ provingLogDerivativeInverseMs: times['prove/log_derivative_inverse_round'],
147
+ provingLogDerivativeInverseCommitmentsMs: times['prove/log_derivative_inverse_commitments_round'],
148
+ provingWireCommitmentsMs: times['prove/wire_commitments_round'],
149
+ });
150
+ }
151
+
152
+ public async simProveVerify(
153
+ sender: AztecAddress,
154
+ setupCalls: TestEnqueuedCall[],
155
+ appCalls: TestEnqueuedCall[],
156
+ teardownCall: TestEnqueuedCall | undefined,
157
+ expectRevert: boolean | undefined,
158
+ feePayer = sender,
159
+ privateInsertions?: TestPrivateInsertions,
160
+ txLabel: string = 'unlabeledTx',
161
+ disableRevertCheck: boolean = false,
162
+ gasLimits?: Gas,
163
+ ): Promise<PublicTxResult> {
164
+ const simTimer = new Timer();
165
+ const simRes = await this.simulateTx(
166
+ sender,
167
+ setupCalls,
168
+ appCalls,
169
+ teardownCall,
170
+ feePayer,
171
+ privateInsertions,
172
+ txLabel,
173
+ gasLimits,
174
+ );
175
+ const simDuration = simTimer.ms();
176
+ this.logger.info(`Simulation took ${simDuration} ms for tx ${txLabel}`);
177
+
178
+ if (!disableRevertCheck) {
179
+ expect(simRes.revertCode.isOK()).toBe(expectRevert ? false : true);
180
+ }
181
+
182
+ const opString = this.checkCircuitOnly ? 'Check circuit' : 'Proving and verification';
183
+
184
+ const avmCircuitInputs = new AvmCircuitInputs(simRes.hints!, simRes.publicInputs!);
185
+ const timer = new Timer();
186
+ await this.proveVerify(avmCircuitInputs, txLabel);
187
+ this.logger.info(`${opString} took ${timer.ms()} ms for tx ${txLabel}`);
188
+
189
+ return simRes;
190
+ }
191
+
192
+ public override async executeTxWithLabel(
193
+ txLabel: string,
194
+ sender: AztecAddress,
195
+ setupCalls?: TestEnqueuedCall[],
196
+ appCalls?: TestEnqueuedCall[],
197
+ teardownCall?: TestEnqueuedCall,
198
+ feePayer?: AztecAddress,
199
+ privateInsertions?: TestPrivateInsertions,
200
+ gasLimits?: Gas,
201
+ ) {
202
+ return await this.simProveVerify(
203
+ sender,
204
+ setupCalls ?? [],
205
+ appCalls ?? [],
206
+ teardownCall,
207
+ undefined,
208
+ feePayer,
209
+ privateInsertions,
210
+ txLabel,
211
+ true,
212
+ gasLimits,
213
+ );
214
+ }
215
+
216
+ public async simProveVerifyAppLogic(
217
+ appCall: TestEnqueuedCall,
218
+ expectRevert?: boolean,
219
+ txLabel: string = 'unlabeledTx',
220
+ gasLimits?: Gas,
221
+ ) {
222
+ await this.simProveVerify(
223
+ /*sender=*/ AztecAddress.fromNumberUnsafe(42),
224
+ /*setupCalls=*/ [],
225
+ [appCall],
226
+ undefined,
227
+ expectRevert,
228
+ /*feePayer=*/ undefined,
229
+ /*privateInsertions=*/ undefined,
230
+ txLabel,
231
+ /*disableRevertCheck=*/ false,
232
+ gasLimits,
233
+ );
234
+ }
235
+ }