@aztec/bb-prover 0.0.1-commit.2f68f620 → 0.0.1-commit.3100065
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.js +1 -1
- package/dest/prover/client/bb_private_kernel_prover.d.ts +4 -4
- package/dest/prover/client/bb_private_kernel_prover.d.ts.map +1 -1
- package/dest/prover/client/bb_private_kernel_prover.js +9 -7
- package/dest/prover/server/bb_prover.d.ts +3 -3
- package/dest/prover/server/bb_prover.d.ts.map +1 -1
- package/dest/prover/server/bb_prover.js +4 -6
- package/dest/test/test_circuit_prover.d.ts +3 -3
- package/dest/test/test_circuit_prover.d.ts.map +1 -1
- package/dest/test/test_circuit_prover.js +2 -2
- package/dest/verifier/batch_chonk_verifier.d.ts +2 -13
- package/dest/verifier/batch_chonk_verifier.d.ts.map +1 -1
- package/dest/verifier/batch_chonk_verifier.js +58 -210
- package/package.json +16 -16
- package/src/avm_proving_tests/avm_proving_tester.ts +1 -1
- package/src/prover/client/bb_private_kernel_prover.ts +18 -15
- package/src/prover/server/bb_prover.ts +6 -16
- package/src/test/test_circuit_prover.ts +3 -5
- package/src/verifier/batch_chonk_verifier.ts +65 -204
|
@@ -6,21 +6,19 @@ import { Timer } from '@aztec/foundation/timer';
|
|
|
6
6
|
import { ProtocolCircuitVks } from '@aztec/noir-protocol-circuits-types/server/vks';
|
|
7
7
|
import { Unpackr } from 'msgpackr';
|
|
8
8
|
import { execFile } from 'node:child_process';
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
9
|
+
import { unlinkSync } from 'node:fs';
|
|
10
|
+
import { unlink } from 'node:fs/promises';
|
|
11
11
|
import * as os from 'node:os';
|
|
12
12
|
import * as path from 'node:path';
|
|
13
13
|
import { promisify } from 'node:util';
|
|
14
14
|
const execFileAsync = promisify(execFile);
|
|
15
|
-
const RESULT_TIMEOUT_MS = 5 * 60 * 1000;
|
|
16
|
-
const STOP_DRAIN_TIMEOUT_MS = 5_000;
|
|
17
15
|
/** Maps client protocol artifacts used for chonk verification to VK indices. */ const CHONK_VK_ARTIFACTS = [
|
|
18
16
|
'HidingKernelToRollup',
|
|
19
17
|
'HidingKernelToPublic'
|
|
20
18
|
];
|
|
21
19
|
/**
|
|
22
20
|
* Batch verifier for Chonk IVC proofs. Uses the bb batch verifier service
|
|
23
|
-
* which batches IPA verification into a
|
|
21
|
+
* which batches IPA verification into a single SRS MSM for better throughput.
|
|
24
22
|
*
|
|
25
23
|
* Architecture:
|
|
26
24
|
* - Spawns a persistent `bb msgpack run` process via Barretenberg (native backend)
|
|
@@ -33,7 +31,6 @@ const STOP_DRAIN_TIMEOUT_MS = 5_000;
|
|
|
33
31
|
batchSize;
|
|
34
32
|
label;
|
|
35
33
|
bb;
|
|
36
|
-
fifoDir;
|
|
37
34
|
fifoPath;
|
|
38
35
|
nextRequestId;
|
|
39
36
|
pendingRequests;
|
|
@@ -42,22 +39,17 @@ const STOP_DRAIN_TIMEOUT_MS = 5_000;
|
|
|
42
39
|
logger;
|
|
43
40
|
/** Maps artifact name to VK index in the batch verifier. */ vkIndexMap;
|
|
44
41
|
/** Bound cleanup handler for process exit signals. */ exitCleanup;
|
|
45
|
-
stopped;
|
|
46
|
-
fatalError;
|
|
47
|
-
pendingDrainedResolvers;
|
|
48
42
|
constructor(config, vkBuffers, batchSize, label){
|
|
49
43
|
this.config = config;
|
|
50
44
|
this.vkBuffers = vkBuffers;
|
|
51
45
|
this.batchSize = batchSize;
|
|
52
46
|
this.label = label;
|
|
53
|
-
this.fifoPath = '';
|
|
54
47
|
this.nextRequestId = 0;
|
|
55
48
|
this.pendingRequests = new Map();
|
|
56
49
|
this.logger = createLogger('bb-prover:batch_chonk_verifier');
|
|
57
50
|
this.vkIndexMap = new Map();
|
|
58
51
|
this.exitCleanup = null;
|
|
59
|
-
this.
|
|
60
|
-
this.pendingDrainedResolvers = new Set();
|
|
52
|
+
this.fifoPath = path.join(os.tmpdir(), `bb-batch-${label}-${process.pid}-${Date.now()}.fifo`);
|
|
61
53
|
this.fifoReader = new FifoFrameReader();
|
|
62
54
|
this.sendQueue = new SerialQueue();
|
|
63
55
|
this.sendQueue.start(1);
|
|
@@ -88,91 +80,47 @@ const STOP_DRAIN_TIMEOUT_MS = 5_000;
|
|
|
88
80
|
}
|
|
89
81
|
async start() {
|
|
90
82
|
this.logger.info('Starting BatchChonkVerifier');
|
|
91
|
-
|
|
92
|
-
this.
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
this.
|
|
104
|
-
this.
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
numCores: this.config.bbChonkVerifyConcurrency || 0,
|
|
108
|
-
batchSize: this.batchSize,
|
|
109
|
-
fifoPath: this.fifoPath
|
|
110
|
-
});
|
|
111
|
-
} catch (err) {
|
|
112
|
-
this.fifoReader.stop();
|
|
113
|
-
this.deregisterExitCleanup();
|
|
114
|
-
await this.cleanupFifo();
|
|
115
|
-
await this.bb?.destroy().catch(()=>{});
|
|
116
|
-
throw err;
|
|
117
|
-
}
|
|
83
|
+
this.bb = await Barretenberg.new({
|
|
84
|
+
bbPath: this.config.bbBinaryPath,
|
|
85
|
+
backend: BackendType.NativeUnixSocket
|
|
86
|
+
});
|
|
87
|
+
await this.bb.initSRSChonk();
|
|
88
|
+
await execFileAsync('mkfifo', [
|
|
89
|
+
this.fifoPath
|
|
90
|
+
]);
|
|
91
|
+
this.registerExitCleanup();
|
|
92
|
+
await this.bb.chonkBatchVerifierStart({
|
|
93
|
+
vks: this.vkBuffers,
|
|
94
|
+
numCores: this.config.bbChonkVerifyConcurrency || 0,
|
|
95
|
+
batchSize: this.batchSize,
|
|
96
|
+
fifoPath: this.fifoPath
|
|
97
|
+
});
|
|
98
|
+
this.startFifoReader();
|
|
118
99
|
this.logger.info('BatchChonkVerifier started', {
|
|
119
100
|
fifoPath: this.fifoPath
|
|
120
101
|
});
|
|
121
102
|
}
|
|
122
103
|
verifyProof(tx) {
|
|
123
|
-
const
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
const proofFields = proofWithPubInputs.fieldsWithPublicInputs.map((f)=>f.toBuffer());
|
|
132
|
-
return await this.enqueueProof(vkIndex, proofFields);
|
|
133
|
-
})().catch((err)=>{
|
|
134
|
-
this.logger.warn(`Failed to verify Chonk proof for tx ${tx.getTxHash().toString()}: ${String(err)}`);
|
|
135
|
-
return {
|
|
136
|
-
valid: false,
|
|
137
|
-
durationMs: 0,
|
|
138
|
-
totalDurationMs: totalTimer.ms()
|
|
139
|
-
};
|
|
140
|
-
});
|
|
104
|
+
const circuit = tx.data.forPublic ? 'HidingKernelToPublic' : 'HidingKernelToRollup';
|
|
105
|
+
const vkIndex = this.vkIndexMap.get(circuit);
|
|
106
|
+
if (vkIndex === undefined) {
|
|
107
|
+
throw new Error(`No VK index for circuit ${circuit}`);
|
|
108
|
+
}
|
|
109
|
+
const proofWithPubInputs = tx.chonkProof.attachPublicInputs(tx.data.publicInputs().toFields());
|
|
110
|
+
const proofFields = proofWithPubInputs.fieldsWithPublicInputs.map((f)=>f.toBuffer());
|
|
111
|
+
return this.enqueueProof(vkIndex, proofFields);
|
|
141
112
|
}
|
|
142
113
|
/** Enqueue raw proof fields for verification. Used directly by tests with custom VKs. */ enqueueProof(vkIndex, proofFields) {
|
|
143
|
-
if (this.stopped) {
|
|
144
|
-
return Promise.reject(new Error('BatchChonkVerifier stopped'));
|
|
145
|
-
}
|
|
146
|
-
if (this.fatalError) {
|
|
147
|
-
return Promise.reject(this.fatalError);
|
|
148
|
-
}
|
|
149
114
|
const totalTimer = new Timer();
|
|
150
115
|
const requestId = this.nextRequestId++;
|
|
151
116
|
const resultPromise = new Promise((resolve, reject)=>{
|
|
152
|
-
const timeout = setTimeout(()=>{
|
|
153
|
-
const pending = this.pendingRequests.get(requestId);
|
|
154
|
-
if (!pending) {
|
|
155
|
-
return;
|
|
156
|
-
}
|
|
157
|
-
this.pendingRequests.delete(requestId);
|
|
158
|
-
pending.reject(new Error(`BatchChonkVerifier result timed out for request_id=${requestId}`));
|
|
159
|
-
this.notifyPendingDrained();
|
|
160
|
-
}, RESULT_TIMEOUT_MS);
|
|
161
|
-
// A pending result timer must never keep the host process alive on its own (e.g. an
|
|
162
|
-
// orphaned request at process exit); the FIFO reader keeps the loop alive while results
|
|
163
|
-
// are genuinely awaited.
|
|
164
|
-
timeout.unref();
|
|
165
117
|
this.pendingRequests.set(requestId, {
|
|
166
118
|
resolve,
|
|
167
119
|
reject,
|
|
168
|
-
totalTimer
|
|
169
|
-
timeout
|
|
120
|
+
totalTimer
|
|
170
121
|
});
|
|
171
122
|
});
|
|
172
123
|
void this.sendQueue.put(async ()=>{
|
|
173
|
-
if (this.fatalError) {
|
|
174
|
-
throw this.fatalError;
|
|
175
|
-
}
|
|
176
124
|
await this.bb.chonkBatchVerifierQueue({
|
|
177
125
|
requestId,
|
|
178
126
|
vkIndex,
|
|
@@ -182,62 +130,35 @@ const STOP_DRAIN_TIMEOUT_MS = 5_000;
|
|
|
182
130
|
const pending = this.pendingRequests.get(requestId);
|
|
183
131
|
if (pending) {
|
|
184
132
|
this.pendingRequests.delete(requestId);
|
|
185
|
-
clearTimeout(pending.timeout);
|
|
186
133
|
pending.reject(err instanceof Error ? err : new Error(String(err)));
|
|
187
|
-
this.notifyPendingDrained();
|
|
188
134
|
}
|
|
189
135
|
});
|
|
190
136
|
return resultPromise;
|
|
191
137
|
}
|
|
192
138
|
async stop() {
|
|
193
139
|
this.logger.info('Stopping BatchChonkVerifier');
|
|
194
|
-
|
|
140
|
+
// Stop accepting new proofs
|
|
141
|
+
await this.sendQueue.end();
|
|
142
|
+
// Stop the bb service (flushes remaining proofs)
|
|
195
143
|
try {
|
|
196
|
-
|
|
197
|
-
// native process can't block teardown of our own event-loop handles indefinitely.
|
|
198
|
-
await this.withTimeout(this.sendQueue.end(), STOP_DRAIN_TIMEOUT_MS, 'send queue flush');
|
|
199
|
-
// Stop the bb service (flushes remaining proofs).
|
|
200
|
-
await this.withTimeout(this.bb.chonkBatchVerifierStop({}), STOP_DRAIN_TIMEOUT_MS, 'chonkBatchVerifierStop');
|
|
201
|
-
// Native stop flushes callbacks; keep the FIFO open until those frames are observed.
|
|
202
|
-
const drained = await this.waitForPendingRequestsToDrain(STOP_DRAIN_TIMEOUT_MS);
|
|
203
|
-
if (!drained) {
|
|
204
|
-
this.rejectPendingRequests(new Error('Timed out waiting for BatchChonkVerifier results during stop'));
|
|
205
|
-
}
|
|
144
|
+
await this.bb.chonkBatchVerifierStop({});
|
|
206
145
|
} catch (err) {
|
|
207
|
-
this.logger.warn(`Error
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
146
|
+
this.logger.warn(`Error stopping batch verifier service: ${err}`);
|
|
147
|
+
}
|
|
148
|
+
// Stop FIFO reader
|
|
149
|
+
this.fifoReader.stop();
|
|
150
|
+
// Clean up FIFO file and deregister exit handler
|
|
151
|
+
await unlink(this.fifoPath).catch(()=>{});
|
|
152
|
+
this.deregisterExitCleanup();
|
|
153
|
+
// Reject any remaining pending requests
|
|
154
|
+
for (const [id, pending] of this.pendingRequests){
|
|
155
|
+
pending.reject(new Error('BatchChonkVerifier stopped'));
|
|
156
|
+
this.pendingRequests.delete(id);
|
|
217
157
|
}
|
|
158
|
+
// Destroy bb process
|
|
159
|
+
await this.bb.destroy();
|
|
218
160
|
this.logger.info('BatchChonkVerifier stopped');
|
|
219
161
|
}
|
|
220
|
-
/**
|
|
221
|
-
* Races a promise against a timeout so a wedged native backend can't block teardown. The
|
|
222
|
-
* timer is unref'd so it never keeps the process alive; the underlying promise stays handled
|
|
223
|
-
* by the race even if the timeout wins, so it cannot surface as an unhandled rejection.
|
|
224
|
-
*/ async withTimeout(promise, timeoutMs, label) {
|
|
225
|
-
let timer;
|
|
226
|
-
const timeout = new Promise((_, reject)=>{
|
|
227
|
-
timer = setTimeout(()=>reject(new Error(`BatchChonkVerifier ${label} timed out after ${timeoutMs}ms`)), timeoutMs);
|
|
228
|
-
timer.unref();
|
|
229
|
-
});
|
|
230
|
-
try {
|
|
231
|
-
return await Promise.race([
|
|
232
|
-
promise,
|
|
233
|
-
timeout
|
|
234
|
-
]);
|
|
235
|
-
} finally{
|
|
236
|
-
if (timer) {
|
|
237
|
-
clearTimeout(timer);
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
162
|
startFifoReader() {
|
|
242
163
|
const unpackr = new Unpackr({
|
|
243
164
|
useRecords: false
|
|
@@ -248,18 +169,16 @@ const STOP_DRAIN_TIMEOUT_MS = 5_000;
|
|
|
248
169
|
this.handleResult(result);
|
|
249
170
|
} catch (err) {
|
|
250
171
|
this.logger.error(`FIFO: failed to decode msgpack result: ${err}`);
|
|
251
|
-
// A corrupt result stream cannot safely be matched to outstanding requests.
|
|
252
|
-
this.failVerifier(err instanceof Error ? err : new Error(String(err)));
|
|
253
172
|
}
|
|
254
173
|
});
|
|
255
174
|
this.fifoReader.on('error', (err)=>{
|
|
256
175
|
this.logger.error(`FIFO reader error: ${err}`);
|
|
257
|
-
this.failVerifier(err);
|
|
258
176
|
});
|
|
259
177
|
this.fifoReader.on('end', ()=>{
|
|
260
178
|
this.logger.debug('FIFO reader: stream ended');
|
|
261
|
-
|
|
262
|
-
|
|
179
|
+
for (const [id, pending] of this.pendingRequests){
|
|
180
|
+
pending.reject(new Error('FIFO stream ended unexpectedly'));
|
|
181
|
+
this.pendingRequests.delete(id);
|
|
263
182
|
}
|
|
264
183
|
});
|
|
265
184
|
this.fifoReader.start(this.fifoPath);
|
|
@@ -271,7 +190,6 @@ const STOP_DRAIN_TIMEOUT_MS = 5_000;
|
|
|
271
190
|
return;
|
|
272
191
|
}
|
|
273
192
|
this.pendingRequests.delete(result.request_id);
|
|
274
|
-
clearTimeout(pending.timeout);
|
|
275
193
|
const valid = result.status === 0; // VerifyStatus::OK
|
|
276
194
|
const durationMs = result.time_in_verify_ms;
|
|
277
195
|
const totalDurationMs = pending.totalTimer.ms();
|
|
@@ -290,95 +208,25 @@ const STOP_DRAIN_TIMEOUT_MS = 5_000;
|
|
|
290
208
|
});
|
|
291
209
|
}
|
|
292
210
|
pending.resolve(ivcResult);
|
|
293
|
-
this.notifyPendingDrained();
|
|
294
211
|
}
|
|
295
212
|
registerExitCleanup() {
|
|
213
|
+
// Signal handlers must be synchronous — unlinkSync is intentional here
|
|
296
214
|
this.exitCleanup = ()=>{
|
|
297
|
-
|
|
215
|
+
try {
|
|
216
|
+
unlinkSync(this.fifoPath);
|
|
217
|
+
} catch {
|
|
218
|
+
/* ignore */ }
|
|
298
219
|
};
|
|
299
220
|
process.on('exit', this.exitCleanup);
|
|
221
|
+
process.on('SIGINT', this.exitCleanup);
|
|
222
|
+
process.on('SIGTERM', this.exitCleanup);
|
|
300
223
|
}
|
|
301
224
|
deregisterExitCleanup() {
|
|
302
225
|
if (this.exitCleanup) {
|
|
303
226
|
process.removeListener('exit', this.exitCleanup);
|
|
227
|
+
process.removeListener('SIGINT', this.exitCleanup);
|
|
228
|
+
process.removeListener('SIGTERM', this.exitCleanup);
|
|
304
229
|
this.exitCleanup = null;
|
|
305
230
|
}
|
|
306
231
|
}
|
|
307
|
-
rejectPendingRequests(error) {
|
|
308
|
-
for (const [id, pending] of Array.from(this.pendingRequests)){
|
|
309
|
-
pending.reject(error);
|
|
310
|
-
clearTimeout(pending.timeout);
|
|
311
|
-
this.pendingRequests.delete(id);
|
|
312
|
-
}
|
|
313
|
-
this.notifyPendingDrained();
|
|
314
|
-
}
|
|
315
|
-
failVerifier(error) {
|
|
316
|
-
if (!this.fatalError) {
|
|
317
|
-
this.fatalError = error;
|
|
318
|
-
}
|
|
319
|
-
this.rejectPendingRequests(error);
|
|
320
|
-
}
|
|
321
|
-
waitForPendingRequestsToDrain(timeoutMs) {
|
|
322
|
-
if (this.pendingRequests.size === 0) {
|
|
323
|
-
return Promise.resolve(true);
|
|
324
|
-
}
|
|
325
|
-
let timeout;
|
|
326
|
-
let onDrain;
|
|
327
|
-
const drained = new Promise((resolve)=>{
|
|
328
|
-
onDrain = ()=>resolve(true);
|
|
329
|
-
this.pendingDrainedResolvers.add(onDrain);
|
|
330
|
-
});
|
|
331
|
-
const timedOut = new Promise((resolve)=>{
|
|
332
|
-
timeout = setTimeout(()=>resolve(false), timeoutMs);
|
|
333
|
-
timeout.unref();
|
|
334
|
-
});
|
|
335
|
-
return Promise.race([
|
|
336
|
-
drained,
|
|
337
|
-
timedOut
|
|
338
|
-
]).finally(()=>{
|
|
339
|
-
if (timeout) {
|
|
340
|
-
clearTimeout(timeout);
|
|
341
|
-
}
|
|
342
|
-
if (onDrain) {
|
|
343
|
-
this.pendingDrainedResolvers.delete(onDrain);
|
|
344
|
-
}
|
|
345
|
-
});
|
|
346
|
-
}
|
|
347
|
-
notifyPendingDrained() {
|
|
348
|
-
if (this.pendingRequests.size > 0) {
|
|
349
|
-
return;
|
|
350
|
-
}
|
|
351
|
-
for (const resolve of Array.from(this.pendingDrainedResolvers)){
|
|
352
|
-
resolve();
|
|
353
|
-
}
|
|
354
|
-
}
|
|
355
|
-
async cleanupFifo() {
|
|
356
|
-
if (this.fifoDir) {
|
|
357
|
-
await rm(this.fifoDir, {
|
|
358
|
-
recursive: true,
|
|
359
|
-
force: true
|
|
360
|
-
}).catch(()=>{});
|
|
361
|
-
} else if (this.fifoPath) {
|
|
362
|
-
await rm(this.fifoPath, {
|
|
363
|
-
force: true
|
|
364
|
-
}).catch(()=>{});
|
|
365
|
-
}
|
|
366
|
-
this.fifoDir = undefined;
|
|
367
|
-
this.fifoPath = '';
|
|
368
|
-
}
|
|
369
|
-
cleanupFifoSync() {
|
|
370
|
-
try {
|
|
371
|
-
if (this.fifoDir) {
|
|
372
|
-
rmSync(this.fifoDir, {
|
|
373
|
-
recursive: true,
|
|
374
|
-
force: true
|
|
375
|
-
});
|
|
376
|
-
} else if (this.fifoPath) {
|
|
377
|
-
rmSync(this.fifoPath, {
|
|
378
|
-
force: true
|
|
379
|
-
});
|
|
380
|
-
}
|
|
381
|
-
} catch {
|
|
382
|
-
/* ignore */ }
|
|
383
|
-
}
|
|
384
232
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aztec/bb-prover",
|
|
3
|
-
"version": "0.0.1-commit.
|
|
3
|
+
"version": "0.0.1-commit.3100065",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": "./dest/index.js",
|
|
@@ -70,16 +70,16 @@
|
|
|
70
70
|
]
|
|
71
71
|
},
|
|
72
72
|
"dependencies": {
|
|
73
|
-
"@aztec/bb.js": "0.0.1-commit.
|
|
74
|
-
"@aztec/constants": "0.0.1-commit.
|
|
75
|
-
"@aztec/foundation": "0.0.1-commit.
|
|
76
|
-
"@aztec/noir-noirc_abi": "0.0.1-commit.
|
|
77
|
-
"@aztec/noir-protocol-circuits-types": "0.0.1-commit.
|
|
78
|
-
"@aztec/noir-types": "0.0.1-commit.
|
|
79
|
-
"@aztec/simulator": "0.0.1-commit.
|
|
80
|
-
"@aztec/stdlib": "0.0.1-commit.
|
|
81
|
-
"@aztec/telemetry-client": "0.0.1-commit.
|
|
82
|
-
"@aztec/world-state": "0.0.1-commit.
|
|
73
|
+
"@aztec/bb.js": "0.0.1-commit.3100065",
|
|
74
|
+
"@aztec/constants": "0.0.1-commit.3100065",
|
|
75
|
+
"@aztec/foundation": "0.0.1-commit.3100065",
|
|
76
|
+
"@aztec/noir-noirc_abi": "0.0.1-commit.3100065",
|
|
77
|
+
"@aztec/noir-protocol-circuits-types": "0.0.1-commit.3100065",
|
|
78
|
+
"@aztec/noir-types": "0.0.1-commit.3100065",
|
|
79
|
+
"@aztec/simulator": "0.0.1-commit.3100065",
|
|
80
|
+
"@aztec/stdlib": "0.0.1-commit.3100065",
|
|
81
|
+
"@aztec/telemetry-client": "0.0.1-commit.3100065",
|
|
82
|
+
"@aztec/world-state": "0.0.1-commit.3100065",
|
|
83
83
|
"commander": "^12.1.0",
|
|
84
84
|
"msgpackr": "^1.11.2",
|
|
85
85
|
"pako": "^2.1.0",
|
|
@@ -87,11 +87,11 @@
|
|
|
87
87
|
"tslib": "^2.4.0"
|
|
88
88
|
},
|
|
89
89
|
"devDependencies": {
|
|
90
|
-
"@aztec/ethereum": "0.0.1-commit.
|
|
91
|
-
"@aztec/kv-store": "0.0.1-commit.
|
|
92
|
-
"@aztec/noir-contracts.js": "0.0.1-commit.
|
|
93
|
-
"@aztec/noir-test-contracts.js": "0.0.1-commit.
|
|
94
|
-
"@aztec/protocol-contracts": "0.0.1-commit.
|
|
90
|
+
"@aztec/ethereum": "0.0.1-commit.3100065",
|
|
91
|
+
"@aztec/kv-store": "0.0.1-commit.3100065",
|
|
92
|
+
"@aztec/noir-contracts.js": "0.0.1-commit.3100065",
|
|
93
|
+
"@aztec/noir-test-contracts.js": "0.0.1-commit.3100065",
|
|
94
|
+
"@aztec/protocol-contracts": "0.0.1-commit.3100065",
|
|
95
95
|
"@jest/globals": "^30.0.0",
|
|
96
96
|
"@types/jest": "^30.0.0",
|
|
97
97
|
"@types/node": "^22.15.17",
|
|
@@ -192,7 +192,7 @@ export class AvmProvingTester extends PublicTxSimulationTester {
|
|
|
192
192
|
gasLimits?: Gas,
|
|
193
193
|
) {
|
|
194
194
|
await this.simProveVerify(
|
|
195
|
-
/*sender=*/ AztecAddress.
|
|
195
|
+
/*sender=*/ AztecAddress.fromNumberUnsafe(42),
|
|
196
196
|
/*setupCalls=*/ [],
|
|
197
197
|
[appCall],
|
|
198
198
|
undefined,
|
|
@@ -19,12 +19,13 @@ import {
|
|
|
19
19
|
convertPrivateKernelInnerOutputsFromWitnessMapWithAbi,
|
|
20
20
|
convertPrivateKernelResetInputsToWitnessMapWithAbi,
|
|
21
21
|
convertPrivateKernelResetOutputsFromWitnessMapWithAbi,
|
|
22
|
+
convertPrivateKernelResetTailInputsToWitnessMapWithAbi,
|
|
23
|
+
convertPrivateKernelResetTailToPublicInputsToWitnessMapWithAbi,
|
|
22
24
|
convertPrivateKernelTailForPublicOutputsFromWitnessMapWithAbi,
|
|
23
|
-
convertPrivateKernelTailInputsToWitnessMapWithAbi,
|
|
24
25
|
convertPrivateKernelTailOutputsFromWitnessMapWithAbi,
|
|
25
|
-
convertPrivateKernelTailToPublicInputsToWitnessMapWithAbi,
|
|
26
26
|
foreignCallHandler,
|
|
27
27
|
getPrivateKernelResetArtifactName,
|
|
28
|
+
getPrivateKernelResetTailArtifactName,
|
|
28
29
|
updateResetCircuitSampleInputs,
|
|
29
30
|
} from '@aztec/noir-protocol-circuits-types/client';
|
|
30
31
|
import {
|
|
@@ -47,8 +48,8 @@ import type {
|
|
|
47
48
|
PrivateKernelInner3CircuitPrivateInputs,
|
|
48
49
|
PrivateKernelInnerCircuitPrivateInputs,
|
|
49
50
|
PrivateKernelResetCircuitPrivateInputs,
|
|
51
|
+
PrivateKernelResetTailCircuitPrivateInputs,
|
|
50
52
|
PrivateKernelSimulateOutput,
|
|
51
|
-
PrivateKernelTailCircuitPrivateInputs,
|
|
52
53
|
PrivateKernelTailCircuitPublicInputs,
|
|
53
54
|
} from '@aztec/stdlib/kernel';
|
|
54
55
|
import type { NoirCompiledCircuitWithName } from '@aztec/stdlib/noir';
|
|
@@ -228,40 +229,42 @@ export abstract class BBPrivateKernelProver implements PrivateKernelProver {
|
|
|
228
229
|
);
|
|
229
230
|
}
|
|
230
231
|
|
|
231
|
-
public async
|
|
232
|
-
inputs:
|
|
232
|
+
public async generateResetTailOutput(
|
|
233
|
+
inputs: PrivateKernelResetTailCircuitPrivateInputs,
|
|
233
234
|
): Promise<PrivateKernelSimulateOutput<PrivateKernelTailCircuitPublicInputs>> {
|
|
235
|
+
const artifactName = getPrivateKernelResetTailArtifactName(inputs.dimensions, inputs.isForPublic());
|
|
234
236
|
if (!inputs.isForPublic()) {
|
|
235
237
|
return await this.generateCircuitOutput(
|
|
236
238
|
inputs,
|
|
237
|
-
|
|
238
|
-
|
|
239
|
+
artifactName,
|
|
240
|
+
convertPrivateKernelResetTailInputsToWitnessMapWithAbi,
|
|
239
241
|
convertPrivateKernelTailOutputsFromWitnessMapWithAbi,
|
|
240
242
|
);
|
|
241
243
|
}
|
|
242
244
|
return await this.generateCircuitOutput(
|
|
243
245
|
inputs,
|
|
244
|
-
|
|
245
|
-
|
|
246
|
+
artifactName,
|
|
247
|
+
convertPrivateKernelResetTailToPublicInputsToWitnessMapWithAbi,
|
|
246
248
|
convertPrivateKernelTailForPublicOutputsFromWitnessMapWithAbi,
|
|
247
249
|
);
|
|
248
250
|
}
|
|
249
251
|
|
|
250
|
-
public async
|
|
251
|
-
inputs:
|
|
252
|
+
public async simulateResetTail(
|
|
253
|
+
inputs: PrivateKernelResetTailCircuitPrivateInputs,
|
|
252
254
|
): Promise<PrivateKernelSimulateOutput<PrivateKernelTailCircuitPublicInputs>> {
|
|
255
|
+
const artifactName = getPrivateKernelResetTailArtifactName(inputs.dimensions, inputs.isForPublic());
|
|
253
256
|
if (!inputs.isForPublic()) {
|
|
254
257
|
return await this.simulateCircuitOutput(
|
|
255
258
|
inputs,
|
|
256
|
-
|
|
257
|
-
|
|
259
|
+
artifactName,
|
|
260
|
+
convertPrivateKernelResetTailInputsToWitnessMapWithAbi,
|
|
258
261
|
convertPrivateKernelTailOutputsFromWitnessMapWithAbi,
|
|
259
262
|
);
|
|
260
263
|
}
|
|
261
264
|
return await this.simulateCircuitOutput(
|
|
262
265
|
inputs,
|
|
263
|
-
|
|
264
|
-
|
|
266
|
+
artifactName,
|
|
267
|
+
convertPrivateKernelResetTailToPublicInputsToWitnessMapWithAbi,
|
|
265
268
|
convertPrivateKernelTailForPublicOutputsFromWitnessMapWithAbi,
|
|
266
269
|
);
|
|
267
270
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
2
|
+
AVM_V2_PROOF_LENGTH_IN_FIELDS,
|
|
3
3
|
NESTED_RECURSIVE_PROOF_LENGTH,
|
|
4
4
|
NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH,
|
|
5
5
|
PAIRING_POINTS_SIZE,
|
|
@@ -177,9 +177,7 @@ export class BBNativeRollupProver implements ServerCircuitProver {
|
|
|
177
177
|
@trackSpan('BBNativeRollupProver.getAvmProof', inputs => ({
|
|
178
178
|
[Attributes.APP_CIRCUIT_NAME]: inputs.hints.tx.hash,
|
|
179
179
|
}))
|
|
180
|
-
public async getAvmProof(
|
|
181
|
-
inputs: AvmCircuitInputs,
|
|
182
|
-
): Promise<RecursiveProof<typeof AVM_V2_PROOF_LENGTH_IN_FIELDS_PADDED>> {
|
|
180
|
+
public async getAvmProof(inputs: AvmCircuitInputs): Promise<RecursiveProof<typeof AVM_V2_PROOF_LENGTH_IN_FIELDS>> {
|
|
183
181
|
const proof = await this.createAvmProof(inputs);
|
|
184
182
|
await this.verifyAvmProof(proof.binaryProof, inputs.publicInputs);
|
|
185
183
|
return proof;
|
|
@@ -508,9 +506,7 @@ export class BBNativeRollupProver implements ServerCircuitProver {
|
|
|
508
506
|
};
|
|
509
507
|
}
|
|
510
508
|
|
|
511
|
-
private async createAvmProof(
|
|
512
|
-
input: AvmCircuitInputs,
|
|
513
|
-
): Promise<RecursiveProof<typeof AVM_V2_PROOF_LENGTH_IN_FIELDS_PADDED>> {
|
|
509
|
+
private async createAvmProof(input: AvmCircuitInputs): Promise<RecursiveProof<typeof AVM_V2_PROOF_LENGTH_IN_FIELDS>> {
|
|
514
510
|
logger.info(`Proving avm-circuit for TX ${input.hints.tx.hash}...`);
|
|
515
511
|
|
|
516
512
|
const inputsBuffer = input.serializeWithMessagePack();
|
|
@@ -520,20 +516,14 @@ export class BBNativeRollupProver implements ServerCircuitProver {
|
|
|
520
516
|
// Convert Uint8Array[] (32-byte field elements) to Fr[]
|
|
521
517
|
const proofFields = proofFieldArrays.map(f => Fr.fromBuffer(Buffer.from(f)));
|
|
522
518
|
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
throw new Error(
|
|
526
|
-
`Proof has ${proofFields.length} fields, expected no more than ${AVM_V2_PROOF_LENGTH_IN_FIELDS_PADDED}.`,
|
|
527
|
-
);
|
|
519
|
+
if (proofFields.length !== AVM_V2_PROOF_LENGTH_IN_FIELDS) {
|
|
520
|
+
throw new Error(`Proof has ${proofFields.length} fields, expected exactly ${AVM_V2_PROOF_LENGTH_IN_FIELDS}.`);
|
|
528
521
|
}
|
|
529
|
-
const proofFieldsPadded = proofFields.concat(
|
|
530
|
-
Array(AVM_V2_PROOF_LENGTH_IN_FIELDS_PADDED - proofFields.length).fill(new Fr(0)),
|
|
531
|
-
);
|
|
532
522
|
|
|
533
523
|
// Build the binary proof from the raw field data
|
|
534
524
|
const rawProofBuffer = Buffer.concat(proofFieldArrays.map(f => Buffer.from(f)));
|
|
535
525
|
const binaryProof = new Proof(rawProofBuffer, /*numPublicInputs=*/ 0);
|
|
536
|
-
const avmProof = new RecursiveProof(
|
|
526
|
+
const avmProof = new RecursiveProof(proofFields, binaryProof, true, AVM_V2_PROOF_LENGTH_IN_FIELDS);
|
|
537
527
|
|
|
538
528
|
const circuitType = 'avm-circuit' as const;
|
|
539
529
|
const appCircuitName = 'unknown' as const;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
2
|
+
AVM_V2_PROOF_LENGTH_IN_FIELDS,
|
|
3
3
|
NESTED_RECURSIVE_PROOF_LENGTH,
|
|
4
4
|
NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH,
|
|
5
5
|
RECURSIVE_PROOF_LENGTH,
|
|
@@ -402,13 +402,11 @@ export class TestCircuitProver implements ServerCircuitProver {
|
|
|
402
402
|
);
|
|
403
403
|
}
|
|
404
404
|
|
|
405
|
-
public getAvmProof(_inputs: AvmCircuitInputs): Promise<RecursiveProof<typeof
|
|
405
|
+
public getAvmProof(_inputs: AvmCircuitInputs): Promise<RecursiveProof<typeof AVM_V2_PROOF_LENGTH_IN_FIELDS>> {
|
|
406
406
|
// We can't simulate the AVM because we don't have enough context to do so (e.g., DBs).
|
|
407
407
|
// We just return an empty proof.
|
|
408
408
|
this.logger.debug('Skipping AVM simulation in TestCircuitProver.');
|
|
409
|
-
return this.applyDelay(ProvingRequestType.PUBLIC_VM, () =>
|
|
410
|
-
makeEmptyRecursiveProof(AVM_V2_PROOF_LENGTH_IN_FIELDS_PADDED),
|
|
411
|
-
);
|
|
409
|
+
return this.applyDelay(ProvingRequestType.PUBLIC_VM, () => makeEmptyRecursiveProof(AVM_V2_PROOF_LENGTH_IN_FIELDS));
|
|
412
410
|
}
|
|
413
411
|
|
|
414
412
|
private async applyDelay<F extends () => any>(type: ProvingRequestType, fn: F): Promise<Awaited<ReturnType<F>>> {
|