@aztec/prover-client 0.56.0 → 0.57.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dest/index.d.ts +1 -1
- package/dest/index.d.ts.map +1 -1
- package/dest/mocks/test_context.d.ts +5 -5
- package/dest/mocks/test_context.d.ts.map +1 -1
- package/dest/mocks/test_context.js +8 -8
- package/dest/orchestrator/block-proving-state.d.ts +6 -7
- package/dest/orchestrator/block-proving-state.d.ts.map +1 -1
- package/dest/orchestrator/block-proving-state.js +10 -33
- package/dest/orchestrator/epoch-proving-state.d.ts +8 -2
- package/dest/orchestrator/epoch-proving-state.d.ts.map +1 -1
- package/dest/orchestrator/epoch-proving-state.js +8 -16
- package/dest/orchestrator/orchestrator.d.ts +12 -15
- package/dest/orchestrator/orchestrator.d.ts.map +1 -1
- package/dest/orchestrator/orchestrator.js +134 -98
- package/dest/prover-agent/memory-proving-queue.d.ts +2 -2
- package/dest/prover-agent/memory-proving-queue.d.ts.map +1 -1
- package/dest/prover-agent/memory-proving-queue.js +3 -3
- package/dest/prover-agent/prover-agent.js +4 -4
- package/dest/prover-agent/rpc.d.ts.map +1 -1
- package/dest/prover-agent/rpc.js +4 -2
- package/dest/test/mock_prover.d.ts +3 -3
- package/dest/test/mock_prover.d.ts.map +1 -1
- package/dest/test/mock_prover.js +3 -3
- package/dest/tx-prover/tx-prover.d.ts +3 -3
- package/dest/tx-prover/tx-prover.d.ts.map +1 -1
- package/dest/tx-prover/tx-prover.js +1 -1
- package/package.json +13 -10
- package/src/index.ts +1 -1
- package/src/mocks/test_context.ts +8 -8
- package/src/orchestrator/block-proving-state.ts +9 -35
- package/src/orchestrator/epoch-proving-state.ts +9 -20
- package/src/orchestrator/orchestrator.ts +167 -131
- package/src/prover-agent/memory-proving-queue.ts +4 -3
- package/src/prover-agent/prover-agent.ts +4 -4
- package/src/prover-agent/rpc.ts +3 -0
- package/src/test/mock_prover.ts +2 -2
- package/src/tx-prover/tx-prover.ts +4 -4
|
@@ -1,20 +1,14 @@
|
|
|
1
1
|
import {
|
|
2
|
-
BlockProofError,
|
|
3
2
|
Body,
|
|
4
3
|
EncryptedNoteTxL2Logs,
|
|
5
4
|
EncryptedTxL2Logs,
|
|
6
5
|
L2Block,
|
|
7
6
|
MerkleTreeId,
|
|
8
|
-
PROVING_STATUS,
|
|
9
7
|
type PaddingProcessedTx,
|
|
10
8
|
type ProcessedTx,
|
|
11
|
-
type ProvingBlockResult,
|
|
12
9
|
ProvingRequestType,
|
|
13
|
-
type ProvingResult,
|
|
14
|
-
type ProvingTicket,
|
|
15
10
|
type PublicInputsAndRecursiveProof,
|
|
16
11
|
type ServerCircuitProver,
|
|
17
|
-
Tx,
|
|
18
12
|
type TxEffect,
|
|
19
13
|
UnencryptedTxL2Logs,
|
|
20
14
|
makeEmptyProcessedTx,
|
|
@@ -31,6 +25,7 @@ import {
|
|
|
31
25
|
type BaseRollupInputs,
|
|
32
26
|
type BlockRootOrBlockMergePublicInputs,
|
|
33
27
|
BlockRootRollupInputs,
|
|
28
|
+
EmptyBlockRootRollupInputs,
|
|
34
29
|
Fr,
|
|
35
30
|
type GlobalVariables,
|
|
36
31
|
type KernelCircuitPublicInputs,
|
|
@@ -83,7 +78,12 @@ import {
|
|
|
83
78
|
validateTx,
|
|
84
79
|
} from './block-building-helpers.js';
|
|
85
80
|
import { type BlockProvingState, type MergeRollupInputData } from './block-proving-state.js';
|
|
86
|
-
import {
|
|
81
|
+
import {
|
|
82
|
+
type BlockMergeRollupInputData,
|
|
83
|
+
EpochProvingState,
|
|
84
|
+
type ProvingResult,
|
|
85
|
+
type TreeSnapshots,
|
|
86
|
+
} from './epoch-proving-state.js';
|
|
87
87
|
import { ProvingOrchestratorMetrics } from './orchestrator_metrics.js';
|
|
88
88
|
import { TX_PROVING_CODE, type TxProvingInstruction, TxProvingState } from './tx-proving-state.js';
|
|
89
89
|
|
|
@@ -108,6 +108,7 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
108
108
|
private pendingProvingJobs: AbortController[] = [];
|
|
109
109
|
private paddingTx: PaddingProcessedTx | undefined = undefined;
|
|
110
110
|
|
|
111
|
+
private provingPromise: Promise<ProvingResult> | undefined = undefined;
|
|
111
112
|
private metrics: ProvingOrchestratorMetrics;
|
|
112
113
|
|
|
113
114
|
constructor(
|
|
@@ -134,26 +135,20 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
134
135
|
this.paddingTx = undefined;
|
|
135
136
|
}
|
|
136
137
|
|
|
137
|
-
|
|
138
|
-
[Attributes.EPOCH_SIZE]: totalNumBlocks,
|
|
139
|
-
[Attributes.EPOCH_NUMBER]: epochNumber,
|
|
140
|
-
}))
|
|
141
|
-
public startNewEpoch(epochNumber: number, totalNumBlocks: number): ProvingTicket {
|
|
138
|
+
public startNewEpoch(epochNumber: number, totalNumBlocks: number) {
|
|
142
139
|
const { promise: _promise, resolve, reject } = promiseWithResolvers<ProvingResult>();
|
|
143
|
-
const promise = _promise.catch(
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
);
|
|
149
|
-
|
|
140
|
+
const promise = _promise.catch((reason): ProvingResult => ({ status: 'failure', reason }));
|
|
141
|
+
if (totalNumBlocks <= 0 || !Number.isInteger(totalNumBlocks)) {
|
|
142
|
+
throw new Error(`Invalid number of blocks for epoch (got ${totalNumBlocks})`);
|
|
143
|
+
}
|
|
144
|
+
logger.info(`Starting epoch ${epochNumber} with ${totalNumBlocks} blocks`);
|
|
150
145
|
this.provingState = new EpochProvingState(epochNumber, totalNumBlocks, resolve, reject);
|
|
151
|
-
|
|
146
|
+
this.provingPromise = promise;
|
|
152
147
|
}
|
|
153
148
|
|
|
154
149
|
/**
|
|
155
150
|
* Starts off a new block
|
|
156
|
-
* @param numTxs - The total number of transactions in the block.
|
|
151
|
+
* @param numTxs - The total number of transactions in the block.
|
|
157
152
|
* @param globalVariables - The global variables for the block
|
|
158
153
|
* @param l1ToL2Messages - The l1 to l2 messages for the block
|
|
159
154
|
* @param verificationKeys - The private kernel verification keys
|
|
@@ -163,14 +158,9 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
163
158
|
[Attributes.BLOCK_SIZE]: numTxs,
|
|
164
159
|
[Attributes.BLOCK_NUMBER]: globalVariables.blockNumber.toNumber(),
|
|
165
160
|
}))
|
|
166
|
-
public async startNewBlock(
|
|
167
|
-
numTxs: number,
|
|
168
|
-
globalVariables: GlobalVariables,
|
|
169
|
-
l1ToL2Messages: Fr[],
|
|
170
|
-
): Promise<ProvingTicket> {
|
|
171
|
-
// If no proving state, assume we only care about proving this block and initialize a 1-block epoch
|
|
161
|
+
public async startNewBlock(numTxs: number, globalVariables: GlobalVariables, l1ToL2Messages: Fr[]) {
|
|
172
162
|
if (!this.provingState) {
|
|
173
|
-
|
|
163
|
+
throw new Error(`Invalid proving state, call startNewEpoch before starting a block`);
|
|
174
164
|
}
|
|
175
165
|
|
|
176
166
|
if (!this.provingState?.isAcceptingBlocks()) {
|
|
@@ -178,10 +168,14 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
178
168
|
}
|
|
179
169
|
|
|
180
170
|
if (!Number.isInteger(numTxs) || numTxs < 2) {
|
|
181
|
-
throw new Error(`
|
|
171
|
+
throw new Error(`Invalid number of txs for block (got ${numTxs})`);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
if (this.provingState.currentBlock && !this.provingState.currentBlock.block) {
|
|
175
|
+
throw new Error(`Must end previous block before starting a new one`);
|
|
182
176
|
}
|
|
183
177
|
|
|
184
|
-
// TODO(palla/prover
|
|
178
|
+
// TODO(palla/prover): Store block number in the db itself to make this check more reliable,
|
|
185
179
|
// and turn this warning into an exception that we throw.
|
|
186
180
|
const { blockNumber } = globalVariables;
|
|
187
181
|
const dbBlockNumber = (await this.db.getTreeInfo(MerkleTreeId.ARCHIVE)).size - 1n;
|
|
@@ -234,9 +228,6 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
234
228
|
BigInt(startArchiveSnapshot.nextAvailableLeafIndex - 1),
|
|
235
229
|
);
|
|
236
230
|
|
|
237
|
-
const { promise: _promise, resolve, reject } = promiseWithResolvers<ProvingResult>();
|
|
238
|
-
const promise = _promise.catch((reason): ProvingResult => ({ status: PROVING_STATUS.FAILURE, reason }));
|
|
239
|
-
|
|
240
231
|
this.provingState!.startNewBlock(
|
|
241
232
|
numTxs,
|
|
242
233
|
globalVariables,
|
|
@@ -247,16 +238,12 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
247
238
|
startArchiveSnapshot,
|
|
248
239
|
newArchiveSiblingPath,
|
|
249
240
|
previousBlockHash!,
|
|
250
|
-
resolve,
|
|
251
|
-
reject,
|
|
252
241
|
);
|
|
253
242
|
|
|
254
243
|
// Enqueue base parity circuits for the block
|
|
255
244
|
for (let i = 0; i < baseParityInputs.length; i++) {
|
|
256
245
|
this.enqueueBaseParityCircuit(this.provingState!.currentBlock!, baseParityInputs[i], i);
|
|
257
246
|
}
|
|
258
|
-
|
|
259
|
-
return { provingPromise: promise };
|
|
260
247
|
}
|
|
261
248
|
|
|
262
249
|
/**
|
|
@@ -276,6 +263,10 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
276
263
|
throw new Error(`Rollup not accepting further transactions`);
|
|
277
264
|
}
|
|
278
265
|
|
|
266
|
+
if (!provingState.verifyState()) {
|
|
267
|
+
throw new Error(`Invalid proving state when adding a tx`);
|
|
268
|
+
}
|
|
269
|
+
|
|
279
270
|
validateTx(tx);
|
|
280
271
|
|
|
281
272
|
logger.info(`Received transaction: ${tx.hash}`);
|
|
@@ -289,10 +280,7 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
289
280
|
this.enqueueFirstProofs(inputs, treeSnapshots, tx, provingState);
|
|
290
281
|
|
|
291
282
|
if (provingState.transactionsReceived === provingState.totalNumTxs) {
|
|
292
|
-
logger.verbose(
|
|
293
|
-
`All transactions received for block ${provingState.globalVariables.blockNumber}. Assembling header.`,
|
|
294
|
-
);
|
|
295
|
-
await this.buildBlockHeader(provingState);
|
|
283
|
+
logger.verbose(`All transactions received for block ${provingState.globalVariables.blockNumber}.`);
|
|
296
284
|
}
|
|
297
285
|
}
|
|
298
286
|
|
|
@@ -311,53 +299,125 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
311
299
|
[Attributes.BLOCK_TXS_COUNT]: block.transactionsReceived,
|
|
312
300
|
};
|
|
313
301
|
})
|
|
314
|
-
public async setBlockCompleted() {
|
|
302
|
+
public async setBlockCompleted(): Promise<L2Block> {
|
|
315
303
|
const provingState = this.provingState?.currentBlock;
|
|
316
304
|
if (!provingState) {
|
|
317
305
|
throw new Error(`Invalid proving state, call startNewBlock before adding transactions or completing the block`);
|
|
318
306
|
}
|
|
319
307
|
|
|
320
|
-
//
|
|
308
|
+
// We may need to pad the rollup with empty transactions
|
|
321
309
|
const paddingTxCount = provingState.totalNumTxs - provingState.transactionsReceived;
|
|
322
|
-
if (paddingTxCount
|
|
323
|
-
return;
|
|
324
|
-
} else if (provingState.totalNumTxs > 2) {
|
|
310
|
+
if (paddingTxCount > 0 && provingState.totalNumTxs > 2) {
|
|
325
311
|
throw new Error(`Block not ready for completion: expecting ${paddingTxCount} more transactions.`);
|
|
326
312
|
}
|
|
327
313
|
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
314
|
+
if (paddingTxCount > 0) {
|
|
315
|
+
logger.debug(`Padding rollup with ${paddingTxCount} empty transactions`);
|
|
316
|
+
// Make an empty padding transaction
|
|
317
|
+
// Required for:
|
|
318
|
+
// 0 (when we want an empty block, largely for testing), or
|
|
319
|
+
// 1 (we need to pad with one tx as all rollup circuits require a pair of inputs) txs
|
|
320
|
+
// Insert it into the tree the required number of times to get all of the
|
|
321
|
+
// base rollup inputs
|
|
322
|
+
// Then enqueue the proving of all the transactions
|
|
323
|
+
const unprovenPaddingTx = makeEmptyProcessedTx(
|
|
324
|
+
this.db.getInitialHeader(),
|
|
325
|
+
provingState.globalVariables.chainId,
|
|
326
|
+
provingState.globalVariables.version,
|
|
327
|
+
getVKTreeRoot(),
|
|
328
|
+
);
|
|
329
|
+
const txInputs: Array<{ inputs: BaseRollupInputs; snapshot: TreeSnapshots }> = [];
|
|
330
|
+
for (let i = 0; i < paddingTxCount; i++) {
|
|
331
|
+
const [inputs, snapshot] = await this.prepareTransaction(unprovenPaddingTx, provingState);
|
|
332
|
+
const txInput = {
|
|
333
|
+
inputs,
|
|
334
|
+
snapshot,
|
|
335
|
+
};
|
|
336
|
+
txInputs.push(txInput);
|
|
337
|
+
}
|
|
351
338
|
|
|
352
|
-
|
|
353
|
-
|
|
339
|
+
// Now enqueue the proving
|
|
340
|
+
this.enqueuePaddingTxs(provingState, txInputs, unprovenPaddingTx);
|
|
341
|
+
}
|
|
354
342
|
|
|
355
343
|
// And build the block header
|
|
356
|
-
logger.verbose(`Block ${provingState.globalVariables.blockNumber}
|
|
357
|
-
await this.
|
|
344
|
+
logger.verbose(`Block ${provingState.globalVariables.blockNumber} completed. Assembling header.`);
|
|
345
|
+
await this.buildBlock(provingState);
|
|
346
|
+
|
|
347
|
+
// If the proofs were faster than the block building, then we need to try the block root rollup again here
|
|
348
|
+
this.checkAndEnqueueBlockRootRollup(provingState);
|
|
349
|
+
return provingState.block!;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
/** Returns the block as built for a given index. */
|
|
353
|
+
public getBlock(index: number): L2Block {
|
|
354
|
+
const block = this.provingState?.blocks[index].block;
|
|
355
|
+
if (!block) {
|
|
356
|
+
throw new Error(`Block at index ${index} not available`);
|
|
357
|
+
}
|
|
358
|
+
return block;
|
|
358
359
|
}
|
|
359
360
|
|
|
360
|
-
|
|
361
|
+
@trackSpan('ProvingOrchestrator.padEpoch', function () {
|
|
362
|
+
if (!this.provingState) {
|
|
363
|
+
return {};
|
|
364
|
+
}
|
|
365
|
+
return {
|
|
366
|
+
[Attributes.EPOCH_NUMBER]: this.provingState.epochNumber,
|
|
367
|
+
[Attributes.EPOCH_SIZE]: this.provingState.totalNumBlocks,
|
|
368
|
+
};
|
|
369
|
+
})
|
|
370
|
+
private padEpoch() {
|
|
371
|
+
const provingState = this.provingState!;
|
|
372
|
+
const lastBlock = provingState.currentBlock?.block;
|
|
373
|
+
if (!lastBlock) {
|
|
374
|
+
throw new Error(`Epoch needs at least one completed block in order to be padded`);
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
const paddingBlockCount = Math.max(2, provingState.totalNumBlocks) - provingState.blocks.length;
|
|
378
|
+
if (paddingBlockCount === 0) {
|
|
379
|
+
return;
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
logger.debug(`Padding epoch proof with ${paddingBlockCount} empty block proofs`);
|
|
383
|
+
|
|
384
|
+
const inputs = EmptyBlockRootRollupInputs.from({
|
|
385
|
+
archive: lastBlock.archive,
|
|
386
|
+
blockHash: lastBlock.header.hash(),
|
|
387
|
+
globalVariables: lastBlock.header.globalVariables,
|
|
388
|
+
vkTreeRoot: getVKTreeRoot(),
|
|
389
|
+
proverId: this.proverId,
|
|
390
|
+
});
|
|
391
|
+
|
|
392
|
+
logger.debug(`Enqueuing deferred proving for padding block to enqueue ${paddingBlockCount} paddings`);
|
|
393
|
+
this.deferredProving(
|
|
394
|
+
provingState,
|
|
395
|
+
wrapCallbackInSpan(
|
|
396
|
+
this.tracer,
|
|
397
|
+
'ProvingOrchestrator.prover.getEmptyBlockRootRollupProof',
|
|
398
|
+
{
|
|
399
|
+
[Attributes.PROTOCOL_CIRCUIT_TYPE]: 'server',
|
|
400
|
+
[Attributes.PROTOCOL_CIRCUIT_NAME]: 'empty-block-root-rollup' satisfies CircuitName,
|
|
401
|
+
},
|
|
402
|
+
signal => this.prover.getEmptyBlockRootRollupProof(inputs, signal, provingState.epochNumber),
|
|
403
|
+
),
|
|
404
|
+
result => {
|
|
405
|
+
logger.debug(`Completed proof for padding block`);
|
|
406
|
+
const currentLevel = provingState.numMergeLevels + 1n;
|
|
407
|
+
for (let i = 0; i < paddingBlockCount; i++) {
|
|
408
|
+
logger.debug(`Enqueuing padding block with index ${provingState.blocks.length + i}`);
|
|
409
|
+
const index = BigInt(provingState.blocks.length + i);
|
|
410
|
+
this.storeAndExecuteNextBlockMergeLevel(provingState, currentLevel, index, [
|
|
411
|
+
result.inputs,
|
|
412
|
+
result.proof,
|
|
413
|
+
result.verificationKey.keyAsFields,
|
|
414
|
+
]);
|
|
415
|
+
}
|
|
416
|
+
},
|
|
417
|
+
);
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
private async buildBlock(provingState: BlockProvingState) {
|
|
361
421
|
// Collect all new nullifiers, commitments, and contracts from all txs in this block to build body
|
|
362
422
|
const gasFees = provingState.globalVariables.gasFees;
|
|
363
423
|
const nonEmptyTxEffects: TxEffect[] = provingState!.allTxs
|
|
@@ -379,7 +439,7 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
379
439
|
|
|
380
440
|
// Assemble the L2 block
|
|
381
441
|
const newArchive = await getTreeSnapshot(MerkleTreeId.ARCHIVE, this.db);
|
|
382
|
-
const l2Block = L2Block
|
|
442
|
+
const l2Block = new L2Block(newArchive, header, body);
|
|
383
443
|
|
|
384
444
|
if (!l2Block.body.getTxsEffectsHash().equals(header.contentCommitment.txsEffectsHash)) {
|
|
385
445
|
throw new Error(
|
|
@@ -499,52 +559,29 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
499
559
|
}
|
|
500
560
|
|
|
501
561
|
/**
|
|
502
|
-
* Returns the
|
|
503
|
-
* @param index - The index of the block to finalise. Defaults to the last block.
|
|
504
|
-
* @returns The fully proven block and proof.
|
|
562
|
+
* Returns the proof for the current epoch.
|
|
505
563
|
*/
|
|
506
|
-
public
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
if (!block || !block.blockRootRollupPublicInputs || !block.finalProof || !block.block) {
|
|
511
|
-
throw new Error(`Invalid proving state, a block must be proven before it can be finalised`);
|
|
512
|
-
}
|
|
564
|
+
public async finaliseEpoch() {
|
|
565
|
+
if (!this.provingState || !this.provingPromise) {
|
|
566
|
+
throw new Error(`Invalid proving state, an epoch must be proven before it can be finalised`);
|
|
567
|
+
}
|
|
513
568
|
|
|
514
|
-
|
|
515
|
-
proof: block.finalProof,
|
|
516
|
-
aggregationObject: block.finalProof.extractAggregationObject(),
|
|
517
|
-
block: block.block!,
|
|
518
|
-
};
|
|
519
|
-
|
|
520
|
-
pushTestData('blockResults', {
|
|
521
|
-
proverId: this.proverId.toString(),
|
|
522
|
-
vkTreeRoot: getVKTreeRoot().toString(),
|
|
523
|
-
block: blockResult.block.toString(),
|
|
524
|
-
proof: blockResult.proof.toString(),
|
|
525
|
-
aggregationObject: blockResult.aggregationObject.map(x => x.toString()),
|
|
526
|
-
});
|
|
569
|
+
this.padEpoch();
|
|
527
570
|
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
throw new
|
|
531
|
-
err && typeof err === 'object' && 'message' in err ? String(err.message) : String(err),
|
|
532
|
-
this.provingState?.blocks[index ?? this.provingState?.blocks.length - 1]?.allTxs.map(x =>
|
|
533
|
-
Tx.getHash(x.processedTx),
|
|
534
|
-
) ?? [],
|
|
535
|
-
);
|
|
571
|
+
const result = await this.provingPromise!;
|
|
572
|
+
if (result.status === 'failure') {
|
|
573
|
+
throw new Error(`Epoch proving failed: ${result.reason}`);
|
|
536
574
|
}
|
|
537
|
-
}
|
|
538
575
|
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
* Requires proving to have been completed.
|
|
542
|
-
*/
|
|
543
|
-
public finaliseEpoch() {
|
|
544
|
-
if (!this.provingState || !this.provingState.rootRollupPublicInputs || !this.provingState.finalProof) {
|
|
545
|
-
throw new Error(`Invalid proving state, an epoch must be proven before it can be finalised`);
|
|
576
|
+
if (!this.provingState.rootRollupPublicInputs || !this.provingState.finalProof) {
|
|
577
|
+
throw new Error(`Invalid proving state, missing root rollup public inputs or final proof`);
|
|
546
578
|
}
|
|
547
579
|
|
|
580
|
+
pushTestData('epochProofResult', {
|
|
581
|
+
proof: this.provingState.finalProof.toString(),
|
|
582
|
+
publicInputs: this.provingState.rootRollupPublicInputs.toString(),
|
|
583
|
+
});
|
|
584
|
+
|
|
548
585
|
return { proof: this.provingState.finalProof, publicInputs: this.provingState.rootRollupPublicInputs };
|
|
549
586
|
}
|
|
550
587
|
|
|
@@ -836,11 +873,17 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
836
873
|
}
|
|
837
874
|
|
|
838
875
|
// Executes the block root rollup circuit
|
|
839
|
-
private enqueueBlockRootRollup(provingState: BlockProvingState
|
|
840
|
-
if (!provingState
|
|
876
|
+
private enqueueBlockRootRollup(provingState: BlockProvingState) {
|
|
877
|
+
if (!provingState.block) {
|
|
878
|
+
throw new Error(`Invalid proving state for block root rollup, block not available`);
|
|
879
|
+
}
|
|
880
|
+
|
|
881
|
+
if (!provingState.verifyState()) {
|
|
841
882
|
logger.debug('Not running block root rollup, state no longer valid');
|
|
842
883
|
return;
|
|
843
884
|
}
|
|
885
|
+
|
|
886
|
+
provingState.blockRootRollupStarted = true;
|
|
844
887
|
const mergeInputData = provingState.getMergeInputs(0);
|
|
845
888
|
const rootParityInput = provingState.finalRootParityInput!;
|
|
846
889
|
|
|
@@ -868,8 +911,6 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
868
911
|
proverId: this.proverId,
|
|
869
912
|
});
|
|
870
913
|
|
|
871
|
-
const shouldProveEpoch = this.provingState!.totalNumBlocks > 1;
|
|
872
|
-
|
|
873
914
|
this.deferredProving(
|
|
874
915
|
provingState,
|
|
875
916
|
wrapCallbackInSpan(
|
|
@@ -879,10 +920,7 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
879
920
|
[Attributes.PROTOCOL_CIRCUIT_TYPE]: 'server',
|
|
880
921
|
[Attributes.PROTOCOL_CIRCUIT_NAME]: 'block-root-rollup' satisfies CircuitName,
|
|
881
922
|
},
|
|
882
|
-
signal =>
|
|
883
|
-
shouldProveEpoch
|
|
884
|
-
? this.prover.getBlockRootRollupProof(inputs, signal, provingState.epochNumber)
|
|
885
|
-
: this.prover.getBlockRootRollupFinalProof(inputs, signal, provingState.epochNumber),
|
|
923
|
+
signal => this.prover.getBlockRootRollupProof(inputs, signal, provingState.epochNumber),
|
|
886
924
|
),
|
|
887
925
|
result => {
|
|
888
926
|
const header = this.extractBlockHeaderFromPublicInputs(provingState, result.inputs);
|
|
@@ -895,17 +933,10 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
895
933
|
|
|
896
934
|
provingState.blockRootRollupPublicInputs = result.inputs;
|
|
897
935
|
provingState.finalProof = result.proof.binaryProof;
|
|
898
|
-
provingState.resolve({ status: PROVING_STATUS.SUCCESS });
|
|
899
936
|
|
|
900
937
|
logger.debug(`Completed proof for block root rollup for ${provingState.block?.number}`);
|
|
901
938
|
// validatePartialState(result.inputs.end, tx.treeSnapshots); // TODO(palla/prover)
|
|
902
939
|
|
|
903
|
-
// TODO(palla/prover): Remove this once we've dropped the flow for proving single blocks
|
|
904
|
-
if (!shouldProveEpoch) {
|
|
905
|
-
logger.verbose(`Skipping epoch rollup, only one block in epoch`);
|
|
906
|
-
return;
|
|
907
|
-
}
|
|
908
|
-
|
|
909
940
|
const currentLevel = this.provingState!.numMergeLevels + 1n;
|
|
910
941
|
this.storeAndExecuteNextBlockMergeLevel(this.provingState!, currentLevel, BigInt(provingState.index), [
|
|
911
942
|
result.inputs,
|
|
@@ -1032,18 +1063,23 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
1032
1063
|
signal => this.prover.getRootRollupProof(inputs, signal, provingState.epochNumber),
|
|
1033
1064
|
),
|
|
1034
1065
|
result => {
|
|
1066
|
+
logger.verbose(`Orchestrator completed root rollup for epoch ${provingState.epochNumber}`);
|
|
1035
1067
|
provingState.rootRollupPublicInputs = result.inputs;
|
|
1036
1068
|
provingState.finalProof = result.proof.binaryProof;
|
|
1037
|
-
provingState.resolve({ status:
|
|
1069
|
+
provingState.resolve({ status: 'success' });
|
|
1038
1070
|
},
|
|
1039
1071
|
);
|
|
1040
1072
|
}
|
|
1041
1073
|
|
|
1042
|
-
private checkAndEnqueueBlockRootRollup(provingState: BlockProvingState
|
|
1074
|
+
private checkAndEnqueueBlockRootRollup(provingState: BlockProvingState) {
|
|
1043
1075
|
if (!provingState?.isReadyForBlockRootRollup()) {
|
|
1044
1076
|
logger.debug('Not ready for root rollup');
|
|
1045
1077
|
return;
|
|
1046
1078
|
}
|
|
1079
|
+
if (provingState.blockRootRollupStarted) {
|
|
1080
|
+
logger.debug('Block root rollup already started');
|
|
1081
|
+
return;
|
|
1082
|
+
}
|
|
1047
1083
|
this.enqueueBlockRootRollup(provingState);
|
|
1048
1084
|
}
|
|
1049
1085
|
|
|
@@ -16,6 +16,7 @@ import type {
|
|
|
16
16
|
BlockMergeRollupInputs,
|
|
17
17
|
BlockRootOrBlockMergePublicInputs,
|
|
18
18
|
BlockRootRollupInputs,
|
|
19
|
+
EmptyBlockRootRollupInputs,
|
|
19
20
|
KernelCircuitPublicInputs,
|
|
20
21
|
MergeRollupInputs,
|
|
21
22
|
NESTED_RECURSIVE_PROOF_LENGTH,
|
|
@@ -351,12 +352,12 @@ export class MemoryProvingQueue implements ServerCircuitProver, ProvingJobSource
|
|
|
351
352
|
return this.enqueue({ type: ProvingRequestType.BLOCK_ROOT_ROLLUP, inputs: input }, signal, epochNumber);
|
|
352
353
|
}
|
|
353
354
|
|
|
354
|
-
|
|
355
|
-
input:
|
|
355
|
+
getEmptyBlockRootRollupProof(
|
|
356
|
+
input: EmptyBlockRootRollupInputs,
|
|
356
357
|
signal?: AbortSignal,
|
|
357
358
|
epochNumber?: number,
|
|
358
359
|
): Promise<PublicInputsAndRecursiveProof<BlockRootOrBlockMergePublicInputs>> {
|
|
359
|
-
return this.enqueue({ type: ProvingRequestType.
|
|
360
|
+
return this.enqueue({ type: ProvingRequestType.EMPTY_BLOCK_ROOT_ROLLUP, inputs: input }, signal, epochNumber);
|
|
360
361
|
}
|
|
361
362
|
|
|
362
363
|
/**
|
|
@@ -181,12 +181,12 @@ export class ProverAgent {
|
|
|
181
181
|
return this.circuitProver.getMergeRollupProof(inputs);
|
|
182
182
|
}
|
|
183
183
|
|
|
184
|
-
case ProvingRequestType.
|
|
185
|
-
return this.circuitProver.
|
|
184
|
+
case ProvingRequestType.EMPTY_BLOCK_ROOT_ROLLUP: {
|
|
185
|
+
return this.circuitProver.getEmptyBlockRootRollupProof(inputs);
|
|
186
186
|
}
|
|
187
187
|
|
|
188
|
-
case ProvingRequestType.
|
|
189
|
-
return this.circuitProver.
|
|
188
|
+
case ProvingRequestType.BLOCK_ROOT_ROLLUP: {
|
|
189
|
+
return this.circuitProver.getBlockRootRollupProof(inputs);
|
|
190
190
|
}
|
|
191
191
|
|
|
192
192
|
case ProvingRequestType.BLOCK_MERGE_ROLLUP: {
|
package/src/prover-agent/rpc.ts
CHANGED
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
BlockMergeRollupInputs,
|
|
10
10
|
BlockRootOrBlockMergePublicInputs,
|
|
11
11
|
BlockRootRollupInputs,
|
|
12
|
+
EmptyBlockRootRollupInputs,
|
|
12
13
|
EthAddress,
|
|
13
14
|
Fr,
|
|
14
15
|
Header,
|
|
@@ -68,6 +69,7 @@ export function createProvingJobSourceServer(queue: ProvingJobSource): JsonRpcSe
|
|
|
68
69
|
BlockRootOrBlockMergePublicInputs,
|
|
69
70
|
BlockMergeRollupInputs,
|
|
70
71
|
BlockRootRollupInputs,
|
|
72
|
+
EmptyBlockRootRollupInputs,
|
|
71
73
|
},
|
|
72
74
|
{},
|
|
73
75
|
);
|
|
@@ -109,6 +111,7 @@ export function createProvingJobSourceClient(
|
|
|
109
111
|
BlockRootOrBlockMergePublicInputs,
|
|
110
112
|
BlockMergeRollupInputs,
|
|
111
113
|
BlockRootRollupInputs,
|
|
114
|
+
EmptyBlockRootRollupInputs,
|
|
112
115
|
},
|
|
113
116
|
{},
|
|
114
117
|
false,
|
package/src/test/mock_prover.ts
CHANGED
|
@@ -78,7 +78,7 @@ export class MockProver implements ServerCircuitProver {
|
|
|
78
78
|
);
|
|
79
79
|
}
|
|
80
80
|
|
|
81
|
-
|
|
81
|
+
getEmptyBlockRootRollupProof(): Promise<PublicInputsAndRecursiveProof<BlockRootOrBlockMergePublicInputs>> {
|
|
82
82
|
return Promise.resolve(
|
|
83
83
|
makePublicInputsAndRecursiveProof(
|
|
84
84
|
makeBlockRootOrBlockMergeRollupPublicInputs(),
|
|
@@ -88,7 +88,7 @@ export class MockProver implements ServerCircuitProver {
|
|
|
88
88
|
);
|
|
89
89
|
}
|
|
90
90
|
|
|
91
|
-
|
|
91
|
+
getBlockRootRollupProof(): Promise<PublicInputsAndRecursiveProof<BlockRootOrBlockMergePublicInputs>> {
|
|
92
92
|
return Promise.resolve(
|
|
93
93
|
makePublicInputsAndRecursiveProof(
|
|
94
94
|
makeBlockRootOrBlockMergeRollupPublicInputs(),
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { BBNativeRollupProver, TestCircuitProver } from '@aztec/bb-prover';
|
|
2
2
|
import {
|
|
3
|
-
type
|
|
4
|
-
type
|
|
3
|
+
type EpochProver,
|
|
4
|
+
type EpochProverManager,
|
|
5
5
|
type ProvingJobSource,
|
|
6
6
|
type ServerCircuitProver,
|
|
7
7
|
} from '@aztec/circuit-types/interfaces';
|
|
@@ -19,7 +19,7 @@ import { ProverAgent } from '../prover-agent/prover-agent.js';
|
|
|
19
19
|
* A prover factory.
|
|
20
20
|
* TODO(palla/prover-node): Rename this class
|
|
21
21
|
*/
|
|
22
|
-
export class TxProver implements
|
|
22
|
+
export class TxProver implements EpochProverManager {
|
|
23
23
|
private queue: MemoryProvingQueue;
|
|
24
24
|
private running = false;
|
|
25
25
|
|
|
@@ -33,7 +33,7 @@ export class TxProver implements ProverClient {
|
|
|
33
33
|
this.queue = new MemoryProvingQueue(telemetry, config.proverJobTimeoutMs, config.proverJobPollIntervalMs);
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
public
|
|
36
|
+
public createEpochProver(db: MerkleTreeOperations): EpochProver {
|
|
37
37
|
return new ProvingOrchestrator(db, this.queue, this.telemetry, this.config.proverId);
|
|
38
38
|
}
|
|
39
39
|
|