@aztec/bb-prover 0.73.0 → 0.75.0-commit.c03ba01a2a4122e43e90d5133ba017e54b90e9d2

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