@aztec/sequencer-client 0.0.1-commit.b64cb54f6 → 0.0.1-commit.b6e433891

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 (35) hide show
  1. package/dest/client/sequencer-client.d.ts +1 -12
  2. package/dest/client/sequencer-client.d.ts.map +1 -1
  3. package/dest/client/sequencer-client.js +19 -63
  4. package/dest/config.d.ts +4 -3
  5. package/dest/config.d.ts.map +1 -1
  6. package/dest/config.js +9 -2
  7. package/dest/global_variable_builder/global_builder.d.ts +1 -1
  8. package/dest/global_variable_builder/global_builder.d.ts.map +1 -1
  9. package/dest/global_variable_builder/global_builder.js +5 -4
  10. package/dest/publisher/sequencer-publisher.d.ts +6 -4
  11. package/dest/publisher/sequencer-publisher.d.ts.map +1 -1
  12. package/dest/publisher/sequencer-publisher.js +24 -8
  13. package/dest/sequencer/checkpoint_proposal_job.d.ts +12 -4
  14. package/dest/sequencer/checkpoint_proposal_job.d.ts.map +1 -1
  15. package/dest/sequencer/checkpoint_proposal_job.js +137 -93
  16. package/dest/sequencer/events.d.ts +2 -1
  17. package/dest/sequencer/events.d.ts.map +1 -1
  18. package/dest/sequencer/metrics.d.ts +5 -1
  19. package/dest/sequencer/metrics.d.ts.map +1 -1
  20. package/dest/sequencer/metrics.js +11 -0
  21. package/dest/sequencer/sequencer.d.ts +6 -4
  22. package/dest/sequencer/sequencer.d.ts.map +1 -1
  23. package/dest/sequencer/sequencer.js +57 -45
  24. package/dest/test/mock_checkpoint_builder.d.ts +4 -4
  25. package/dest/test/mock_checkpoint_builder.d.ts.map +1 -1
  26. package/package.json +27 -28
  27. package/src/client/sequencer-client.ts +26 -84
  28. package/src/config.ts +12 -1
  29. package/src/global_variable_builder/global_builder.ts +3 -2
  30. package/src/publisher/sequencer-publisher.ts +28 -10
  31. package/src/sequencer/checkpoint_proposal_job.ts +186 -96
  32. package/src/sequencer/events.ts +1 -1
  33. package/src/sequencer/metrics.ts +14 -0
  34. package/src/sequencer/sequencer.ts +82 -51
  35. package/src/test/mock_checkpoint_builder.ts +3 -3
@@ -446,9 +446,9 @@ import { Timer } from '@aztec/foundation/timer';
446
446
  import { isErrorClass, unfreeze } from '@aztec/foundation/types';
447
447
  import { CommitteeAttestationsAndSigners, MaliciousCommitteeAttestationsAndSigners } from '@aztec/stdlib/block';
448
448
  import { validateCheckpoint } from '@aztec/stdlib/checkpoint';
449
- import { getSlotStartBuildTimestamp } from '@aztec/stdlib/epoch-helpers';
449
+ import { getSlotStartBuildTimestamp, getTimestampForSlot } from '@aztec/stdlib/epoch-helpers';
450
450
  import { Gas } from '@aztec/stdlib/gas';
451
- import { NoValidTxsError } from '@aztec/stdlib/interfaces/server';
451
+ import { InsufficientValidTxsError } from '@aztec/stdlib/interfaces/server';
452
452
  import { computeInHashFromL1ToL2Messages } from '@aztec/stdlib/messaging';
453
453
  import { orderAttestations, trimAttestations } from '@aztec/stdlib/p2p';
454
454
  import { AttestationTimeoutError } from '@aztec/stdlib/validators';
@@ -462,7 +462,7 @@ _dec = trackSpan('CheckpointProposalJob.execute'), _dec1 = trackSpan('Checkpoint
462
462
  return {
463
463
  // nullish operator needed for tests
464
464
  [Attributes.COINBASE]: this.validatorClient.getCoinbaseForAttestor(this.attestorAddress)?.toString(),
465
- [Attributes.SLOT_NUMBER]: this.slot
465
+ [Attributes.SLOT_NUMBER]: this.targetSlot
466
466
  };
467
467
  }), _dec2 = trackSpan('CheckpointProposalJob.buildBlocksForCheckpoint'), _dec3 = trackSpan('CheckpointProposalJob.waitUntilNextSubslot'), _dec4 = trackSpan('CheckpointProposalJob.buildSingleBlock'), _dec5 = trackSpan('CheckpointProposalJob.waitForMinTxs'), _dec6 = trackSpan('CheckpointProposalJob.waitForAttestations'), _dec7 = trackSpan('CheckpointProposalJob.waitUntilTimeInSlot');
468
468
  /**
@@ -471,8 +471,10 @@ _dec = trackSpan('CheckpointProposalJob.execute'), _dec1 = trackSpan('Checkpoint
471
471
  * as well as enqueueing votes for slashing and governance proposals. This class is created from
472
472
  * the Sequencer once the check for being the proposer for the slot has succeeded.
473
473
  */ export class CheckpointProposalJob {
474
- epoch;
475
- slot;
474
+ slotNow;
475
+ targetSlot;
476
+ epochNow;
477
+ targetEpoch;
476
478
  checkpointNumber;
477
479
  syncedToBlockNumber;
478
480
  proposer;
@@ -542,10 +544,12 @@ _dec = trackSpan('CheckpointProposalJob.execute'), _dec1 = trackSpan('Checkpoint
542
544
  ], []));
543
545
  }
544
546
  log;
545
- constructor(epoch, slot, checkpointNumber, syncedToBlockNumber, // TODO(palla/mbps): Can we remove the proposer in favor of attestorAddress? Need to check fisherman-node flows.
547
+ constructor(slotNow, targetSlot, epochNow, targetEpoch, checkpointNumber, syncedToBlockNumber, // TODO(palla/mbps): Can we remove the proposer in favor of attestorAddress? Need to check fisherman-node flows.
546
548
  proposer, publisher, attestorAddress, invalidateCheckpoint, validatorClient, globalsBuilder, p2pClient, worldState, l1ToL2MessageSource, l2BlockSource, checkpointsBuilder, blockSink, l1Constants, config, timetable, slasherClient, epochCache, dateProvider, metrics, eventEmitter, setStateFn, tracer, bindings){
547
- this.epoch = epoch;
548
- this.slot = slot;
549
+ this.slotNow = slotNow;
550
+ this.targetSlot = targetSlot;
551
+ this.epochNow = epochNow;
552
+ this.targetEpoch = targetEpoch;
549
553
  this.checkpointNumber = checkpointNumber;
550
554
  this.syncedToBlockNumber = syncedToBlockNumber;
551
555
  this.proposer = proposer;
@@ -573,9 +577,15 @@ _dec = trackSpan('CheckpointProposalJob.execute'), _dec1 = trackSpan('Checkpoint
573
577
  _initProto(this);
574
578
  this.log = createLogger('sequencer:checkpoint-proposal', {
575
579
  ...bindings,
576
- instanceId: `slot-${slot}`
580
+ instanceId: `slot-${this.slotNow}`
577
581
  });
578
582
  }
583
+ /** The wall-clock slot during which the proposer builds. */ get slot() {
584
+ return this.slotNow;
585
+ }
586
+ /** The wall-clock epoch. */ get epoch() {
587
+ return this.epochNow;
588
+ }
579
589
  /**
580
590
  * Executes the checkpoint proposal job.
581
591
  * Returns the published checkpoint if successful, undefined otherwise.
@@ -583,7 +593,7 @@ _dec = trackSpan('CheckpointProposalJob.execute'), _dec1 = trackSpan('Checkpoint
583
593
  // Enqueue governance and slashing votes (returns promises that will be awaited later)
584
594
  // In fisherman mode, we simulate slashing but don't actually publish to L1
585
595
  // These are constant for the whole slot, so we only enqueue them once
586
- const votesPromises = new CheckpointVoter(this.slot, this.publisher, this.attestorAddress, this.validatorClient, this.slasherClient, this.l1Constants, this.config, this.metrics, this.log).enqueueVotes();
596
+ const votesPromises = new CheckpointVoter(this.targetSlot, this.publisher, this.attestorAddress, this.validatorClient, this.slasherClient, this.l1Constants, this.config, this.metrics, this.log).enqueueVotes();
587
597
  // Build and propose the checkpoint. This will enqueue the request on the publisher if a checkpoint is built.
588
598
  const checkpoint = await this.proposeCheckpoint();
589
599
  // Wait until the voting promises have resolved, so all requests are enqueued (not sent)
@@ -596,6 +606,24 @@ _dec = trackSpan('CheckpointProposalJob.execute'), _dec1 = trackSpan('Checkpoint
596
606
  await this.handleCheckpointEndAsFisherman(checkpoint);
597
607
  return;
598
608
  }
609
+ // If pipelining, wait until the submission slot so L1 recognizes the pipelined proposer
610
+ if (this.epochCache.isProposerPipeliningEnabled()) {
611
+ const submissionSlotTimestamp = getTimestampForSlot(this.targetSlot, this.l1Constants) - BigInt(this.l1Constants.ethereumSlotDuration);
612
+ this.log.info(`Waiting until submission slot ${this.targetSlot} for L1 submission`, {
613
+ slot: this.slot,
614
+ submissionSlot: this.targetSlot,
615
+ submissionSlotTimestamp
616
+ });
617
+ await sleepUntil(new Date(Number(submissionSlotTimestamp) * 1000), this.dateProvider.nowAsDate());
618
+ // After waking, verify the parent checkpoint wasn't pruned during the sleep.
619
+ // We check L1's pending tip directly instead of canProposeAt, which also validates the proposer
620
+ // identity and would fail because the timestamp resolves to a different slot's proposer.
621
+ const l1Tips = await this.publisher.rollupContract.getTips();
622
+ if (l1Tips.pending < this.checkpointNumber - 1) {
623
+ this.log.warn(`Parent checkpoint was pruned during pipelining sleep (L1 pending=${l1Tips.pending}, expected>=${this.checkpointNumber - 1}), skipping L1 submission for checkpoint ${this.checkpointNumber}`);
624
+ return undefined;
625
+ }
626
+ }
599
627
  // Then send everything to L1
600
628
  const l1Response = await this.publisher.sendRequests();
601
629
  const proposedAction = l1Response?.successfulActions.find((a)=>a === 'propose');
@@ -627,19 +655,26 @@ _dec = trackSpan('CheckpointProposalJob.execute'), _dec1 = trackSpan('Checkpoint
627
655
  const coinbase = this.validatorClient.getCoinbaseForAttestor(this.attestorAddress);
628
656
  const feeRecipient = this.validatorClient.getFeeRecipientForAttestor(this.attestorAddress);
629
657
  // Start the checkpoint
630
- this.setStateFn(SequencerState.INITIALIZING_CHECKPOINT, this.slot);
631
- this.metrics.incOpenSlot(this.slot, this.proposer?.toString() ?? 'unknown');
658
+ this.setStateFn(SequencerState.INITIALIZING_CHECKPOINT, this.targetSlot);
659
+ this.log.info(`Starting checkpoint proposal`, {
660
+ buildSlot: this.slot,
661
+ submissionSlot: this.targetSlot,
662
+ pipelining: this.epochCache.isProposerPipeliningEnabled(),
663
+ proposer: this.proposer?.toString(),
664
+ coinbase: coinbase.toString()
665
+ });
666
+ this.metrics.incOpenSlot(this.targetSlot, this.proposer?.toString() ?? 'unknown');
632
667
  // Enqueues checkpoint invalidation (constant for the whole slot)
633
668
  if (this.invalidateCheckpoint && !this.config.skipInvalidateBlockAsProposer) {
634
669
  this.publisher.enqueueInvalidateCheckpoint(this.invalidateCheckpoint);
635
670
  }
636
671
  // Create checkpoint builder for the slot
637
- const checkpointGlobalVariables = await this.globalsBuilder.buildCheckpointGlobalVariables(coinbase, feeRecipient, this.slot);
672
+ const checkpointGlobalVariables = await this.globalsBuilder.buildCheckpointGlobalVariables(coinbase, feeRecipient, this.targetSlot);
638
673
  // Collect L1 to L2 messages for the checkpoint and compute their hash
639
674
  const l1ToL2Messages = await this.l1ToL2MessageSource.getL1ToL2Messages(this.checkpointNumber);
640
675
  const inHash = computeInHashFromL1ToL2Messages(l1ToL2Messages);
641
676
  // Collect the out hashes of all the checkpoints before this one in the same epoch
642
- const previousCheckpointOutHashes = (await this.l2BlockSource.getCheckpointsDataForEpoch(this.epoch)).filter((c)=>c.checkpointNumber < this.checkpointNumber).map((c)=>c.checkpointOutHash);
677
+ const previousCheckpointOutHashes = (await this.l2BlockSource.getCheckpointsDataForEpoch(this.targetEpoch)).filter((c)=>c.checkpointNumber < this.checkpointNumber).map((c)=>c.checkpointOutHash);
643
678
  // Get the fee asset price modifier from the oracle
644
679
  const feeAssetPriceModifier = await this.publisher.getFeeAssetPriceModifier();
645
680
  const fork = _ts_add_disposable_resource(env, await this.worldState.fork(this.syncedToBlockNumber, {
@@ -674,18 +709,18 @@ _dec = trackSpan('CheckpointProposalJob.execute'), _dec1 = trackSpan('Checkpoint
674
709
  throw err;
675
710
  }
676
711
  if (blocksInCheckpoint.length === 0) {
677
- this.log.warn(`No blocks were built for slot ${this.slot}`, {
678
- slot: this.slot
712
+ this.log.warn(`No blocks were built for slot ${this.targetSlot}`, {
713
+ slot: this.targetSlot
679
714
  });
680
715
  this.eventEmitter.emit('checkpoint-empty', {
681
- slot: this.slot
716
+ slot: this.targetSlot
682
717
  });
683
718
  return undefined;
684
719
  }
685
720
  const minBlocksForCheckpoint = this.config.minBlocksForCheckpoint;
686
721
  if (minBlocksForCheckpoint !== undefined && blocksInCheckpoint.length < minBlocksForCheckpoint) {
687
722
  this.log.warn(`Checkpoint has fewer blocks than minimum (${blocksInCheckpoint.length} < ${minBlocksForCheckpoint}), skipping proposal`, {
688
- slot: this.slot,
723
+ slot: this.targetSlot,
689
724
  blocksBuilt: blocksInCheckpoint.length,
690
725
  minBlocksForCheckpoint
691
726
  });
@@ -693,9 +728,10 @@ _dec = trackSpan('CheckpointProposalJob.execute'), _dec1 = trackSpan('Checkpoint
693
728
  }
694
729
  // Assemble and broadcast the checkpoint proposal, including the last block that was not
695
730
  // broadcasted yet, and wait to collect the committee attestations.
696
- this.setStateFn(SequencerState.ASSEMBLING_CHECKPOINT, this.slot);
731
+ this.setStateFn(SequencerState.ASSEMBLING_CHECKPOINT, this.targetSlot);
697
732
  const checkpoint = await checkpointBuilder.completeCheckpoint();
698
- // Final validation round for the checkpoint before we propose it, just for safety
733
+ // Final validation: per-block limits are only checked if the operator set them explicitly.
734
+ // Otherwise, checkpoint-level budgets were already enforced by the redistribution logic.
699
735
  try {
700
736
  validateCheckpoint(checkpoint, {
701
737
  rollupManaLimit: this.l1Constants.rollupManaLimit,
@@ -714,8 +750,8 @@ _dec = trackSpan('CheckpointProposalJob.execute'), _dec1 = trackSpan('Checkpoint
714
750
  this.metrics.recordCheckpointBuild(checkpointBuildTimer.ms(), blocksInCheckpoint.length, checkpoint.getStats().txCount, Number(checkpoint.header.totalManaUsed.toBigInt()));
715
751
  // Do not collect attestations nor publish to L1 in fisherman mode
716
752
  if (this.config.fishermanMode) {
717
- this.log.info(`Built checkpoint for slot ${this.slot} with ${blocksInCheckpoint.length} blocks. ` + `Skipping proposal in fisherman mode.`, {
718
- slot: this.slot,
753
+ this.log.info(`Built checkpoint for slot ${this.targetSlot} with ${blocksInCheckpoint.length} blocks. ` + `Skipping proposal in fisherman mode.`, {
754
+ slot: this.targetSlot,
719
755
  checkpoint: checkpoint.header.toInspect(),
720
756
  blocksBuilt: blocksInCheckpoint.length
721
757
  });
@@ -732,7 +768,7 @@ _dec = trackSpan('CheckpointProposalJob.execute'), _dec1 = trackSpan('Checkpoint
732
768
  const proposal = await this.validatorClient.createCheckpointProposal(checkpoint.header, checkpoint.archive.root, feeAssetPriceModifier, lastBlock, this.proposer, checkpointProposalOptions);
733
769
  const blockProposedAt = this.dateProvider.now();
734
770
  await this.p2pClient.broadcastCheckpointProposal(proposal);
735
- this.setStateFn(SequencerState.COLLECTING_ATTESTATIONS, this.slot);
771
+ this.setStateFn(SequencerState.COLLECTING_ATTESTATIONS, this.targetSlot);
736
772
  const attestations = await this.waitForAttestations(proposal);
737
773
  const blockAttestedAt = this.dateProvider.now();
738
774
  this.metrics.recordCheckpointAttestationDelay(blockAttestedAt - blockProposedAt);
@@ -740,7 +776,7 @@ _dec = trackSpan('CheckpointProposalJob.execute'), _dec1 = trackSpan('Checkpoint
740
776
  const signer = this.proposer ?? this.publisher.getSenderAddress();
741
777
  let attestationsSignature;
742
778
  try {
743
- attestationsSignature = await this.validatorClient.signAttestationsAndSigners(attestations, signer, this.slot, this.checkpointNumber);
779
+ attestationsSignature = await this.validatorClient.signAttestationsAndSigners(attestations, signer, this.targetSlot, this.checkpointNumber);
744
780
  } catch (err) {
745
781
  // We shouldn't really get here since we yield to another HA node
746
782
  // as soon as we see these errors when creating block or checkpoint proposals.
@@ -750,10 +786,10 @@ _dec = trackSpan('CheckpointProposalJob.execute'), _dec1 = trackSpan('Checkpoint
750
786
  throw err;
751
787
  }
752
788
  // Enqueue publishing the checkpoint to L1
753
- this.setStateFn(SequencerState.PUBLISHING_CHECKPOINT, this.slot);
789
+ this.setStateFn(SequencerState.PUBLISHING_CHECKPOINT, this.targetSlot);
754
790
  const aztecSlotDuration = this.l1Constants.slotDuration;
755
- const slotStartBuildTimestamp = this.getSlotStartBuildTimestamp();
756
- const txTimeoutAt = new Date((slotStartBuildTimestamp + aztecSlotDuration) * 1000);
791
+ const submissionSlotStart = Number(getTimestampForSlot(this.targetSlot, this.l1Constants));
792
+ const txTimeoutAt = new Date((submissionSlotStart + aztecSlotDuration) * 1000);
757
793
  // If we have been configured to potentially skip publishing checkpoint then roll the dice here
758
794
  if (this.config.skipPublishingCheckpointsPercent !== undefined && this.config.skipPublishingCheckpointsPercent > 0) {
759
795
  const result = Math.max(0, randomInt(100));
@@ -799,7 +835,7 @@ _dec = trackSpan('CheckpointProposalJob.execute'), _dec1 = trackSpan('Checkpoint
799
835
  const timingInfo = this.timetable.canStartNextBlock(secondsIntoSlot);
800
836
  if (!timingInfo.canStart) {
801
837
  this.log.debug(`Not enough time left in slot to start another block`, {
802
- slot: this.slot,
838
+ slot: this.targetSlot,
803
839
  blocksBuilt,
804
840
  secondsIntoSlot
805
841
  });
@@ -828,8 +864,8 @@ _dec = trackSpan('CheckpointProposalJob.execute'), _dec1 = trackSpan('Checkpoint
828
864
  } else if ('error' in buildResult) {
829
865
  // If there was an error building the block, just exit the loop and give up the rest of the slot
830
866
  if (!(buildResult.error instanceof SequencerInterruptedError)) {
831
- this.log.warn(`Halting block building for slot ${this.slot}`, {
832
- slot: this.slot,
867
+ this.log.warn(`Halting block building for slot ${this.targetSlot}`, {
868
+ slot: this.targetSlot,
833
869
  blocksBuilt,
834
870
  error: buildResult.error
835
871
  });
@@ -838,21 +874,13 @@ _dec = trackSpan('CheckpointProposalJob.execute'), _dec1 = trackSpan('Checkpoint
838
874
  }
839
875
  const { block, usedTxs } = buildResult;
840
876
  blocksInCheckpoint.push(block);
841
- // Sync the proposed block to the archiver to make it available
842
- // Note that the checkpoint builder uses its own fork so it should not need to wait for this syncing
843
- // Eventually we should refactor the checkpoint builder to not need a separate long-lived fork
844
- // Fire and forget - don't block the critical path, but log errors
845
- this.syncProposedBlockToArchiver(block).catch((err)=>{
846
- this.log.error(`Failed to sync proposed block ${block.number} to archiver`, {
847
- blockNumber: block.number,
848
- err
849
- });
850
- });
851
877
  usedTxs.forEach((tx)=>txHashesAlreadyIncluded.add(tx.txHash.toString()));
852
- // If this is the last block, exit the loop now so we start collecting attestations
878
+ // If this is the last block, sync it to the archiver and exit the loop
879
+ // so we can build the checkpoint and start collecting attestations.
853
880
  if (timingInfo.isLastBlock) {
854
- this.log.verbose(`Completed final block ${blockNumber} for slot ${this.slot}`, {
855
- slot: this.slot,
881
+ await this.syncProposedBlockToArchiver(block);
882
+ this.log.verbose(`Completed final block ${blockNumber} for slot ${this.targetSlot}`, {
883
+ slot: this.targetSlot,
856
884
  blockNumber,
857
885
  blocksBuilt
858
886
  });
@@ -862,17 +890,22 @@ _dec = trackSpan('CheckpointProposalJob.execute'), _dec1 = trackSpan('Checkpoint
862
890
  };
863
891
  break;
864
892
  }
865
- // For non-last blocks, broadcast the block proposal (unless we're in fisherman mode)
866
- // If the block is the last one, we'll broadcast it along with the checkpoint at the end of the loop
867
- if (!this.config.fishermanMode) {
868
- const proposal = await this.validatorClient.createBlockProposal(block.header, block.indexWithinCheckpoint, inHash, block.archive.root, usedTxs, this.proposer, blockProposalOptions);
869
- await this.p2pClient.broadcastProposal(proposal);
870
- }
893
+ // Broadcast the block proposal (unless we're in fisherman mode) unless the block is the last one,
894
+ // in which case we'll broadcast it along with the checkpoint at the end of the loop.
895
+ // Note that we only send the block to the archiver if we manage to create the proposal, so if there's
896
+ // a HA error we don't pollute our archiver with a block that won't make it to the chain.
897
+ const proposal = await this.createBlockProposal(block, inHash, usedTxs, blockProposalOptions);
898
+ // Sync the proposed block to the archiver to make it available, only after we've managed to sign the proposal.
899
+ // We wait for the sync to succeed, as this helps catch consistency errors, even if it means we lose some time for block-building.
900
+ // If this throws, we abort the entire checkpoint.
901
+ await this.syncProposedBlockToArchiver(block);
902
+ // Once we have a signed proposal and the archiver agreed with our proposed block, then we broadcast it.
903
+ proposal && await this.p2pClient.broadcastProposal(proposal);
871
904
  // Wait until the next block's start time
872
905
  await this.waitUntilNextSubslot(timingInfo.deadline);
873
906
  }
874
- this.log.verbose(`Block building loop completed for slot ${this.slot}`, {
875
- slot: this.slot,
907
+ this.log.verbose(`Block building loop completed for slot ${this.targetSlot}`, {
908
+ slot: this.targetSlot,
876
909
  blocksBuilt: blocksInCheckpoint.length
877
910
  });
878
911
  return {
@@ -880,16 +913,23 @@ _dec = trackSpan('CheckpointProposalJob.execute'), _dec1 = trackSpan('Checkpoint
880
913
  blockPendingBroadcast
881
914
  };
882
915
  }
916
+ /** Creates a block proposal for a given block via the validator client (unless in fisherman mode) */ createBlockProposal(block, inHash, usedTxs, blockProposalOptions) {
917
+ if (this.config.fishermanMode) {
918
+ this.log.info(`Skipping block proposal for block ${block.number} in fisherman mode`);
919
+ return Promise.resolve(undefined);
920
+ }
921
+ return this.validatorClient.createBlockProposal(block.header, block.indexWithinCheckpoint, inHash, block.archive.root, usedTxs, this.proposer, blockProposalOptions);
922
+ }
883
923
  /** Sleeps until it is time to produce the next block in the slot */ async waitUntilNextSubslot(nextSubslotStart) {
884
- this.setStateFn(SequencerState.WAITING_UNTIL_NEXT_BLOCK, this.slot);
924
+ this.setStateFn(SequencerState.WAITING_UNTIL_NEXT_BLOCK, this.targetSlot);
885
925
  this.log.verbose(`Waiting until time for the next block at ${nextSubslotStart}s into slot`, {
886
- slot: this.slot
926
+ slot: this.targetSlot
887
927
  });
888
928
  await this.waitUntilTimeInSlot(nextSubslotStart);
889
929
  }
890
930
  /** Builds a single block. Called from the main block building loop. */ async buildSingleBlock(checkpointBuilder, opts) {
891
931
  const { blockTimestamp, forceCreate, blockNumber, indexWithinCheckpoint, buildDeadline, txHashesAlreadyIncluded } = opts;
892
- this.log.verbose(`Preparing block ${blockNumber} index ${indexWithinCheckpoint} at checkpoint ${this.checkpointNumber} for slot ${this.slot}`, {
932
+ this.log.verbose(`Preparing block ${blockNumber} index ${indexWithinCheckpoint} at checkpoint ${this.checkpointNumber} for slot ${this.targetSlot}`, {
893
933
  ...checkpointBuilder.getConstantData(),
894
934
  ...opts
895
935
  });
@@ -897,15 +937,15 @@ _dec = trackSpan('CheckpointProposalJob.execute'), _dec1 = trackSpan('Checkpoint
897
937
  // Wait until we have enough txs to build the block
898
938
  const { availableTxs, canStartBuilding, minTxs } = await this.waitForMinTxs(opts);
899
939
  if (!canStartBuilding) {
900
- this.log.warn(`Not enough txs to build block ${blockNumber} at index ${indexWithinCheckpoint} in slot ${this.slot} (got ${availableTxs} txs but needs ${minTxs})`, {
940
+ this.log.warn(`Not enough txs to build block ${blockNumber} at index ${indexWithinCheckpoint} in slot ${this.targetSlot} (got ${availableTxs} txs but needs ${minTxs})`, {
901
941
  blockNumber,
902
- slot: this.slot,
942
+ slot: this.targetSlot,
903
943
  indexWithinCheckpoint
904
944
  });
905
945
  this.eventEmitter.emit('block-tx-count-check-failed', {
906
946
  minTxs,
907
947
  availableTxs,
908
- slot: this.slot
948
+ slot: this.targetSlot
909
949
  });
910
950
  this.metrics.recordBlockProposalFailed('insufficient_txs');
911
951
  return undefined;
@@ -913,46 +953,48 @@ _dec = trackSpan('CheckpointProposalJob.execute'), _dec1 = trackSpan('Checkpoint
913
953
  // Create iterator to pending txs. We filter out txs already included in previous blocks in the checkpoint
914
954
  // just in case p2p failed to sync the provisional block and didn't get to remove those txs from the mempool yet.
915
955
  const pendingTxs = filter(this.p2pClient.iterateEligiblePendingTxs(), (tx)=>!txHashesAlreadyIncluded.has(tx.txHash.toString()));
916
- this.log.debug(`Building block ${blockNumber} at index ${indexWithinCheckpoint} for slot ${this.slot} with ${availableTxs} available txs`, {
917
- slot: this.slot,
956
+ this.log.debug(`Building block ${blockNumber} at index ${indexWithinCheckpoint} for slot ${this.targetSlot} with ${availableTxs} available txs`, {
957
+ slot: this.targetSlot,
918
958
  blockNumber,
919
959
  indexWithinCheckpoint
920
960
  });
921
- this.setStateFn(SequencerState.CREATING_BLOCK, this.slot);
922
- // Per-block limits derived at startup by computeBlockLimits(), further capped
961
+ this.setStateFn(SequencerState.CREATING_BLOCK, this.targetSlot);
962
+ // Per-block limits are operator overrides (from SEQ_MAX_L2_BLOCK_GAS etc.) further capped
923
963
  // by remaining checkpoint-level budgets inside CheckpointBuilder before each block is built.
964
+ // minValidTxs is passed into the builder so it can reject the block *before* updating state.
965
+ const minValidTxs = forceCreate ? 0 : this.config.minValidTxsPerBlock ?? minTxs;
924
966
  const blockBuilderOptions = {
925
967
  maxTransactions: this.config.maxTxsPerBlock,
926
968
  maxBlockGas: this.config.maxL2BlockGas !== undefined || this.config.maxDABlockGas !== undefined ? new Gas(this.config.maxDABlockGas ?? Infinity, this.config.maxL2BlockGas ?? Infinity) : undefined,
927
969
  deadline: buildDeadline,
928
- isBuildingProposal: true
970
+ isBuildingProposal: true,
971
+ minValidTxs,
972
+ maxBlocksPerCheckpoint: this.timetable.maxNumberOfBlocks,
973
+ perBlockAllocationMultiplier: this.config.perBlockAllocationMultiplier
929
974
  };
930
- // Actually build the block by executing txs
975
+ // Actually build the block by executing txs. The builder throws InsufficientValidTxsError
976
+ // if the number of successfully processed txs is below minValidTxs, ensuring state is not
977
+ // updated for blocks that will be discarded.
931
978
  const buildResult = await this.buildSingleBlockWithCheckpointBuilder(checkpointBuilder, pendingTxs, blockNumber, blockTimestamp, blockBuilderOptions);
932
979
  // If any txs failed during execution, drop them from the mempool so we don't pick them up again
933
980
  await this.dropFailedTxsFromP2P(buildResult.failedTxs);
934
- // Check if we have created a block with enough txs. If there were invalid txs in the pool, or if execution took
935
- // too long, then we may not get to minTxsPerBlock after executing public functions.
936
- const minValidTxs = this.config.minValidTxsPerBlock ?? minTxs;
937
- const numTxs = buildResult.status === 'no-valid-txs' ? 0 : buildResult.numTxs;
938
- if (buildResult.status === 'no-valid-txs' || !forceCreate && numTxs < minValidTxs) {
939
- this.log.warn(`Block ${blockNumber} at index ${indexWithinCheckpoint} on slot ${this.slot} has too few valid txs to be proposed`, {
940
- slot: this.slot,
981
+ if (buildResult.status === 'insufficient-valid-txs') {
982
+ this.log.warn(`Block ${blockNumber} at index ${indexWithinCheckpoint} on slot ${this.targetSlot} has too few valid txs to be proposed`, {
983
+ slot: this.targetSlot,
941
984
  blockNumber,
942
- numTxs,
985
+ numTxs: buildResult.processedCount,
943
986
  indexWithinCheckpoint,
944
- minValidTxs,
945
- buildResult: buildResult.status
987
+ minValidTxs
946
988
  });
947
989
  this.eventEmitter.emit('block-build-failed', {
948
990
  reason: `Insufficient valid txs`,
949
- slot: this.slot
991
+ slot: this.targetSlot
950
992
  });
951
993
  this.metrics.recordBlockProposalFailed('insufficient_valid_txs');
952
994
  return undefined;
953
995
  }
954
996
  // Block creation succeeded, emit stats and metrics
955
- const { block, publicProcessorDuration, usedTxs, blockBuildDuration } = buildResult;
997
+ const { block, publicProcessorDuration, usedTxs, blockBuildDuration, numTxs } = buildResult;
956
998
  const blockStats = {
957
999
  eventName: 'l2-block-built',
958
1000
  duration: blockBuildDuration,
@@ -962,7 +1004,7 @@ _dec = trackSpan('CheckpointProposalJob.execute'), _dec1 = trackSpan('Checkpoint
962
1004
  const blockHash = await block.hash();
963
1005
  const txHashes = block.body.txEffects.map((tx)=>tx.txHash);
964
1006
  const manaPerSec = block.header.totalManaUsed.toNumberUnsafe() / (blockBuildDuration / 1000);
965
- this.log.info(`Built block ${block.number} at checkpoint ${this.checkpointNumber} for slot ${this.slot} with ${numTxs} txs`, {
1007
+ this.log.info(`Built block ${block.number} at checkpoint ${this.checkpointNumber} for slot ${this.targetSlot} with ${numTxs} txs`, {
966
1008
  blockHash,
967
1009
  txHashes,
968
1010
  manaPerSec,
@@ -970,7 +1012,8 @@ _dec = trackSpan('CheckpointProposalJob.execute'), _dec1 = trackSpan('Checkpoint
970
1012
  });
971
1013
  this.eventEmitter.emit('block-proposed', {
972
1014
  blockNumber: block.number,
973
- slot: this.slot
1015
+ slot: this.targetSlot,
1016
+ buildSlot: this.slotNow
974
1017
  });
975
1018
  this.metrics.recordBuiltBlock(blockBuildDuration, block.header.totalManaUsed.toNumberUnsafe());
976
1019
  return {
@@ -980,11 +1023,11 @@ _dec = trackSpan('CheckpointProposalJob.execute'), _dec1 = trackSpan('Checkpoint
980
1023
  } catch (err) {
981
1024
  this.eventEmitter.emit('block-build-failed', {
982
1025
  reason: err.message,
983
- slot: this.slot
1026
+ slot: this.targetSlot
984
1027
  });
985
1028
  this.log.error(`Error building block`, err, {
986
1029
  blockNumber,
987
- slot: this.slot
1030
+ slot: this.targetSlot
988
1031
  });
989
1032
  this.metrics.recordBlockProposalFailed(err.name || 'unknown_error');
990
1033
  this.metrics.recordFailedBlock();
@@ -993,7 +1036,7 @@ _dec = trackSpan('CheckpointProposalJob.execute'), _dec1 = trackSpan('Checkpoint
993
1036
  };
994
1037
  }
995
1038
  }
996
- /** Uses the checkpoint builder to build a block, catching specific txs */ async buildSingleBlockWithCheckpointBuilder(checkpointBuilder, pendingTxs, blockNumber, blockTimestamp, blockBuilderOptions) {
1039
+ /** Uses the checkpoint builder to build a block, catching InsufficientValidTxsError. */ async buildSingleBlockWithCheckpointBuilder(checkpointBuilder, pendingTxs, blockNumber, blockTimestamp, blockBuilderOptions) {
997
1040
  try {
998
1041
  const workTimer = new Timer();
999
1042
  const result = await checkpointBuilder.buildBlock(pendingTxs, blockNumber, blockTimestamp, blockBuilderOptions);
@@ -1004,10 +1047,11 @@ _dec = trackSpan('CheckpointProposalJob.execute'), _dec1 = trackSpan('Checkpoint
1004
1047
  status: 'success'
1005
1048
  };
1006
1049
  } catch (err) {
1007
- if (isErrorClass(err, NoValidTxsError)) {
1050
+ if (isErrorClass(err, InsufficientValidTxsError)) {
1008
1051
  return {
1009
1052
  failedTxs: err.failedTxs,
1010
- status: 'no-valid-txs'
1053
+ processedCount: err.processedCount,
1054
+ status: 'insufficient-valid-txs'
1011
1055
  };
1012
1056
  }
1013
1057
  throw err;
@@ -1031,10 +1075,10 @@ _dec = trackSpan('CheckpointProposalJob.execute'), _dec1 = trackSpan('Checkpoint
1031
1075
  };
1032
1076
  }
1033
1077
  // Wait a bit before checking again
1034
- this.setStateFn(SequencerState.WAITING_FOR_TXS, this.slot);
1035
- this.log.verbose(`Waiting for enough txs to build block ${blockNumber} at index ${indexWithinCheckpoint} in slot ${this.slot} (have ${availableTxs} but need ${minTxs})`, {
1078
+ this.setStateFn(SequencerState.WAITING_FOR_TXS, this.targetSlot);
1079
+ this.log.verbose(`Waiting for enough txs to build block ${blockNumber} at index ${indexWithinCheckpoint} in slot ${this.targetSlot} (have ${availableTxs} but need ${minTxs})`, {
1036
1080
  blockNumber,
1037
- slot: this.slot,
1081
+ slot: this.targetSlot,
1038
1082
  indexWithinCheckpoint
1039
1083
  });
1040
1084
  await this.waitForTxsPollingInterval();
@@ -1188,16 +1232,16 @@ _dec = trackSpan('CheckpointProposalJob.execute'), _dec1 = trackSpan('Checkpoint
1188
1232
  /** Runs fee analysis and logs checkpoint outcome as fisherman */ async handleCheckpointEndAsFisherman(checkpoint) {
1189
1233
  // Perform L1 fee analysis before clearing requests
1190
1234
  // The callback is invoked asynchronously after the next block is mined
1191
- const feeAnalysis = await this.publisher.analyzeL1Fees(this.slot, (analysis)=>this.metrics.recordFishermanFeeAnalysis(analysis));
1235
+ const feeAnalysis = await this.publisher.analyzeL1Fees(this.targetSlot, (analysis)=>this.metrics.recordFishermanFeeAnalysis(analysis));
1192
1236
  if (checkpoint) {
1193
- this.log.info(`Validation checkpoint building SUCCEEDED for slot ${this.slot}`, {
1237
+ this.log.info(`Validation checkpoint building SUCCEEDED for slot ${this.targetSlot}`, {
1194
1238
  ...checkpoint.toCheckpointInfo(),
1195
1239
  ...checkpoint.getStats(),
1196
1240
  feeAnalysisId: feeAnalysis?.id
1197
1241
  });
1198
1242
  } else {
1199
- this.log.warn(`Validation block building FAILED for slot ${this.slot}`, {
1200
- slot: this.slot,
1243
+ this.log.warn(`Validation block building FAILED for slot ${this.targetSlot}`, {
1244
+ slot: this.targetSlot,
1201
1245
  feeAnalysisId: feeAnalysis?.id
1202
1246
  });
1203
1247
  this.metrics.recordCheckpointProposalFailed('block_build_failed');
@@ -1208,15 +1252,15 @@ _dec = trackSpan('CheckpointProposalJob.execute'), _dec1 = trackSpan('Checkpoint
1208
1252
  * Helper to handle HA double-signing errors. Returns true if the error was handled (caller should yield).
1209
1253
  */ handleHASigningError(err, errorContext) {
1210
1254
  if (err instanceof DutyAlreadySignedError) {
1211
- this.log.info(`${errorContext} for slot ${this.slot} already signed by another HA node, yielding`, {
1212
- slot: this.slot,
1255
+ this.log.info(`${errorContext} for slot ${this.targetSlot} already signed by another HA node, yielding`, {
1256
+ slot: this.targetSlot,
1213
1257
  signedByNode: err.signedByNode
1214
1258
  });
1215
1259
  return true;
1216
1260
  }
1217
1261
  if (err instanceof SlashingProtectionError) {
1218
- this.log.info(`${errorContext} for slot ${this.slot} blocked by slashing protection, yielding`, {
1219
- slot: this.slot,
1262
+ this.log.info(`${errorContext} for slot ${this.targetSlot} blocked by slashing protection, yielding`, {
1263
+ slot: this.targetSlot,
1220
1264
  existingMessageHash: err.existingMessageHash,
1221
1265
  attemptedMessageHash: err.attemptedMessageHash
1222
1266
  });
@@ -24,6 +24,7 @@ export type SequencerEvents = {
24
24
  ['block-proposed']: (args: {
25
25
  blockNumber: BlockNumber;
26
26
  slot: SlotNumber;
27
+ buildSlot: SlotNumber;
27
28
  }) => void;
28
29
  ['checkpoint-empty']: (args: {
29
30
  slot: SlotNumber;
@@ -43,4 +44,4 @@ export type SequencerEvents = {
43
44
  error: Error;
44
45
  }) => void;
45
46
  };
46
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXZlbnRzLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc2VxdWVuY2VyL2V2ZW50cy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssRUFBRSxXQUFXLEVBQUUsZ0JBQWdCLEVBQUUsVUFBVSxFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFFakcsT0FBTyxLQUFLLEVBQUUsTUFBTSxFQUFFLE1BQU0scUNBQXFDLENBQUM7QUFDbEUsT0FBTyxLQUFLLEVBQUUsY0FBYyxFQUFFLE1BQU0sWUFBWSxDQUFDO0FBRWpELE1BQU0sTUFBTSxlQUFlLEdBQUc7SUFDNUIsQ0FBQyxlQUFlLENBQUMsRUFBRSxDQUFDLElBQUksRUFBRTtRQUN4QixRQUFRLEVBQUUsY0FBYyxDQUFDO1FBQ3pCLFFBQVEsRUFBRSxjQUFjLENBQUM7UUFDekIsZUFBZSxDQUFDLEVBQUUsTUFBTSxDQUFDO1FBQ3pCLElBQUksQ0FBQyxFQUFFLFVBQVUsQ0FBQztLQUNuQixLQUFLLElBQUksQ0FBQztJQUNYLENBQUMsOEJBQThCLENBQUMsRUFBRSxDQUFDLElBQUksRUFBRTtRQUFFLE1BQU0sRUFBRSxNQUFNLENBQUM7UUFBQyxJQUFJLEVBQUUsVUFBVSxDQUFBO0tBQUUsS0FBSyxJQUFJLENBQUM7SUFDdkYsQ0FBQyw2QkFBNkIsQ0FBQyxFQUFFLENBQUMsSUFBSSxFQUFFO1FBQUUsTUFBTSxFQUFFLE1BQU0sQ0FBQztRQUFDLFlBQVksRUFBRSxNQUFNLENBQUM7UUFBQyxJQUFJLEVBQUUsVUFBVSxDQUFBO0tBQUUsS0FBSyxJQUFJLENBQUM7SUFDNUcsQ0FBQyxvQkFBb0IsQ0FBQyxFQUFFLENBQUMsSUFBSSxFQUFFO1FBQUUsTUFBTSxFQUFFLE1BQU0sQ0FBQztRQUFDLElBQUksRUFBRSxVQUFVLENBQUE7S0FBRSxLQUFLLElBQUksQ0FBQztJQUM3RSxDQUFDLGdCQUFnQixDQUFDLEVBQUUsQ0FBQyxJQUFJLEVBQUU7UUFBRSxXQUFXLEVBQUUsV0FBVyxDQUFDO1FBQUMsSUFBSSxFQUFFLFVBQVUsQ0FBQTtLQUFFLEtBQUssSUFBSSxDQUFDO0lBQ25GLENBQUMsa0JBQWtCLENBQUMsRUFBRSxDQUFDLElBQUksRUFBRTtRQUFFLElBQUksRUFBRSxVQUFVLENBQUE7S0FBRSxLQUFLLElBQUksQ0FBQztJQUMzRCxDQUFDLDJCQUEyQixDQUFDLEVBQUUsQ0FBQyxJQUFJLEVBQUU7UUFDcEMsSUFBSSxFQUFFLFVBQVUsQ0FBQztRQUNqQixpQkFBaUIsQ0FBQyxFQUFFLE1BQU0sRUFBRSxDQUFDO1FBQzdCLGFBQWEsQ0FBQyxFQUFFLE1BQU0sRUFBRSxDQUFDO1FBQ3pCLFdBQVcsQ0FBQyxFQUFFLE1BQU0sRUFBRSxDQUFDO1FBQ3ZCLGNBQWMsQ0FBQyxFQUFFLE1BQU0sRUFBRSxDQUFDO0tBQzNCLEtBQUssSUFBSSxDQUFDO0lBQ1gsQ0FBQyxzQkFBc0IsQ0FBQyxFQUFFLENBQUMsSUFBSSxFQUFFO1FBQUUsVUFBVSxFQUFFLGdCQUFnQixDQUFDO1FBQUMsSUFBSSxFQUFFLFVBQVUsQ0FBQTtLQUFFLEtBQUssSUFBSSxDQUFDO0lBQzdGLENBQUMsa0JBQWtCLENBQUMsRUFBRSxDQUFDLElBQUksRUFBRTtRQUFFLEtBQUssRUFBRSxLQUFLLENBQUE7S0FBRSxLQUFLLElBQUksQ0FBQztDQUN4RCxDQUFDIn0=
47
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXZlbnRzLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc2VxdWVuY2VyL2V2ZW50cy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssRUFBRSxXQUFXLEVBQUUsZ0JBQWdCLEVBQUUsVUFBVSxFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFFakcsT0FBTyxLQUFLLEVBQUUsTUFBTSxFQUFFLE1BQU0scUNBQXFDLENBQUM7QUFDbEUsT0FBTyxLQUFLLEVBQUUsY0FBYyxFQUFFLE1BQU0sWUFBWSxDQUFDO0FBRWpELE1BQU0sTUFBTSxlQUFlLEdBQUc7SUFDNUIsQ0FBQyxlQUFlLENBQUMsRUFBRSxDQUFDLElBQUksRUFBRTtRQUN4QixRQUFRLEVBQUUsY0FBYyxDQUFDO1FBQ3pCLFFBQVEsRUFBRSxjQUFjLENBQUM7UUFDekIsZUFBZSxDQUFDLEVBQUUsTUFBTSxDQUFDO1FBQ3pCLElBQUksQ0FBQyxFQUFFLFVBQVUsQ0FBQztLQUNuQixLQUFLLElBQUksQ0FBQztJQUNYLENBQUMsOEJBQThCLENBQUMsRUFBRSxDQUFDLElBQUksRUFBRTtRQUFFLE1BQU0sRUFBRSxNQUFNLENBQUM7UUFBQyxJQUFJLEVBQUUsVUFBVSxDQUFBO0tBQUUsS0FBSyxJQUFJLENBQUM7SUFDdkYsQ0FBQyw2QkFBNkIsQ0FBQyxFQUFFLENBQUMsSUFBSSxFQUFFO1FBQUUsTUFBTSxFQUFFLE1BQU0sQ0FBQztRQUFDLFlBQVksRUFBRSxNQUFNLENBQUM7UUFBQyxJQUFJLEVBQUUsVUFBVSxDQUFBO0tBQUUsS0FBSyxJQUFJLENBQUM7SUFDNUcsQ0FBQyxvQkFBb0IsQ0FBQyxFQUFFLENBQUMsSUFBSSxFQUFFO1FBQUUsTUFBTSxFQUFFLE1BQU0sQ0FBQztRQUFDLElBQUksRUFBRSxVQUFVLENBQUE7S0FBRSxLQUFLLElBQUksQ0FBQztJQUM3RSxDQUFDLGdCQUFnQixDQUFDLEVBQUUsQ0FBQyxJQUFJLEVBQUU7UUFBRSxXQUFXLEVBQUUsV0FBVyxDQUFDO1FBQUMsSUFBSSxFQUFFLFVBQVUsQ0FBQztRQUFDLFNBQVMsRUFBRSxVQUFVLENBQUE7S0FBRSxLQUFLLElBQUksQ0FBQztJQUMxRyxDQUFDLGtCQUFrQixDQUFDLEVBQUUsQ0FBQyxJQUFJLEVBQUU7UUFBRSxJQUFJLEVBQUUsVUFBVSxDQUFBO0tBQUUsS0FBSyxJQUFJLENBQUM7SUFDM0QsQ0FBQywyQkFBMkIsQ0FBQyxFQUFFLENBQUMsSUFBSSxFQUFFO1FBQ3BDLElBQUksRUFBRSxVQUFVLENBQUM7UUFDakIsaUJBQWlCLENBQUMsRUFBRSxNQUFNLEVBQUUsQ0FBQztRQUM3QixhQUFhLENBQUMsRUFBRSxNQUFNLEVBQUUsQ0FBQztRQUN6QixXQUFXLENBQUMsRUFBRSxNQUFNLEVBQUUsQ0FBQztRQUN2QixjQUFjLENBQUMsRUFBRSxNQUFNLEVBQUUsQ0FBQztLQUMzQixLQUFLLElBQUksQ0FBQztJQUNYLENBQUMsc0JBQXNCLENBQUMsRUFBRSxDQUFDLElBQUksRUFBRTtRQUFFLFVBQVUsRUFBRSxnQkFBZ0IsQ0FBQztRQUFDLElBQUksRUFBRSxVQUFVLENBQUE7S0FBRSxLQUFLLElBQUksQ0FBQztJQUM3RixDQUFDLGtCQUFrQixDQUFDLEVBQUUsQ0FBQyxJQUFJLEVBQUU7UUFBRSxLQUFLLEVBQUUsS0FBSyxDQUFBO0tBQUUsS0FBSyxJQUFJLENBQUM7Q0FDeEQsQ0FBQyJ9
@@ -1 +1 @@
1
- {"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../src/sequencer/events.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAEjG,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qCAAqC,CAAC;AAClE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD,MAAM,MAAM,eAAe,GAAG;IAC5B,CAAC,eAAe,CAAC,EAAE,CAAC,IAAI,EAAE;QACxB,QAAQ,EAAE,cAAc,CAAC;QACzB,QAAQ,EAAE,cAAc,CAAC;QACzB,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,IAAI,CAAC,EAAE,UAAU,CAAC;KACnB,KAAK,IAAI,CAAC;IACX,CAAC,8BAA8B,CAAC,EAAE,CAAC,IAAI,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,UAAU,CAAA;KAAE,KAAK,IAAI,CAAC;IACvF,CAAC,6BAA6B,CAAC,EAAE,CAAC,IAAI,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,UAAU,CAAA;KAAE,KAAK,IAAI,CAAC;IAC5G,CAAC,oBAAoB,CAAC,EAAE,CAAC,IAAI,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,UAAU,CAAA;KAAE,KAAK,IAAI,CAAC;IAC7E,CAAC,gBAAgB,CAAC,EAAE,CAAC,IAAI,EAAE;QAAE,WAAW,EAAE,WAAW,CAAC;QAAC,IAAI,EAAE,UAAU,CAAA;KAAE,KAAK,IAAI,CAAC;IACnF,CAAC,kBAAkB,CAAC,EAAE,CAAC,IAAI,EAAE;QAAE,IAAI,EAAE,UAAU,CAAA;KAAE,KAAK,IAAI,CAAC;IAC3D,CAAC,2BAA2B,CAAC,EAAE,CAAC,IAAI,EAAE;QACpC,IAAI,EAAE,UAAU,CAAC;QACjB,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;QAC7B,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;QACzB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;QACvB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;KAC3B,KAAK,IAAI,CAAC;IACX,CAAC,sBAAsB,CAAC,EAAE,CAAC,IAAI,EAAE;QAAE,UAAU,EAAE,gBAAgB,CAAC;QAAC,IAAI,EAAE,UAAU,CAAA;KAAE,KAAK,IAAI,CAAC;IAC7F,CAAC,kBAAkB,CAAC,EAAE,CAAC,IAAI,EAAE;QAAE,KAAK,EAAE,KAAK,CAAA;KAAE,KAAK,IAAI,CAAC;CACxD,CAAC"}
1
+ {"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../src/sequencer/events.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAEjG,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qCAAqC,CAAC;AAClE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD,MAAM,MAAM,eAAe,GAAG;IAC5B,CAAC,eAAe,CAAC,EAAE,CAAC,IAAI,EAAE;QACxB,QAAQ,EAAE,cAAc,CAAC;QACzB,QAAQ,EAAE,cAAc,CAAC;QACzB,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,IAAI,CAAC,EAAE,UAAU,CAAC;KACnB,KAAK,IAAI,CAAC;IACX,CAAC,8BAA8B,CAAC,EAAE,CAAC,IAAI,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,UAAU,CAAA;KAAE,KAAK,IAAI,CAAC;IACvF,CAAC,6BAA6B,CAAC,EAAE,CAAC,IAAI,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,UAAU,CAAA;KAAE,KAAK,IAAI,CAAC;IAC5G,CAAC,oBAAoB,CAAC,EAAE,CAAC,IAAI,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,UAAU,CAAA;KAAE,KAAK,IAAI,CAAC;IAC7E,CAAC,gBAAgB,CAAC,EAAE,CAAC,IAAI,EAAE;QAAE,WAAW,EAAE,WAAW,CAAC;QAAC,IAAI,EAAE,UAAU,CAAC;QAAC,SAAS,EAAE,UAAU,CAAA;KAAE,KAAK,IAAI,CAAC;IAC1G,CAAC,kBAAkB,CAAC,EAAE,CAAC,IAAI,EAAE;QAAE,IAAI,EAAE,UAAU,CAAA;KAAE,KAAK,IAAI,CAAC;IAC3D,CAAC,2BAA2B,CAAC,EAAE,CAAC,IAAI,EAAE;QACpC,IAAI,EAAE,UAAU,CAAC;QACjB,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;QAC7B,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;QACzB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;QACvB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;KAC3B,KAAK,IAAI,CAAC;IACX,CAAC,sBAAsB,CAAC,EAAE,CAAC,IAAI,EAAE;QAAE,UAAU,EAAE,gBAAgB,CAAC;QAAC,IAAI,EAAE,UAAU,CAAA;KAAE,KAAK,IAAI,CAAC;IAC7F,CAAC,kBAAkB,CAAC,EAAE,CAAC,IAAI,EAAE;QAAE,KAAK,EAAE,KAAK,CAAA;KAAE,KAAK,IAAI,CAAC;CACxD,CAAC"}
@@ -31,6 +31,8 @@ export declare class SequencerMetrics {
31
31
  private checkpointBlockCount;
32
32
  private checkpointTxCount;
33
33
  private checkpointTotalMana;
34
+ private pipelineDepth;
35
+ private pipelineDiscards;
34
36
  private fishermanWouldBeIncluded;
35
37
  private fishermanTimeBeforeBlock;
36
38
  private fishermanPendingBlobTxCount;
@@ -53,6 +55,8 @@ export declare class SequencerMetrics {
53
55
  recordBuiltBlock(buildDurationMs: number, totalMana: number): void;
54
56
  recordFailedBlock(): void;
55
57
  recordStateTransitionBufferMs(durationMs: number, state: SequencerState): void;
58
+ recordPipelineDepth(depth: number): void;
59
+ recordPipelineDiscard(count?: number): void;
56
60
  incOpenSlot(slot: SlotNumber, proposer: string): void;
57
61
  incFilledSlot(proposer: string, coinbase: Hex | EthAddress | undefined): Promise<void>;
58
62
  recordCheckpointSuccess(): void;
@@ -69,4 +73,4 @@ export declare class SequencerMetrics {
69
73
  */
70
74
  recordFishermanFeeAnalysis(analysis: L1FeeAnalysisResult): void;
71
75
  }
72
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWV0cmljcy5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3NlcXVlbmNlci9tZXRyaWNzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUN2RCxPQUFPLEtBQUssRUFBRSxjQUFjLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUNoRSxPQUFPLEtBQUssRUFBRSxtQkFBbUIsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBQzNFLE9BQU8sS0FBSyxFQUFFLFVBQVUsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBQ2xFLE9BQU8sRUFNTCxLQUFLLGVBQWUsRUFDcEIsS0FBSyxNQUFNLEVBR1osTUFBTSx5QkFBeUIsQ0FBQztBQUVqQyxPQUFPLEVBQUUsS0FBSyxHQUFHLEVBQWUsTUFBTSxNQUFNLENBQUM7QUFFN0MsT0FBTyxLQUFLLEVBQUUsY0FBYyxFQUFFLE1BQU0sWUFBWSxDQUFDO0FBRWpELHFCQUFhLGdCQUFnQjtJQW9EekIsT0FBTyxDQUFDLE1BQU07SUFuRGhCLFNBQWdCLE1BQU0sRUFBRSxNQUFNLENBQUM7SUFDL0IsT0FBTyxDQUFDLEtBQUssQ0FBUTtJQUVyQixPQUFPLENBQUMsWUFBWSxDQUFnQjtJQUNwQyxPQUFPLENBQUMsa0JBQWtCLENBQVk7SUFDdEMsT0FBTyxDQUFDLHVCQUF1QixDQUFRO0lBQ3ZDLE9BQU8sQ0FBQyw2QkFBNkIsQ0FBWTtJQUdqRCxPQUFPLENBQUMseUJBQXlCLENBQVE7SUFDekMsT0FBTyxDQUFDLDhCQUE4QixDQUFRO0lBQzlDLE9BQU8sQ0FBQyxrQkFBa0IsQ0FBUTtJQUNsQyxPQUFPLENBQUMsbUJBQW1CLENBQVE7SUFFbkMsT0FBTyxDQUFDLE9BQU8sQ0FBUTtJQUV2QixPQUFPLENBQUMsS0FBSyxDQUFnQjtJQUM3QixPQUFPLENBQUMsV0FBVyxDQUFnQjtJQUVuQyxPQUFPLENBQUMsbUJBQW1CLENBQWdCO0lBQzND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
76
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWV0cmljcy5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3NlcXVlbmNlci9tZXRyaWNzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUN2RCxPQUFPLEtBQUssRUFBRSxjQUFjLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUNoRSxPQUFPLEtBQUssRUFBRSxtQkFBbUIsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBQzNFLE9BQU8sS0FBSyxFQUFFLFVBQVUsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBQ2xFLE9BQU8sRUFNTCxLQUFLLGVBQWUsRUFDcEIsS0FBSyxNQUFNLEVBR1osTUFBTSx5QkFBeUIsQ0FBQztBQUVqQyxPQUFPLEVBQUUsS0FBSyxHQUFHLEVBQWUsTUFBTSxNQUFNLENBQUM7QUFFN0MsT0FBTyxLQUFLLEVBQUUsY0FBYyxFQUFFLE1BQU0sWUFBWSxDQUFDO0FBRWpELHFCQUFhLGdCQUFnQjtJQXNEekIsT0FBTyxDQUFDLE1BQU07SUFyRGhCLFNBQWdCLE1BQU0sRUFBRSxNQUFNLENBQUM7SUFDL0IsT0FBTyxDQUFDLEtBQUssQ0FBUTtJQUVyQixPQUFPLENBQUMsWUFBWSxDQUFnQjtJQUNwQyxPQUFPLENBQUMsa0JBQWtCLENBQVk7SUFDdEMsT0FBTyxDQUFDLHVCQUF1QixDQUFRO0lBQ3ZDLE9BQU8sQ0FBQyw2QkFBNkIsQ0FBWTtJQUdqRCxPQUFPLENBQUMseUJBQXlCLENBQVE7SUFDekMsT0FBTyxDQUFDLDhCQUE4QixDQUFRO0lBQzlDLE9BQU8sQ0FBQyxrQkFBa0IsQ0FBUTtJQUNsQyxPQUFPLENBQUMsbUJBQW1CLENBQVE7SUFFbkMsT0FBTyxDQUFDLE9BQU8sQ0FBUTtJQUV2QixPQUFPLENBQUMsS0FBSyxDQUFnQjtJQUM3QixPQUFPLENBQUMsV0FBVyxDQUFnQjtJQUVuQyxPQUFPLENBQUMsbUJBQW1CLENBQWdCO0lBQzND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
@@ -1 +1 @@
1
- {"version":3,"file":"metrics.d.ts","sourceRoot":"","sources":["../../src/sequencer/metrics.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"metrics.d.ts","sourceRoot":"","sources":["../../src/sequencer/metrics.ts"],"names":[],"mappings":"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"}
@@ -27,6 +27,8 @@ export class SequencerMetrics {
27
27
  checkpointBlockCount;
28
28
  checkpointTxCount;
29
29
  checkpointTotalMana;
30
+ pipelineDepth;
31
+ pipelineDiscards;
30
32
  // Fisherman fee analysis metrics
31
33
  fishermanWouldBeIncluded;
32
34
  fishermanTimeBeforeBlock;
@@ -84,6 +86,9 @@ export class SequencerMetrics {
84
86
  this.checkpointTxCount = this.meter.createGauge(Metrics.SEQUENCER_CHECKPOINT_TX_COUNT);
85
87
  this.checkpointTotalMana = this.meter.createGauge(Metrics.SEQUENCER_CHECKPOINT_TOTAL_MANA);
86
88
  this.slashingAttempts = createUpDownCounterWithDefault(this.meter, Metrics.SEQUENCER_SLASHING_ATTEMPTS_COUNT);
89
+ this.pipelineDepth = this.meter.createGauge(Metrics.SEQUENCER_PIPELINE_DEPTH);
90
+ this.pipelineDiscards = createUpDownCounterWithDefault(this.meter, Metrics.SEQUENCER_PIPELINE_DISCARDS_COUNT);
91
+ this.pipelineDepth.record(0);
87
92
  // Fisherman fee analysis metrics
88
93
  this.fishermanWouldBeIncluded = createUpDownCounterWithDefault(this.meter, Metrics.FISHERMAN_FEE_ANALYSIS_WOULD_BE_INCLUDED, {
89
94
  [Attributes.OK]: [
@@ -145,6 +150,12 @@ export class SequencerMetrics {
145
150
  [Attributes.SEQUENCER_STATE]: state
146
151
  });
147
152
  }
153
+ recordPipelineDepth(depth) {
154
+ this.pipelineDepth.record(depth);
155
+ }
156
+ recordPipelineDiscard(count = 1) {
157
+ this.pipelineDiscards.add(count);
158
+ }
148
159
  incOpenSlot(slot, proposer) {
149
160
  // sequencer went through the loop a second time. Noop
150
161
  if (slot === this.lastSeenSlot) {