@aztec/bb-prover 0.0.0-test.0 → 0.0.1-commit.0208eb9

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 (112) hide show
  1. package/dest/avm_proving_tests/avm_proving_tester.d.ts +14 -18
  2. package/dest/avm_proving_tests/avm_proving_tester.d.ts.map +1 -1
  3. package/dest/avm_proving_tests/avm_proving_tester.js +146 -79
  4. package/dest/bb/cli.d.ts +1 -1
  5. package/dest/bb/execute.d.ts +17 -50
  6. package/dest/bb/execute.d.ts.map +1 -1
  7. package/dest/bb/execute.js +145 -278
  8. package/dest/bb/index.d.ts +1 -1
  9. package/dest/config.d.ts +3 -1
  10. package/dest/config.d.ts.map +1 -1
  11. package/dest/honk.d.ts +3 -3
  12. package/dest/honk.d.ts.map +1 -1
  13. package/dest/honk.js +3 -2
  14. package/dest/index.d.ts +2 -1
  15. package/dest/index.d.ts.map +1 -1
  16. package/dest/index.js +1 -0
  17. package/dest/instrumentation.d.ts +3 -3
  18. package/dest/instrumentation.d.ts.map +1 -1
  19. package/dest/instrumentation.js +11 -43
  20. package/dest/prover/client/bb_private_kernel_prover.d.ts +38 -0
  21. package/dest/prover/client/bb_private_kernel_prover.d.ts.map +1 -0
  22. package/dest/prover/{bb_private_kernel_prover.js → client/bb_private_kernel_prover.js} +53 -21
  23. package/dest/prover/client/bundle.d.ts +6 -0
  24. package/dest/prover/client/bundle.d.ts.map +1 -0
  25. package/dest/prover/client/bundle.js +7 -0
  26. package/dest/prover/client/lazy.d.ts +6 -0
  27. package/dest/prover/client/lazy.d.ts.map +1 -0
  28. package/dest/prover/client/lazy.js +7 -0
  29. package/dest/prover/index.d.ts +3 -4
  30. package/dest/prover/index.d.ts.map +1 -1
  31. package/dest/prover/index.js +2 -3
  32. package/dest/prover/proof_utils.d.ts +19 -0
  33. package/dest/prover/proof_utils.d.ts.map +1 -0
  34. package/dest/prover/proof_utils.js +72 -0
  35. package/dest/prover/server/bb_prover.d.ts +97 -0
  36. package/dest/prover/server/bb_prover.d.ts.map +1 -0
  37. package/dest/prover/server/bb_prover.js +712 -0
  38. package/dest/test/delay_values.d.ts +1 -1
  39. package/dest/test/delay_values.d.ts.map +1 -1
  40. package/dest/test/delay_values.js +37 -23
  41. package/dest/test/index.d.ts +2 -1
  42. package/dest/test/index.d.ts.map +1 -1
  43. package/dest/test/index.js +1 -0
  44. package/dest/test/test_circuit_prover.d.ts +27 -36
  45. package/dest/test/test_circuit_prover.d.ts.map +1 -1
  46. package/dest/test/test_circuit_prover.js +517 -88
  47. package/dest/test/test_verifier.d.ts +6 -3
  48. package/dest/test/test_verifier.d.ts.map +1 -1
  49. package/dest/test/test_verifier.js +23 -1
  50. package/dest/verification_key/verification_key_data.d.ts +1 -2
  51. package/dest/verification_key/verification_key_data.d.ts.map +1 -1
  52. package/dest/verification_key/verification_key_data.js +9 -34
  53. package/dest/verifier/bb_verifier.d.ts +6 -5
  54. package/dest/verifier/bb_verifier.d.ts.map +1 -1
  55. package/dest/verifier/bb_verifier.js +45 -27
  56. package/dest/verifier/index.d.ts +2 -1
  57. package/dest/verifier/index.d.ts.map +1 -1
  58. package/dest/verifier/index.js +1 -0
  59. package/dest/verifier/queued_chonk_verifier.d.ts +15 -0
  60. package/dest/verifier/queued_chonk_verifier.d.ts.map +1 -0
  61. package/dest/verifier/queued_chonk_verifier.js +101 -0
  62. package/package.json +35 -33
  63. package/src/avm_proving_tests/avm_proving_tester.ts +223 -113
  64. package/src/bb/execute.ts +116 -291
  65. package/src/config.ts +2 -0
  66. package/src/honk.ts +3 -2
  67. package/src/index.ts +1 -0
  68. package/src/instrumentation.ts +10 -43
  69. package/src/prover/{bb_private_kernel_prover.ts → client/bb_private_kernel_prover.ts} +94 -33
  70. package/src/prover/client/bundle.ts +10 -0
  71. package/src/prover/client/lazy.ts +10 -0
  72. package/src/prover/index.ts +2 -3
  73. package/src/prover/proof_utils.ts +115 -0
  74. package/src/prover/server/bb_prover.ts +718 -0
  75. package/src/test/delay_values.ts +38 -22
  76. package/src/test/index.ts +1 -0
  77. package/src/test/test_circuit_prover.ts +264 -154
  78. package/src/test/test_verifier.ts +15 -3
  79. package/src/verification_key/verification_key_data.ts +11 -31
  80. package/src/verifier/bb_verifier.ts +62 -35
  81. package/src/verifier/index.ts +1 -0
  82. package/src/verifier/queued_chonk_verifier.ts +109 -0
  83. package/dest/prover/bb_native_private_kernel_prover.d.ts +0 -25
  84. package/dest/prover/bb_native_private_kernel_prover.d.ts.map +0 -1
  85. package/dest/prover/bb_native_private_kernel_prover.js +0 -69
  86. package/dest/prover/bb_private_kernel_prover.d.ts +0 -32
  87. package/dest/prover/bb_private_kernel_prover.d.ts.map +0 -1
  88. package/dest/prover/bb_prover.d.ts +0 -120
  89. package/dest/prover/bb_prover.d.ts.map +0 -1
  90. package/dest/prover/bb_prover.js +0 -423
  91. package/dest/prover/client_ivc_proof_utils.d.ts +0 -25
  92. package/dest/prover/client_ivc_proof_utils.d.ts.map +0 -1
  93. package/dest/prover/client_ivc_proof_utils.js +0 -43
  94. package/dest/stats.d.ts +0 -5
  95. package/dest/stats.d.ts.map +0 -1
  96. package/dest/stats.js +0 -62
  97. package/dest/wasm/bb_wasm_private_kernel_prover.d.ts +0 -17
  98. package/dest/wasm/bb_wasm_private_kernel_prover.d.ts.map +0 -1
  99. package/dest/wasm/bb_wasm_private_kernel_prover.js +0 -46
  100. package/dest/wasm/bundle.d.ts +0 -6
  101. package/dest/wasm/bundle.d.ts.map +0 -1
  102. package/dest/wasm/bundle.js +0 -8
  103. package/dest/wasm/lazy.d.ts +0 -6
  104. package/dest/wasm/lazy.d.ts.map +0 -1
  105. package/dest/wasm/lazy.js +0 -8
  106. package/src/prover/bb_native_private_kernel_prover.ts +0 -119
  107. package/src/prover/bb_prover.ts +0 -781
  108. package/src/prover/client_ivc_proof_utils.ts +0 -42
  109. package/src/stats.ts +0 -64
  110. package/src/wasm/bb_wasm_private_kernel_prover.ts +0 -55
  111. package/src/wasm/bundle.ts +0 -11
  112. package/src/wasm/lazy.ts +0 -11
package/src/bb/execute.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { sha256 } from '@aztec/foundation/crypto';
1
+ import { sha256 } from '@aztec/foundation/crypto/sha256';
2
2
  import type { LogFn, Logger } from '@aztec/foundation/log';
3
3
  import { Timer } from '@aztec/foundation/timer';
4
4
  import type { AvmCircuitInputs, AvmCircuitPublicInputs } from '@aztec/stdlib/avm';
@@ -6,18 +6,16 @@ import type { AvmCircuitInputs, AvmCircuitPublicInputs } from '@aztec/stdlib/avm
6
6
  import * as proc from 'child_process';
7
7
  import { promises as fs } from 'fs';
8
8
  import { basename, dirname, join } from 'path';
9
+ import readline from 'readline';
9
10
 
10
11
  import type { UltraHonkFlavor } from '../honk.js';
11
- import { CLIENT_IVC_PROOF_FILE_NAME, CLIENT_IVC_VK_FILE_NAME } from '../prover/client_ivc_proof_utils.js';
12
12
 
13
13
  export const VK_FILENAME = 'vk';
14
- export const VK_FIELDS_FILENAME = 'vk_fields.json';
14
+ export const PUBLIC_INPUTS_FILENAME = 'public_inputs';
15
15
  export const PROOF_FILENAME = 'proof';
16
- export const PROOF_FIELDS_FILENAME = 'proof_fields.json';
17
16
  export const AVM_INPUTS_FILENAME = 'avm_inputs.bin';
18
17
  export const AVM_BYTECODE_FILENAME = 'avm_bytecode.bin';
19
18
  export const AVM_PUBLIC_INPUTS_FILENAME = 'avm_public_inputs.bin';
20
- export const AVM_HINTS_FILENAME = 'avm_hints.bin';
21
19
 
22
20
  export enum BB_RESULT {
23
21
  SUCCESS,
@@ -31,7 +29,7 @@ export type BBSuccess = {
31
29
  /** Full path of the public key. */
32
30
  pkPath?: string;
33
31
  /** Base directory for the VKs (raw, fields). */
34
- vkPath?: string;
32
+ vkDirectoryPath?: string;
35
33
  /** Full path of the proof. */
36
34
  proofPath?: string;
37
35
  /** Full path of the contract. */
@@ -48,8 +46,6 @@ export type BBFailure = {
48
46
 
49
47
  export type BBResult = BBSuccess | BBFailure;
50
48
 
51
- export type VerificationFunction = typeof verifyProof | typeof verifyAvmProof;
52
-
53
49
  type BBExecResult = {
54
50
  status: BB_RESULT;
55
51
  exitCode: number;
@@ -62,6 +58,7 @@ type BBExecResult = {
62
58
  * @param command - The command to execute
63
59
  * @param args - The arguments to pass
64
60
  * @param logger - A log function
61
+ * @param timeout - An optional timeout before killing the BB process
65
62
  * @param resultParser - An optional handler for detecting success or failure
66
63
  * @returns The completed partial witness outputted from the circuit
67
64
  */
@@ -70,25 +67,47 @@ export function executeBB(
70
67
  command: string,
71
68
  args: string[],
72
69
  logger: LogFn,
70
+ concurrency?: number,
71
+ timeout?: number,
73
72
  resultParser = (code: number) => code === 0,
74
73
  ): Promise<BBExecResult> {
75
74
  return new Promise<BBExecResult>(resolve => {
76
75
  // spawn the bb process
77
76
  const { HARDWARE_CONCURRENCY: _, ...envWithoutConcurrency } = process.env;
78
- const env = process.env.HARDWARE_CONCURRENCY ? process.env : envWithoutConcurrency;
77
+
78
+ const env = envWithoutConcurrency;
79
+ // We prioritise the concurrency argument if provided and > 0
80
+ if (concurrency && concurrency > 0) {
81
+ env.HARDWARE_CONCURRENCY = concurrency.toString();
82
+ } else if (process.env.HARDWARE_CONCURRENCY) {
83
+ env.HARDWARE_CONCURRENCY = process.env.HARDWARE_CONCURRENCY;
84
+ }
85
+
86
+ logger(`BB concurrency: ${env.HARDWARE_CONCURRENCY}`);
79
87
  logger(`Executing BB with: ${pathToBB} ${command} ${args.join(' ')}`);
80
88
  const bb = proc.spawn(pathToBB, [command, ...args], {
89
+ stdio: ['ignore', 'pipe', 'pipe'],
81
90
  env,
82
91
  });
83
- bb.stdout.on('data', data => {
84
- const message = data.toString('utf-8').replace(/\n$/, '');
85
- logger(message);
86
- });
87
- bb.stderr.on('data', data => {
88
- const message = data.toString('utf-8').replace(/\n$/, '');
89
- logger(message);
90
- });
92
+
93
+ let timeoutId: NodeJS.Timeout | undefined;
94
+ if (timeout !== undefined) {
95
+ timeoutId = setTimeout(() => {
96
+ logger(`BB execution timed out after ${timeout}ms, killing process`);
97
+ if (bb.pid) {
98
+ bb.kill('SIGKILL');
99
+ }
100
+ resolve({ status: BB_RESULT.FAILURE, exitCode: -1, signal: 'TIMEOUT' });
101
+ }, timeout);
102
+ }
103
+
104
+ readline.createInterface({ input: bb.stdout }).on('line', logger);
105
+ readline.createInterface({ input: bb.stderr }).on('line', logger);
106
+
91
107
  bb.on('close', (exitCode: number, signal?: string) => {
108
+ if (timeoutId) {
109
+ clearTimeout(timeoutId);
110
+ }
92
111
  if (resultParser(exitCode)) {
93
112
  resolve({ status: BB_RESULT.SUCCESS, exitCode, signal });
94
113
  } else {
@@ -98,18 +117,17 @@ export function executeBB(
98
117
  }).catch(_ => ({ status: BB_RESULT.FAILURE, exitCode: -1, signal: undefined }));
99
118
  }
100
119
 
101
- // TODO(#7369) comment this etc (really just take inspiration from this and rewrite it all O:))
102
- export async function executeBbClientIvcProof(
120
+ export async function executeBbChonkProof(
103
121
  pathToBB: string,
104
122
  workingDirectory: string,
105
- bytecodeStackPath: string,
106
- witnessStackPath: string,
123
+ inputsPath: string,
107
124
  log: LogFn,
125
+ writeVk = false,
108
126
  ): Promise<BBFailure | BBSuccess> {
109
127
  // Check that the working directory exists
110
128
  try {
111
129
  await fs.access(workingDirectory);
112
- } catch (error) {
130
+ } catch {
113
131
  return { status: BB_RESULT.FAILURE, reason: `Working directory ${workingDirectory} does not exist` };
114
132
  }
115
133
 
@@ -126,28 +144,16 @@ export async function executeBbClientIvcProof(
126
144
 
127
145
  try {
128
146
  // Write the bytecode to the working directory
129
- log(`bytecodePath ${bytecodeStackPath}`);
130
- log(`outputPath ${outputPath}`);
131
- const args = [
132
- '-o',
133
- outputPath,
134
- '-b',
135
- bytecodeStackPath,
136
- '-w',
137
- witnessStackPath,
138
- '-v',
139
- '--scheme',
140
- 'client_ivc',
141
- '--input_type',
142
- 'runtime_stack',
143
- '--write_vk',
144
- ];
145
-
147
+ log(`inputsPath ${inputsPath}`);
146
148
  const timer = new Timer();
147
149
  const logFunction = (message: string) => {
148
150
  log(`bb - ${message}`);
149
151
  };
150
152
 
153
+ const args = ['-o', outputPath, '--ivc_inputs_path', inputsPath, '-v', '--scheme', 'chonk'];
154
+ if (writeVk) {
155
+ args.push('--write_vk');
156
+ }
151
157
  const result = await executeBB(pathToBB, 'prove', args, logFunction);
152
158
  const durationMs = timer.ms();
153
159
 
@@ -157,7 +163,7 @@ export async function executeBbClientIvcProof(
157
163
  durationMs,
158
164
  proofPath: `${outputPath}`,
159
165
  pkPath: undefined,
160
- vkPath: `${outputPath}`,
166
+ vkDirectoryPath: `${outputPath}`,
161
167
  };
162
168
  }
163
169
  // Not a great error message here but it is difficult to decipher what comes from bb
@@ -179,6 +185,9 @@ function getArgs(flavor: UltraHonkFlavor) {
179
185
  case 'ultra_keccak_honk': {
180
186
  return ['--scheme', 'ultra_honk', '--oracle_hash', 'keccak'];
181
187
  }
188
+ case 'ultra_starknet_honk': {
189
+ return ['--scheme', 'ultra_honk', '--oracle_hash', 'starknet'];
190
+ }
182
191
  case 'ultra_rollup_honk': {
183
192
  return ['--scheme', 'ultra_honk', '--oracle_hash', 'poseidon2', '--ipa_accumulation'];
184
193
  }
@@ -201,20 +210,21 @@ export async function generateProof(
201
210
  workingDirectory: string,
202
211
  circuitName: string,
203
212
  bytecode: Buffer,
204
- recursive: boolean,
213
+ verificationKey: Buffer,
205
214
  inputWitnessFile: string,
206
215
  flavor: UltraHonkFlavor,
207
- log: LogFn,
216
+ log: Logger,
208
217
  ): Promise<BBFailure | BBSuccess> {
209
218
  // Check that the working directory exists
210
219
  try {
211
220
  await fs.access(workingDirectory);
212
- } catch (error) {
221
+ } catch {
213
222
  return { status: BB_RESULT.FAILURE, reason: `Working directory ${workingDirectory} does not exist` };
214
223
  }
215
224
 
216
- // The bytecode is written to e.g. /workingDirectory/BaseParityArtifact-bytecode
225
+ // The bytecode is written to e.g. /workingDirectory/ParityBaseArtifact-bytecode
217
226
  const bytecodePath = `${workingDirectory}/${circuitName}-bytecode`;
227
+ const vkPath = `${workingDirectory}/${circuitName}-vk`;
218
228
 
219
229
  // The proof is written to e.g. /workingDirectory/ultra_honk/proof
220
230
  const outputPath = `${workingDirectory}`;
@@ -228,26 +238,28 @@ export async function generateProof(
228
238
  }
229
239
 
230
240
  try {
231
- // Write the bytecode to the working directory
232
- await fs.writeFile(bytecodePath, bytecode);
241
+ // Write the bytecode and vk to the working directory
242
+ await Promise.all([fs.writeFile(bytecodePath, bytecode), fs.writeFile(vkPath, verificationKey)]);
233
243
  const args = getArgs(flavor).concat([
234
- '--output_format',
235
- 'bytes_and_fields',
236
- '--write_vk',
244
+ '--disable_zk',
237
245
  '-o',
238
246
  outputPath,
239
247
  '-b',
240
248
  bytecodePath,
249
+ '-k',
250
+ vkPath,
241
251
  '-w',
242
252
  inputWitnessFile,
243
253
  '-v',
244
254
  ]);
245
- if (recursive) {
246
- args.push('--init_kzg_accumulator');
255
+ const loggingArg = log.level === 'debug' || log.level === 'trace' ? '-d' : log.level === 'verbose' ? '-v' : '';
256
+ if (loggingArg !== '') {
257
+ args.push(loggingArg);
247
258
  }
259
+
248
260
  const timer = new Timer();
249
261
  const logFunction = (message: string) => {
250
- log(`${circuitName} BB out - ${message}`);
262
+ log.info(`${circuitName} BB out - ${message}`);
251
263
  };
252
264
  const result = await executeBB(pathToBB, `prove`, args, logFunction);
253
265
  const duration = timer.ms();
@@ -258,80 +270,7 @@ export async function generateProof(
258
270
  durationMs: duration,
259
271
  proofPath: `${outputPath}`,
260
272
  pkPath: undefined,
261
- vkPath: `${outputPath}`,
262
- };
263
- }
264
- // Not a great error message here but it is difficult to decipher what comes from bb
265
- return {
266
- status: BB_RESULT.FAILURE,
267
- reason: `Failed to generate proof. Exit code ${result.exitCode}. Signal ${result.signal}.`,
268
- retry: !!result.signal,
269
- };
270
- } catch (error) {
271
- return { status: BB_RESULT.FAILURE, reason: `${error}` };
272
- }
273
- }
274
-
275
- /**
276
- * Used for generating proofs of the tube circuit
277
- * It is assumed that the working directory is a temporary and/or random directory used solely for generating this proof.
278
- * @param pathToBB - The full path to the bb binary
279
- * @param workingDirectory - A working directory for use by bb
280
- * @param circuitName - An identifier for the circuit
281
- * @param bytecode - The compiled circuit bytecode
282
- * @param inputWitnessFile - The circuit input witness
283
- * @param log - A logging function
284
- * @returns An object containing a result indication, the location of the proof and the duration taken
285
- */
286
- export async function generateTubeProof(
287
- pathToBB: string,
288
- workingDirectory: string,
289
- log: LogFn,
290
- ): Promise<BBFailure | BBSuccess> {
291
- // Check that the working directory exists
292
- try {
293
- await fs.access(workingDirectory);
294
- } catch (error) {
295
- return { status: BB_RESULT.FAILURE, reason: `Working directory ${workingDirectory} does not exist` };
296
- }
297
-
298
- // // Paths for the inputs
299
- const vkPath = join(workingDirectory, CLIENT_IVC_VK_FILE_NAME);
300
- const proofPath = join(workingDirectory, CLIENT_IVC_PROOF_FILE_NAME);
301
-
302
- // The proof is written to e.g. /workingDirectory/proof
303
- const outputPath = workingDirectory;
304
- const filePresent = async (file: string) =>
305
- await fs
306
- .access(file, fs.constants.R_OK)
307
- .then(_ => true)
308
- .catch(_ => false);
309
-
310
- const binaryPresent = await filePresent(pathToBB);
311
- if (!binaryPresent) {
312
- return { status: BB_RESULT.FAILURE, reason: `Failed to find bb binary at ${pathToBB}` };
313
- }
314
-
315
- try {
316
- if (!(await filePresent(vkPath)) || !(await filePresent(proofPath))) {
317
- return { status: BB_RESULT.FAILURE, reason: `Client IVC input files not present in ${workingDirectory}` };
318
- }
319
- const args = ['-o', outputPath, '-v'];
320
-
321
- const timer = new Timer();
322
- const logFunction = (message: string) => {
323
- log(`TubeCircuit (prove) BB out - ${message}`);
324
- };
325
- const result = await executeBB(pathToBB, 'prove_tube', args, logFunction);
326
- const durationMs = timer.ms();
327
-
328
- if (result.status == BB_RESULT.SUCCESS) {
329
- return {
330
- status: BB_RESULT.SUCCESS,
331
- durationMs,
332
- proofPath: outputPath,
333
- pkPath: undefined,
334
- vkPath: outputPath,
273
+ vkDirectoryPath: `${outputPath}`,
335
274
  };
336
275
  }
337
276
  // Not a great error message here but it is difficult to decipher what comes from bb
@@ -351,19 +290,21 @@ export async function generateTubeProof(
351
290
  * @param pathToBB - The full path to the bb binary
352
291
  * @param workingDirectory - A working directory for use by bb
353
292
  * @param input - The inputs for the public function to be proven
354
- * @param log - A logging function
293
+ * @param logger - A logging function
294
+ * @param checkCircuitOnly - A boolean to toggle a "check-circuit only" operation instead of proving.
355
295
  * @returns An object containing a result indication, the location of the proof and the duration taken
356
296
  */
357
- export async function generateAvmProofV2(
297
+ export async function generateAvmProof(
358
298
  pathToBB: string,
359
299
  workingDirectory: string,
360
300
  input: AvmCircuitInputs,
361
301
  logger: Logger,
302
+ checkCircuitOnly: boolean = false,
362
303
  ): Promise<BBFailure | BBSuccess> {
363
304
  // Check that the working directory exists
364
305
  try {
365
306
  await fs.access(workingDirectory);
366
- } catch (error) {
307
+ } catch {
367
308
  return { status: BB_RESULT.FAILURE, reason: `Working directory ${workingDirectory} does not exist` };
368
309
  }
369
310
 
@@ -391,107 +332,19 @@ export async function generateAvmProofV2(
391
332
  return { status: BB_RESULT.FAILURE, reason: `Could not write avm inputs to ${avmInputsPath}` };
392
333
  }
393
334
 
394
- const args = ['--avm-inputs', avmInputsPath, '-o', outputPath];
335
+ const args = checkCircuitOnly ? ['--avm-inputs', avmInputsPath] : ['--avm-inputs', avmInputsPath, '-o', outputPath];
395
336
  const loggingArg =
396
337
  logger.level === 'debug' || logger.level === 'trace' ? '-d' : logger.level === 'verbose' ? '-v' : '';
397
338
  if (loggingArg !== '') {
398
339
  args.push(loggingArg);
399
340
  }
400
341
  const timer = new Timer();
401
- const logFunction = (message: string) => {
402
- logger.verbose(`AvmCircuit (prove) BB out - ${message}`);
403
- };
404
- const result = await executeBB(pathToBB, 'avm2_prove', args, logFunction);
405
- const duration = timer.ms();
406
342
 
407
- if (result.status == BB_RESULT.SUCCESS) {
408
- return {
409
- status: BB_RESULT.SUCCESS,
410
- durationMs: duration,
411
- proofPath: join(outputPath, PROOF_FILENAME),
412
- pkPath: undefined,
413
- vkPath: outputPath,
414
- };
415
- }
416
- // Not a great error message here but it is difficult to decipher what comes from bb
417
- return {
418
- status: BB_RESULT.FAILURE,
419
- reason: `Failed to generate proof. Exit code ${result.exitCode}. Signal ${result.signal}.`,
420
- retry: !!result.signal,
421
- };
422
- } catch (error) {
423
- return { status: BB_RESULT.FAILURE, reason: `${error}` };
424
- }
425
- }
426
-
427
- /**
428
- * Used for generating AVM proofs (or doing check-circuit).
429
- * It is assumed that the working directory is a temporary and/or random directory used solely for generating this proof.
430
- * @param pathToBB - The full path to the bb binary
431
- * @param workingDirectory - A working directory for use by bb
432
- * @param bytecode - The AVM bytecode for the public function to be proven (expected to be decompressed)
433
- * @param log - A logging function
434
- * @returns An object containing a result indication, the location of the proof and the duration taken
435
- */
436
- export async function generateAvmProof(
437
- pathToBB: string,
438
- workingDirectory: string,
439
- _input: AvmCircuitInputs,
440
- logger: Logger,
441
- checkCircuitOnly: boolean = false,
442
- ): Promise<BBFailure | BBSuccess> {
443
- // Check that the working directory exists
444
- try {
445
- await fs.access(workingDirectory);
446
- } catch (error) {
447
- return { status: BB_RESULT.FAILURE, reason: `Working directory ${workingDirectory} does not exist` };
448
- }
449
-
450
- // Paths for the inputs
451
- const publicInputsPath = join(workingDirectory, AVM_PUBLIC_INPUTS_FILENAME);
452
- const avmHintsPath = join(workingDirectory, AVM_HINTS_FILENAME);
453
-
454
- // The proof is written to e.g. /workingDirectory/proof
455
- const outputPath = workingDirectory;
456
-
457
- const filePresent = async (file: string) =>
458
- await fs
459
- .access(file, fs.constants.R_OK)
460
- .then(_ => true)
461
- .catch(_ => false);
462
-
463
- const binaryPresent = await filePresent(pathToBB);
464
- if (!binaryPresent) {
465
- return { status: BB_RESULT.FAILURE, reason: `Failed to find bb binary at ${pathToBB}` };
466
- }
467
-
468
- try {
469
- // Write the inputs to the working directory.
470
-
471
- // WARNING: Not writing the inputs since VM1 is disabled!
472
- // await fs.writeFile(publicInputsPath, input.publicInputs.toBuffer());
473
- // if (!(await filePresent(publicInputsPath))) {
474
- // return { status: BB_RESULT.FAILURE, reason: `Could not write publicInputs at ${publicInputsPath}` };
475
- // }
476
-
477
- // await fs.writeFile(avmHintsPath, input.avmHints.toBuffer());
478
- // if (!(await filePresent(avmHintsPath))) {
479
- // return { status: BB_RESULT.FAILURE, reason: `Could not write avmHints at ${avmHintsPath}` };
480
- // }
481
-
482
- const args = ['--avm-public-inputs', publicInputsPath, '--avm-hints', avmHintsPath, '-o', outputPath];
483
- const loggingArg =
484
- logger.level === 'debug' || logger.level === 'trace' ? '-d' : logger.level === 'verbose' ? '-v' : '';
485
- if (loggingArg !== '') {
486
- args.push(loggingArg);
487
- }
488
-
489
- const timer = new Timer();
490
- const cmd = checkCircuitOnly ? 'check_circuit' : 'prove';
343
+ const cmd = checkCircuitOnly ? 'avm_check_circuit' : 'avm_prove';
491
344
  const logFunction = (message: string) => {
492
345
  logger.verbose(`AvmCircuit (${cmd}) BB out - ${message}`);
493
346
  };
494
- const result = await executeBB(pathToBB, `avm_${cmd}`, args, logFunction);
347
+ const result = await executeBB(pathToBB, cmd, args, logFunction);
495
348
  const duration = timer.ms();
496
349
 
497
350
  if (result.status == BB_RESULT.SUCCESS) {
@@ -500,14 +353,14 @@ export async function generateAvmProof(
500
353
  durationMs: duration,
501
354
  proofPath: join(outputPath, PROOF_FILENAME),
502
355
  pkPath: undefined,
503
- vkPath: outputPath,
356
+ vkDirectoryPath: undefined, // AVM VK is fixed in the binary.
504
357
  };
505
358
  }
506
359
  // Not a great error message here but it is difficult to decipher what comes from bb
507
360
  return {
508
361
  status: BB_RESULT.FAILURE,
509
- reason: `Failed to generate proof. Exit code ${result.exitCode}. Signal ${result.signal}.`,
510
- retry: !!result.signal,
362
+ reason: `Failed to generate proof. AVM proof for TX hash ${input.hints.tx.hash}. Exit code ${result.exitCode}. Signal ${result.signal}.`,
363
+ retry: result.signal === 'SIGKILL', // retry on SIGKILL because the oomkiller might have stopped the process
511
364
  };
512
365
  } catch (error) {
513
366
  return { status: BB_RESULT.FAILURE, reason: `${error}` };
@@ -519,7 +372,7 @@ export async function generateAvmProof(
519
372
  * @param pathToBB - The full path to the bb binary
520
373
  * @param proofFullPath - The full path to the proof to be verified
521
374
  * @param verificationKeyPath - The full path to the circuit verification key
522
- * @param log - A logging function
375
+ * @param logger - A logger
523
376
  * @returns An object containing a result indication and duration taken
524
377
  */
525
378
  export async function verifyProof(
@@ -527,41 +380,32 @@ export async function verifyProof(
527
380
  proofFullPath: string,
528
381
  verificationKeyPath: string,
529
382
  ultraHonkFlavor: UltraHonkFlavor,
530
- log: Logger,
383
+ logger: Logger,
531
384
  ): Promise<BBFailure | BBSuccess> {
532
- return await verifyProofInternal(
533
- pathToBB,
385
+ // Specify the public inputs path in the case of UH verification.
386
+ // Take proofFullPath and remove the suffix past the / to get the directory.
387
+ const proofDir = proofFullPath.substring(0, proofFullPath.lastIndexOf('/'));
388
+ const publicInputsFullPath = join(proofDir, '/public_inputs');
389
+ logger.debug(`public inputs path: ${publicInputsFullPath}`);
390
+
391
+ const args = [
392
+ '-p',
534
393
  proofFullPath,
394
+ '-k',
535
395
  verificationKeyPath,
536
- `verify`,
537
- log,
538
- getArgs(ultraHonkFlavor),
539
- );
396
+ '-i',
397
+ publicInputsFullPath,
398
+ '--disable_zk',
399
+ ...getArgs(ultraHonkFlavor),
400
+ ];
401
+ return await verifyProofInternal(pathToBB, `verify`, args, logger);
540
402
  }
541
403
 
542
- /**
543
- * Used for verifying proofs of the AVM
544
- * @param pathToBB - The full path to the bb binary
545
- * @param proofFullPath - The full path to the proof to be verified
546
- * @param verificationKeyPath - The full path to the circuit verification key
547
- * @param log - A logging function
548
- * @returns An object containing a result indication and duration taken
549
- */
550
404
  export async function verifyAvmProof(
551
- pathToBB: string,
552
- proofFullPath: string,
553
- verificationKeyPath: string,
554
- logger: Logger,
555
- ): Promise<BBFailure | BBSuccess> {
556
- return await verifyProofInternal(pathToBB, proofFullPath, verificationKeyPath, 'avm_verify', logger);
557
- }
558
-
559
- export async function verifyAvmProofV2(
560
405
  pathToBB: string,
561
406
  workingDirectory: string,
562
407
  proofFullPath: string,
563
408
  publicInputs: AvmCircuitPublicInputs,
564
- verificationKeyPath: string,
565
409
  logger: Logger,
566
410
  ): Promise<BBFailure | BBSuccess> {
567
411
  const inputsBuffer = publicInputs.serializeWithMessagePack();
@@ -578,25 +422,25 @@ export async function verifyAvmProofV2(
578
422
  return { status: BB_RESULT.FAILURE, reason: `Could not write avm inputs to ${avmInputsPath}` };
579
423
  }
580
424
 
581
- return await verifyProofInternal(pathToBB, proofFullPath, verificationKeyPath, 'avm2_verify', logger, [
582
- '--avm-public-inputs',
583
- avmInputsPath,
584
- ]);
425
+ const args = ['-p', proofFullPath, '--avm-public-inputs', avmInputsPath];
426
+ return await verifyProofInternal(pathToBB, 'avm_verify', args, logger);
585
427
  }
586
428
 
587
429
  /**
588
- * Verifies a ClientIvcProof
430
+ * Verifies a ChonkProof
589
431
  * TODO(#7370) The verification keys should be supplied separately
590
432
  * @param pathToBB - The full path to the bb binary
591
433
  * @param targetPath - The path to the folder with the proof, accumulator, and verification keys
592
- * @param log - A logging function
434
+ * @param logger - A logger
435
+ * @param concurrency - The number of threads to use for the verification
593
436
  * @returns An object containing a result indication and duration taken
594
437
  */
595
- export async function verifyClientIvcProof(
438
+ export async function verifyChonkProof(
596
439
  pathToBB: string,
597
440
  proofPath: string,
598
441
  keyPath: string,
599
- log: LogFn,
442
+ logger: Logger,
443
+ concurrency = 1,
600
444
  ): Promise<BBFailure | BBSuccess> {
601
445
  const binaryPresent = await fs
602
446
  .access(pathToBB, fs.constants.R_OK)
@@ -606,42 +450,25 @@ export async function verifyClientIvcProof(
606
450
  return { status: BB_RESULT.FAILURE, reason: `Failed to find bb binary at ${pathToBB}` };
607
451
  }
608
452
 
609
- try {
610
- const args = ['--scheme', 'client_ivc', '-p', proofPath, '-k', keyPath];
611
- const timer = new Timer();
612
- const command = 'verify';
613
- const result = await executeBB(pathToBB, command, args, log);
614
- const duration = timer.ms();
615
- if (result.status == BB_RESULT.SUCCESS) {
616
- return { status: BB_RESULT.SUCCESS, durationMs: duration };
617
- }
618
- // Not a great error message here but it is difficult to decipher what comes from bb
619
- return {
620
- status: BB_RESULT.FAILURE,
621
- reason: `Failed to verify proof. Exit code ${result.exitCode}. Signal ${result.signal}.`,
622
- retry: !!result.signal,
623
- };
624
- } catch (error) {
625
- return { status: BB_RESULT.FAILURE, reason: `${error}` };
626
- }
453
+ const args = ['--scheme', 'chonk', '-p', proofPath, '-k', keyPath, '-v'];
454
+ return await verifyProofInternal(pathToBB, 'verify', args, logger, concurrency);
627
455
  }
628
456
 
629
457
  /**
630
458
  * Used for verifying proofs with BB
631
459
  * @param pathToBB - The full path to the bb binary
632
- * @param proofFullPath - The full path to the proof to be verified
633
- * @param verificationKeyPath - The full path to the circuit verification key
634
460
  * @param command - The BB command to execute (verify/avm_verify)
635
- * @param log - A logging function
461
+ * @param args - The arguments to pass to the command
462
+ * @param logger - A logger
463
+ * @param concurrency - The number of threads to use for the verification
636
464
  * @returns An object containing a result indication and duration taken
637
465
  */
638
466
  async function verifyProofInternal(
639
467
  pathToBB: string,
640
- proofFullPath: string,
641
- verificationKeyPath: string,
642
- command: 'verify' | 'avm_verify' | 'avm2_verify',
468
+ command: 'verify' | 'avm_verify',
469
+ args: string[],
643
470
  logger: Logger,
644
- extraArgs: string[] = [],
471
+ concurrency?: number,
645
472
  ): Promise<BBFailure | BBSuccess> {
646
473
  const binaryPresent = await fs
647
474
  .access(pathToBB, fs.constants.R_OK)
@@ -656,14 +483,12 @@ async function verifyProofInternal(
656
483
  };
657
484
 
658
485
  try {
659
- const args = ['-p', proofFullPath, '-k', verificationKeyPath, ...extraArgs];
660
486
  const loggingArg =
661
487
  logger.level === 'debug' || logger.level === 'trace' ? '-d' : logger.level === 'verbose' ? '-v' : '';
662
- if (loggingArg !== '') {
663
- args.push(loggingArg);
664
- }
488
+ const finalArgs = loggingArg !== '' ? [...args, loggingArg] : args;
489
+
665
490
  const timer = new Timer();
666
- const result = await executeBB(pathToBB, command, args, logFunction);
491
+ const result = await executeBB(pathToBB, command, finalArgs, logFunction, concurrency);
667
492
  const duration = timer.ms();
668
493
  if (result.status == BB_RESULT.SUCCESS) {
669
494
  return { status: BB_RESULT.SUCCESS, durationMs: duration };
@@ -752,11 +577,11 @@ export async function computeGateCountForCircuit(
752
577
  // Check that the working directory exists
753
578
  try {
754
579
  await fs.access(workingDirectory);
755
- } catch (error) {
580
+ } catch {
756
581
  return { status: BB_RESULT.FAILURE, reason: `Working directory ${workingDirectory} does not exist` };
757
582
  }
758
583
 
759
- // The bytecode is written to e.g. /workingDirectory/BaseParityArtifact-bytecode
584
+ // The bytecode is written to e.g. /workingDirectory/ParityBaseArtifact-bytecode
760
585
  const bytecodePath = `${workingDirectory}/${circuitName}-bytecode`;
761
586
 
762
587
  const binaryPresent = await fs
@@ -782,7 +607,7 @@ export async function computeGateCountForCircuit(
782
607
  const result = await executeBB(
783
608
  pathToBB,
784
609
  'gates',
785
- ['--scheme', flavor === 'mega_honk' ? 'client_ivc' : 'ultra_honk', '-b', bytecodePath, '-v'],
610
+ ['--scheme', flavor === 'mega_honk' ? 'chonk' : 'ultra_honk', '-b', bytecodePath, '-v'],
786
611
  logHandler,
787
612
  );
788
613
  const duration = timer.ms();
@@ -844,7 +669,7 @@ async function fsCache<T>(
844
669
 
845
670
  try {
846
671
  await fs.writeFile(cacheFilePath, expectedCacheKey);
847
- } catch (err) {
672
+ } catch {
848
673
  logger(`Couldn't write cache data to ${cacheFilePath}. Skipping cache...`);
849
674
  // ignore
850
675
  }
package/src/config.ts CHANGED
@@ -3,6 +3,8 @@ export interface BBConfig {
3
3
  bbWorkingDirectory: string;
4
4
  /** Whether to skip tmp dir cleanup for debugging purposes */
5
5
  bbSkipCleanup: boolean;
6
+ numConcurrentIVCVerifiers: number;
7
+ bbIVCConcurrency: number;
6
8
  }
7
9
 
8
10
  export interface ACVMConfig {