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