@aztec/prover-node 5.0.0-rc.1 → 5.0.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 (36) hide show
  1. package/README.md +73 -68
  2. package/dest/actions/rerun-epoch-proving-job.d.ts +2 -2
  3. package/dest/actions/rerun-epoch-proving-job.d.ts.map +1 -1
  4. package/dest/checkpoint-store.d.ts +42 -37
  5. package/dest/checkpoint-store.d.ts.map +1 -1
  6. package/dest/checkpoint-store.js +65 -77
  7. package/dest/job/checkpoint-prover.d.ts +6 -16
  8. package/dest/job/checkpoint-prover.d.ts.map +1 -1
  9. package/dest/job/checkpoint-prover.js +15 -35
  10. package/dest/job/epoch-session.d.ts +2 -2
  11. package/dest/job/epoch-session.d.ts.map +1 -1
  12. package/dest/job/epoch-session.js +20 -9
  13. package/dest/metrics.d.ts +7 -4
  14. package/dest/metrics.d.ts.map +1 -1
  15. package/dest/metrics.js +14 -6
  16. package/dest/proof-publishing-service.d.ts +4 -2
  17. package/dest/proof-publishing-service.d.ts.map +1 -1
  18. package/dest/proof-publishing-service.js +1 -0
  19. package/dest/prover-node-publisher.d.ts +5 -5
  20. package/dest/prover-node-publisher.d.ts.map +1 -1
  21. package/dest/prover-node-publisher.js +2 -3
  22. package/dest/prover-node.d.ts +25 -15
  23. package/dest/prover-node.d.ts.map +1 -1
  24. package/dest/prover-node.js +152 -51
  25. package/dest/session-manager.d.ts +2 -2
  26. package/dest/session-manager.d.ts.map +1 -1
  27. package/dest/session-manager.js +38 -8
  28. package/package.json +23 -23
  29. package/src/checkpoint-store.ts +66 -85
  30. package/src/job/checkpoint-prover.ts +17 -40
  31. package/src/job/epoch-session.ts +21 -9
  32. package/src/metrics.ts +15 -12
  33. package/src/proof-publishing-service.ts +4 -1
  34. package/src/prover-node-publisher.ts +11 -10
  35. package/src/prover-node.ts +170 -60
  36. package/src/session-manager.ts +38 -7
@@ -371,15 +371,16 @@ function _apply_decs_2203_r(targetClass, memberDecs, classDecs, parentClass) {
371
371
  return (_apply_decs_2203_r = applyDecs2203RFactory())(targetClass, memberDecs, classDecs, parentClass);
372
372
  }
373
373
  var _initProto;
374
- import { BlockNumber, EpochNumber } from '@aztec/foundation/branded-types';
374
+ import { BlockNumber, CheckpointNumber, EpochNumber } from '@aztec/foundation/branded-types';
375
375
  import { assertRequired, compact, pick } from '@aztec/foundation/collection';
376
376
  import { memoize } from '@aztec/foundation/decorators';
377
377
  import { createLogger } from '@aztec/foundation/log';
378
+ import { RunningPromise } from '@aztec/foundation/running-promise';
378
379
  import { DateProvider, executeTimeout } from '@aztec/foundation/timer';
379
380
  import { getLastSiblingPath } from '@aztec/prover-client/helpers';
380
381
  import { ChonkCache } from '@aztec/prover-client/orchestrator';
381
382
  import { PublicProcessorFactory } from '@aztec/simulator/server';
382
- import { L2BlockStream, L2TipsMemoryStore } from '@aztec/stdlib/block';
383
+ import { EventDrivenL2BlockStream, L2TipsMemoryStore } from '@aztec/stdlib/block';
383
384
  import { getEpochAtSlot, getProofSubmissionDeadlineEpoch } from '@aztec/stdlib/epoch-helpers';
384
385
  import { EpochProvingJobTerminalState, tryStop } from '@aztec/stdlib/interfaces/server';
385
386
  import { MerkleTreeId } from '@aztec/stdlib/trees';
@@ -440,6 +441,13 @@ import { SessionManager } from './session-manager.js';
440
441
  * event by comparing the archiver's latest synced L2 slot against each epoch's
441
442
  * submission deadline. Protected so tests can verify the start() seeding.
442
443
  */ lastExpiredEpoch;
444
+ /**
445
+ * Highest checkpoint number whose proving-side handling has completed (or that was legitimately skipped).
446
+ * The catch-up loop walks from here to each `chain-checkpointed` tip event. Seeded at start() from the last
447
+ * checkpoint of the last fully-proven epoch (or 0), so a restart reprocesses the partially-proven epoch rather
448
+ * than trusting a checkpointed tip that may sit ahead of unproven checkpoints. Clamped down on a prune.
449
+ */ lastProcessedCheckpoint;
450
+ /** Periodic tick that runs the epoch-expiry sweep during idle periods when no block-stream events arrive. */ expiryTicker;
443
451
  tracer;
444
452
  publishingService;
445
453
  constructor(prover, publisherFactory, l2BlockSource, l1ToL2MessageSource, contractDataSource, worldState, p2pClient, rollupContract, l1Metrics, config = {}, telemetryClient = getTelemetryClient(), delayer, dateProvider = new DateProvider()){
@@ -456,6 +464,7 @@ import { SessionManager } from './session-manager.js';
456
464
  this.delayer = delayer;
457
465
  this.dateProvider = dateProvider;
458
466
  this.log = (_initProto(this), createLogger('prover-node'));
467
+ this.lastProcessedCheckpoint = CheckpointNumber.ZERO;
459
468
  this.config = {
460
469
  proverNodePollingIntervalMs: 1_000,
461
470
  proverNodeMaxPendingJobs: 100,
@@ -486,8 +495,6 @@ import { SessionManager } from './session-manager.js';
486
495
  metrics: this.jobMetrics,
487
496
  txGatheringTimeoutMs: this.config.txGatheringTimeoutMs,
488
497
  deadline: undefined
489
- }, {
490
- slotWatcherPollIntervalMs: this.config.proverNodePollingIntervalMs
491
498
  }, this.log.getBindings());
492
499
  }
493
500
  getProverId() {
@@ -514,13 +521,6 @@ import { SessionManager } from './session-manager.js';
514
521
  }
515
522
  return this.sessionManager;
516
523
  }
517
- /** Returns world state status. */ async getWorldStateSyncStatus() {
518
- const { syncSummary } = await this.worldState.status();
519
- return syncSummary;
520
- }
521
- /** Returns archiver status. */ getL2Tips() {
522
- return this.l2BlockSource.getL2Tips();
523
- }
524
524
  /** Returns the underlying prover instance. */ getProver() {
525
525
  return this.prover;
526
526
  }
@@ -528,17 +528,26 @@ import { SessionManager } from './session-manager.js';
528
528
  async handleBlockStreamEvent(event) {
529
529
  switch(event.type){
530
530
  case 'chain-checkpointed':
531
- await this.handleCheckpointEvent(event.checkpoint);
531
+ await this.processCheckpointJump(event.checkpoint.number);
532
532
  break;
533
533
  case 'chain-pruned':
534
- await this.handlePruneEvent(event.checkpointed.checkpoint);
534
+ await this.handlePruneEvent(event.block);
535
535
  break;
536
536
  case 'chain-proven':
537
537
  this.publishingService?.onChainProven(BlockNumber(event.block.number));
538
538
  break;
539
+ // The proposed tip drives only the tips store's walk-back history (recorded below); the prover-node
540
+ // tracks checkpoints, not proposed blocks. `blocks-added` is never emitted in tips-only mode, and
541
+ // `chain-finalized` carries nothing the prover-node acts on.
542
+ case 'chain-proposed':
539
543
  case 'chain-finalized':
540
544
  case 'blocks-added':
541
545
  break;
546
+ default:
547
+ {
548
+ const _ = event;
549
+ break;
550
+ }
542
551
  }
543
552
  // Expiry is driven by the archiver's latest synced L2 slot
544
553
  await this.checkEpochExpiry();
@@ -547,27 +556,87 @@ import { SessionManager } from './session-manager.js';
547
556
  // skips this update, so the event is re-emitted on the next poll rather than skipped (A-1041).
548
557
  await this.tipsStore.handleBlockStreamEvent(event);
549
558
  }
550
- /** Register a new checkpoint with the store and notify the session manager. */ async handleCheckpointEvent(publishedCheckpoint) {
551
- const checkpoint = publishedCheckpoint.checkpoint;
552
- const slotNumber = checkpoint.header.slotNumber;
553
- const l1Constants = await this.getL1Constants();
554
- const epochNumber = getEpochAtSlot(slotNumber, l1Constants);
555
- if (await this.isEpochFullyProven(epochNumber, l1Constants)) {
556
- this.log.debug(`Skipping checkpoint ${checkpoint.number} for already-proven epoch ${epochNumber}`);
559
+ /**
560
+ * Walks every checkpoint between the local cursor and the newly-reported checkpointed tip, registering
561
+ * each one that belongs to an epoch that can still be proven. The block stream now delivers a single thin
562
+ * `chain-checkpointed` tip event per pass rather than one fat event per checkpoint, so this drives the
563
+ * catch-up itself: light metadata first (`getCheckpointsData`) to decide relevance per epoch, then a heavy
564
+ * `getCheckpoints` fetch only for checkpoints in provable epochs.
565
+ *
566
+ * The cursor advances one checkpoint at a time and only after that checkpoint's proving-side handling has
567
+ * fully succeeded, preserving the A-1041 at-least-once semantics: a mid-jump failure leaves the cursor
568
+ * behind so the next pass retries from the first checkpoint that did not complete.
569
+ */ async processCheckpointJump(targetCheckpoint) {
570
+ if (targetCheckpoint <= this.lastProcessedCheckpoint) {
557
571
  return;
558
572
  }
559
- if (await this.isEpochPastProofSubmissionWindow(epochNumber, l1Constants)) {
560
- this.log.debug(`Skipping checkpoint ${checkpoint.number} for epoch ${epochNumber} past its proof-submission window`);
561
- return;
573
+ const l1Constants = await this.getL1Constants();
574
+ // Cap the catch-up at the `(proofSubmissionEpochs + 1) * epochDuration` most recent checkpoints.
575
+ // When the cursor is much further behind (e.g. resyncing after a long time offline), fetching the whole gap could
576
+ // load thousands of checkpoints we cannot act on: anything older than the last two epochs is already past
577
+ // its proof-submission window, so we skip it and jump the cursor forward to the start of the capped range.
578
+ const maxCheckpoints = (l1Constants.proofSubmissionEpochs + 1) * l1Constants.epochDuration;
579
+ let from = CheckpointNumber(this.lastProcessedCheckpoint + 1);
580
+ if (Number(targetCheckpoint - from) + 1 > maxCheckpoints) {
581
+ const cappedFrom = CheckpointNumber(targetCheckpoint - maxCheckpoints + 1);
582
+ this.log.warn(`Skipping unprovable checkpoints during catch-up; the prover node is far behind`, {
583
+ from,
584
+ cappedFrom,
585
+ targetCheckpoint,
586
+ maxCheckpoints
587
+ });
588
+ // Advance the cursor past the skipped checkpoints so they are never retried.
589
+ this.lastProcessedCheckpoint = CheckpointNumber(cappedFrom - 1);
590
+ from = cappedFrom;
591
+ }
592
+ const limit = Number(targetCheckpoint - from) + 1;
593
+ const metadatas = await this.l2BlockSource.getCheckpointsData({
594
+ from,
595
+ limit
596
+ });
597
+ // Per-epoch relevance is cached so a multi-checkpoint epoch resolves it once. Skipping is whole-epoch
598
+ // only: the SessionManager requires an epoch's checkpoints fully covered before it opens a session, so we
599
+ // never drop an individual checkpoint inside an epoch we will prove.
600
+ const epochSkippable = new Map();
601
+ for (const metadata of metadatas){
602
+ const epochNumber = getEpochAtSlot(metadata.header.slotNumber, l1Constants);
603
+ let skippable = epochSkippable.get(epochNumber);
604
+ if (skippable === undefined) {
605
+ skippable = await this.isEpochFullyProven(epochNumber, l1Constants) || await this.isEpochPastProofSubmissionWindow(epochNumber, l1Constants);
606
+ epochSkippable.set(epochNumber, skippable);
607
+ }
608
+ if (skippable) {
609
+ this.log.debug(`Skipping checkpoint ${metadata.checkpointNumber} for unprovable epoch ${epochNumber}`);
610
+ } else {
611
+ await this.registerCheckpoint(metadata.checkpointNumber, epochNumber);
612
+ }
613
+ // Advance only after the checkpoint's handling succeeded (or it was legitimately skipped). registerCheckpoint
614
+ // throws on failure, which leaves the cursor here for the next pass to retry (A-1041).
615
+ this.lastProcessedCheckpoint = metadata.checkpointNumber;
562
616
  }
617
+ }
618
+ /** Heavy-fetch a single checkpoint, register it with the store, and notify the session manager. */ async registerCheckpoint(checkpointNumber, epochNumber) {
619
+ const published = await this.l2BlockSource.getCheckpoint({
620
+ number: checkpointNumber
621
+ });
622
+ if (!published) {
623
+ throw new Error(`Checkpoint ${checkpointNumber} not found in block source during catch-up`);
624
+ }
625
+ const checkpoint = published.checkpoint;
563
626
  this.log.info(`New checkpoint ${checkpoint.number} for epoch ${epochNumber}`, {
564
627
  checkpointNumber: checkpoint.number,
565
628
  epochNumber,
566
- slotNumber
629
+ slotNumber: checkpoint.header.slotNumber
567
630
  });
568
- const registerData = await this.collectRegisterData(checkpoint, publishedCheckpoint.attestations);
631
+ const registerData = await this.collectRegisterData(checkpoint, published.attestations);
569
632
  await this.checkpointStore.addOrUpdate(checkpoint, registerData);
570
633
  await this.sessionManager?.onCheckpointAdded(epochNumber);
634
+ // Tips-only mode delivers no blocks, so record one witness per checkpointed block: a reorg into the checkpoint's
635
+ // range then prunes at the true divergence instead of the nearest sparse tip anchor.
636
+ await this.tipsStore.recordBlockHashes(await Promise.all(checkpoint.blocks.map(async (block)=>({
637
+ number: block.number,
638
+ hash: (await block.header.hash()).toString()
639
+ }))));
571
640
  }
572
641
  /**
573
642
  * Gathers register-time data for a checkpoint: previous block header, L1-to-L2 messages,
@@ -587,11 +656,38 @@ import { SessionManager } from './session-manager.js';
587
656
  previousArchiveSiblingPath
588
657
  };
589
658
  }
590
- /** Mark every prover above the prune threshold as pruned and notify the session manager. */ async handlePruneEvent(prunedCheckpoint) {
591
- this.log.warn(`Chain pruned to checkpoint ${prunedCheckpoint.number}`, {
592
- prunedCheckpoint
659
+ /**
660
+ * Marks every prover orphaned by the prune as pruned, clamps the catch-up cursor below the prune target's
661
+ * checkpoint, and notifies the session manager. Keyed off the prune target block (the highest surviving block)
662
+ * rather than the source's checkpointed tip, which can sit above the target after a re-checkpoint and would leave
663
+ * orphaned provers canonical. Throws (rather than warning) if the cursor floor cannot be resolved, so the pass
664
+ * fails and the prune is retried next iteration.
665
+ */ async handlePruneEvent(prunedToBlock) {
666
+ this.log.warn(`Chain pruned to block ${prunedToBlock.number}`, {
667
+ prunedToBlock
593
668
  });
594
- const affected = this.checkpointStore.markPrunedAfter(prunedCheckpoint.number);
669
+ // Resolve the cursor floor BEFORE removing provers: cancelAndRemoveAboveBlock returns only the provers it removed,
670
+ // so a throw after removing would leave a retry pass with nothing to act on. Resolving first means a throw leaves
671
+ // everything untouched and the next pass retries the whole handler (the tips cursor only advances on success).
672
+ let cursorFloor;
673
+ if (prunedToBlock.number === 0) {
674
+ cursorFloor = CheckpointNumber.ZERO;
675
+ } else {
676
+ const targetData = await this.l2BlockSource.getBlockData({
677
+ number: prunedToBlock.number
678
+ });
679
+ if (targetData === undefined) {
680
+ throw new Error(`No block data found for prune target block ${prunedToBlock.number}; cannot clamp checkpoint cursor`);
681
+ }
682
+ // Clamp to `cpAtTarget - 1`: a mid-checkpoint target leaves that checkpoint partially orphaned and it must be
683
+ // reprocessed. Over-clamping merely re-registers a checkpoint (at-least-once by design — A-1041); under-clamping
684
+ // would permanently skip a rebuilt same-number checkpoint.
685
+ cursorFloor = CheckpointNumber(Math.max(0, Number(targetData.checkpointNumber) - 1));
686
+ }
687
+ const affected = this.checkpointStore.cancelAndRemoveAboveBlock(prunedToBlock.number);
688
+ if (this.lastProcessedCheckpoint > cursorFloor) {
689
+ this.lastProcessedCheckpoint = cursorFloor;
690
+ }
595
691
  if (affected.length === 0) {
596
692
  return;
597
693
  }
@@ -689,13 +785,18 @@ import { SessionManager } from './session-manager.js';
689
785
  this.sessionManager.start();
690
786
  // Now that the store + manager exist, arm the live-state observable gauges.
691
787
  this.jobMetrics.observeState(this.checkpointStore, this.sessionManager);
692
- const { startingBlock, lastFullyProvenEpoch } = await this.computeStartupState();
788
+ const { lastFullyProvenEpoch } = await this.resolveLastFullyProvenEpoch();
693
789
  this.lastExpiredEpoch = lastFullyProvenEpoch;
694
- this.blockStream = new L2BlockStream(this.l2BlockSource, this.tipsStore, this, this.log, {
790
+ this.lastProcessedCheckpoint = await this.computeStartingCheckpoint(lastFullyProvenEpoch);
791
+ this.blockStream = new EventDrivenL2BlockStream(this.l2BlockSource, this.tipsStore, this, this.log, {
695
792
  pollIntervalMS: this.config.proverNodePollingIntervalMs,
696
- startingBlock
793
+ tipsOnly: true
697
794
  });
698
795
  this.blockStream.start();
796
+ // With thin once-per-pass tip events, the expiry sweep no longer fires once per checkpoint; drive it
797
+ // from a periodic tick so epochs still expire during idle/no-event periods.
798
+ this.expiryTicker = new RunningPromise(()=>this.checkEpochExpiry(), this.log, this.config.proverNodePollingIntervalMs);
799
+ this.expiryTicker.start();
699
800
  await this.rewardsMetrics.start();
700
801
  this.l1Metrics.start();
701
802
  this.log.info(`Started Prover Node with prover id ${this.prover.getProverId().toString()}`, this.config);
@@ -704,6 +805,7 @@ import { SessionManager } from './session-manager.js';
704
805
  this.log.info('Stopping ProverNode');
705
806
  this.jobMetrics.stopObservingState();
706
807
  await this.blockStream?.stop();
808
+ await this.expiryTicker?.stop();
707
809
  if (this.sessionManager) {
708
810
  await this.sessionManager.stop();
709
811
  }
@@ -803,18 +905,16 @@ import { SessionManager } from './session-manager.js';
803
905
  return this.l2BlockSource.isEpochComplete(provenEpoch);
804
906
  }
805
907
  /**
806
- * Resolves the L2BlockStream's starting block and the last fully-proven epoch in one
807
- * pass. The starting block is the first block of the next unproven epoch (or the start
808
- * of the partially-proven epoch if the proven tip falls mid-epoch). The fully-proven
809
- * epoch is `provenEpoch` when the proven tip is the last block of its epoch, otherwise
810
- * `provenEpoch - 1`, or `undefined` if no block is proven yet.
811
- */ async computeStartupState() {
908
+ * Resolves the last fully-proven epoch from L1 proven state, used to seed the catch-up cursor (via
909
+ * `computeStartingCheckpoint`) and `lastExpiredEpoch`. The fully-proven epoch is `provenEpoch` when the
910
+ * proven tip is the last block of its epoch, otherwise `provenEpoch - 1`, or `undefined` if no block is
911
+ * proven yet (so a restart reprocesses the partially-proven epoch rather than trusting a stale tip).
912
+ */ async resolveLastFullyProvenEpoch() {
812
913
  const provenBlockNumber = await this.l2BlockSource.getBlockNumber({
813
914
  tag: 'proven'
814
915
  });
815
916
  if (!provenBlockNumber || provenBlockNumber <= 0) {
816
917
  return {
817
- startingBlock: BlockNumber(1),
818
918
  lastFullyProvenEpoch: undefined
819
919
  };
820
920
  }
@@ -824,32 +924,33 @@ import { SessionManager } from './session-manager.js';
824
924
  }))?.header;
825
925
  if (!provenHeader) {
826
926
  return {
827
- startingBlock: BlockNumber(provenBlockNumber + 1),
828
927
  lastFullyProvenEpoch: undefined
829
928
  };
830
929
  }
831
930
  const provenEpoch = getEpochAtSlot(provenHeader.getSlot(), l1Constants);
832
931
  if (await this.isProvenBlockLastOfItsEpoch(BlockNumber(provenBlockNumber), provenEpoch, l1Constants)) {
833
932
  return {
834
- startingBlock: BlockNumber(provenBlockNumber + 1),
835
933
  lastFullyProvenEpoch: provenEpoch
836
934
  };
837
935
  }
838
- const epochCheckpoints = await this.l2BlockSource.getCheckpointsData({
839
- epoch: provenEpoch
840
- });
841
- const firstBlockOfEpoch = epochCheckpoints.length > 0 ? epochCheckpoints[0].startBlock : BlockNumber(provenBlockNumber);
842
- this.log.info(`Starting L2BlockStream at block ${firstBlockOfEpoch} (start of partially-proven epoch ${provenEpoch})`, {
843
- provenBlockNumber,
844
- provenEpoch,
845
- firstBlockOfEpoch
846
- });
847
936
  const lastFullyProvenEpoch = provenEpoch > 0 ? EpochNumber(provenEpoch - 1) : undefined;
848
937
  return {
849
- startingBlock: firstBlockOfEpoch,
850
938
  lastFullyProvenEpoch
851
939
  };
852
940
  }
941
+ /**
942
+ * Resolves the catch-up cursor seed: the last checkpoint of the last fully-proven epoch, or 0 if none. Seeding
943
+ * from a checkpoint (rather than a checkpointed tip) guarantees a restart reprocesses every checkpoint of the
944
+ * partially-proven epoch, since the checkpointed tip can sit ahead of the last fully-proven checkpoint.
945
+ */ async computeStartingCheckpoint(lastFullyProvenEpoch) {
946
+ if (lastFullyProvenEpoch === undefined) {
947
+ return CheckpointNumber.ZERO;
948
+ }
949
+ const checkpoints = await this.l2BlockSource.getCheckpointsData({
950
+ epoch: lastFullyProvenEpoch
951
+ });
952
+ return checkpoints.at(-1)?.checkpointNumber ?? CheckpointNumber.ZERO;
953
+ }
853
954
  async gatherPreviousBlockHeader(previousBlockNumber) {
854
955
  const data = await this.l2BlockSource.getBlockData({
855
956
  number: BlockNumber(previousBlockNumber)
@@ -148,11 +148,11 @@ export declare class SessionManager {
148
148
  private atMaxSessionLimit;
149
149
  private epochsForTrigger;
150
150
  private nextUnprovenEpoch;
151
- private canonicalCheckpointsForSpec;
151
+ private checkpointsForSpec;
152
152
  private fireAndForgetCancel;
153
153
  private checkpointsMatch;
154
154
  private archiverFullyCovered;
155
155
  private isProvenChainEncompassing;
156
156
  private getL1Constants;
157
157
  }
158
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2Vzc2lvbi1tYW5hZ2VyLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvc2Vzc2lvbi1tYW5hZ2VyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBZSxLQUFLLFdBQVcsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBRWhGLE9BQU8sS0FBSyxFQUFFLFVBQVUsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBQ2hFLE9BQU8sRUFBZSxLQUFLLGNBQWMsRUFBZ0IsTUFBTSx1QkFBdUIsQ0FBQztBQUd2RixPQUFPLEtBQUssRUFBRSxZQUFZLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUM1RCxPQUFPLEtBQUssRUFBRSxrQkFBa0IsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQy9ELE9BQU8sS0FBSyxFQUFFLGFBQWEsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBUXpELE9BQU8sS0FBSyxFQUFFLG9CQUFvQixFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFFNUUsT0FBTyxLQUFLLEVBQUUsZUFBZSxFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDN0QsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDOUQsT0FBTyxLQUFLLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUMzRSxPQUFPLEVBQ0wsWUFBWSxFQUNaLEtBQUssZ0JBQWdCLEVBQ3JCLEtBQUssaUJBQWlCLEVBRXRCLEtBQUssV0FBVyxFQUVqQixNQUFNLHdCQUF3QixDQUFDO0FBQ2hDLE9BQU8sS0FBSyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sY0FBYyxDQUFDO0FBQ3pELE9BQU8sS0FBSyxFQUFFLHNCQUFzQixFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFFNUUsdUNBQXVDO0FBQ3ZDLE1BQU0sTUFBTSxnQkFBZ0IsR0FDeEI7SUFBRSxJQUFJLEVBQUUsWUFBWSxDQUFDO0lBQUMsS0FBSyxFQUFFLFdBQVcsQ0FBQTtDQUFFLEdBQzFD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
158
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2Vzc2lvbi1tYW5hZ2VyLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvc2Vzc2lvbi1tYW5hZ2VyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBZSxLQUFLLFdBQVcsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBRWhGLE9BQU8sS0FBSyxFQUFFLFVBQVUsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBQ2hFLE9BQU8sRUFBZSxLQUFLLGNBQWMsRUFBZ0IsTUFBTSx1QkFBdUIsQ0FBQztBQUd2RixPQUFPLEtBQUssRUFBRSxZQUFZLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUM1RCxPQUFPLEtBQUssRUFBRSxrQkFBa0IsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQy9ELE9BQU8sS0FBSyxFQUFFLGFBQWEsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBUXpELE9BQU8sS0FBSyxFQUFFLG9CQUFvQixFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFFNUUsT0FBTyxLQUFLLEVBQUUsZUFBZSxFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDN0QsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDOUQsT0FBTyxLQUFLLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUMzRSxPQUFPLEVBQ0wsWUFBWSxFQUNaLEtBQUssZ0JBQWdCLEVBQ3JCLEtBQUssaUJBQWlCLEVBRXRCLEtBQUssV0FBVyxFQUVqQixNQUFNLHdCQUF3QixDQUFDO0FBQ2hDLE9BQU8sS0FBSyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sY0FBYyxDQUFDO0FBQ3pELE9BQU8sS0FBSyxFQUFFLHNCQUFzQixFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFFNUUsdUNBQXVDO0FBQ3ZDLE1BQU0sTUFBTSxnQkFBZ0IsR0FDeEI7SUFBRSxJQUFJLEVBQUUsWUFBWSxDQUFDO0lBQUMsS0FBSyxFQUFFLFdBQVcsQ0FBQTtDQUFFLEdBQzFD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
@@ -1 +1 @@
1
- {"version":3,"file":"session-manager.d.ts","sourceRoot":"","sources":["../src/session-manager.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"session-manager.d.ts","sourceRoot":"","sources":["../src/session-manager.ts"],"names":[],"mappings":"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"}
@@ -109,7 +109,7 @@ import { EpochSession, specKey } from './job/epoch-session.js';
109
109
  * partial's spec stops at the last canonical slot, while the full's stops at the epoch's last
110
110
  * slot. Dedupes against any existing session covering the same range, returning its id.
111
111
  */ async startProof(epoch) {
112
- const canonical = await this.deps.checkpointStore.listCanonicalForEpoch(epoch);
112
+ const canonical = await this.deps.checkpointStore.listForEpoch(epoch);
113
113
  if (canonical.length === 0) {
114
114
  throw new EmptyEpochError(epoch);
115
115
  }
@@ -185,7 +185,7 @@ import { EpochSession, specKey } from './job/epoch-session.js';
185
185
  this.fullSessions.delete(key);
186
186
  continue;
187
187
  }
188
- const canonical = this.canonicalCheckpointsForSpec(session.getSpec());
188
+ const canonical = this.checkpointsForSpec(session.getSpec());
189
189
  if (!this.checkpointsMatch(session.getCheckpoints(), canonical)) {
190
190
  this.fireAndForgetCancel(session, 'canonical content changed');
191
191
  this.fullSessions.delete(key);
@@ -201,7 +201,7 @@ import { EpochSession, specKey } from './job/epoch-session.js';
201
201
  this.partialSessions.delete(key);
202
202
  continue;
203
203
  }
204
- const canonical = this.canonicalCheckpointsForSpec(session.getSpec());
204
+ const canonical = this.checkpointsForSpec(session.getSpec());
205
205
  if (!this.checkpointsMatch(session.getCheckpoints(), canonical)) {
206
206
  this.fireAndForgetCancel(session, 'canonical content changed');
207
207
  this.partialSessions.delete(key);
@@ -214,6 +214,8 @@ import { EpochSession, specKey } from './job/epoch-session.js';
214
214
  }
215
215
  }
216
216
  async openFullSessionIfReady(epoch) {
217
+ // `recreateInvalidSessions` runs at the top of every reconcile and deletes terminal sessions
218
+ // before this is called, so a session present here is live and already covers the epoch.
217
219
  if (this.fullSessions.has(epoch)) {
218
220
  return;
219
221
  }
@@ -232,7 +234,7 @@ import { EpochSession, specKey } from './job/epoch-session.js';
232
234
  return;
233
235
  }
234
236
  const [fromSlot, toSlot] = getSlotRangeForEpoch(epoch, l1Constants);
235
- const canonical = this.deps.checkpointStore.listCanonicalInSlotRange(fromSlot, toSlot);
237
+ const canonical = this.deps.checkpointStore.listInSlotRange(fromSlot, toSlot);
236
238
  if (!this.archiverFullyCovered(archiverCps, canonical)) {
237
239
  this.log.debug(`Skipping full-session open for epoch ${epoch}: archiver checkpoints not all in store`, {
238
240
  archiverCount: archiverCps.length,
@@ -251,7 +253,7 @@ import { EpochSession, specKey } from './job/epoch-session.js';
251
253
  void this.runSession(session);
252
254
  }
253
255
  openPartialSession(spec) {
254
- const canonical = this.deps.checkpointStore.listCanonicalInSlotRange(spec.fromSlot, spec.toSlot);
256
+ const canonical = this.deps.checkpointStore.listInSlotRange(spec.fromSlot, spec.toSlot);
255
257
  if (canonical.length === 0) {
256
258
  return;
257
259
  }
@@ -311,6 +313,17 @@ import { EpochSession, specKey } from './job/epoch-session.js';
311
313
  const state = await session.start();
312
314
  this.log.info(`Session ${session.getId()} exited with state ${state}`);
313
315
  if (state === 'failed' && this.deps.onSessionFailed) {
316
+ // Best-effort suppression of the spurious post-mortem upload a prune produces: if the session's
317
+ // checkpoints no longer match the store's current set, the failure was caused by the content
318
+ // changing under it, not a genuine proving fault, so skip the upload. This is inherently racy —
319
+ // the store lags the world-state unwind, so a fault observed before the prune is reconciled here
320
+ // still uploads. The epoch is recovered regardless by recreating the session on re-add.
321
+ if (!this.checkpointsMatch(session.getCheckpoints(), this.checkpointsForSpec(session.getSpec()))) {
322
+ this.log.info(`Skipping failure upload for session ${session.getId()}: canonical content changed`, {
323
+ ...session.getSpec()
324
+ });
325
+ return;
326
+ }
314
327
  try {
315
328
  await this.deps.onSessionFailed(session);
316
329
  } catch (err) {
@@ -350,7 +363,24 @@ import { EpochSession, specKey } from './job/epoch-session.js';
350
363
  const live = this.allSessions().filter((s)=>!s.isTerminal()).length;
351
364
  return live >= max;
352
365
  }
353
- async epochsForTrigger(trigger) {
366
+ /**
367
+ * Maps a reconcile trigger to the epochs whose full session should be (re)opened.
368
+ *
369
+ * This is where the "don't retry a genuinely-failed epoch, but do recover a pruned one" invariant
370
+ * lives — enforced by which triggers are gated by `lastTickEpoch`:
371
+ *
372
+ * - The periodic `tick` IS gated: once a tick has opened a session for an epoch, `lastTickEpoch`
373
+ * advances to it and later ticks skip it (`epoch <= lastTickEpoch`). So a failed attempt is never
374
+ * resubmitted on a loop by the tick.
375
+ * - `checkpoint` and `prune` are deliberately NOT gated. They only fire when the epoch's canonical
376
+ * content actually changes — a checkpoint arrives, or a reorg prunes/replaces one — which is
377
+ * exactly when re-attempting is correct.
378
+ *
379
+ * A genuine proving failure produces no content change, hence no checkpoint/prune event, so only
380
+ * the gated tick could reopen it — and it won't. A prune + re-add fires ungated events, so the
381
+ * epoch is reopened through this path (and `openFullSessionIfReady` rebuilds over the fresh
382
+ * provers). See the "onTick does not retry ... but recovers ... re-added" test.
383
+ */ async epochsForTrigger(trigger) {
354
384
  switch(trigger.kind){
355
385
  case 'checkpoint':
356
386
  return [
@@ -390,8 +420,8 @@ import { EpochSession, specKey } from './job/epoch-session.js';
390
420
  }
391
421
  return getEpochAtSlot(header.getSlot(), await this.getL1Constants());
392
422
  }
393
- canonicalCheckpointsForSpec(spec) {
394
- return this.deps.checkpointStore.listCanonicalInSlotRange(spec.fromSlot, spec.toSlot);
423
+ checkpointsForSpec(spec) {
424
+ return this.deps.checkpointStore.listInSlotRange(spec.fromSlot, spec.toSlot);
395
425
  }
396
426
  fireAndForgetCancel(session, reason) {
397
427
  void session.cancel(reason).catch((err)=>this.log.warn(`Error cancelling session ${session.getId()}`, err));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aztec/prover-node",
3
- "version": "5.0.0-rc.1",
3
+ "version": "5.0.0",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": "./dest/index.js",
@@ -56,28 +56,28 @@
56
56
  ]
57
57
  },
58
58
  "dependencies": {
59
- "@aztec/archiver": "5.0.0-rc.1",
60
- "@aztec/bb-prover": "5.0.0-rc.1",
61
- "@aztec/blob-client": "5.0.0-rc.1",
62
- "@aztec/blob-lib": "5.0.0-rc.1",
63
- "@aztec/constants": "5.0.0-rc.1",
64
- "@aztec/epoch-cache": "5.0.0-rc.1",
65
- "@aztec/ethereum": "5.0.0-rc.1",
66
- "@aztec/foundation": "5.0.0-rc.1",
67
- "@aztec/kv-store": "5.0.0-rc.1",
68
- "@aztec/l1-artifacts": "5.0.0-rc.1",
69
- "@aztec/native": "5.0.0-rc.1",
70
- "@aztec/node-keystore": "5.0.0-rc.1",
71
- "@aztec/node-lib": "5.0.0-rc.1",
72
- "@aztec/noir-protocol-circuits-types": "5.0.0-rc.1",
73
- "@aztec/p2p": "5.0.0-rc.1",
74
- "@aztec/protocol-contracts": "5.0.0-rc.1",
75
- "@aztec/prover-client": "5.0.0-rc.1",
76
- "@aztec/sequencer-client": "5.0.0-rc.1",
77
- "@aztec/simulator": "5.0.0-rc.1",
78
- "@aztec/stdlib": "5.0.0-rc.1",
79
- "@aztec/telemetry-client": "5.0.0-rc.1",
80
- "@aztec/world-state": "5.0.0-rc.1",
59
+ "@aztec/archiver": "5.0.0",
60
+ "@aztec/bb-prover": "5.0.0",
61
+ "@aztec/blob-client": "5.0.0",
62
+ "@aztec/blob-lib": "5.0.0",
63
+ "@aztec/constants": "5.0.0",
64
+ "@aztec/epoch-cache": "5.0.0",
65
+ "@aztec/ethereum": "5.0.0",
66
+ "@aztec/foundation": "5.0.0",
67
+ "@aztec/kv-store": "5.0.0",
68
+ "@aztec/l1-artifacts": "5.0.0",
69
+ "@aztec/native": "5.0.0",
70
+ "@aztec/node-keystore": "5.0.0",
71
+ "@aztec/node-lib": "5.0.0",
72
+ "@aztec/noir-protocol-circuits-types": "5.0.0",
73
+ "@aztec/p2p": "5.0.0",
74
+ "@aztec/protocol-contracts": "5.0.0",
75
+ "@aztec/prover-client": "5.0.0",
76
+ "@aztec/sequencer-client": "5.0.0",
77
+ "@aztec/simulator": "5.0.0",
78
+ "@aztec/stdlib": "5.0.0",
79
+ "@aztec/telemetry-client": "5.0.0",
80
+ "@aztec/world-state": "5.0.0",
81
81
  "source-map-support": "^0.5.21",
82
82
  "tslib": "^2.4.0",
83
83
  "viem": "npm:@aztec/viem@2.38.2"