@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.
Files changed (37) hide show
  1. package/dest/index.d.ts +1 -1
  2. package/dest/index.d.ts.map +1 -1
  3. package/dest/mocks/test_context.d.ts +5 -5
  4. package/dest/mocks/test_context.d.ts.map +1 -1
  5. package/dest/mocks/test_context.js +8 -8
  6. package/dest/orchestrator/block-proving-state.d.ts +6 -7
  7. package/dest/orchestrator/block-proving-state.d.ts.map +1 -1
  8. package/dest/orchestrator/block-proving-state.js +10 -33
  9. package/dest/orchestrator/epoch-proving-state.d.ts +8 -2
  10. package/dest/orchestrator/epoch-proving-state.d.ts.map +1 -1
  11. package/dest/orchestrator/epoch-proving-state.js +8 -16
  12. package/dest/orchestrator/orchestrator.d.ts +12 -15
  13. package/dest/orchestrator/orchestrator.d.ts.map +1 -1
  14. package/dest/orchestrator/orchestrator.js +134 -98
  15. package/dest/prover-agent/memory-proving-queue.d.ts +2 -2
  16. package/dest/prover-agent/memory-proving-queue.d.ts.map +1 -1
  17. package/dest/prover-agent/memory-proving-queue.js +3 -3
  18. package/dest/prover-agent/prover-agent.js +4 -4
  19. package/dest/prover-agent/rpc.d.ts.map +1 -1
  20. package/dest/prover-agent/rpc.js +4 -2
  21. package/dest/test/mock_prover.d.ts +3 -3
  22. package/dest/test/mock_prover.d.ts.map +1 -1
  23. package/dest/test/mock_prover.js +3 -3
  24. package/dest/tx-prover/tx-prover.d.ts +3 -3
  25. package/dest/tx-prover/tx-prover.d.ts.map +1 -1
  26. package/dest/tx-prover/tx-prover.js +1 -1
  27. package/package.json +13 -10
  28. package/src/index.ts +1 -1
  29. package/src/mocks/test_context.ts +8 -8
  30. package/src/orchestrator/block-proving-state.ts +9 -35
  31. package/src/orchestrator/epoch-proving-state.ts +9 -20
  32. package/src/orchestrator/orchestrator.ts +167 -131
  33. package/src/prover-agent/memory-proving-queue.ts +4 -3
  34. package/src/prover-agent/prover-agent.ts +4 -4
  35. package/src/prover-agent/rpc.ts +3 -0
  36. package/src/test/mock_prover.ts +2 -2
  37. 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 { type BlockMergeRollupInputData, EpochProvingState, type TreeSnapshots } from './epoch-proving-state.js';
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
- @trackSpan('ProvingOrchestrator.startNewEpoch', (epochNumber, totalNumBlocks) => ({
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
- (reason): ProvingResult => ({
145
- status: PROVING_STATUS.FAILURE,
146
- reason,
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
- return { provingPromise: promise };
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. Must be a power of 2
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
- this.startNewEpoch(globalVariables.blockNumber.toNumber(), 1);
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(`Length of txs for the block should be at least two (got ${numTxs})`);
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-node): Store block number in the db itself to make this check more reliable,
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
- // we may need to pad the rollup with empty transactions
308
+ // We may need to pad the rollup with empty transactions
321
309
  const paddingTxCount = provingState.totalNumTxs - provingState.transactionsReceived;
322
- if (paddingTxCount === 0) {
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
- logger.debug(`Padding rollup with ${paddingTxCount} empty transactions`);
329
- // Make an empty padding transaction
330
- // Required for:
331
- // 0 (when we want an empty block, largely for testing), or
332
- // 1 (we need to pad with one tx as all rollup circuits require a pair of inputs) txs
333
- // Insert it into the tree the required number of times to get all of the
334
- // base rollup inputs
335
- // Then enqueue the proving of all the transactions
336
- const unprovenPaddingTx = makeEmptyProcessedTx(
337
- this.db.getInitialHeader(),
338
- provingState.globalVariables.chainId,
339
- provingState.globalVariables.version,
340
- getVKTreeRoot(),
341
- );
342
- const txInputs: Array<{ inputs: BaseRollupInputs; snapshot: TreeSnapshots }> = [];
343
- for (let i = 0; i < paddingTxCount; i++) {
344
- const [inputs, snapshot] = await this.prepareTransaction(unprovenPaddingTx, provingState);
345
- const txInput = {
346
- inputs,
347
- snapshot,
348
- };
349
- txInputs.push(txInput);
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
- // Now enqueue the proving
353
- this.enqueuePaddingTxs(provingState, txInputs, unprovenPaddingTx);
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} padded with empty tx(s). Assembling header.`);
357
- await this.buildBlockHeader(provingState);
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
- private async buildBlockHeader(provingState: BlockProvingState) {
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.fromFields({ archive: newArchive, header, body });
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 fully proven block. Requires proving to have been completed.
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 finaliseBlock(index?: number) {
507
- try {
508
- const block = this.provingState?.blocks[index ?? this.provingState?.blocks.length - 1];
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
- const blockResult: ProvingBlockResult = {
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
- return Promise.resolve(blockResult);
529
- } catch (err) {
530
- throw new BlockProofError(
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
- * Returns the proof for the current epoch.
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 | undefined) {
840
- if (!provingState?.verifyState()) {
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: PROVING_STATUS.SUCCESS });
1069
+ provingState.resolve({ status: 'success' });
1038
1070
  },
1039
1071
  );
1040
1072
  }
1041
1073
 
1042
- private checkAndEnqueueBlockRootRollup(provingState: BlockProvingState | undefined) {
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
- getBlockRootRollupFinalProof(
355
- input: BlockRootRollupInputs,
355
+ getEmptyBlockRootRollupProof(
356
+ input: EmptyBlockRootRollupInputs,
356
357
  signal?: AbortSignal,
357
358
  epochNumber?: number,
358
359
  ): Promise<PublicInputsAndRecursiveProof<BlockRootOrBlockMergePublicInputs>> {
359
- return this.enqueue({ type: ProvingRequestType.BLOCK_ROOT_ROLLUP_FINAL, inputs: input }, signal, epochNumber);
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.BLOCK_ROOT_ROLLUP: {
185
- return this.circuitProver.getBlockRootRollupProof(inputs);
184
+ case ProvingRequestType.EMPTY_BLOCK_ROOT_ROLLUP: {
185
+ return this.circuitProver.getEmptyBlockRootRollupProof(inputs);
186
186
  }
187
187
 
188
- case ProvingRequestType.BLOCK_ROOT_ROLLUP_FINAL: {
189
- return this.circuitProver.getBlockRootRollupFinalProof(inputs);
188
+ case ProvingRequestType.BLOCK_ROOT_ROLLUP: {
189
+ return this.circuitProver.getBlockRootRollupProof(inputs);
190
190
  }
191
191
 
192
192
  case ProvingRequestType.BLOCK_MERGE_ROLLUP: {
@@ -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,
@@ -78,7 +78,7 @@ export class MockProver implements ServerCircuitProver {
78
78
  );
79
79
  }
80
80
 
81
- getBlockRootRollupProof(): Promise<PublicInputsAndRecursiveProof<BlockRootOrBlockMergePublicInputs>> {
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
- getBlockRootRollupFinalProof(): Promise<PublicInputsAndRecursiveProof<BlockRootOrBlockMergePublicInputs>> {
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 BlockProver,
4
- type ProverClient,
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 ProverClient {
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 createBlockProver(db: MerkleTreeOperations): BlockProver {
36
+ public createEpochProver(db: MerkleTreeOperations): EpochProver {
37
37
  return new ProvingOrchestrator(db, this.queue, this.telemetry, this.config.proverId);
38
38
  }
39
39