@aztec/prover-client 0.0.1-commit.d1f2d6c → 0.0.1-commit.d20b825a7

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