@aztec/bb-prover 0.75.0-commit.c03ba01a2a4122e43e90d5133ba017e54b90e9d2 → 0.76.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.
Files changed (71) hide show
  1. package/dest/avm_proving_tests/avm_proving_tester.d.ts +25 -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 +16 -14
  4. package/dest/bb/cli.d.ts +12 -0
  5. package/dest/bb/cli.d.ts.map +1 -0
  6. package/dest/bb/cli.js +9 -4
  7. package/dest/bb/execute.d.ts +170 -0
  8. package/dest/bb/execute.d.ts.map +1 -0
  9. package/dest/bb/execute.js +267 -395
  10. package/dest/bb/index.d.ts +3 -0
  11. package/dest/bb/index.d.ts.map +1 -0
  12. package/dest/bb/index.js +6 -4
  13. package/dest/config.d.ts +13 -0
  14. package/dest/config.d.ts.map +1 -0
  15. package/dest/config.js +2 -1
  16. package/dest/honk.d.ts +13 -0
  17. package/dest/honk.d.ts.map +1 -0
  18. package/dest/honk.js +5 -8
  19. package/dest/index.d.ts +8 -0
  20. package/dest/index.d.ts.map +1 -0
  21. package/dest/index.js +1 -0
  22. package/dest/instrumentation.d.ts +47 -0
  23. package/dest/instrumentation.d.ts.map +1 -0
  24. package/dest/instrumentation.js +41 -44
  25. package/dest/prover/bb_native_private_kernel_prover.d.ts +25 -0
  26. package/dest/prover/bb_native_private_kernel_prover.d.ts.map +1 -0
  27. package/dest/prover/bb_native_private_kernel_prover.js +19 -19
  28. package/dest/prover/bb_private_kernel_prover.d.ts +31 -0
  29. package/dest/prover/bb_private_kernel_prover.d.ts.map +1 -0
  30. package/dest/prover/bb_private_kernel_prover.js +11 -11
  31. package/dest/prover/bb_prover.d.ts +123 -0
  32. package/dest/prover/bb_prover.d.ts.map +1 -0
  33. package/dest/prover/bb_prover.js +445 -431
  34. package/dest/prover/client_ivc_proof_utils.d.ts +25 -0
  35. package/dest/prover/client_ivc_proof_utils.d.ts.map +1 -0
  36. package/dest/prover/client_ivc_proof_utils.js +9 -15
  37. package/dest/prover/index.d.ts +4 -0
  38. package/dest/prover/index.d.ts.map +1 -0
  39. package/dest/prover/index.js +1 -0
  40. package/dest/stats.d.ts +5 -0
  41. package/dest/stats.d.ts.map +1 -0
  42. package/dest/stats.js +14 -15
  43. package/dest/test/index.d.ts +3 -0
  44. package/dest/test/index.d.ts.map +1 -0
  45. package/dest/test/index.js +1 -0
  46. package/dest/test/test_circuit_prover.d.ts +72 -0
  47. package/dest/test/test_circuit_prover.d.ts.map +1 -0
  48. package/dest/test/test_circuit_prover.js +160 -156
  49. package/dest/test/test_verifier.d.ts +5 -0
  50. package/dest/test/test_verifier.d.ts.map +1 -0
  51. package/dest/test/test_verifier.js +1 -0
  52. package/dest/verification_key/verification_key_data.d.ts +9 -0
  53. package/dest/verification_key/verification_key_data.d.ts.map +1 -0
  54. package/dest/verification_key/verification_key_data.js +8 -10
  55. package/dest/verifier/bb_verifier.d.ts +15 -0
  56. package/dest/verifier/bb_verifier.d.ts.map +1 -0
  57. package/dest/verifier/bb_verifier.js +13 -13
  58. package/dest/verifier/index.d.ts +2 -0
  59. package/dest/verifier/index.d.ts.map +1 -0
  60. package/dest/verifier/index.js +1 -0
  61. package/dest/wasm/bb_wasm_private_kernel_prover.d.ts +16 -0
  62. package/dest/wasm/bb_wasm_private_kernel_prover.d.ts.map +1 -0
  63. package/dest/wasm/bb_wasm_private_kernel_prover.js +10 -11
  64. package/dest/wasm/bundle.d.ts +6 -0
  65. package/dest/wasm/bundle.d.ts.map +1 -0
  66. package/dest/wasm/bundle.js +2 -1
  67. package/dest/wasm/lazy.d.ts +6 -0
  68. package/dest/wasm/lazy.d.ts.map +1 -0
  69. package/dest/wasm/lazy.js +2 -1
  70. package/package.json +10 -10
  71. package/src/avm_proving_tests/avm_proving_tester.ts +15 -3
@@ -12,12 +12,12 @@ export const PROOF_FIELDS_FILENAME = 'proof_fields.json';
12
12
  export const AVM_BYTECODE_FILENAME = 'avm_bytecode.bin';
13
13
  export const AVM_PUBLIC_INPUTS_FILENAME = 'avm_public_inputs.bin';
14
14
  export const AVM_HINTS_FILENAME = 'avm_hints.bin';
15
- export var BB_RESULT = /*#__PURE__*/ function(BB_RESULT) {
15
+ export var BB_RESULT;
16
+ (function (BB_RESULT) {
16
17
  BB_RESULT[BB_RESULT["SUCCESS"] = 0] = "SUCCESS";
17
18
  BB_RESULT[BB_RESULT["FAILURE"] = 1] = "FAILURE";
18
19
  BB_RESULT[BB_RESULT["ALREADY_PRESENT"] = 2] = "ALREADY_PRESENT";
19
- return BB_RESULT;
20
- }({});
20
+ })(BB_RESULT || (BB_RESULT = {}));
21
21
  /**
22
22
  * Invokes the Barretenberg binary with the provided command and args
23
23
  * @param pathToBB - The path to the BB binary
@@ -26,66 +26,51 @@ export var BB_RESULT = /*#__PURE__*/ function(BB_RESULT) {
26
26
  * @param logger - A log function
27
27
  * @param resultParser - An optional handler for detecting success or failure
28
28
  * @returns The completed partial witness outputted from the circuit
29
- */ export function executeBB(pathToBB, command, args, logger, resultParser = (code)=>code === 0) {
30
- return new Promise((resolve)=>{
29
+ */
30
+ export function executeBB(pathToBB, command, args, logger, resultParser = (code) => code === 0) {
31
+ return new Promise(resolve => {
31
32
  // spawn the bb process
32
33
  const { HARDWARE_CONCURRENCY: _, ...envWithoutConcurrency } = process.env;
33
34
  const env = process.env.HARDWARE_CONCURRENCY ? process.env : envWithoutConcurrency;
34
35
  logger(`Executing BB with: ${pathToBB} ${command} ${args.join(' ')}`);
35
- const bb = proc.spawn(pathToBB, [
36
- command,
37
- ...args
38
- ], {
39
- env
36
+ const bb = proc.spawn(pathToBB, [command, ...args], {
37
+ env,
40
38
  });
41
- bb.stdout.on('data', (data)=>{
39
+ bb.stdout.on('data', data => {
42
40
  const message = data.toString('utf-8').replace(/\n$/, '');
43
41
  logger(message);
44
42
  });
45
- bb.stderr.on('data', (data)=>{
43
+ bb.stderr.on('data', data => {
46
44
  const message = data.toString('utf-8').replace(/\n$/, '');
47
45
  logger(message);
48
46
  });
49
- bb.on('close', (exitCode, signal)=>{
47
+ bb.on('close', (exitCode, signal) => {
50
48
  if (resultParser(exitCode)) {
51
- resolve({
52
- status: 0,
53
- exitCode,
54
- signal
55
- });
56
- } else {
57
- resolve({
58
- status: 1,
59
- exitCode,
60
- signal
61
- });
49
+ resolve({ status: BB_RESULT.SUCCESS, exitCode, signal });
50
+ }
51
+ else {
52
+ resolve({ status: BB_RESULT.FAILURE, exitCode, signal });
62
53
  }
63
54
  });
64
- }).catch((_)=>({
65
- status: 1,
66
- exitCode: -1,
67
- signal: undefined
68
- }));
55
+ }).catch(_ => ({ status: BB_RESULT.FAILURE, exitCode: -1, signal: undefined }));
69
56
  }
70
57
  // TODO(#7369) comment this etc (really just take inspiration from this and rewrite it all O:))
71
58
  export async function executeBbClientIvcProof(pathToBB, workingDirectory, bytecodeStackPath, witnessStackPath, log) {
72
59
  // Check that the working directory exists
73
60
  try {
74
61
  await fs.access(workingDirectory);
75
- } catch (error) {
76
- return {
77
- status: 1,
78
- reason: `Working directory ${workingDirectory} does not exist`
79
- };
62
+ }
63
+ catch (error) {
64
+ return { status: BB_RESULT.FAILURE, reason: `Working directory ${workingDirectory} does not exist` };
80
65
  }
81
66
  // The proof is written to e.g. /workingDirectory/proof
82
67
  const outputPath = `${workingDirectory}`;
83
- const binaryPresent = await fs.access(pathToBB, fs.constants.R_OK).then((_)=>true).catch((_)=>false);
68
+ const binaryPresent = await fs
69
+ .access(pathToBB, fs.constants.R_OK)
70
+ .then(_ => true)
71
+ .catch(_ => false);
84
72
  if (!binaryPresent) {
85
- return {
86
- status: 1,
87
- reason: `Failed to find bb binary at ${pathToBB}`
88
- };
73
+ return { status: BB_RESULT.FAILURE, reason: `Failed to find bb binary at ${pathToBB}` };
89
74
  }
90
75
  try {
91
76
  // Write the bytecode to the working directory
@@ -102,35 +87,33 @@ export async function executeBbClientIvcProof(pathToBB, workingDirectory, byteco
102
87
  '--scheme',
103
88
  'client_ivc',
104
89
  '--input_type',
105
- 'runtime_stack'
90
+ 'runtime_stack',
106
91
  ];
107
92
  const timer = new Timer();
108
- const logFunction = (message)=>{
93
+ const logFunction = (message) => {
109
94
  log(`bb - ${message}`);
110
95
  };
111
96
  const result = await executeBB(pathToBB, 'prove', args, logFunction);
112
97
  const durationMs = timer.ms();
113
- if (result.status == 0) {
98
+ if (result.status == BB_RESULT.SUCCESS) {
114
99
  return {
115
- status: 0,
100
+ status: BB_RESULT.SUCCESS,
116
101
  durationMs,
117
102
  proofPath: `${outputPath}`,
118
103
  pkPath: undefined,
119
- vkPath: `${outputPath}`
104
+ vkPath: `${outputPath}`,
120
105
  };
121
106
  }
122
107
  // Not a great error message here but it is difficult to decipher what comes from bb
123
108
  return {
124
- status: 1,
109
+ status: BB_RESULT.FAILURE,
125
110
  reason: `Failed to generate proof. Exit code ${result.exitCode}. Signal ${result.signal}.`,
126
- retry: !!result.signal
127
- };
128
- } catch (error) {
129
- return {
130
- status: 1,
131
- reason: `${error}`
111
+ retry: !!result.signal,
132
112
  };
133
113
  }
114
+ catch (error) {
115
+ return { status: BB_RESULT.FAILURE, reason: `${error}` };
116
+ }
134
117
  }
135
118
  /**
136
119
  * Used for generating verification keys of noir circuits.
@@ -142,77 +125,58 @@ export async function executeBbClientIvcProof(pathToBB, workingDirectory, byteco
142
125
  * @param inputWitnessFile - The circuit input witness
143
126
  * @param log - A logging function
144
127
  * @returns An object containing a result indication, the location of the VK and the duration taken
145
- */ export async function computeVerificationKey(pathToBB, workingDirectory, circuitName, bytecode, recursive, flavor, log) {
128
+ */
129
+ export async function computeVerificationKey(pathToBB, workingDirectory, circuitName, bytecode, recursive, flavor, log) {
146
130
  // Check that the working directory exists
147
131
  try {
148
132
  await fs.access(workingDirectory);
149
- } catch (error) {
150
- return {
151
- status: 1,
152
- reason: `Working directory ${workingDirectory} does not exist`
153
- };
133
+ }
134
+ catch (error) {
135
+ return { status: BB_RESULT.FAILURE, reason: `Working directory ${workingDirectory} does not exist` };
154
136
  }
155
137
  // The bytecode is written to e.g. /workingDirectory/BaseParityArtifact-bytecode
156
138
  const bytecodePath = `${workingDirectory}/${circuitName}-bytecode`;
157
139
  // The verification key is written to this path
158
140
  const outputPath = `${workingDirectory}/vk`;
159
- const binaryPresent = await fs.access(pathToBB, fs.constants.R_OK).then((_)=>true).catch((_)=>false);
141
+ const binaryPresent = await fs
142
+ .access(pathToBB, fs.constants.R_OK)
143
+ .then(_ => true)
144
+ .catch(_ => false);
160
145
  if (!binaryPresent) {
161
- return {
162
- status: 1,
163
- reason: `Failed to find bb binary at ${pathToBB}`
164
- };
146
+ return { status: BB_RESULT.FAILURE, reason: `Failed to find bb binary at ${pathToBB}` };
165
147
  }
166
148
  try {
167
149
  // Write the bytecode to the working directory
168
150
  await fs.writeFile(bytecodePath, bytecode);
169
151
  const timer = new Timer();
170
- const logFunction = (message)=>{
152
+ const logFunction = (message) => {
171
153
  log(`computeVerificationKey(${circuitName}) BB out - ${message}`);
172
154
  };
173
- const args = [
174
- '-o',
175
- outputPath,
176
- '-b',
177
- bytecodePath,
178
- '-v',
179
- recursive ? '--recursive' : ''
180
- ];
155
+ const args = ['-o', outputPath, '-b', bytecodePath, '-v', recursive ? '--recursive' : ''];
181
156
  let result = await executeBB(pathToBB, `write_vk_${flavor}`, args, logFunction);
182
- if (result.status == 1) {
183
- return {
184
- status: 1,
185
- reason: 'Failed writing VK.'
186
- };
157
+ if (result.status == BB_RESULT.FAILURE) {
158
+ return { status: BB_RESULT.FAILURE, reason: 'Failed writing VK.' };
187
159
  }
188
- result = await executeBB(pathToBB, `vk_as_fields_${flavor}`, [
189
- '-o',
190
- outputPath + '_fields.json',
191
- '-k',
192
- outputPath,
193
- '-v'
194
- ], logFunction);
160
+ result = await executeBB(pathToBB, `vk_as_fields_${flavor}`, ['-o', outputPath + '_fields.json', '-k', outputPath, '-v'], logFunction);
195
161
  const duration = timer.ms();
196
- if (result.status == 0) {
162
+ if (result.status == BB_RESULT.SUCCESS) {
197
163
  return {
198
- status: 0,
164
+ status: BB_RESULT.SUCCESS,
199
165
  durationMs: duration,
200
166
  pkPath: undefined,
201
- vkPath: `${outputPath}`
167
+ vkPath: `${outputPath}`,
202
168
  };
203
169
  }
204
170
  // Not a great error message here but it is difficult to decipher what comes from bb
205
171
  return {
206
- status: 1,
172
+ status: BB_RESULT.FAILURE,
207
173
  reason: `Failed to write VK. Exit code ${result.exitCode}. Signal ${result.signal}.`,
208
- retry: !!result.signal
209
- };
210
- } catch (error) {
211
- return {
212
- status: 1,
213
- reason: `${error}`
174
+ retry: !!result.signal,
214
175
  };
215
176
  }
177
+ catch (error) {
178
+ return { status: BB_RESULT.FAILURE, reason: `${error}` };
179
+ }
216
180
  }
217
181
  /**
218
182
  * Used for generating proofs of noir circuits.
@@ -224,67 +188,55 @@ export async function executeBbClientIvcProof(pathToBB, workingDirectory, byteco
224
188
  * @param inputWitnessFile - The circuit input witness
225
189
  * @param log - A logging function
226
190
  * @returns An object containing a result indication, the location of the proof and the duration taken
227
- */ export async function generateProof(pathToBB, workingDirectory, circuitName, bytecode, recursive, inputWitnessFile, flavor, log) {
191
+ */
192
+ export async function generateProof(pathToBB, workingDirectory, circuitName, bytecode, recursive, inputWitnessFile, flavor, log) {
228
193
  // Check that the working directory exists
229
194
  try {
230
195
  await fs.access(workingDirectory);
231
- } catch (error) {
232
- return {
233
- status: 1,
234
- reason: `Working directory ${workingDirectory} does not exist`
235
- };
196
+ }
197
+ catch (error) {
198
+ return { status: BB_RESULT.FAILURE, reason: `Working directory ${workingDirectory} does not exist` };
236
199
  }
237
200
  // The bytecode is written to e.g. /workingDirectory/BaseParityArtifact-bytecode
238
201
  const bytecodePath = `${workingDirectory}/${circuitName}-bytecode`;
239
202
  // The proof is written to e.g. /workingDirectory/ultra_honk/proof
240
203
  const outputPath = `${workingDirectory}`;
241
- const binaryPresent = await fs.access(pathToBB, fs.constants.R_OK).then((_)=>true).catch((_)=>false);
204
+ const binaryPresent = await fs
205
+ .access(pathToBB, fs.constants.R_OK)
206
+ .then(_ => true)
207
+ .catch(_ => false);
242
208
  if (!binaryPresent) {
243
- return {
244
- status: 1,
245
- reason: `Failed to find bb binary at ${pathToBB}`
246
- };
209
+ return { status: BB_RESULT.FAILURE, reason: `Failed to find bb binary at ${pathToBB}` };
247
210
  }
248
211
  try {
249
212
  // Write the bytecode to the working directory
250
213
  await fs.writeFile(bytecodePath, bytecode);
251
- const args = [
252
- '-o',
253
- outputPath,
254
- '-b',
255
- bytecodePath,
256
- '-w',
257
- inputWitnessFile,
258
- '-v',
259
- recursive ? '--recursive' : ''
260
- ];
214
+ const args = ['-o', outputPath, '-b', bytecodePath, '-w', inputWitnessFile, '-v', recursive ? '--recursive' : ''];
261
215
  const timer = new Timer();
262
- const logFunction = (message)=>{
216
+ const logFunction = (message) => {
263
217
  log(`${circuitName} BB out - ${message}`);
264
218
  };
265
219
  const result = await executeBB(pathToBB, `prove_${flavor}_output_all`, args, logFunction);
266
220
  const duration = timer.ms();
267
- if (result.status == 0) {
221
+ if (result.status == BB_RESULT.SUCCESS) {
268
222
  return {
269
- status: 0,
223
+ status: BB_RESULT.SUCCESS,
270
224
  durationMs: duration,
271
225
  proofPath: `${outputPath}`,
272
226
  pkPath: undefined,
273
- vkPath: `${outputPath}`
227
+ vkPath: `${outputPath}`,
274
228
  };
275
229
  }
276
230
  // Not a great error message here but it is difficult to decipher what comes from bb
277
231
  return {
278
- status: 1,
232
+ status: BB_RESULT.FAILURE,
279
233
  reason: `Failed to generate proof. Exit code ${result.exitCode}. Signal ${result.signal}.`,
280
- retry: !!result.signal
281
- };
282
- } catch (error) {
283
- return {
284
- status: 1,
285
- reason: `${error}`
234
+ retry: !!result.signal,
286
235
  };
287
236
  }
237
+ catch (error) {
238
+ return { status: BB_RESULT.FAILURE, reason: `${error}` };
239
+ }
288
240
  }
289
241
  /**
290
242
  * Used for generating proofs of the tube circuit
@@ -296,68 +248,58 @@ export async function executeBbClientIvcProof(pathToBB, workingDirectory, byteco
296
248
  * @param inputWitnessFile - The circuit input witness
297
249
  * @param log - A logging function
298
250
  * @returns An object containing a result indication, the location of the proof and the duration taken
299
- */ export async function generateTubeProof(pathToBB, workingDirectory, log) {
251
+ */
252
+ export async function generateTubeProof(pathToBB, workingDirectory, log) {
300
253
  // Check that the working directory exists
301
254
  try {
302
255
  await fs.access(workingDirectory);
303
- } catch (error) {
304
- return {
305
- status: 1,
306
- reason: `Working directory ${workingDirectory} does not exist`
307
- };
256
+ }
257
+ catch (error) {
258
+ return { status: BB_RESULT.FAILURE, reason: `Working directory ${workingDirectory} does not exist` };
308
259
  }
309
260
  // // Paths for the inputs
310
261
  const vkPath = join(workingDirectory, CLIENT_IVC_VK_FILE_NAME);
311
262
  const proofPath = join(workingDirectory, CLIENT_IVC_PROOF_FILE_NAME);
312
263
  // The proof is written to e.g. /workingDirectory/proof
313
264
  const outputPath = workingDirectory;
314
- const filePresent = async (file)=>await fs.access(file, fs.constants.R_OK).then((_)=>true).catch((_)=>false);
265
+ const filePresent = async (file) => await fs
266
+ .access(file, fs.constants.R_OK)
267
+ .then(_ => true)
268
+ .catch(_ => false);
315
269
  const binaryPresent = await filePresent(pathToBB);
316
270
  if (!binaryPresent) {
317
- return {
318
- status: 1,
319
- reason: `Failed to find bb binary at ${pathToBB}`
320
- };
271
+ return { status: BB_RESULT.FAILURE, reason: `Failed to find bb binary at ${pathToBB}` };
321
272
  }
322
273
  try {
323
- if (!await filePresent(vkPath) || !await filePresent(proofPath)) {
324
- return {
325
- status: 1,
326
- reason: `Client IVC input files not present in ${workingDirectory}`
327
- };
274
+ if (!(await filePresent(vkPath)) || !(await filePresent(proofPath))) {
275
+ return { status: BB_RESULT.FAILURE, reason: `Client IVC input files not present in ${workingDirectory}` };
328
276
  }
329
- const args = [
330
- '-o',
331
- outputPath,
332
- '-v'
333
- ];
277
+ const args = ['-o', outputPath, '-v'];
334
278
  const timer = new Timer();
335
- const logFunction = (message)=>{
279
+ const logFunction = (message) => {
336
280
  log(`TubeCircuit (prove) BB out - ${message}`);
337
281
  };
338
282
  const result = await executeBB(pathToBB, 'prove_tube', args, logFunction);
339
283
  const durationMs = timer.ms();
340
- if (result.status == 0) {
284
+ if (result.status == BB_RESULT.SUCCESS) {
341
285
  return {
342
- status: 0,
286
+ status: BB_RESULT.SUCCESS,
343
287
  durationMs,
344
288
  proofPath: outputPath,
345
289
  pkPath: undefined,
346
- vkPath: outputPath
290
+ vkPath: outputPath,
347
291
  };
348
292
  }
349
293
  // Not a great error message here but it is difficult to decipher what comes from bb
350
294
  return {
351
- status: 1,
295
+ status: BB_RESULT.FAILURE,
352
296
  reason: `Failed to generate proof. Exit code ${result.exitCode}. Signal ${result.signal}.`,
353
- retry: !!result.signal
354
- };
355
- } catch (error) {
356
- return {
357
- status: 1,
358
- reason: `${error}`
297
+ retry: !!result.signal,
359
298
  };
360
299
  }
300
+ catch (error) {
301
+ return { status: BB_RESULT.FAILURE, reason: `${error}` };
302
+ }
361
303
  }
362
304
  /**
363
305
  * Used for generating AVM proofs.
@@ -367,71 +309,65 @@ export async function executeBbClientIvcProof(pathToBB, workingDirectory, byteco
367
309
  * @param input - The inputs for the public function to be proven
368
310
  * @param log - A logging function
369
311
  * @returns An object containing a result indication, the location of the proof and the duration taken
370
- */ export async function generateAvmProofV2(pathToBB, workingDirectory, input, logger) {
312
+ */
313
+ export async function generateAvmProofV2(pathToBB, workingDirectory, input, logger) {
371
314
  // Check that the working directory exists
372
315
  try {
373
316
  await fs.access(workingDirectory);
374
- } catch (error) {
375
- return {
376
- status: 1,
377
- reason: `Working directory ${workingDirectory} does not exist`
378
- };
317
+ }
318
+ catch (error) {
319
+ return { status: BB_RESULT.FAILURE, reason: `Working directory ${workingDirectory} does not exist` };
379
320
  }
380
321
  // The proof is written to e.g. /workingDirectory/proof
381
322
  const outputPath = workingDirectory;
382
- const filePresent = async (file)=>await fs.access(file, fs.constants.R_OK).then((_)=>true).catch((_)=>false);
323
+ const filePresent = async (file) => await fs
324
+ .access(file, fs.constants.R_OK)
325
+ .then(_ => true)
326
+ .catch(_ => false);
383
327
  const binaryPresent = await filePresent(pathToBB);
384
328
  if (!binaryPresent) {
385
- return {
386
- status: 1,
387
- reason: `Failed to find bb binary at ${pathToBB}`
388
- };
329
+ return { status: BB_RESULT.FAILURE, reason: `Failed to find bb binary at ${pathToBB}` };
389
330
  }
390
331
  const inputsBuffer = input.serializeForAvm2();
391
332
  try {
392
333
  // Write the inputs to the working directory.
393
334
  const avmInputsPath = join(workingDirectory, 'avm_inputs.bin');
394
335
  await fs.writeFile(avmInputsPath, inputsBuffer);
395
- if (!await filePresent(avmInputsPath)) {
396
- return {
397
- status: 1,
398
- reason: `Could not write avm inputs to ${avmInputsPath}`
399
- };
336
+ if (!(await filePresent(avmInputsPath))) {
337
+ return { status: BB_RESULT.FAILURE, reason: `Could not write avm inputs to ${avmInputsPath}` };
400
338
  }
401
339
  const args = [
402
340
  '--avm-inputs',
403
341
  avmInputsPath,
404
342
  '-o',
405
343
  outputPath,
406
- logger.level === 'debug' || logger.level === 'trace' ? '-d' : logger.level === 'verbose' ? '-v' : ''
344
+ logger.level === 'debug' || logger.level === 'trace' ? '-d' : logger.level === 'verbose' ? '-v' : '',
407
345
  ];
408
346
  const timer = new Timer();
409
- const logFunction = (message)=>{
347
+ const logFunction = (message) => {
410
348
  logger.verbose(`AvmCircuit (prove) BB out - ${message}`);
411
349
  };
412
350
  const result = await executeBB(pathToBB, 'avm2_prove', args, logFunction);
413
351
  const duration = timer.ms();
414
- if (result.status == 0) {
352
+ if (result.status == BB_RESULT.SUCCESS) {
415
353
  return {
416
- status: 0,
354
+ status: BB_RESULT.SUCCESS,
417
355
  durationMs: duration,
418
356
  proofPath: join(outputPath, PROOF_FILENAME),
419
357
  pkPath: undefined,
420
- vkPath: outputPath
358
+ vkPath: outputPath,
421
359
  };
422
360
  }
423
361
  // Not a great error message here but it is difficult to decipher what comes from bb
424
362
  return {
425
- status: 1,
363
+ status: BB_RESULT.FAILURE,
426
364
  reason: `Failed to generate proof. Exit code ${result.exitCode}. Signal ${result.signal}.`,
427
- retry: !!result.signal
428
- };
429
- } catch (error) {
430
- return {
431
- status: 1,
432
- reason: `${error}`
365
+ retry: !!result.signal,
433
366
  };
434
367
  }
368
+ catch (error) {
369
+ return { status: BB_RESULT.FAILURE, reason: `${error}` };
370
+ }
435
371
  }
436
372
  /**
437
373
  * Used for generating AVM proofs (or doing check-circuit).
@@ -441,44 +377,37 @@ export async function executeBbClientIvcProof(pathToBB, workingDirectory, byteco
441
377
  * @param bytecode - The AVM bytecode for the public function to be proven (expected to be decompressed)
442
378
  * @param log - A logging function
443
379
  * @returns An object containing a result indication, the location of the proof and the duration taken
444
- */ export async function generateAvmProof(pathToBB, workingDirectory, input, logger, checkCircuitOnly = false) {
380
+ */
381
+ export async function generateAvmProof(pathToBB, workingDirectory, input, logger, checkCircuitOnly = false) {
445
382
  // Check that the working directory exists
446
383
  try {
447
384
  await fs.access(workingDirectory);
448
- } catch (error) {
449
- return {
450
- status: 1,
451
- reason: `Working directory ${workingDirectory} does not exist`
452
- };
385
+ }
386
+ catch (error) {
387
+ return { status: BB_RESULT.FAILURE, reason: `Working directory ${workingDirectory} does not exist` };
453
388
  }
454
389
  // Paths for the inputs
455
390
  const publicInputsPath = join(workingDirectory, AVM_PUBLIC_INPUTS_FILENAME);
456
391
  const avmHintsPath = join(workingDirectory, AVM_HINTS_FILENAME);
457
392
  // The proof is written to e.g. /workingDirectory/proof
458
393
  const outputPath = workingDirectory;
459
- const filePresent = async (file)=>await fs.access(file, fs.constants.R_OK).then((_)=>true).catch((_)=>false);
394
+ const filePresent = async (file) => await fs
395
+ .access(file, fs.constants.R_OK)
396
+ .then(_ => true)
397
+ .catch(_ => false);
460
398
  const binaryPresent = await filePresent(pathToBB);
461
399
  if (!binaryPresent) {
462
- return {
463
- status: 1,
464
- reason: `Failed to find bb binary at ${pathToBB}`
465
- };
400
+ return { status: BB_RESULT.FAILURE, reason: `Failed to find bb binary at ${pathToBB}` };
466
401
  }
467
402
  try {
468
403
  // Write the inputs to the working directory.
469
404
  await fs.writeFile(publicInputsPath, input.publicInputs.toBuffer());
470
- if (!await filePresent(publicInputsPath)) {
471
- return {
472
- status: 1,
473
- reason: `Could not write publicInputs at ${publicInputsPath}`
474
- };
405
+ if (!(await filePresent(publicInputsPath))) {
406
+ return { status: BB_RESULT.FAILURE, reason: `Could not write publicInputs at ${publicInputsPath}` };
475
407
  }
476
408
  await fs.writeFile(avmHintsPath, input.avmHints.toBuffer());
477
- if (!await filePresent(avmHintsPath)) {
478
- return {
479
- status: 1,
480
- reason: `Could not write avmHints at ${avmHintsPath}`
481
- };
409
+ if (!(await filePresent(avmHintsPath))) {
410
+ return { status: BB_RESULT.FAILURE, reason: `Could not write avmHints at ${avmHintsPath}` };
482
411
  }
483
412
  const args = [
484
413
  '--avm-public-inputs',
@@ -488,36 +417,34 @@ export async function executeBbClientIvcProof(pathToBB, workingDirectory, byteco
488
417
  '-o',
489
418
  outputPath,
490
419
  logger.level === 'debug' || logger.level === 'trace' ? '-d' : logger.level === 'verbose' ? '-v' : '',
491
- checkCircuitOnly ? '--check-circuit-only' : ''
420
+ checkCircuitOnly ? '--check-circuit-only' : '',
492
421
  ];
493
422
  const timer = new Timer();
494
423
  const cmd = checkCircuitOnly ? 'check_circuit' : 'prove';
495
- const logFunction = (message)=>{
424
+ const logFunction = (message) => {
496
425
  logger.verbose(`AvmCircuit (${cmd}) BB out - ${message}`);
497
426
  };
498
427
  const result = await executeBB(pathToBB, `avm_${cmd}`, args, logFunction);
499
428
  const duration = timer.ms();
500
- if (result.status == 0) {
429
+ if (result.status == BB_RESULT.SUCCESS) {
501
430
  return {
502
- status: 0,
431
+ status: BB_RESULT.SUCCESS,
503
432
  durationMs: duration,
504
433
  proofPath: join(outputPath, PROOF_FILENAME),
505
434
  pkPath: undefined,
506
- vkPath: outputPath
435
+ vkPath: outputPath,
507
436
  };
508
437
  }
509
438
  // Not a great error message here but it is difficult to decipher what comes from bb
510
439
  return {
511
- status: 1,
440
+ status: BB_RESULT.FAILURE,
512
441
  reason: `Failed to generate proof. Exit code ${result.exitCode}. Signal ${result.signal}.`,
513
- retry: !!result.signal
514
- };
515
- } catch (error) {
516
- return {
517
- status: 1,
518
- reason: `${error}`
442
+ retry: !!result.signal,
519
443
  };
520
444
  }
445
+ catch (error) {
446
+ return { status: BB_RESULT.FAILURE, reason: `${error}` };
447
+ }
521
448
  }
522
449
  /**
523
450
  * Used for verifying proofs of noir circuits
@@ -526,7 +453,8 @@ export async function executeBbClientIvcProof(pathToBB, workingDirectory, byteco
526
453
  * @param verificationKeyPath - The full path to the circuit verification key
527
454
  * @param log - A logging function
528
455
  * @returns An object containing a result indication and duration taken
529
- */ export async function verifyProof(pathToBB, proofFullPath, verificationKeyPath, ultraHonkFlavor, log) {
456
+ */
457
+ export async function verifyProof(pathToBB, proofFullPath, verificationKeyPath, ultraHonkFlavor, log) {
530
458
  return await verifyProofInternal(pathToBB, proofFullPath, verificationKeyPath, `verify_${ultraHonkFlavor}`, log);
531
459
  }
532
460
  /**
@@ -536,24 +464,25 @@ export async function executeBbClientIvcProof(pathToBB, workingDirectory, byteco
536
464
  * @param verificationKeyPath - The full path to the circuit verification key
537
465
  * @param log - A logging function
538
466
  * @returns An object containing a result indication and duration taken
539
- */ export async function verifyAvmProof(pathToBB, proofFullPath, verificationKeyPath, logger) {
467
+ */
468
+ export async function verifyAvmProof(pathToBB, proofFullPath, verificationKeyPath, logger) {
540
469
  return await verifyProofInternal(pathToBB, proofFullPath, verificationKeyPath, 'avm_verify', logger);
541
470
  }
542
471
  export async function verifyAvmProofV2(pathToBB, workingDirectory, proofFullPath, publicInputs, verificationKeyPath, logger) {
543
472
  const inputsBuffer = serializeWithMessagePack(publicInputs);
544
473
  // Write the inputs to the working directory.
545
- const filePresent = async (file)=>await fs.access(file, fs.constants.R_OK).then((_)=>true).catch((_)=>false);
474
+ const filePresent = async (file) => await fs
475
+ .access(file, fs.constants.R_OK)
476
+ .then(_ => true)
477
+ .catch(_ => false);
546
478
  const avmInputsPath = join(workingDirectory, 'avm_public_inputs.bin');
547
479
  await fs.writeFile(avmInputsPath, inputsBuffer);
548
- if (!await filePresent(avmInputsPath)) {
549
- return {
550
- status: 1,
551
- reason: `Could not write avm inputs to ${avmInputsPath}`
552
- };
480
+ if (!(await filePresent(avmInputsPath))) {
481
+ return { status: BB_RESULT.FAILURE, reason: `Could not write avm inputs to ${avmInputsPath}` };
553
482
  }
554
483
  return await verifyProofInternal(pathToBB, proofFullPath, verificationKeyPath, 'avm2_verify', logger, [
555
484
  '--avm-public-inputs',
556
- avmInputsPath
485
+ avmInputsPath,
557
486
  ]);
558
487
  }
559
488
  /**
@@ -563,43 +492,34 @@ export async function verifyAvmProofV2(pathToBB, workingDirectory, proofFullPath
563
492
  * @param targetPath - The path to the folder with the proof, accumulator, and verification keys
564
493
  * @param log - A logging function
565
494
  * @returns An object containing a result indication and duration taken
566
- */ export async function verifyClientIvcProof(pathToBB, targetPath, log) {
567
- const binaryPresent = await fs.access(pathToBB, fs.constants.R_OK).then((_)=>true).catch((_)=>false);
495
+ */
496
+ export async function verifyClientIvcProof(pathToBB, targetPath, log) {
497
+ const binaryPresent = await fs
498
+ .access(pathToBB, fs.constants.R_OK)
499
+ .then(_ => true)
500
+ .catch(_ => false);
568
501
  if (!binaryPresent) {
569
- return {
570
- status: 1,
571
- reason: `Failed to find bb binary at ${pathToBB}`
572
- };
502
+ return { status: BB_RESULT.FAILURE, reason: `Failed to find bb binary at ${pathToBB}` };
573
503
  }
574
504
  try {
575
- const args = [
576
- '-o',
577
- targetPath,
578
- '--scheme',
579
- 'client_ivc'
580
- ];
505
+ const args = ['-o', targetPath, '--scheme', 'client_ivc'];
581
506
  const timer = new Timer();
582
507
  const command = 'verify';
583
508
  const result = await executeBB(pathToBB, command, args, log);
584
509
  const duration = timer.ms();
585
- if (result.status == 0) {
586
- return {
587
- status: 0,
588
- durationMs: duration
589
- };
510
+ if (result.status == BB_RESULT.SUCCESS) {
511
+ return { status: BB_RESULT.SUCCESS, durationMs: duration };
590
512
  }
591
513
  // Not a great error message here but it is difficult to decipher what comes from bb
592
514
  return {
593
- status: 1,
515
+ status: BB_RESULT.FAILURE,
594
516
  reason: `Failed to verify proof. Exit code ${result.exitCode}. Signal ${result.signal}.`,
595
- retry: !!result.signal
596
- };
597
- } catch (error) {
598
- return {
599
- status: 1,
600
- reason: `${error}`
517
+ retry: !!result.signal,
601
518
  };
602
519
  }
520
+ catch (error) {
521
+ return { status: BB_RESULT.FAILURE, reason: `${error}` };
522
+ }
603
523
  }
604
524
  /**
605
525
  * Used for verifying proofs with BB
@@ -609,15 +529,16 @@ export async function verifyAvmProofV2(pathToBB, workingDirectory, proofFullPath
609
529
  * @param command - The BB command to execute (verify/avm_verify)
610
530
  * @param log - A logging function
611
531
  * @returns An object containing a result indication and duration taken
612
- */ async function verifyProofInternal(pathToBB, proofFullPath, verificationKeyPath, command, logger, extraArgs = []) {
613
- const binaryPresent = await fs.access(pathToBB, fs.constants.R_OK).then((_)=>true).catch((_)=>false);
532
+ */
533
+ async function verifyProofInternal(pathToBB, proofFullPath, verificationKeyPath, command, logger, extraArgs = []) {
534
+ const binaryPresent = await fs
535
+ .access(pathToBB, fs.constants.R_OK)
536
+ .then(_ => true)
537
+ .catch(_ => false);
614
538
  if (!binaryPresent) {
615
- return {
616
- status: 1,
617
- reason: `Failed to find bb binary at ${pathToBB}`
618
- };
539
+ return { status: BB_RESULT.FAILURE, reason: `Failed to find bb binary at ${pathToBB}` };
619
540
  }
620
- const logFunction = (message)=>{
541
+ const logFunction = (message) => {
621
542
  logger.verbose(`AvmCircuit (verify) BB out - ${message}`);
622
543
  };
623
544
  try {
@@ -627,29 +548,24 @@ export async function verifyAvmProofV2(pathToBB, workingDirectory, proofFullPath
627
548
  '-k',
628
549
  verificationKeyPath,
629
550
  logger.level === 'debug' || logger.level === 'trace' ? '-d' : logger.level === 'verbose' ? '-v' : '',
630
- ...extraArgs
551
+ ...extraArgs,
631
552
  ];
632
553
  const timer = new Timer();
633
554
  const result = await executeBB(pathToBB, command, args, logFunction);
634
555
  const duration = timer.ms();
635
- if (result.status == 0) {
636
- return {
637
- status: 0,
638
- durationMs: duration
639
- };
556
+ if (result.status == BB_RESULT.SUCCESS) {
557
+ return { status: BB_RESULT.SUCCESS, durationMs: duration };
640
558
  }
641
559
  // Not a great error message here but it is difficult to decipher what comes from bb
642
560
  return {
643
- status: 1,
561
+ status: BB_RESULT.FAILURE,
644
562
  reason: `Failed to verify proof. Exit code ${result.exitCode}. Signal ${result.signal}.`,
645
- retry: !!result.signal
646
- };
647
- } catch (error) {
648
- return {
649
- status: 1,
650
- reason: `${error}`
563
+ retry: !!result.signal,
651
564
  };
652
565
  }
566
+ catch (error) {
567
+ return { status: BB_RESULT.FAILURE, reason: `${error}` };
568
+ }
653
569
  }
654
570
  /**
655
571
  * Used for verifying proofs of noir circuits
@@ -658,42 +574,33 @@ export async function verifyAvmProofV2(pathToBB, workingDirectory, proofFullPath
658
574
  * @param verificationKeyFilename - The filename of the verification key
659
575
  * @param log - A logging function
660
576
  * @returns An object containing a result indication and duration taken
661
- */ export async function writeVkAsFields(pathToBB, verificationKeyPath, verificationKeyFilename, log) {
662
- const binaryPresent = await fs.access(pathToBB, fs.constants.R_OK).then((_)=>true).catch((_)=>false);
577
+ */
578
+ export async function writeVkAsFields(pathToBB, verificationKeyPath, verificationKeyFilename, log) {
579
+ const binaryPresent = await fs
580
+ .access(pathToBB, fs.constants.R_OK)
581
+ .then(_ => true)
582
+ .catch(_ => false);
663
583
  if (!binaryPresent) {
664
- return {
665
- status: 1,
666
- reason: `Failed to find bb binary at ${pathToBB}`
667
- };
584
+ return { status: BB_RESULT.FAILURE, reason: `Failed to find bb binary at ${pathToBB}` };
668
585
  }
669
586
  try {
670
- const args = [
671
- '-k',
672
- `${verificationKeyPath}/${verificationKeyFilename}`,
673
- '-v'
674
- ];
587
+ const args = ['-k', `${verificationKeyPath}/${verificationKeyFilename}`, '-v'];
675
588
  const timer = new Timer();
676
589
  const result = await executeBB(pathToBB, 'vk_as_fields_ultra_honk', args, log);
677
590
  const duration = timer.ms();
678
- if (result.status == 0) {
679
- return {
680
- status: 0,
681
- durationMs: duration,
682
- vkPath: verificationKeyPath
683
- };
591
+ if (result.status == BB_RESULT.SUCCESS) {
592
+ return { status: BB_RESULT.SUCCESS, durationMs: duration, vkPath: verificationKeyPath };
684
593
  }
685
594
  // Not a great error message here but it is difficult to decipher what comes from bb
686
595
  return {
687
- status: 1,
596
+ status: BB_RESULT.FAILURE,
688
597
  reason: `Failed to create vk as fields. Exit code ${result.exitCode}. Signal ${result.signal}.`,
689
- retry: !!result.signal
690
- };
691
- } catch (error) {
692
- return {
693
- status: 1,
694
- reason: `${error}`
598
+ retry: !!result.signal,
695
599
  };
696
600
  }
601
+ catch (error) {
602
+ return { status: BB_RESULT.FAILURE, reason: `${error}` };
603
+ }
697
604
  }
698
605
  /**
699
606
  * Used for verifying proofs of noir circuits
@@ -703,100 +610,72 @@ export async function verifyAvmProofV2(pathToBB, workingDirectory, proofFullPath
703
610
  * @param vkFileName - The filename of the verification key
704
611
  * @param log - A logging function
705
612
  * @returns An object containing a result indication and duration taken
706
- */ export async function writeProofAsFields(pathToBB, proofPath, proofFileName, vkFilePath, log) {
707
- const binaryPresent = await fs.access(pathToBB, fs.constants.R_OK).then((_)=>true).catch((_)=>false);
613
+ */
614
+ export async function writeProofAsFields(pathToBB, proofPath, proofFileName, vkFilePath, log) {
615
+ const binaryPresent = await fs
616
+ .access(pathToBB, fs.constants.R_OK)
617
+ .then(_ => true)
618
+ .catch(_ => false);
708
619
  if (!binaryPresent) {
709
- return {
710
- status: 1,
711
- reason: `Failed to find bb binary at ${pathToBB}`
712
- };
620
+ return { status: BB_RESULT.FAILURE, reason: `Failed to find bb binary at ${pathToBB}` };
713
621
  }
714
622
  try {
715
- const args = [
716
- '-p',
717
- `${proofPath}/${proofFileName}`,
718
- '-k',
719
- vkFilePath,
720
- '-v'
721
- ];
623
+ const args = ['-p', `${proofPath}/${proofFileName}`, '-k', vkFilePath, '-v'];
722
624
  const timer = new Timer();
723
625
  const result = await executeBB(pathToBB, 'proof_as_fields_honk', args, log);
724
626
  const duration = timer.ms();
725
- if (result.status == 0) {
726
- return {
727
- status: 0,
728
- durationMs: duration,
729
- proofPath: proofPath
730
- };
627
+ if (result.status == BB_RESULT.SUCCESS) {
628
+ return { status: BB_RESULT.SUCCESS, durationMs: duration, proofPath: proofPath };
731
629
  }
732
630
  // Not a great error message here but it is difficult to decipher what comes from bb
733
631
  return {
734
- status: 1,
632
+ status: BB_RESULT.FAILURE,
735
633
  reason: `Failed to create proof as fields. Exit code ${result.exitCode}. Signal ${result.signal}.`,
736
- retry: !!result.signal
737
- };
738
- } catch (error) {
739
- return {
740
- status: 1,
741
- reason: `${error}`
634
+ retry: !!result.signal,
742
635
  };
743
636
  }
637
+ catch (error) {
638
+ return { status: BB_RESULT.FAILURE, reason: `${error}` };
639
+ }
744
640
  }
745
641
  export async function generateContractForVerificationKey(pathToBB, vkFilePath, contractPath, log) {
746
- const binaryPresent = await fs.access(pathToBB, fs.constants.R_OK).then((_)=>true).catch((_)=>false);
642
+ const binaryPresent = await fs
643
+ .access(pathToBB, fs.constants.R_OK)
644
+ .then(_ => true)
645
+ .catch(_ => false);
747
646
  if (!binaryPresent) {
748
- return {
749
- status: 1,
750
- reason: `Failed to find bb binary at ${pathToBB}`
751
- };
647
+ return { status: BB_RESULT.FAILURE, reason: `Failed to find bb binary at ${pathToBB}` };
752
648
  }
753
649
  const outputDir = dirname(contractPath);
754
650
  const contractName = basename(contractPath);
755
651
  // cache contract generation based on vk file and contract name
756
- const cacheKey = sha256(Buffer.concat([
757
- Buffer.from(contractName),
758
- await fs.readFile(vkFilePath)
759
- ]));
760
- await fs.mkdir(outputDir, {
761
- recursive: true
762
- });
763
- const res = await fsCache(outputDir, cacheKey, log, false, async ()=>{
652
+ const cacheKey = sha256(Buffer.concat([Buffer.from(contractName), await fs.readFile(vkFilePath)]));
653
+ await fs.mkdir(outputDir, { recursive: true });
654
+ const res = await fsCache(outputDir, cacheKey, log, false, async () => {
764
655
  try {
765
- const args = [
766
- '-k',
767
- vkFilePath,
768
- '-o',
769
- contractPath,
770
- '-v'
771
- ];
656
+ const args = ['-k', vkFilePath, '-o', contractPath, '-v'];
772
657
  const timer = new Timer();
773
658
  const result = await executeBB(pathToBB, 'contract_ultra_honk', args, log);
774
659
  const duration = timer.ms();
775
- if (result.status == 0) {
776
- return {
777
- status: 0,
778
- durationMs: duration,
779
- contractPath
780
- };
660
+ if (result.status == BB_RESULT.SUCCESS) {
661
+ return { status: BB_RESULT.SUCCESS, durationMs: duration, contractPath };
781
662
  }
782
663
  // Not a great error message here but it is difficult to decipher what comes from bb
783
664
  return {
784
- status: 1,
665
+ status: BB_RESULT.FAILURE,
785
666
  reason: `Failed to write verifier contract. Exit code ${result.exitCode}. Signal ${result.signal}.`,
786
- retry: !!result.signal
787
- };
788
- } catch (error) {
789
- return {
790
- status: 1,
791
- reason: `${error}`
667
+ retry: !!result.signal,
792
668
  };
793
669
  }
670
+ catch (error) {
671
+ return { status: BB_RESULT.FAILURE, reason: `${error}` };
672
+ }
794
673
  });
795
674
  if (!res) {
796
675
  return {
797
- status: 2,
676
+ status: BB_RESULT.ALREADY_PRESENT,
798
677
  durationMs: 0,
799
- contractPath
678
+ contractPath,
800
679
  };
801
680
  }
802
681
  return res;
@@ -809,28 +688,27 @@ export async function generateContractForVerificationKey(pathToBB, vkFilePath, c
809
688
  * @param bytecode - The bytecode of the circuit
810
689
  * @param flavor - The flavor of the backend - mega_honk or ultra_honk variants
811
690
  * @returns An object containing the status, gate count, and time taken
812
- */ export async function computeGateCountForCircuit(pathToBB, workingDirectory, circuitName, bytecode, flavor, log) {
691
+ */
692
+ export async function computeGateCountForCircuit(pathToBB, workingDirectory, circuitName, bytecode, flavor, log) {
813
693
  // Check that the working directory exists
814
694
  try {
815
695
  await fs.access(workingDirectory);
816
- } catch (error) {
817
- return {
818
- status: 1,
819
- reason: `Working directory ${workingDirectory} does not exist`
820
- };
696
+ }
697
+ catch (error) {
698
+ return { status: BB_RESULT.FAILURE, reason: `Working directory ${workingDirectory} does not exist` };
821
699
  }
822
700
  // The bytecode is written to e.g. /workingDirectory/BaseParityArtifact-bytecode
823
701
  const bytecodePath = `${workingDirectory}/${circuitName}-bytecode`;
824
- const binaryPresent = await fs.access(pathToBB, fs.constants.R_OK).then((_)=>true).catch((_)=>false);
702
+ const binaryPresent = await fs
703
+ .access(pathToBB, fs.constants.R_OK)
704
+ .then(_ => true)
705
+ .catch(_ => false);
825
706
  if (!binaryPresent) {
826
- return {
827
- status: 1,
828
- reason: `Failed to find bb binary at ${pathToBB}`
829
- };
707
+ return { status: BB_RESULT.FAILURE, reason: `Failed to find bb binary at ${pathToBB}` };
830
708
  }
831
709
  // Accumulate the stdout from bb
832
710
  let stdout = '';
833
- const logHandler = (message)=>{
711
+ const logHandler = (message) => {
834
712
  stdout += message;
835
713
  log(message);
836
714
  };
@@ -838,37 +716,25 @@ export async function generateContractForVerificationKey(pathToBB, vkFilePath, c
838
716
  // Write the bytecode to the working directory
839
717
  await fs.writeFile(bytecodePath, bytecode);
840
718
  const timer = new Timer();
841
- const result = await executeBB(pathToBB, flavor === 'mega_honk' ? `gates_for_ivc` : `gates`, [
842
- '-b',
843
- bytecodePath,
844
- '-v'
845
- ], logHandler);
719
+ const result = await executeBB(pathToBB, flavor === 'mega_honk' ? `gates_for_ivc` : `gates`, ['-b', bytecodePath, '-v'], logHandler);
846
720
  const duration = timer.ms();
847
- if (result.status == 0) {
721
+ if (result.status == BB_RESULT.SUCCESS) {
848
722
  // Look for "circuit_size" in the stdout and parse the number
849
723
  const circuitSizeMatch = stdout.match(/circuit_size": (\d+)/);
850
724
  if (!circuitSizeMatch) {
851
- return {
852
- status: 1,
853
- reason: 'Failed to parse circuit_size from bb gates stdout.'
854
- };
725
+ return { status: BB_RESULT.FAILURE, reason: 'Failed to parse circuit_size from bb gates stdout.' };
855
726
  }
856
727
  const circuitSize = parseInt(circuitSizeMatch[1]);
857
728
  return {
858
- status: 0,
729
+ status: BB_RESULT.SUCCESS,
859
730
  durationMs: duration,
860
- circuitSize: circuitSize
731
+ circuitSize: circuitSize,
861
732
  };
862
733
  }
863
- return {
864
- status: 1,
865
- reason: 'Failed getting the gate count.'
866
- };
867
- } catch (error) {
868
- return {
869
- status: 1,
870
- reason: `${error}`
871
- };
734
+ return { status: BB_RESULT.FAILURE, reason: 'Failed getting the gate count.' };
735
+ }
736
+ catch (error) {
737
+ return { status: BB_RESULT.FAILURE, reason: `${error}` };
872
738
  }
873
739
  }
874
740
  const CACHE_FILENAME = '.cache';
@@ -877,14 +743,17 @@ async function fsCache(dir, expectedCacheKey, logger, force, action) {
877
743
  let run;
878
744
  if (force) {
879
745
  run = true;
880
- } else {
746
+ }
747
+ else {
881
748
  try {
882
749
  run = !expectedCacheKey.equals(await fs.readFile(cacheFilePath));
883
- } catch (err) {
750
+ }
751
+ catch (err) {
884
752
  if (err && 'code' in err && err.code === 'ENOENT') {
885
753
  // cache file doesn't exist, swallow error and run
886
754
  run = true;
887
- } else {
755
+ }
756
+ else {
888
757
  throw err;
889
758
  }
890
759
  }
@@ -893,14 +762,17 @@ async function fsCache(dir, expectedCacheKey, logger, force, action) {
893
762
  if (run) {
894
763
  logger(`Cache miss or forced run. Running operation in ${dir}...`);
895
764
  res = await action();
896
- } else {
765
+ }
766
+ else {
897
767
  logger(`Cache hit. Skipping operation in ${dir}...`);
898
768
  }
899
769
  try {
900
770
  await fs.writeFile(cacheFilePath, expectedCacheKey);
901
- } catch (err) {
771
+ }
772
+ catch (err) {
902
773
  logger(`Couldn't write cache data to ${cacheFilePath}. Skipping cache...`);
903
- // ignore
774
+ // ignore
904
775
  }
905
776
  return res;
906
777
  }
778
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXhlY3V0ZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9iYi9leGVjdXRlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBeUIsd0JBQXdCLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUNyRixPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFFbEQsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBRWhELE9BQU8sS0FBSyxJQUFJLE1BQU0sZUFBZSxDQUFDO0FBQ3RDLE9BQU8sRUFBRSxRQUFRLElBQUksRUFBRSxFQUFFLE1BQU0sSUFBSSxDQUFDO0FBQ3BDLE9BQU8sRUFBRSxRQUFRLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUcvQyxPQUFPLEVBQUUsMEJBQTBCLEVBQUUsdUJBQXVCLEVBQUUsTUFBTSxxQ0FBcUMsQ0FBQztBQUUxRyxNQUFNLENBQUMsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDO0FBQ2hDLE1BQU0sQ0FBQyxNQUFNLGtCQUFrQixHQUFHLGdCQUFnQixDQUFDO0FBQ25ELE1BQU0sQ0FBQyxNQUFNLGNBQWMsR0FBRyxPQUFPLENBQUM7QUFDdEMsTUFBTSxDQUFDLE1BQU0scUJBQXFCLEdBQUcsbUJBQW1CLENBQUM7QUFDekQsTUFBTSxDQUFDLE1BQU0scUJBQXFCLEdBQUcsa0JBQWtCLENBQUM7QUFDeEQsTUFBTSxDQUFDLE1BQU0sMEJBQTBCLEdBQUcsdUJBQXVCLENBQUM7QUFDbEUsTUFBTSxDQUFDLE1BQU0sa0JBQWtCLEdBQUcsZUFBZSxDQUFDO0FBRWxELE1BQU0sQ0FBTixJQUFZLFNBSVg7QUFKRCxXQUFZLFNBQVM7SUFDbkIsK0NBQU8sQ0FBQTtJQUNQLCtDQUFPLENBQUE7SUFDUCwrREFBZSxDQUFBO0FBQ2pCLENBQUMsRUFKVyxTQUFTLEtBQVQsU0FBUyxRQUlwQjtBQWlDRDs7Ozs7Ozs7R0FRRztBQUNI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