@aztec/prover-client 0.0.1-commit.2ed92850 → 0.0.1-commit.343b43af6

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 (80) hide show
  1. package/dest/light/lightweight_checkpoint_builder.d.ts +13 -5
  2. package/dest/light/lightweight_checkpoint_builder.d.ts.map +1 -1
  3. package/dest/light/lightweight_checkpoint_builder.js +45 -20
  4. package/dest/mocks/fixtures.d.ts +1 -1
  5. package/dest/mocks/fixtures.d.ts.map +1 -1
  6. package/dest/mocks/fixtures.js +2 -1
  7. package/dest/mocks/test_context.js +6 -3
  8. package/dest/orchestrator/block-building-helpers.d.ts +4 -4
  9. package/dest/orchestrator/block-building-helpers.d.ts.map +1 -1
  10. package/dest/orchestrator/block-building-helpers.js +4 -4
  11. package/dest/orchestrator/block-proving-state.d.ts +4 -1
  12. package/dest/orchestrator/block-proving-state.d.ts.map +1 -1
  13. package/dest/orchestrator/block-proving-state.js +7 -0
  14. package/dest/orchestrator/checkpoint-proving-state.d.ts +3 -3
  15. package/dest/orchestrator/checkpoint-proving-state.d.ts.map +1 -1
  16. package/dest/orchestrator/checkpoint-proving-state.js +3 -3
  17. package/dest/orchestrator/epoch-proving-state.d.ts +3 -3
  18. package/dest/orchestrator/epoch-proving-state.d.ts.map +1 -1
  19. package/dest/orchestrator/epoch-proving-state.js +5 -3
  20. package/dest/orchestrator/orchestrator.d.ts +7 -3
  21. package/dest/orchestrator/orchestrator.d.ts.map +1 -1
  22. package/dest/orchestrator/orchestrator.js +122 -117
  23. package/dest/prover-client/prover-client.d.ts +4 -4
  24. package/dest/prover-client/prover-client.d.ts.map +1 -1
  25. package/dest/prover-client/prover-client.js +15 -10
  26. package/dest/proving_broker/broker_prover_facade.d.ts +4 -3
  27. package/dest/proving_broker/broker_prover_facade.d.ts.map +1 -1
  28. package/dest/proving_broker/broker_prover_facade.js +6 -6
  29. package/dest/proving_broker/config.d.ts +10 -2
  30. package/dest/proving_broker/config.d.ts.map +1 -1
  31. package/dest/proving_broker/config.js +14 -3
  32. package/dest/proving_broker/proof_store/factory.d.ts +2 -5
  33. package/dest/proving_broker/proof_store/factory.d.ts.map +1 -1
  34. package/dest/proving_broker/proof_store/factory.js +7 -30
  35. package/dest/proving_broker/proof_store/file_store_proof_store.d.ts +18 -0
  36. package/dest/proving_broker/proof_store/file_store_proof_store.d.ts.map +1 -0
  37. package/dest/proving_broker/proof_store/file_store_proof_store.js +60 -0
  38. package/dest/proving_broker/proof_store/index.d.ts +2 -2
  39. package/dest/proving_broker/proof_store/index.d.ts.map +1 -1
  40. package/dest/proving_broker/proof_store/index.js +1 -1
  41. package/dest/proving_broker/proving_agent.d.ts +4 -3
  42. package/dest/proving_broker/proving_agent.d.ts.map +1 -1
  43. package/dest/proving_broker/proving_agent.js +4 -4
  44. package/dest/proving_broker/proving_broker.d.ts +7 -4
  45. package/dest/proving_broker/proving_broker.d.ts.map +1 -1
  46. package/dest/proving_broker/proving_broker.js +36 -4
  47. package/dest/proving_broker/proving_broker_instrumentation.d.ts +3 -1
  48. package/dest/proving_broker/proving_broker_instrumentation.d.ts.map +1 -1
  49. package/dest/proving_broker/proving_broker_instrumentation.js +18 -7
  50. package/dest/proving_broker/proving_job_controller.d.ts +4 -3
  51. package/dest/proving_broker/proving_job_controller.d.ts.map +1 -1
  52. package/dest/proving_broker/proving_job_controller.js +6 -3
  53. package/dest/proving_broker/rpc.d.ts +4 -2
  54. package/dest/proving_broker/rpc.d.ts.map +1 -1
  55. package/dest/proving_broker/rpc.js +8 -0
  56. package/dest/test/mock_prover.d.ts +4 -4
  57. package/package.json +17 -18
  58. package/src/light/lightweight_checkpoint_builder.ts +52 -21
  59. package/src/mocks/fixtures.ts +2 -1
  60. package/src/mocks/test_context.ts +3 -3
  61. package/src/orchestrator/block-building-helpers.ts +4 -4
  62. package/src/orchestrator/block-proving-state.ts +9 -0
  63. package/src/orchestrator/checkpoint-proving-state.ts +4 -4
  64. package/src/orchestrator/epoch-proving-state.ts +6 -4
  65. package/src/orchestrator/orchestrator.ts +132 -125
  66. package/src/prover-client/prover-client.ts +24 -14
  67. package/src/proving_broker/broker_prover_facade.ts +15 -7
  68. package/src/proving_broker/config.ts +14 -1
  69. package/src/proving_broker/proof_store/factory.ts +10 -32
  70. package/src/proving_broker/proof_store/file_store_proof_store.ts +78 -0
  71. package/src/proving_broker/proof_store/index.ts +1 -1
  72. package/src/proving_broker/proving_agent.ts +5 -2
  73. package/src/proving_broker/proving_broker.ts +37 -3
  74. package/src/proving_broker/proving_broker_instrumentation.ts +19 -6
  75. package/src/proving_broker/proving_job_controller.ts +9 -3
  76. package/src/proving_broker/rpc.ts +14 -0
  77. package/dest/proving_broker/proof_store/gcs_proof_store.d.ts +0 -14
  78. package/dest/proving_broker/proof_store/gcs_proof_store.d.ts.map +0 -1
  79. package/dest/proving_broker/proof_store/gcs_proof_store.js +0 -52
  80. package/src/proving_broker/proof_store/gcs_proof_store.ts +0 -76
@@ -10,8 +10,9 @@ import { BlockNumber, EpochNumber } from '@aztec/foundation/branded-types';
10
10
  import { padArrayEnd } from '@aztec/foundation/collection';
11
11
  import { Fr } from '@aztec/foundation/curves/bn254';
12
12
  import { AbortError } from '@aztec/foundation/error';
13
- import { createLogger } from '@aztec/foundation/log';
13
+ import { type Logger, type LoggerBindings, createLogger } from '@aztec/foundation/log';
14
14
  import { promiseWithResolvers } from '@aztec/foundation/promise';
15
+ import { SerialQueue } from '@aztec/foundation/queue';
15
16
  import { assertLength } from '@aztec/foundation/serialize';
16
17
  import { pushTestData } from '@aztec/foundation/testing';
17
18
  import { elapsed } from '@aztec/foundation/timer';
@@ -71,13 +72,6 @@ import { EpochProvingState, type ProvingResult, type TreeSnapshots } from './epo
71
72
  import { ProvingOrchestratorMetrics } from './orchestrator_metrics.js';
72
73
  import { TxProvingState } from './tx-proving-state.js';
73
74
 
74
- const logger = createLogger('prover-client:orchestrator');
75
-
76
- type WorldStateFork = {
77
- fork: MerkleTreeWriteOperations;
78
- cleanupPromise: Promise<void> | undefined;
79
- };
80
-
81
75
  /**
82
76
  * Implements an event driven proving scheduler to build the recursive proof tree. The idea being:
83
77
  * 1. Transactions are provided to the scheduler post simulation.
@@ -99,16 +93,22 @@ export class ProvingOrchestrator implements EpochProver {
99
93
  private provingPromise: Promise<ProvingResult> | undefined = undefined;
100
94
  private metrics: ProvingOrchestratorMetrics;
101
95
  // eslint-disable-next-line aztec-custom/no-non-primitive-in-collections
102
- private dbs: Map<BlockNumber, WorldStateFork> = new Map();
96
+ private dbs: Map<BlockNumber, MerkleTreeWriteOperations> = new Map();
97
+ private logger: Logger;
98
+ private deferredJobQueue = new SerialQueue();
103
99
 
104
100
  constructor(
105
101
  private dbProvider: ReadonlyWorldStateAccess & ForkMerkleTreeOperations,
106
102
  private prover: ServerCircuitProver,
107
103
  private readonly proverId: EthAddress,
108
104
  private readonly cancelJobsOnStop: boolean = false,
105
+ private readonly enqueueConcurrency: number,
109
106
  telemetryClient: TelemetryClient = getTelemetryClient(),
107
+ bindings?: LoggerBindings,
110
108
  ) {
109
+ this.logger = createLogger('prover-client:orchestrator', bindings);
111
110
  this.metrics = new ProvingOrchestratorMetrics(telemetryClient, 'ProvingOrchestrator');
111
+ this.deferredJobQueue.start(this.enqueueConcurrency);
112
112
  }
113
113
 
114
114
  get tracer(): Tracer {
@@ -123,9 +123,11 @@ export class ProvingOrchestrator implements EpochProver {
123
123
  return this.dbs.size;
124
124
  }
125
125
 
126
- public stop(): Promise<void> {
126
+ public async stop(): Promise<void> {
127
+ // Grab the old queue before cancel() replaces it, so we can await its draining.
128
+ const oldQueue = this.deferredJobQueue;
127
129
  this.cancel();
128
- return Promise.resolve();
130
+ await oldQueue.cancel();
129
131
  }
130
132
 
131
133
  public startNewEpoch(
@@ -141,7 +143,7 @@ export class ProvingOrchestrator implements EpochProver {
141
143
 
142
144
  const { promise: _promise, resolve, reject } = promiseWithResolvers<ProvingResult>();
143
145
  const promise = _promise.catch((reason): ProvingResult => ({ status: 'failure', reason }));
144
- logger.info(`Starting epoch ${epochNumber} with ${totalNumCheckpoints} checkpoints.`);
146
+ this.logger.info(`Starting epoch ${epochNumber} with ${totalNumCheckpoints} checkpoints.`);
145
147
  this.provingState = new EpochProvingState(
146
148
  epochNumber,
147
149
  totalNumCheckpoints,
@@ -181,7 +183,7 @@ export class ProvingOrchestrator implements EpochProver {
181
183
  const db = await this.dbProvider.fork(lastBlockNumber);
182
184
 
183
185
  const firstBlockNumber = BlockNumber(lastBlockNumber + 1);
184
- this.dbs.set(firstBlockNumber, { fork: db, cleanupPromise: undefined });
186
+ this.dbs.set(firstBlockNumber, db);
185
187
 
186
188
  // Get archive sibling path before any block in this checkpoint lands.
187
189
  const lastArchiveSiblingPath = await getLastSiblingPath(MerkleTreeId.ARCHIVE, db);
@@ -233,15 +235,15 @@ export class ProvingOrchestrator implements EpochProver {
233
235
  }
234
236
 
235
237
  const constants = checkpointProvingState.constants;
236
- logger.info(`Starting block ${blockNumber} for slot ${constants.slotNumber}.`);
238
+ this.logger.info(`Starting block ${blockNumber} for slot ${constants.slotNumber}.`);
237
239
 
238
240
  // Fork the db only when it's not already set. The db for the first block is set in `startNewCheckpoint`.
239
241
  if (!this.dbs.has(blockNumber)) {
240
242
  // Fork world state at the end of the immediately previous block
241
243
  const db = await this.dbProvider.fork(BlockNumber(blockNumber - 1));
242
- this.dbs.set(blockNumber, { fork: db, cleanupPromise: undefined });
244
+ this.dbs.set(blockNumber, db);
243
245
  }
244
- const db = this.dbs.get(blockNumber)!.fork;
246
+ const db = this.getDbForBlock(blockNumber);
245
247
 
246
248
  // Get archive snapshot and sibling path before any txs in this block lands.
247
249
  const lastArchiveTreeSnapshot = await getTreeSnapshot(MerkleTreeId.ARCHIVE, db);
@@ -294,7 +296,7 @@ export class ProvingOrchestrator implements EpochProver {
294
296
  if (!txs.length) {
295
297
  // To avoid an ugly throw below. If we require an empty block, we can just call setBlockCompleted
296
298
  // on a block with no txs. We cannot do that here because we cannot find the blockNumber without any txs.
297
- logger.warn(`Provided no txs to orchestrator addTxs.`);
299
+ this.logger.warn(`Provided no txs to orchestrator addTxs.`);
298
300
  return;
299
301
  }
300
302
 
@@ -314,9 +316,9 @@ export class ProvingOrchestrator implements EpochProver {
314
316
  throw new Error(`Block ${blockNumber} has been initialized with transactions.`);
315
317
  }
316
318
 
317
- logger.info(`Adding ${txs.length} transactions to block ${blockNumber}`);
319
+ this.logger.info(`Adding ${txs.length} transactions to block ${blockNumber}`);
318
320
 
319
- const db = this.dbs.get(blockNumber)!.fork;
321
+ const db = this.getDbForBlock(blockNumber);
320
322
  const lastArchive = provingState.lastArchiveTreeSnapshot;
321
323
  const newL1ToL2MessageTreeSnapshot = provingState.newL1ToL2MessageTreeSnapshot;
322
324
  const spongeBlobState = provingState.getStartSpongeBlob().clone();
@@ -329,7 +331,7 @@ export class ProvingOrchestrator implements EpochProver {
329
331
 
330
332
  validateTx(tx);
331
333
 
332
- logger.debug(`Received transaction: ${tx.hash}`);
334
+ this.logger.debug(`Received transaction: ${tx.hash}`);
333
335
 
334
336
  const startSpongeBlob = spongeBlobState.clone();
335
337
  const [hints, treeSnapshots] = await this.prepareBaseRollupInputs(
@@ -350,10 +352,10 @@ export class ProvingOrchestrator implements EpochProver {
350
352
  const txIndex = provingState.addNewTx(txProvingState);
351
353
  if (txProvingState.requireAvmProof) {
352
354
  this.getOrEnqueueChonkVerifier(provingState, txIndex);
353
- logger.debug(`Enqueueing public VM for tx ${txIndex}`);
355
+ this.logger.debug(`Enqueueing public VM for tx ${txIndex}`);
354
356
  this.enqueueVM(provingState, txIndex);
355
357
  } else {
356
- logger.debug(`Enqueueing base rollup for private-only tx ${txIndex}`);
358
+ this.logger.debug(`Enqueueing base rollup for private-only tx ${txIndex}`);
357
359
  this.enqueueBaseRollup(provingState, txIndex);
358
360
  }
359
361
  } catch (err: any) {
@@ -396,7 +398,7 @@ export class ProvingOrchestrator implements EpochProver {
396
398
  typeof NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH
397
399
  >
398
400
  >();
399
- logger.debug(`Starting chonk verifier circuit for tx ${txHash}`);
401
+ this.logger.debug(`Starting chonk verifier circuit for tx ${txHash}`);
400
402
  this.doEnqueueChonkVerifier(txHash, privateInputs, proof => {
401
403
  tubeProof.resolve(proof);
402
404
  });
@@ -436,22 +438,28 @@ export class ProvingOrchestrator implements EpochProver {
436
438
  }
437
439
 
438
440
  // Given we've applied every change from this block, now assemble the block header:
439
- logger.verbose(`Block ${blockNumber} completed. Assembling header.`);
441
+ this.logger.verbose(`Block ${blockNumber} completed. Assembling header.`);
440
442
  const header = await provingState.buildBlockHeader();
441
443
 
442
444
  if (expectedHeader && !header.equals(expectedHeader)) {
443
- logger.error(`Block header mismatch: header=${header} expectedHeader=${expectedHeader}`);
445
+ this.logger.error(`Block header mismatch: header=${header} expectedHeader=${expectedHeader}`);
444
446
  throw new Error('Block header mismatch');
445
447
  }
446
448
 
447
- // Get db for this block
448
- const db = this.dbs.get(provingState.blockNumber)!.fork;
449
+ // Get db for this block and remove from map — no other code should use it after this point.
450
+ const db = this.getDbForBlock(provingState.blockNumber);
451
+ this.dbs.delete(provingState.blockNumber);
449
452
 
450
- // Update the archive tree, so we're ready to start processing the next block:
451
- logger.verbose(
452
- `Updating archive tree with block ${provingState.blockNumber} header ${(await header.hash()).toString()}`,
453
- );
454
- await db.updateArchive(header);
453
+ // Update the archive tree, capture the snapshot, and close the fork deterministically.
454
+ try {
455
+ this.logger.verbose(
456
+ `Updating archive tree with block ${provingState.blockNumber} header ${(await header.hash()).toString()}`,
457
+ );
458
+ await db.updateArchive(header);
459
+ provingState.setBuiltArchive(await getTreeSnapshot(MerkleTreeId.ARCHIVE, db));
460
+ } finally {
461
+ await db.close();
462
+ }
455
463
 
456
464
  await this.verifyBuiltBlockAgainstSyncedState(provingState);
457
465
 
@@ -462,31 +470,34 @@ export class ProvingOrchestrator implements EpochProver {
462
470
  protected async verifyBuiltBlockAgainstSyncedState(provingState: BlockProvingState) {
463
471
  const builtBlockHeader = provingState.getBuiltBlockHeader();
464
472
  if (!builtBlockHeader) {
465
- logger.debug('Block header not built yet, skipping header check.');
473
+ this.logger.debug('Block header not built yet, skipping header check.');
466
474
  return;
467
475
  }
468
476
 
469
477
  const output = provingState.getBlockRootRollupOutput();
470
478
  if (!output) {
471
- logger.debug('Block root rollup proof not built yet, skipping header check.');
479
+ this.logger.debug('Block root rollup proof not built yet, skipping header check.');
480
+ return;
481
+ }
482
+
483
+ const newArchive = provingState.getBuiltArchive();
484
+ if (!newArchive) {
485
+ this.logger.debug('Archive snapshot not yet captured, skipping header check.');
472
486
  return;
473
487
  }
488
+
474
489
  const header = await buildHeaderFromCircuitOutputs(output);
475
490
 
476
491
  if (!(await header.hash()).equals(await builtBlockHeader.hash())) {
477
- logger.error(`Block header mismatch.\nCircuit: ${inspect(header)}\nComputed: ${inspect(builtBlockHeader)}`);
492
+ this.logger.error(`Block header mismatch.\nCircuit: ${inspect(header)}\nComputed: ${inspect(builtBlockHeader)}`);
478
493
  provingState.reject(`Block header hash mismatch.`);
479
494
  return;
480
495
  }
481
496
 
482
- // Get db for this block
483
497
  const blockNumber = provingState.blockNumber;
484
- const db = this.dbs.get(blockNumber)!.fork;
485
-
486
- const newArchive = await getTreeSnapshot(MerkleTreeId.ARCHIVE, db);
487
498
  const syncedArchive = await getTreeSnapshot(MerkleTreeId.ARCHIVE, this.dbProvider.getSnapshot(blockNumber));
488
499
  if (!syncedArchive.equals(newArchive)) {
489
- logger.error(
500
+ this.logger.error(
490
501
  `Archive tree mismatch for block ${blockNumber}: world state synced to ${inspect(
491
502
  syncedArchive,
492
503
  )} but built ${inspect(newArchive)}`,
@@ -497,16 +508,10 @@ export class ProvingOrchestrator implements EpochProver {
497
508
 
498
509
  const circuitArchive = output.newArchive;
499
510
  if (!newArchive.equals(circuitArchive)) {
500
- logger.error(`New archive mismatch.\nCircuit: ${output.newArchive}\nComputed: ${newArchive}`);
511
+ this.logger.error(`New archive mismatch.\nCircuit: ${output.newArchive}\nComputed: ${newArchive}`);
501
512
  provingState.reject(`New archive mismatch.`);
502
513
  return;
503
514
  }
504
-
505
- // TODO(palla/prover): This closes the fork only on the happy path. If this epoch orchestrator
506
- // is aborted and never reaches this point, it will leak the fork. We need to add a global cleanup,
507
- // but have to make sure it only runs once all operations are completed, otherwise some function here
508
- // will attempt to access the fork after it was closed.
509
- void this.cleanupDBFork(blockNumber);
510
515
  }
511
516
 
512
517
  /**
@@ -515,6 +520,11 @@ export class ProvingOrchestrator implements EpochProver {
515
520
  * If cancelJobsOnStop is false (default), jobs remain in the broker queue and can be reused on restart/reorg.
516
521
  */
517
522
  public cancel() {
523
+ void this.deferredJobQueue.cancel();
524
+ // Recreate the queue so it can accept jobs for subsequent epochs.
525
+ this.deferredJobQueue = new SerialQueue();
526
+ this.deferredJobQueue.start(this.enqueueConcurrency);
527
+
518
528
  if (this.cancelJobsOnStop) {
519
529
  for (const controller of this.pendingProvingJobs) {
520
530
  controller.abort();
@@ -522,6 +532,19 @@ export class ProvingOrchestrator implements EpochProver {
522
532
  }
523
533
 
524
534
  this.provingState?.cancel();
535
+
536
+ for (const [blockNumber, db] of this.dbs.entries()) {
537
+ void db.close().catch(err => this.logger.error(`Error closing db for block ${blockNumber}`, err));
538
+ }
539
+ this.dbs.clear();
540
+ }
541
+
542
+ private getDbForBlock(blockNumber: BlockNumber): MerkleTreeWriteOperations {
543
+ const db = this.dbs.get(blockNumber);
544
+ if (!db) {
545
+ throw new Error(`World state fork for block ${blockNumber} not found.`);
546
+ }
547
+ return db;
525
548
  }
526
549
 
527
550
  /**
@@ -553,24 +576,6 @@ export class ProvingOrchestrator implements EpochProver {
553
576
  return epochProofResult;
554
577
  }
555
578
 
556
- private async cleanupDBFork(blockNumber: BlockNumber): Promise<void> {
557
- logger.debug(`Cleaning up world state fork for ${blockNumber}`);
558
- const fork = this.dbs.get(blockNumber);
559
- if (!fork) {
560
- return;
561
- }
562
-
563
- try {
564
- if (!fork.cleanupPromise) {
565
- fork.cleanupPromise = fork.fork.close();
566
- }
567
- await fork.cleanupPromise;
568
- this.dbs.delete(blockNumber);
569
- } catch (err) {
570
- logger.error(`Error closing db for block ${blockNumber}`, err);
571
- }
572
- }
573
-
574
579
  /**
575
580
  * Enqueue a job to be scheduled
576
581
  * @param provingState - The proving state object being operated on
@@ -583,7 +588,7 @@ export class ProvingOrchestrator implements EpochProver {
583
588
  callback: (result: T) => void | Promise<void>,
584
589
  ) {
585
590
  if (!provingState.verifyState()) {
586
- logger.debug(`Not enqueuing job, state no longer valid`);
591
+ this.logger.debug(`Not enqueuing job, state no longer valid`);
587
592
  return;
588
593
  }
589
594
 
@@ -601,7 +606,7 @@ export class ProvingOrchestrator implements EpochProver {
601
606
 
602
607
  const result = await request(controller.signal);
603
608
  if (!provingState.verifyState()) {
604
- logger.debug(`State no longer valid, discarding result`);
609
+ this.logger.debug(`State no longer valid, discarding result`);
605
610
  return;
606
611
  }
607
612
 
@@ -619,7 +624,7 @@ export class ProvingOrchestrator implements EpochProver {
619
624
  return;
620
625
  }
621
626
 
622
- logger.error(`Error thrown when proving job`, err);
627
+ this.logger.error(`Error thrown when proving job`, err);
623
628
  provingState!.reject(`${err}`);
624
629
  } finally {
625
630
  const index = this.pendingProvingJobs.indexOf(controller);
@@ -629,8 +634,9 @@ export class ProvingOrchestrator implements EpochProver {
629
634
  }
630
635
  };
631
636
 
632
- // let the callstack unwind before adding the job to the queue
633
- setImmediate(() => void safeJob());
637
+ // Enqueue onto the serial queue with limited workers to avoid starving the event loop.
638
+ // Workers yield between jobs via await, allowing I/O callbacks to process.
639
+ void this.deferredJobQueue.put(() => safeJob());
634
640
  }
635
641
 
636
642
  private async updateL1ToL2MessageTree(l1ToL2Messages: Fr[], db: MerkleTreeWriteOperations) {
@@ -704,12 +710,12 @@ export class ProvingOrchestrator implements EpochProver {
704
710
  // Executes the next level of merge if all inputs are available
705
711
  private enqueueBaseRollup(provingState: BlockProvingState, txIndex: number) {
706
712
  if (!provingState.verifyState()) {
707
- logger.debug('Not running base rollup, state invalid');
713
+ this.logger.debug('Not running base rollup, state invalid');
708
714
  return;
709
715
  }
710
716
 
711
717
  if (!provingState.tryStartProvingBase(txIndex)) {
712
- logger.debug(`Base rollup for tx ${txIndex} already started.`);
718
+ this.logger.debug(`Base rollup for tx ${txIndex} already started.`);
713
719
  return;
714
720
  }
715
721
 
@@ -717,7 +723,7 @@ export class ProvingOrchestrator implements EpochProver {
717
723
  const { processedTx } = txProvingState;
718
724
  const { rollupType, inputs } = txProvingState.getBaseRollupTypeAndInputs();
719
725
 
720
- logger.debug(`Enqueuing deferred proving base rollup for ${processedTx.hash.toString()}`);
726
+ this.logger.debug(`Enqueuing deferred proving base rollup for ${processedTx.hash.toString()}`);
721
727
 
722
728
  this.deferredProving(
723
729
  provingState,
@@ -741,7 +747,7 @@ export class ProvingOrchestrator implements EpochProver {
741
747
  },
742
748
  ),
743
749
  result => {
744
- logger.debug(`Completed proof for ${rollupType} for tx ${processedTx.hash.toString()}`);
750
+ this.logger.debug(`Completed proof for ${rollupType} for tx ${processedTx.hash.toString()}`);
745
751
  validatePartialState(result.inputs.endTreeSnapshots, txProvingState.treeSnapshots);
746
752
  const leafLocation = provingState.setBaseRollupProof(txIndex, result);
747
753
  if (provingState.totalNumTxs === 1) {
@@ -757,7 +763,7 @@ export class ProvingOrchestrator implements EpochProver {
757
763
  // Once completed, will enqueue the the public tx base rollup.
758
764
  private getOrEnqueueChonkVerifier(provingState: BlockProvingState, txIndex: number) {
759
765
  if (!provingState.verifyState()) {
760
- logger.debug('Not running chonk verifier circuit, state invalid');
766
+ this.logger.debug('Not running chonk verifier circuit, state invalid');
761
767
  return;
762
768
  }
763
769
 
@@ -770,19 +776,19 @@ export class ProvingOrchestrator implements EpochProver {
770
776
  typeof NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH
771
777
  >,
772
778
  ) => {
773
- logger.debug(`Got chonk verifier proof for tx index: ${txIndex}`, { txHash });
779
+ this.logger.debug(`Got chonk verifier proof for tx index: ${txIndex}`, { txHash });
774
780
  txProvingState.setPublicChonkVerifierProof(result);
775
781
  this.provingState?.cachedChonkVerifierProofs.delete(txHash);
776
782
  this.checkAndEnqueueBaseRollup(provingState, txIndex);
777
783
  };
778
784
 
779
785
  if (this.provingState?.cachedChonkVerifierProofs.has(txHash)) {
780
- logger.debug(`Chonk verifier proof already enqueued for tx index: ${txIndex}`, { txHash });
786
+ this.logger.debug(`Chonk verifier proof already enqueued for tx index: ${txIndex}`, { txHash });
781
787
  void this.provingState!.cachedChonkVerifierProofs.get(txHash)!.then(handleResult);
782
788
  return;
783
789
  }
784
790
 
785
- logger.debug(`Enqueuing chonk verifier circuit for tx index: ${txIndex}`);
791
+ this.logger.debug(`Enqueuing chonk verifier circuit for tx index: ${txIndex}`);
786
792
  this.doEnqueueChonkVerifier(txHash, txProvingState.getPublicChonkVerifierPrivateInputs(), handleResult);
787
793
  }
788
794
 
@@ -798,7 +804,7 @@ export class ProvingOrchestrator implements EpochProver {
798
804
  provingState: EpochProvingState | BlockProvingState = this.provingState!,
799
805
  ) {
800
806
  if (!provingState.verifyState()) {
801
- logger.debug('Not running chonk verifier circuit, state invalid');
807
+ this.logger.debug('Not running chonk verifier circuit, state invalid');
802
808
  return;
803
809
  }
804
810
 
@@ -821,12 +827,12 @@ export class ProvingOrchestrator implements EpochProver {
821
827
  // Enqueues the next level of merge if all inputs are available
822
828
  private enqueueMergeRollup(provingState: BlockProvingState, location: TreeNodeLocation) {
823
829
  if (!provingState.verifyState()) {
824
- logger.debug('Not running merge rollup. State no longer valid.');
830
+ this.logger.debug('Not running merge rollup. State no longer valid.');
825
831
  return;
826
832
  }
827
833
 
828
834
  if (!provingState.tryStartProvingMerge(location)) {
829
- logger.debug('Merge rollup already started.');
835
+ this.logger.debug('Merge rollup already started.');
830
836
  return;
831
837
  }
832
838
 
@@ -852,18 +858,18 @@ export class ProvingOrchestrator implements EpochProver {
852
858
  // Executes the block root rollup circuit
853
859
  private enqueueBlockRootRollup(provingState: BlockProvingState) {
854
860
  if (!provingState.verifyState()) {
855
- logger.debug('Not running block root rollup, state no longer valid');
861
+ this.logger.debug('Not running block root rollup, state no longer valid');
856
862
  return;
857
863
  }
858
864
 
859
865
  if (!provingState.tryStartProvingBlockRoot()) {
860
- logger.debug('Block root rollup already started.');
866
+ this.logger.debug('Block root rollup already started.');
861
867
  return;
862
868
  }
863
869
 
864
870
  const { rollupType, inputs } = provingState.getBlockRootRollupTypeAndInputs();
865
871
 
866
- logger.debug(`Enqueuing ${rollupType} for block ${provingState.blockNumber}.`);
872
+ this.logger.debug(`Enqueuing ${rollupType} for block ${provingState.blockNumber}.`);
867
873
 
868
874
  this.deferredProving(
869
875
  provingState,
@@ -888,22 +894,20 @@ export class ProvingOrchestrator implements EpochProver {
888
894
  },
889
895
  ),
890
896
  async result => {
891
- logger.debug(`Completed ${rollupType} proof for block ${provingState.blockNumber}`);
897
+ this.logger.debug(`Completed ${rollupType} proof for block ${provingState.blockNumber}`);
892
898
 
893
899
  const leafLocation = provingState.setBlockRootRollupProof(result);
894
900
  const checkpointProvingState = provingState.parentCheckpoint;
895
901
 
896
- // If the proofs were slower than the block header building, then we need to try validating the block header hashes here.
902
+ // Verification is called from both here and setBlockCompleted. Whichever runs last
903
+ // will be the first to see all three pieces (header, proof output, archive) and run the checks.
897
904
  await this.verifyBuiltBlockAgainstSyncedState(provingState);
898
905
 
899
906
  if (checkpointProvingState.totalNumBlocks === 1) {
900
- this.checkAndEnqueueCheckpointRootRollup(checkpointProvingState);
907
+ await this.checkAndEnqueueCheckpointRootRollup(checkpointProvingState);
901
908
  } else {
902
- this.checkAndEnqueueNextBlockMergeRollup(checkpointProvingState, leafLocation);
909
+ await this.checkAndEnqueueNextBlockMergeRollup(checkpointProvingState, leafLocation);
903
910
  }
904
-
905
- // We are finished with the block at this point, ensure the fork is cleaned up
906
- void this.cleanupDBFork(provingState.blockNumber);
907
911
  },
908
912
  );
909
913
  }
@@ -916,12 +920,12 @@ export class ProvingOrchestrator implements EpochProver {
916
920
  baseParityIndex: number,
917
921
  ) {
918
922
  if (!provingState.verifyState()) {
919
- logger.debug('Not running base parity. State no longer valid.');
923
+ this.logger.debug('Not running base parity. State no longer valid.');
920
924
  return;
921
925
  }
922
926
 
923
927
  if (!provingState.tryStartProvingBaseParity(baseParityIndex)) {
924
- logger.warn(`Base parity ${baseParityIndex} already started.`);
928
+ this.logger.warn(`Base parity ${baseParityIndex} already started.`);
925
929
  return;
926
930
  }
927
931
 
@@ -956,12 +960,12 @@ export class ProvingOrchestrator implements EpochProver {
956
960
  // Enqueues the root rollup proof if all inputs are available
957
961
  private enqueueRootParityCircuit(provingState: BlockProvingState) {
958
962
  if (!provingState.verifyState()) {
959
- logger.debug('Not running root parity. State no longer valid.');
963
+ this.logger.debug('Not running root parity. State no longer valid.');
960
964
  return;
961
965
  }
962
966
 
963
967
  if (!provingState.tryStartProvingRootParity()) {
964
- logger.debug('Root parity already started.');
968
+ this.logger.debug('Root parity already started.');
965
969
  return;
966
970
  }
967
971
 
@@ -988,12 +992,12 @@ export class ProvingOrchestrator implements EpochProver {
988
992
  // Enqueues the next level of merge if all inputs are available
989
993
  private enqueueBlockMergeRollup(provingState: CheckpointProvingState, location: TreeNodeLocation) {
990
994
  if (!provingState.verifyState()) {
991
- logger.debug('Not running block merge rollup. State no longer valid.');
995
+ this.logger.debug('Not running block merge rollup. State no longer valid.');
992
996
  return;
993
997
  }
994
998
 
995
999
  if (!provingState.tryStartProvingBlockMerge(location)) {
996
- logger.debug('Block merge rollup already started.');
1000
+ this.logger.debug('Block merge rollup already started.');
997
1001
  return;
998
1002
  }
999
1003
 
@@ -1008,29 +1012,29 @@ export class ProvingOrchestrator implements EpochProver {
1008
1012
  },
1009
1013
  signal => this.prover.getBlockMergeRollupProof(inputs, signal, provingState.epochNumber),
1010
1014
  ),
1011
- result => {
1015
+ async result => {
1012
1016
  provingState.setBlockMergeRollupProof(location, result);
1013
- this.checkAndEnqueueNextBlockMergeRollup(provingState, location);
1017
+ await this.checkAndEnqueueNextBlockMergeRollup(provingState, location);
1014
1018
  },
1015
1019
  );
1016
1020
  }
1017
1021
 
1018
- private enqueueCheckpointRootRollup(provingState: CheckpointProvingState) {
1022
+ private async enqueueCheckpointRootRollup(provingState: CheckpointProvingState) {
1019
1023
  if (!provingState.verifyState()) {
1020
- logger.debug('Not running checkpoint root rollup. State no longer valid.');
1024
+ this.logger.debug('Not running checkpoint root rollup. State no longer valid.');
1021
1025
  return;
1022
1026
  }
1023
1027
 
1024
1028
  if (!provingState.tryStartProvingCheckpointRoot()) {
1025
- logger.debug('Checkpoint root rollup already started.');
1029
+ this.logger.debug('Checkpoint root rollup already started.');
1026
1030
  return;
1027
1031
  }
1028
1032
 
1029
1033
  const rollupType = provingState.getCheckpointRootRollupType();
1030
1034
 
1031
- logger.debug(`Enqueuing ${rollupType} for checkpoint ${provingState.index}.`);
1035
+ this.logger.debug(`Enqueuing ${rollupType} for checkpoint ${provingState.index}.`);
1032
1036
 
1033
- const inputs = provingState.getCheckpointRootRollupInputs();
1037
+ const inputs = await provingState.getCheckpointRootRollupInputs();
1034
1038
 
1035
1039
  this.deferredProving(
1036
1040
  provingState,
@@ -1052,7 +1056,7 @@ export class ProvingOrchestrator implements EpochProver {
1052
1056
  const computedEndBlobAccumulatorState = provingState.getEndBlobAccumulator()!.toBlobAccumulator();
1053
1057
  const circuitEndBlobAccumulatorState = result.inputs.endBlobAccumulator;
1054
1058
  if (!circuitEndBlobAccumulatorState.equals(computedEndBlobAccumulatorState)) {
1055
- logger.error(
1059
+ this.logger.error(
1056
1060
  `Blob accumulator state mismatch.\nCircuit: ${inspect(circuitEndBlobAccumulatorState)}\nComputed: ${inspect(
1057
1061
  computedEndBlobAccumulatorState,
1058
1062
  )}`,
@@ -1061,7 +1065,7 @@ export class ProvingOrchestrator implements EpochProver {
1061
1065
  return;
1062
1066
  }
1063
1067
 
1064
- logger.debug(`Completed ${rollupType} proof for checkpoint ${provingState.index}.`);
1068
+ this.logger.debug(`Completed ${rollupType} proof for checkpoint ${provingState.index}.`);
1065
1069
 
1066
1070
  const leafLocation = provingState.setCheckpointRootRollupProof(result);
1067
1071
  const epochProvingState = provingState.parentEpoch;
@@ -1077,12 +1081,12 @@ export class ProvingOrchestrator implements EpochProver {
1077
1081
 
1078
1082
  private enqueueCheckpointMergeRollup(provingState: EpochProvingState, location: TreeNodeLocation) {
1079
1083
  if (!provingState.verifyState()) {
1080
- logger.debug('Not running checkpoint merge rollup. State no longer valid.');
1084
+ this.logger.debug('Not running checkpoint merge rollup. State no longer valid.');
1081
1085
  return;
1082
1086
  }
1083
1087
 
1084
1088
  if (!provingState.tryStartProvingCheckpointMerge(location)) {
1085
- logger.debug('Checkpoint merge rollup already started.');
1089
+ this.logger.debug('Checkpoint merge rollup already started.');
1086
1090
  return;
1087
1091
  }
1088
1092
 
@@ -1099,7 +1103,7 @@ export class ProvingOrchestrator implements EpochProver {
1099
1103
  signal => this.prover.getCheckpointMergeRollupProof(inputs, signal, provingState.epochNumber),
1100
1104
  ),
1101
1105
  result => {
1102
- logger.debug('Completed proof for checkpoint merge rollup.');
1106
+ this.logger.debug('Completed proof for checkpoint merge rollup.');
1103
1107
  provingState.setCheckpointMergeRollupProof(location, result);
1104
1108
  this.checkAndEnqueueNextCheckpointMergeRollup(provingState, location);
1105
1109
  },
@@ -1108,16 +1112,16 @@ export class ProvingOrchestrator implements EpochProver {
1108
1112
 
1109
1113
  private enqueueEpochPadding(provingState: EpochProvingState) {
1110
1114
  if (!provingState.verifyState()) {
1111
- logger.debug('Not running epoch padding. State no longer valid.');
1115
+ this.logger.debug('Not running epoch padding. State no longer valid.');
1112
1116
  return;
1113
1117
  }
1114
1118
 
1115
1119
  if (!provingState.tryStartProvingPaddingCheckpoint()) {
1116
- logger.debug('Padding checkpoint already started.');
1120
+ this.logger.debug('Padding checkpoint already started.');
1117
1121
  return;
1118
1122
  }
1119
1123
 
1120
- logger.debug('Padding epoch proof with a padding block root proof.');
1124
+ this.logger.debug('Padding epoch proof with a padding block root proof.');
1121
1125
 
1122
1126
  const inputs = provingState.getPaddingCheckpointInputs();
1123
1127
 
@@ -1132,7 +1136,7 @@ export class ProvingOrchestrator implements EpochProver {
1132
1136
  signal => this.prover.getCheckpointPaddingRollupProof(inputs, signal, provingState.epochNumber),
1133
1137
  ),
1134
1138
  result => {
1135
- logger.debug('Completed proof for padding checkpoint.');
1139
+ this.logger.debug('Completed proof for padding checkpoint.');
1136
1140
  provingState.setCheckpointPaddingProof(result);
1137
1141
  this.checkAndEnqueueRootRollup(provingState);
1138
1142
  },
@@ -1142,11 +1146,11 @@ export class ProvingOrchestrator implements EpochProver {
1142
1146
  // Executes the root rollup circuit
1143
1147
  private enqueueRootRollup(provingState: EpochProvingState) {
1144
1148
  if (!provingState.verifyState()) {
1145
- logger.debug('Not running root rollup, state no longer valid');
1149
+ this.logger.debug('Not running root rollup, state no longer valid');
1146
1150
  return;
1147
1151
  }
1148
1152
 
1149
- logger.debug(`Preparing root rollup`);
1153
+ this.logger.debug(`Preparing root rollup`);
1150
1154
 
1151
1155
  const inputs = provingState.getRootRollupInputs();
1152
1156
 
@@ -1161,7 +1165,7 @@ export class ProvingOrchestrator implements EpochProver {
1161
1165
  signal => this.prover.getRootRollupProof(inputs, signal, provingState.epochNumber),
1162
1166
  ),
1163
1167
  result => {
1164
- logger.verbose(`Orchestrator completed root rollup for epoch ${provingState.epochNumber}`);
1168
+ this.logger.verbose(`Orchestrator completed root rollup for epoch ${provingState.epochNumber}`);
1165
1169
  provingState.setRootRollupProof(result);
1166
1170
  provingState.resolve({ status: 'success' });
1167
1171
  },
@@ -1183,32 +1187,35 @@ export class ProvingOrchestrator implements EpochProver {
1183
1187
 
1184
1188
  private checkAndEnqueueBlockRootRollup(provingState: BlockProvingState) {
1185
1189
  if (!provingState.isReadyForBlockRootRollup()) {
1186
- logger.debug('Not ready for block root rollup');
1190
+ this.logger.debug('Not ready for block root rollup');
1187
1191
  return;
1188
1192
  }
1189
1193
 
1190
1194
  this.enqueueBlockRootRollup(provingState);
1191
1195
  }
1192
1196
 
1193
- private checkAndEnqueueNextBlockMergeRollup(provingState: CheckpointProvingState, currentLocation: TreeNodeLocation) {
1197
+ private async checkAndEnqueueNextBlockMergeRollup(
1198
+ provingState: CheckpointProvingState,
1199
+ currentLocation: TreeNodeLocation,
1200
+ ) {
1194
1201
  if (!provingState.isReadyForBlockMerge(currentLocation)) {
1195
1202
  return;
1196
1203
  }
1197
1204
 
1198
1205
  const parentLocation = provingState.getParentLocation(currentLocation);
1199
1206
  if (parentLocation.level === 0) {
1200
- this.checkAndEnqueueCheckpointRootRollup(provingState);
1207
+ await this.checkAndEnqueueCheckpointRootRollup(provingState);
1201
1208
  } else {
1202
1209
  this.enqueueBlockMergeRollup(provingState, parentLocation);
1203
1210
  }
1204
1211
  }
1205
1212
 
1206
- private checkAndEnqueueCheckpointRootRollup(provingState: CheckpointProvingState) {
1213
+ private async checkAndEnqueueCheckpointRootRollup(provingState: CheckpointProvingState) {
1207
1214
  if (!provingState.isReadyForCheckpointRoot()) {
1208
1215
  return;
1209
1216
  }
1210
1217
 
1211
- this.enqueueCheckpointRootRollup(provingState);
1218
+ await this.enqueueCheckpointRootRollup(provingState);
1212
1219
  }
1213
1220
 
1214
1221
  private checkAndEnqueueNextCheckpointMergeRollup(provingState: EpochProvingState, currentLocation: TreeNodeLocation) {
@@ -1226,7 +1233,7 @@ export class ProvingOrchestrator implements EpochProver {
1226
1233
 
1227
1234
  private checkAndEnqueueRootRollup(provingState: EpochProvingState) {
1228
1235
  if (!provingState.isReadyForRootRollup()) {
1229
- logger.debug('Not ready for root rollup');
1236
+ this.logger.debug('Not ready for root rollup');
1230
1237
  return;
1231
1238
  }
1232
1239
 
@@ -1241,7 +1248,7 @@ export class ProvingOrchestrator implements EpochProver {
1241
1248
  */
1242
1249
  private enqueueVM(provingState: BlockProvingState, txIndex: number) {
1243
1250
  if (!provingState.verifyState()) {
1244
- logger.debug(`Not running VM circuit as state is no longer valid`);
1251
+ this.logger.debug(`Not running VM circuit as state is no longer valid`);
1245
1252
  return;
1246
1253
  }
1247
1254
 
@@ -1260,7 +1267,7 @@ export class ProvingOrchestrator implements EpochProver {
1260
1267
  );
1261
1268
 
1262
1269
  this.deferredProving(provingState, doAvmProving, proof => {
1263
- logger.debug(`Proven VM for tx index: ${txIndex}`);
1270
+ this.logger.debug(`Proven VM for tx index: ${txIndex}`);
1264
1271
  txProvingState.setAvmProof(proof);
1265
1272
  this.checkAndEnqueueBaseRollup(provingState, txIndex);
1266
1273
  });
@@ -1273,7 +1280,7 @@ export class ProvingOrchestrator implements EpochProver {
1273
1280
  }
1274
1281
 
1275
1282
  // We must have completed all proving (chonk verifier proof and (if required) vm proof are generated), we now move to the base rollup.
1276
- logger.debug(`Public functions completed for tx ${txIndex} enqueueing base rollup`);
1283
+ this.logger.debug(`Public functions completed for tx ${txIndex} enqueueing base rollup`);
1277
1284
 
1278
1285
  this.enqueueBaseRollup(provingState, txIndex);
1279
1286
  }