@aztec/sequencer-client 0.0.1-commit.f295ac2 → 0.0.1-commit.f504929

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 (75) hide show
  1. package/dest/client/sequencer-client.d.ts +12 -7
  2. package/dest/client/sequencer-client.d.ts.map +1 -1
  3. package/dest/client/sequencer-client.js +15 -4
  4. package/dest/config.d.ts +3 -4
  5. package/dest/config.d.ts.map +1 -1
  6. package/dest/config.js +29 -21
  7. package/dest/global_variable_builder/global_builder.d.ts +2 -4
  8. package/dest/global_variable_builder/global_builder.d.ts.map +1 -1
  9. package/dest/global_variable_builder/global_builder.js +2 -2
  10. package/dest/publisher/config.d.ts +35 -17
  11. package/dest/publisher/config.d.ts.map +1 -1
  12. package/dest/publisher/config.js +106 -42
  13. package/dest/publisher/index.d.ts +2 -1
  14. package/dest/publisher/index.d.ts.map +1 -1
  15. package/dest/publisher/l1_tx_failed_store/factory.d.ts +11 -0
  16. package/dest/publisher/l1_tx_failed_store/factory.d.ts.map +1 -0
  17. package/dest/publisher/l1_tx_failed_store/factory.js +22 -0
  18. package/dest/publisher/l1_tx_failed_store/failed_tx_store.d.ts +59 -0
  19. package/dest/publisher/l1_tx_failed_store/failed_tx_store.d.ts.map +1 -0
  20. package/dest/publisher/l1_tx_failed_store/failed_tx_store.js +1 -0
  21. package/dest/publisher/l1_tx_failed_store/file_store_failed_tx_store.d.ts +15 -0
  22. package/dest/publisher/l1_tx_failed_store/file_store_failed_tx_store.d.ts.map +1 -0
  23. package/dest/publisher/l1_tx_failed_store/file_store_failed_tx_store.js +34 -0
  24. package/dest/publisher/l1_tx_failed_store/index.d.ts +4 -0
  25. package/dest/publisher/l1_tx_failed_store/index.d.ts.map +1 -0
  26. package/dest/publisher/l1_tx_failed_store/index.js +2 -0
  27. package/dest/publisher/sequencer-publisher-factory.d.ts +11 -3
  28. package/dest/publisher/sequencer-publisher-factory.d.ts.map +1 -1
  29. package/dest/publisher/sequencer-publisher-factory.js +27 -2
  30. package/dest/publisher/sequencer-publisher-metrics.d.ts +1 -1
  31. package/dest/publisher/sequencer-publisher-metrics.d.ts.map +1 -1
  32. package/dest/publisher/sequencer-publisher-metrics.js +12 -4
  33. package/dest/publisher/sequencer-publisher.d.ts +26 -8
  34. package/dest/publisher/sequencer-publisher.d.ts.map +1 -1
  35. package/dest/publisher/sequencer-publisher.js +338 -48
  36. package/dest/sequencer/checkpoint_proposal_job.d.ts +32 -9
  37. package/dest/sequencer/checkpoint_proposal_job.d.ts.map +1 -1
  38. package/dest/sequencer/checkpoint_proposal_job.js +157 -74
  39. package/dest/sequencer/metrics.d.ts +17 -5
  40. package/dest/sequencer/metrics.d.ts.map +1 -1
  41. package/dest/sequencer/metrics.js +111 -30
  42. package/dest/sequencer/sequencer.d.ts +20 -8
  43. package/dest/sequencer/sequencer.d.ts.map +1 -1
  44. package/dest/sequencer/sequencer.js +31 -28
  45. package/dest/sequencer/timetable.d.ts +1 -4
  46. package/dest/sequencer/timetable.d.ts.map +1 -1
  47. package/dest/sequencer/timetable.js +2 -5
  48. package/dest/test/index.d.ts +3 -5
  49. package/dest/test/index.d.ts.map +1 -1
  50. package/dest/test/mock_checkpoint_builder.d.ts +14 -9
  51. package/dest/test/mock_checkpoint_builder.d.ts.map +1 -1
  52. package/dest/test/mock_checkpoint_builder.js +24 -10
  53. package/dest/test/utils.d.ts +8 -8
  54. package/dest/test/utils.d.ts.map +1 -1
  55. package/dest/test/utils.js +10 -9
  56. package/package.json +28 -28
  57. package/src/client/sequencer-client.ts +25 -7
  58. package/src/config.ts +41 -30
  59. package/src/global_variable_builder/global_builder.ts +3 -3
  60. package/src/publisher/config.ts +121 -43
  61. package/src/publisher/index.ts +3 -0
  62. package/src/publisher/l1_tx_failed_store/factory.ts +32 -0
  63. package/src/publisher/l1_tx_failed_store/failed_tx_store.ts +55 -0
  64. package/src/publisher/l1_tx_failed_store/file_store_failed_tx_store.ts +46 -0
  65. package/src/publisher/l1_tx_failed_store/index.ts +3 -0
  66. package/src/publisher/sequencer-publisher-factory.ts +38 -6
  67. package/src/publisher/sequencer-publisher-metrics.ts +7 -3
  68. package/src/publisher/sequencer-publisher.ts +333 -60
  69. package/src/sequencer/checkpoint_proposal_job.ts +221 -96
  70. package/src/sequencer/metrics.ts +124 -32
  71. package/src/sequencer/sequencer.ts +41 -33
  72. package/src/sequencer/timetable.ts +7 -6
  73. package/src/test/index.ts +2 -4
  74. package/src/test/mock_checkpoint_builder.ts +44 -19
  75. package/src/test/utils.ts +22 -13
@@ -1,17 +1,18 @@
1
1
  import type { EpochCache } from '@aztec/epoch-cache';
2
- import { BlockNumber, CheckpointNumber, EpochNumber, SlotNumber } from '@aztec/foundation/branded-types';
2
+ import { BlockNumber, CheckpointNumber, EpochNumber, IndexWithinCheckpoint, SlotNumber } from '@aztec/foundation/branded-types';
3
3
  import { EthAddress } from '@aztec/foundation/eth-address';
4
- import type { Logger } from '@aztec/foundation/log';
4
+ import { type Logger, type LoggerBindings } from '@aztec/foundation/log';
5
5
  import { type DateProvider } from '@aztec/foundation/timer';
6
6
  import { type TypedEventEmitter } from '@aztec/foundation/types';
7
7
  import type { P2P } from '@aztec/p2p';
8
8
  import type { SlasherClientInterface } from '@aztec/slasher';
9
- import { type L2BlockSink, type L2BlockSource } from '@aztec/stdlib/block';
9
+ import { L2Block, type L2BlockSink, type L2BlockSource } from '@aztec/stdlib/block';
10
10
  import type { Checkpoint } from '@aztec/stdlib/checkpoint';
11
- import type { ResolvedSequencerConfig, WorldStateSynchronizer } from '@aztec/stdlib/interfaces/server';
11
+ import { type ResolvedSequencerConfig, type WorldStateSynchronizer } from '@aztec/stdlib/interfaces/server';
12
12
  import { type L1ToL2MessageSource } from '@aztec/stdlib/messaging';
13
+ import { Tx } from '@aztec/stdlib/tx';
13
14
  import { type Traceable, type Tracer } from '@aztec/telemetry-client';
14
- import { type FullNodeCheckpointsBuilder, type ValidatorClient } from '@aztec/validator-client';
15
+ import { CheckpointBuilder, type FullNodeCheckpointsBuilder, type ValidatorClient } from '@aztec/validator-client';
15
16
  import type { GlobalVariableBuilder } from '../global_variable_builder/global_builder.js';
16
17
  import type { InvalidateCheckpointRequest, SequencerPublisher } from '../publisher/sequencer-publisher.js';
17
18
  import type { SequencerEvents } from './events.js';
@@ -51,9 +52,9 @@ export declare class CheckpointProposalJob implements Traceable {
51
52
  private readonly metrics;
52
53
  private readonly eventEmitter;
53
54
  private readonly setStateFn;
54
- protected readonly log: Logger;
55
55
  readonly tracer: Tracer;
56
- constructor(epoch: EpochNumber, slot: SlotNumber, checkpointNumber: CheckpointNumber, syncedToBlockNumber: BlockNumber, proposer: EthAddress | undefined, publisher: SequencerPublisher, attestorAddress: EthAddress, invalidateCheckpoint: InvalidateCheckpointRequest | undefined, validatorClient: ValidatorClient, globalsBuilder: GlobalVariableBuilder, p2pClient: P2P, worldState: WorldStateSynchronizer, l1ToL2MessageSource: L1ToL2MessageSource, l2BlockSource: L2BlockSource, checkpointsBuilder: FullNodeCheckpointsBuilder, blockSink: L2BlockSink, l1Constants: SequencerRollupConstants, config: ResolvedSequencerConfig, timetable: SequencerTimetable, slasherClient: SlasherClientInterface | undefined, epochCache: EpochCache, dateProvider: DateProvider, metrics: SequencerMetrics, eventEmitter: TypedEventEmitter<SequencerEvents>, setStateFn: (state: SequencerState, slot?: SlotNumber) => void, log: Logger, tracer: Tracer);
56
+ protected readonly log: Logger;
57
+ constructor(epoch: EpochNumber, slot: SlotNumber, checkpointNumber: CheckpointNumber, syncedToBlockNumber: BlockNumber, proposer: EthAddress | undefined, publisher: SequencerPublisher, attestorAddress: EthAddress, invalidateCheckpoint: InvalidateCheckpointRequest | undefined, validatorClient: ValidatorClient, globalsBuilder: GlobalVariableBuilder, p2pClient: P2P, worldState: WorldStateSynchronizer, l1ToL2MessageSource: L1ToL2MessageSource, l2BlockSource: L2BlockSource, checkpointsBuilder: FullNodeCheckpointsBuilder, blockSink: L2BlockSink, l1Constants: SequencerRollupConstants, config: ResolvedSequencerConfig, timetable: SequencerTimetable, slasherClient: SlasherClientInterface | undefined, epochCache: EpochCache, dateProvider: DateProvider, metrics: SequencerMetrics, eventEmitter: TypedEventEmitter<SequencerEvents>, setStateFn: (state: SequencerState, slot?: SlotNumber) => void, tracer: Tracer, bindings?: LoggerBindings);
57
58
  /**
58
59
  * Executes the checkpoint proposal job.
59
60
  * Returns the published checkpoint if successful, undefined otherwise.
@@ -62,7 +63,23 @@ export declare class CheckpointProposalJob implements Traceable {
62
63
  private proposeCheckpoint;
63
64
  private buildBlocksForCheckpoint;
64
65
  private waitUntilNextSubslot;
65
- private buildSingleBlock;
66
+ /** Builds a single block. Called from the main block building loop. */
67
+ protected buildSingleBlock(checkpointBuilder: CheckpointBuilder, opts: {
68
+ forceCreate?: boolean;
69
+ blockTimestamp: bigint;
70
+ blockNumber: BlockNumber;
71
+ indexWithinCheckpoint: IndexWithinCheckpoint;
72
+ buildDeadline: Date | undefined;
73
+ txHashesAlreadyIncluded: Set<string>;
74
+ remainingBlobFields: number;
75
+ }): Promise<{
76
+ block: L2Block;
77
+ usedTxs: Tx[];
78
+ remainingBlobFields: number;
79
+ } | {
80
+ error: Error;
81
+ } | undefined>;
82
+ private buildSingleBlockWithCheckpointBuilder;
66
83
  private waitForMinTxs;
67
84
  private waitForAttestations;
68
85
  /** Breaks the attestations before publishing based on attack configs */
@@ -70,10 +87,16 @@ export declare class CheckpointProposalJob implements Traceable {
70
87
  private dropFailedTxsFromP2P;
71
88
  private syncProposedBlockToArchiver;
72
89
  private handleCheckpointEndAsFisherman;
90
+ /**
91
+ * Helper to handle HA double-signing errors. Returns true if the error was handled (caller should yield).
92
+ */
93
+ private handleHASigningError;
73
94
  /** Waits until a specific time within the current slot */
74
95
  protected waitUntilTimeInSlot(targetSecondsIntoSlot: number): Promise<void>;
96
+ /** Waits the polling interval for transactions. Extracted for test overriding. */
97
+ protected waitForTxsPollingInterval(): Promise<void>;
75
98
  private getSlotStartBuildTimestamp;
76
99
  private getSecondsIntoSlot;
77
100
  getPublisher(): SequencerPublisher;
78
101
  }
79
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2hlY2twb2ludF9wcm9wb3NhbF9qb2IuZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zZXF1ZW5jZXIvY2hlY2twb2ludF9wcm9wb3NhbF9qb2IudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBRUEsT0FBTyxLQUFLLEVBQUUsVUFBVSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDckQsT0FBTyxFQUFFLFdBQVcsRUFBRSxnQkFBZ0IsRUFBRSxXQUFXLEVBQUUsVUFBVSxFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFHekcsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBRzNELE9BQU8sS0FBSyxFQUFFLE1BQU0sRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBRXBELE9BQU8sRUFBRSxLQUFLLFlBQVksRUFBUyxNQUFNLHlCQUF5QixDQUFDO0FBQ25FLE9BQU8sRUFBRSxLQUFLLGlCQUFpQixFQUFZLE1BQU0seUJBQXlCLENBQUM7QUFDM0UsT0FBTyxLQUFLLEVBQUUsR0FBRyxFQUFFLE1BQU0sWUFBWSxDQUFDO0FBQ3RDLE9BQU8sS0FBSyxFQUFFLHNCQUFzQixFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDN0QsT0FBTyxFQUlMLEtBQUssV0FBVyxFQUNoQixLQUFLLGFBQWEsRUFFbkIsTUFBTSxxQkFBcUIsQ0FBQztBQUM3QixPQUFPLEtBQUssRUFBRSxVQUFVLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUczRCxPQUFPLEtBQUssRUFFVix1QkFBdUIsRUFDdkIsc0JBQXNCLEVBQ3ZCLE1BQU0saUNBQWlDLENBQUM7QUFDekMsT0FBTyxFQUFFLEtBQUssbUJBQW1CLEVBQW1DLE1BQU0seUJBQXlCLENBQUM7QUFNcEcsT0FBTyxFQUFjLEtBQUssU0FBUyxFQUFFLEtBQUssTUFBTSxFQUFhLE1BQU0seUJBQXlCLENBQUM7QUFDN0YsT0FBTyxFQUFxQixLQUFLLDBCQUEwQixFQUFFLEtBQUssZUFBZSxFQUFFLE1B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
102
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2hlY2twb2ludF9wcm9wb3NhbF9qb2IuZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zZXF1ZW5jZXIvY2hlY2twb2ludF9wcm9wb3NhbF9qb2IudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBRUEsT0FBTyxLQUFLLEVBQUUsVUFBVSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDckQsT0FBTyxFQUNMLFdBQVcsRUFDWCxnQkFBZ0IsRUFDaEIsV0FBVyxFQUNYLHFCQUFxQixFQUNyQixVQUFVLEVBQ1gsTUFBTSxpQ0FBaUMsQ0FBQztBQVF6QyxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFHM0QsT0FBTyxFQUFFLEtBQUssTUFBTSxFQUFFLEtBQUssY0FBYyxFQUFnQixNQUFNLHVCQUF1QixDQUFDO0FBRXZGLE9BQU8sRUFBRSxLQUFLLFlBQVksRUFBUyxNQUFNLHlCQUF5QixDQUFDO0FBQ25FLE9BQU8sRUFBRSxLQUFLLGlCQUFpQixFQUEwQixNQUFNLHlCQUF5QixDQUFDO0FBQ3pGLE9BQU8sS0FBSyxFQUFFLEdBQUcsRUFBRSxNQUFNLFlBQVksQ0FBQztBQUN0QyxPQUFPLEtBQUssRUFBRSxzQkFBc0IsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQzdELE9BQU8sRUFHTCxPQUFPLEVBQ1AsS0FBSyxXQUFXLEVBQ2hCLEtBQUssYUFBYSxFQUVuQixNQUFNLHFCQUFxQixDQUFDO0FBQzdCLE9BQU8sS0FBSyxFQUFFLFVBQVUsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBRzNELE9BQU8sRUFHTCxLQUFLLHVCQUF1QixFQUM1QixLQUFLLHNCQUFzQixFQUM1QixNQUFNLGlDQUFpQyxDQUFDO0FBQ3pDLE9BQU8sRUFBRSxLQUFLLG1CQUFtQixFQUFtQyxNQUFNLHlCQUF5QixDQUFDO0FBSXBHLE9BQU8sRUFBaUIsRUFBRSxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFFckQsT0FBTyxFQUFjLEtBQUssU0FB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
@@ -1 +1 @@
1
- {"version":3,"file":"checkpoint_proposal_job.d.ts","sourceRoot":"","sources":["../../src/sequencer/checkpoint_proposal_job.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"checkpoint_proposal_job.d.ts","sourceRoot":"","sources":["../../src/sequencer/checkpoint_proposal_job.ts"],"names":[],"mappings":"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"}
@@ -438,18 +438,20 @@ function _apply_decs_2203_r(targetClass, memberDecs, classDecs, parentClass) {
438
438
  var _dec, _dec1, _dec2, _dec3, _dec4, _dec5, _dec6, _dec7, _initProto;
439
439
  import { NUM_CHECKPOINT_END_MARKER_FIELDS, getNumBlockEndBlobFields } from '@aztec/blob-lib/encoding';
440
440
  import { BLOBS_PER_CHECKPOINT, FIELDS_PER_BLOB } from '@aztec/constants';
441
- import { BlockNumber } from '@aztec/foundation/branded-types';
441
+ import { BlockNumber, IndexWithinCheckpoint } from '@aztec/foundation/branded-types';
442
442
  import { randomInt } from '@aztec/foundation/crypto/random';
443
- import { Signature } from '@aztec/foundation/eth-signature';
443
+ import { flipSignature, generateRecoverableSignature, generateUnrecoverableSignature } from '@aztec/foundation/crypto/secp256k1-signer';
444
444
  import { filter } from '@aztec/foundation/iterator';
445
+ import { createLogger } from '@aztec/foundation/log';
445
446
  import { sleep, sleepUntil } from '@aztec/foundation/sleep';
446
447
  import { Timer } from '@aztec/foundation/timer';
447
- import { unfreeze } from '@aztec/foundation/types';
448
+ import { isErrorClass, unfreeze } from '@aztec/foundation/types';
448
449
  import { CommitteeAttestationsAndSigners, MaliciousCommitteeAttestationsAndSigners } from '@aztec/stdlib/block';
449
450
  import { getSlotStartBuildTimestamp } from '@aztec/stdlib/epoch-helpers';
450
451
  import { Gas } from '@aztec/stdlib/gas';
452
+ import { NoValidTxsError } from '@aztec/stdlib/interfaces/server';
451
453
  import { computeInHashFromL1ToL2Messages } from '@aztec/stdlib/messaging';
452
- import { orderAttestations } from '@aztec/stdlib/p2p';
454
+ import { orderAttestations, trimAttestations } from '@aztec/stdlib/p2p';
453
455
  import { AttestationTimeoutError } from '@aztec/stdlib/validators';
454
456
  import { Attributes, trackSpan } from '@aztec/telemetry-client';
455
457
  import { DutyAlreadySignedError, SlashingProtectionError } from '@aztec/validator-ha-signer/errors';
@@ -495,7 +497,6 @@ _dec = trackSpan('CheckpointProposalJob.execute'), _dec1 = trackSpan('Checkpoint
495
497
  metrics;
496
498
  eventEmitter;
497
499
  setStateFn;
498
- log;
499
500
  tracer;
500
501
  static{
501
502
  ({ e: [_initProto] } = _apply_decs_2203_r(this, [
@@ -541,8 +542,9 @@ _dec = trackSpan('CheckpointProposalJob.execute'), _dec1 = trackSpan('Checkpoint
541
542
  ]
542
543
  ], []));
543
544
  }
545
+ log;
544
546
  constructor(epoch, slot, checkpointNumber, syncedToBlockNumber, // TODO(palla/mbps): Can we remove the proposer in favor of attestorAddress? Need to check fisherman-node flows.
545
- proposer, publisher, attestorAddress, invalidateCheckpoint, validatorClient, globalsBuilder, p2pClient, worldState, l1ToL2MessageSource, l2BlockSource, checkpointsBuilder, blockSink, l1Constants, config, timetable, slasherClient, epochCache, dateProvider, metrics, eventEmitter, setStateFn, log, tracer){
547
+ proposer, publisher, attestorAddress, invalidateCheckpoint, validatorClient, globalsBuilder, p2pClient, worldState, l1ToL2MessageSource, l2BlockSource, checkpointsBuilder, blockSink, l1Constants, config, timetable, slasherClient, epochCache, dateProvider, metrics, eventEmitter, setStateFn, tracer, bindings){
546
548
  this.epoch = epoch;
547
549
  this.slot = slot;
548
550
  this.checkpointNumber = checkpointNumber;
@@ -568,9 +570,12 @@ _dec = trackSpan('CheckpointProposalJob.execute'), _dec1 = trackSpan('Checkpoint
568
570
  this.metrics = metrics;
569
571
  this.eventEmitter = eventEmitter;
570
572
  this.setStateFn = setStateFn;
571
- this.log = log;
572
573
  this.tracer = tracer;
573
574
  _initProto(this);
575
+ this.log = createLogger('sequencer:checkpoint-proposal', {
576
+ ...bindings,
577
+ instanceId: `slot-${slot}`
578
+ });
574
579
  }
575
580
  /**
576
581
  * Executes the checkpoint proposal job.
@@ -585,7 +590,7 @@ _dec = trackSpan('CheckpointProposalJob.execute'), _dec1 = trackSpan('Checkpoint
585
590
  // Wait until the voting promises have resolved, so all requests are enqueued (not sent)
586
591
  await Promise.all(votesPromises);
587
592
  if (checkpoint) {
588
- this.metrics.recordBlockProposalSuccess();
593
+ this.metrics.recordCheckpointProposalSuccess();
589
594
  }
590
595
  // Do not post anything to L1 if we are fishermen, but do perform L1 fee analysis
591
596
  if (this.config.fishermanMode) {
@@ -635,13 +640,14 @@ _dec = trackSpan('CheckpointProposalJob.execute'), _dec1 = trackSpan('Checkpoint
635
640
  const l1ToL2Messages = await this.l1ToL2MessageSource.getL1ToL2Messages(this.checkpointNumber);
636
641
  const inHash = computeInHashFromL1ToL2Messages(l1ToL2Messages);
637
642
  // Collect the out hashes of all the checkpoints before this one in the same epoch
638
- const previousCheckpoints = (await this.l2BlockSource.getCheckpointsForEpoch(this.epoch)).filter((c)=>c.number < this.checkpointNumber);
639
- const previousCheckpointOutHashes = previousCheckpoints.map((c)=>c.getCheckpointOutHash());
643
+ const previousCheckpointOutHashes = (await this.l2BlockSource.getCheckpointsDataForEpoch(this.epoch)).filter((c)=>c.checkpointNumber < this.checkpointNumber).map((c)=>c.checkpointOutHash);
644
+ // Get the fee asset price modifier from the oracle
645
+ const feeAssetPriceModifier = await this.publisher.getFeeAssetPriceModifier();
640
646
  const fork = _ts_add_disposable_resource(env, await this.worldState.fork(this.syncedToBlockNumber, {
641
647
  closeDelayMs: 12_000
642
- }), false);
648
+ }), true);
643
649
  // Create checkpoint builder for the entire slot
644
- const checkpointBuilder = await this.checkpointsBuilder.startCheckpoint(this.checkpointNumber, checkpointGlobalVariables, l1ToL2Messages, previousCheckpointOutHashes, fork);
650
+ const checkpointBuilder = await this.checkpointsBuilder.startCheckpoint(this.checkpointNumber, checkpointGlobalVariables, feeAssetPriceModifier, l1ToL2Messages, previousCheckpointOutHashes, fork, this.log.getBindings());
645
651
  // Options for the validator client when creating block and checkpoint proposals
646
652
  const blockProposalOptions = {
647
653
  publishFullTxs: !!this.config.publishTxsWithProposals,
@@ -653,6 +659,7 @@ _dec = trackSpan('CheckpointProposalJob.execute'), _dec1 = trackSpan('Checkpoint
653
659
  };
654
660
  let blocksInCheckpoint = [];
655
661
  let blockPendingBroadcast = undefined;
662
+ const checkpointBuildTimer = new Timer();
656
663
  try {
657
664
  // Main loop: build blocks for the checkpoint
658
665
  const result = await this.buildBlocksForCheckpoint(checkpointBuilder, checkpointGlobalVariables.timestamp, inHash, blockProposalOptions);
@@ -662,19 +669,7 @@ _dec = trackSpan('CheckpointProposalJob.execute'), _dec1 = trackSpan('Checkpoint
662
669
  // These errors are expected in HA mode, so we yield and let another HA node handle the slot
663
670
  // The only distinction between the 2 errors is SlashingProtectionError throws when the payload is different,
664
671
  // which is normal for block building (may have picked different txs)
665
- if (err instanceof DutyAlreadySignedError) {
666
- this.log.info(`Checkpoint proposal for slot ${this.slot} already signed by another HA node, yielding`, {
667
- slot: this.slot,
668
- signedByNode: err.signedByNode
669
- });
670
- return undefined;
671
- }
672
- if (err instanceof SlashingProtectionError) {
673
- this.log.info(`Checkpoint proposal for slot ${this.slot} blocked by slashing protection, yielding`, {
674
- slot: this.slot,
675
- existingMessageHash: err.existingMessageHash,
676
- attemptedMessageHash: err.attemptedMessageHash
677
- });
672
+ if (this.handleHASigningError(err, 'Block proposal')) {
678
673
  return undefined;
679
674
  }
680
675
  throw err;
@@ -688,10 +683,21 @@ _dec = trackSpan('CheckpointProposalJob.execute'), _dec1 = trackSpan('Checkpoint
688
683
  });
689
684
  return undefined;
690
685
  }
686
+ const minBlocksForCheckpoint = this.config.minBlocksForCheckpoint;
687
+ if (minBlocksForCheckpoint !== undefined && blocksInCheckpoint.length < minBlocksForCheckpoint) {
688
+ this.log.warn(`Checkpoint has fewer blocks than minimum (${blocksInCheckpoint.length} < ${minBlocksForCheckpoint}), skipping proposal`, {
689
+ slot: this.slot,
690
+ blocksBuilt: blocksInCheckpoint.length,
691
+ minBlocksForCheckpoint
692
+ });
693
+ return undefined;
694
+ }
691
695
  // Assemble and broadcast the checkpoint proposal, including the last block that was not
692
696
  // broadcasted yet, and wait to collect the committee attestations.
693
697
  this.setStateFn(SequencerState.ASSEMBLING_CHECKPOINT, this.slot);
694
698
  const checkpoint = await checkpointBuilder.completeCheckpoint();
699
+ // Record checkpoint-level build metrics
700
+ this.metrics.recordCheckpointBuild(checkpointBuildTimer.ms(), blocksInCheckpoint.length, checkpoint.getStats().txCount, Number(checkpoint.header.totalManaUsed.toBigInt()));
695
701
  // Do not collect attestations nor publish to L1 in fisherman mode
696
702
  if (this.config.fishermanMode) {
697
703
  this.log.info(`Built checkpoint for slot ${this.slot} with ${blocksInCheckpoint.length} blocks. ` + `Skipping proposal in fisherman mode.`, {
@@ -709,7 +715,7 @@ _dec = trackSpan('CheckpointProposalJob.execute'), _dec1 = trackSpan('Checkpoint
709
715
  txs: blockPendingBroadcast.txs
710
716
  };
711
717
  // Create the checkpoint proposal and broadcast it
712
- const proposal = await this.validatorClient.createCheckpointProposal(checkpoint.header, checkpoint.archive.root, lastBlock, this.proposer, checkpointProposalOptions);
718
+ const proposal = await this.validatorClient.createCheckpointProposal(checkpoint.header, checkpoint.archive.root, feeAssetPriceModifier, lastBlock, this.proposer, checkpointProposalOptions);
713
719
  const blockProposedAt = this.dateProvider.now();
714
720
  await this.p2pClient.broadcastCheckpointProposal(proposal);
715
721
  this.setStateFn(SequencerState.COLLECTING_ATTESTATIONS, this.slot);
@@ -723,20 +729,8 @@ _dec = trackSpan('CheckpointProposalJob.execute'), _dec1 = trackSpan('Checkpoint
723
729
  attestationsSignature = await this.validatorClient.signAttestationsAndSigners(attestations, signer, this.slot, this.checkpointNumber);
724
730
  } catch (err) {
725
731
  // We shouldn't really get here since we yield to another HA node
726
- // as soon as we see these errors when creating block proposals.
727
- if (err instanceof DutyAlreadySignedError) {
728
- this.log.info(`Attestations signature for slot ${this.slot} already signed by another HA node, yielding`, {
729
- slot: this.slot,
730
- signedByNode: err.signedByNode
731
- });
732
- return undefined;
733
- }
734
- if (err instanceof SlashingProtectionError) {
735
- this.log.info(`Attestations signature for slot ${this.slot} blocked by slashing protection, yielding`, {
736
- slot: this.slot,
737
- existingMessageHash: err.existingMessageHash,
738
- attemptedMessageHash: err.attemptedMessageHash
739
- });
732
+ // as soon as we see these errors when creating block or checkpoint proposals.
733
+ if (this.handleHASigningError(err, 'Attestations signature')) {
740
734
  return undefined;
741
735
  }
742
736
  throw err;
@@ -746,6 +740,14 @@ _dec = trackSpan('CheckpointProposalJob.execute'), _dec1 = trackSpan('Checkpoint
746
740
  const aztecSlotDuration = this.l1Constants.slotDuration;
747
741
  const slotStartBuildTimestamp = this.getSlotStartBuildTimestamp();
748
742
  const txTimeoutAt = new Date((slotStartBuildTimestamp + aztecSlotDuration) * 1000);
743
+ // If we have been configured to potentially skip publishing checkpoint then roll the dice here
744
+ if (this.config.skipPublishingCheckpointsPercent !== undefined && this.config.skipPublishingCheckpointsPercent > 0) {
745
+ const result = Math.max(0, randomInt(100));
746
+ if (result < this.config.skipPublishingCheckpointsPercent) {
747
+ this.log.warn(`Skipping publishing proposal for checkpoint ${checkpoint.number}. Configured percentage: ${this.config.skipPublishingCheckpointsPercent}, generated value: ${result}`);
748
+ return checkpoint;
749
+ }
750
+ }
749
751
  await this.publisher.enqueueProposeCheckpoint(checkpoint, attestations, attestationsSignature, {
750
752
  txTimeoutAt,
751
753
  forcePendingCheckpointNumber: this.invalidateCheckpoint?.forcePendingCheckpointNumber
@@ -755,9 +757,14 @@ _dec = trackSpan('CheckpointProposalJob.execute'), _dec1 = trackSpan('Checkpoint
755
757
  env.error = e;
756
758
  env.hasError = true;
757
759
  } finally{
758
- _ts_dispose_resources(env);
760
+ const result = _ts_dispose_resources(env);
761
+ if (result) await result;
759
762
  }
760
763
  } catch (err) {
764
+ if (err && (err instanceof DutyAlreadySignedError || err instanceof SlashingProtectionError)) {
765
+ // swallow this error. It's already been logged by a function deeper in the stack
766
+ return undefined;
767
+ }
761
768
  this.log.error(`Error building checkpoint at slot ${this.slot}`, err);
762
769
  return undefined;
763
770
  }
@@ -774,7 +781,7 @@ _dec = trackSpan('CheckpointProposalJob.execute'), _dec1 = trackSpan('Checkpoint
774
781
  let blockPendingBroadcast = undefined;
775
782
  while(true){
776
783
  const blocksBuilt = blocksInCheckpoint.length;
777
- const indexWithinCheckpoint = blocksBuilt;
784
+ const indexWithinCheckpoint = IndexWithinCheckpoint(blocksBuilt);
778
785
  const blockNumber = BlockNumber(initialBlockNumber + blocksBuilt);
779
786
  const secondsIntoSlot = this.getSecondsIntoSlot();
780
787
  const timingInfo = this.timetable.canStartNextBlock(secondsIntoSlot);
@@ -798,6 +805,7 @@ _dec = trackSpan('CheckpointProposalJob.execute'), _dec1 = trackSpan('Checkpoint
798
805
  txHashesAlreadyIncluded,
799
806
  remainingBlobFields
800
807
  });
808
+ // TODO(palla/mbps): Review these conditions. We may want to keep trying in some scenarios.
801
809
  if (!buildResult && timingInfo.isLastBlock) {
802
810
  break;
803
811
  } else if (!buildResult && timingInfo.deadline !== undefined) {
@@ -824,7 +832,14 @@ _dec = trackSpan('CheckpointProposalJob.execute'), _dec1 = trackSpan('Checkpoint
824
832
  // Sync the proposed block to the archiver to make it available
825
833
  // Note that the checkpoint builder uses its own fork so it should not need to wait for this syncing
826
834
  // Eventually we should refactor the checkpoint builder to not need a separate long-lived fork
827
- await this.syncProposedBlockToArchiver(block);
835
+ // Fire and forget - don't block the critical path, but log errors
836
+ this.syncProposedBlockToArchiver(block).catch((err)=>{
837
+ this.log.error(`Failed to sync proposed block ${block.number} to archiver`, {
838
+ blockNumber: block.number,
839
+ err
840
+ });
841
+ });
842
+ usedTxs.forEach((tx)=>txHashesAlreadyIncluded.add(tx.txHash.toString()));
828
843
  // If this is the last block, exit the loop now so we start collecting attestations
829
844
  if (timingInfo.isLastBlock) {
830
845
  this.log.verbose(`Completed final block ${blockNumber} for slot ${this.slot}`, {
@@ -889,7 +904,7 @@ _dec = trackSpan('CheckpointProposalJob.execute'), _dec1 = trackSpan('Checkpoint
889
904
  }
890
905
  // Create iterator to pending txs. We filter out txs already included in previous blocks in the checkpoint
891
906
  // just in case p2p failed to sync the provisional block and didn't get to remove those txs from the mempool yet.
892
- const pendingTxs = filter(this.p2pClient.iteratePendingTxs(), (tx)=>!txHashesAlreadyIncluded.has(tx.txHash.toString()));
907
+ const pendingTxs = filter(this.p2pClient.iterateEligiblePendingTxs(), (tx)=>!txHashesAlreadyIncluded.has(tx.txHash.toString()));
893
908
  this.log.debug(`Building block ${blockNumber} at index ${indexWithinCheckpoint} for slot ${this.slot} with ${availableTxs} available txs`, {
894
909
  slot: this.slot,
895
910
  blockNumber,
@@ -907,35 +922,35 @@ _dec = trackSpan('CheckpointProposalJob.execute'), _dec1 = trackSpan('Checkpoint
907
922
  deadline: buildDeadline
908
923
  };
909
924
  // Actually build the block by executing txs
910
- const workTimer = new Timer();
911
- const { publicGas, block, publicProcessorDuration, numTxs, blockBuildingTimer, usedTxs, failedTxs, usedTxBlobFields } = await checkpointBuilder.buildBlock(pendingTxs, blockNumber, blockTimestamp, blockBuilderOptions);
912
- const blockBuildDuration = workTimer.ms();
925
+ const buildResult = await this.buildSingleBlockWithCheckpointBuilder(checkpointBuilder, pendingTxs, blockNumber, blockTimestamp, blockBuilderOptions);
913
926
  // If any txs failed during execution, drop them from the mempool so we don't pick them up again
914
- await this.dropFailedTxsFromP2P(failedTxs);
927
+ await this.dropFailedTxsFromP2P(buildResult.failedTxs);
915
928
  // Check if we have created a block with enough txs. If there were invalid txs in the pool, or if execution took
916
929
  // too long, then we may not get to minTxsPerBlock after executing public functions.
917
930
  const minValidTxs = this.config.minValidTxsPerBlock ?? minTxs;
918
- if (!forceCreate && numTxs < minValidTxs) {
919
- this.log.warn(`Block ${blockNumber} at index ${indexWithinCheckpoint} on slot ${this.slot} has too few valid txs to be proposed (got ${numTxs} but required ${minValidTxs})`, {
931
+ const numTxs = buildResult.status === 'no-valid-txs' ? 0 : buildResult.numTxs;
932
+ if (buildResult.status === 'no-valid-txs' || !forceCreate && numTxs < minValidTxs) {
933
+ this.log.warn(`Block ${blockNumber} at index ${indexWithinCheckpoint} on slot ${this.slot} has too few valid txs to be proposed`, {
920
934
  slot: this.slot,
921
935
  blockNumber,
922
936
  numTxs,
923
- indexWithinCheckpoint
937
+ indexWithinCheckpoint,
938
+ minValidTxs,
939
+ buildResult: buildResult.status
924
940
  });
925
- this.eventEmitter.emit('block-tx-count-check-failed', {
926
- minTxs: minValidTxs,
927
- availableTxs: numTxs,
941
+ this.eventEmitter.emit('block-build-failed', {
942
+ reason: `Insufficient valid txs`,
928
943
  slot: this.slot
929
944
  });
930
945
  this.metrics.recordBlockProposalFailed('insufficient_valid_txs');
931
946
  return undefined;
932
947
  }
933
948
  // Block creation succeeded, emit stats and metrics
949
+ const { publicGas, block, publicProcessorDuration, usedTxs, usedTxBlobFields, blockBuildDuration } = buildResult;
934
950
  const blockStats = {
935
951
  eventName: 'l2-block-built',
936
952
  duration: blockBuildDuration,
937
953
  publicProcessDuration: publicProcessorDuration,
938
- rollupCircuitsDuration: blockBuildingTimer.ms(),
939
954
  ...block.getStats()
940
955
  };
941
956
  const blockHash = await block.hash();
@@ -973,9 +988,30 @@ _dec = trackSpan('CheckpointProposalJob.execute'), _dec1 = trackSpan('Checkpoint
973
988
  };
974
989
  }
975
990
  }
991
+ /** Uses the checkpoint builder to build a block, catching specific txs */ async buildSingleBlockWithCheckpointBuilder(checkpointBuilder, pendingTxs, blockNumber, blockTimestamp, blockBuilderOptions) {
992
+ try {
993
+ const workTimer = new Timer();
994
+ const result = await checkpointBuilder.buildBlock(pendingTxs, blockNumber, blockTimestamp, blockBuilderOptions);
995
+ const blockBuildDuration = workTimer.ms();
996
+ return {
997
+ ...result,
998
+ blockBuildDuration,
999
+ status: 'success'
1000
+ };
1001
+ } catch (err) {
1002
+ if (isErrorClass(err, NoValidTxsError)) {
1003
+ return {
1004
+ failedTxs: err.failedTxs,
1005
+ status: 'no-valid-txs'
1006
+ };
1007
+ }
1008
+ throw err;
1009
+ }
1010
+ }
976
1011
  /** Waits until minTxs are available on the pool for building a block. */ async waitForMinTxs(opts) {
977
- const minTxs = this.config.minTxsPerBlock;
978
1012
  const { indexWithinCheckpoint, blockNumber, buildDeadline, forceCreate } = opts;
1013
+ // We only allow a block with 0 txs in the first block of the checkpoint
1014
+ const minTxs = indexWithinCheckpoint > 0 && this.config.minTxsPerBlock === 0 ? 1 : this.config.minTxsPerBlock;
979
1015
  // Deadline is undefined if we are not enforcing the timetable, meaning we'll exit immediately when out of time
980
1016
  const startBuildingDeadline = buildDeadline ? new Date(buildDeadline.getTime() - this.timetable.minExecutionTime * 1000) : undefined;
981
1017
  let availableTxs = await this.p2pClient.getPendingTxCount();
@@ -995,7 +1031,7 @@ _dec = trackSpan('CheckpointProposalJob.execute'), _dec1 = trackSpan('Checkpoint
995
1031
  slot: this.slot,
996
1032
  indexWithinCheckpoint
997
1033
  });
998
- await sleep(TXS_POLLING_MS);
1034
+ await this.waitForTxsPollingInterval();
999
1035
  availableTxs = await this.p2pClient.getPendingTxCount();
1000
1036
  }
1001
1037
  return {
@@ -1030,17 +1066,23 @@ _dec = trackSpan('CheckpointProposalJob.execute'), _dec1 = trackSpan('Checkpoint
1030
1066
  return new CommitteeAttestationsAndSigners(orderAttestations(attestations ?? [], committee));
1031
1067
  }
1032
1068
  const attestationTimeAllowed = this.config.enforceTimeTable ? this.timetable.getMaxAllowedTime(SequencerState.PUBLISHING_CHECKPOINT) : this.l1Constants.slotDuration;
1033
- const attestationDeadline = new Date(this.dateProvider.now() + attestationTimeAllowed * 1000);
1069
+ const attestationDeadline = new Date((this.getSlotStartBuildTimestamp() + attestationTimeAllowed) * 1000);
1034
1070
  this.metrics.recordRequiredAttestations(numberOfRequiredAttestations, attestationTimeAllowed);
1035
1071
  const collectAttestationsTimer = new Timer();
1036
1072
  let collectedAttestationsCount = 0;
1037
1073
  try {
1038
1074
  const attestations = await this.validatorClient.collectAttestations(proposal, numberOfRequiredAttestations, attestationDeadline);
1039
1075
  collectedAttestationsCount = attestations.length;
1076
+ // Trim attestations to minimum required to save L1 calldata gas
1077
+ const localAddresses = this.validatorClient.getValidatorAddresses();
1078
+ const trimmed = trimAttestations(attestations, numberOfRequiredAttestations, this.attestorAddress, localAddresses);
1079
+ if (trimmed.length < attestations.length) {
1080
+ this.log.debug(`Trimmed attestations from ${attestations.length} to ${trimmed.length} for L1 submission`);
1081
+ }
1040
1082
  // Rollup contract requires that the signatures are provided in the order of the committee
1041
- const sorted = orderAttestations(attestations, committee);
1083
+ const sorted = orderAttestations(trimmed, committee);
1042
1084
  // Manipulate the attestations if we've been configured to do so
1043
- if (this.config.injectFakeAttestation || this.config.shuffleAttestationOrdering) {
1085
+ if (this.config.injectFakeAttestation || this.config.injectHighSValueAttestation || this.config.injectUnrecoverableSignatureAttestation || this.config.shuffleAttestationOrdering) {
1044
1086
  return this.manipulateAttestations(proposal.slotNumber, epoch, seed, committee, sorted);
1045
1087
  }
1046
1088
  return new CommitteeAttestationsAndSigners(sorted);
@@ -1057,7 +1099,7 @@ _dec = trackSpan('CheckpointProposalJob.execute'), _dec1 = trackSpan('Checkpoint
1057
1099
  // Compute the proposer index in the committee, since we dont want to tweak it.
1058
1100
  // Otherwise, the L1 rollup contract will reject the block outright.
1059
1101
  const proposerIndex = Number(this.epochCache.computeProposerIndex(slotNumber, epoch, seed, BigInt(committee.length)));
1060
- if (this.config.injectFakeAttestation) {
1102
+ if (this.config.injectFakeAttestation || this.config.injectHighSValueAttestation || this.config.injectUnrecoverableSignatureAttestation) {
1061
1103
  // Find non-empty attestations that are not from the proposer
1062
1104
  const nonProposerIndices = [];
1063
1105
  for(let i = 0; i < attestations.length; i++){
@@ -1067,8 +1109,16 @@ _dec = trackSpan('CheckpointProposalJob.execute'), _dec1 = trackSpan('Checkpoint
1067
1109
  }
1068
1110
  if (nonProposerIndices.length > 0) {
1069
1111
  const targetIndex = nonProposerIndices[randomInt(nonProposerIndices.length)];
1070
- this.log.warn(`Injecting fake attestation in checkpoint for slot ${slotNumber} at index ${targetIndex}`);
1071
- unfreeze(attestations[targetIndex]).signature = Signature.random();
1112
+ if (this.config.injectHighSValueAttestation) {
1113
+ this.log.warn(`Injecting high-s value attestation in checkpoint for slot ${slotNumber} at index ${targetIndex}`);
1114
+ unfreeze(attestations[targetIndex]).signature = flipSignature(attestations[targetIndex].signature);
1115
+ } else if (this.config.injectUnrecoverableSignatureAttestation) {
1116
+ this.log.warn(`Injecting unrecoverable signature attestation in checkpoint for slot ${slotNumber} at index ${targetIndex}`);
1117
+ unfreeze(attestations[targetIndex]).signature = generateUnrecoverableSignature();
1118
+ } else {
1119
+ this.log.warn(`Injecting fake attestation in checkpoint for slot ${slotNumber} at index ${targetIndex}`);
1120
+ unfreeze(attestations[targetIndex]).signature = generateRecoverableSignature();
1121
+ }
1072
1122
  }
1073
1123
  return new CommitteeAttestationsAndSigners(attestations);
1074
1124
  }
@@ -1077,14 +1127,25 @@ _dec = trackSpan('CheckpointProposalJob.execute'), _dec1 = trackSpan('Checkpoint
1077
1127
  const shuffled = [
1078
1128
  ...attestations
1079
1129
  ];
1080
- const [i, j] = [
1081
- (proposerIndex + 1) % shuffled.length,
1082
- (proposerIndex + 2) % shuffled.length
1083
- ];
1084
- const valueI = shuffled[i];
1085
- const valueJ = shuffled[j];
1086
- shuffled[i] = valueJ;
1087
- shuffled[j] = valueI;
1130
+ // Find two non-proposer positions that both have non-empty signatures to swap.
1131
+ // This ensures the bitmap doesn't change, so the MaliciousCommitteeAttestationsAndSigners
1132
+ // signers array stays correctly aligned with L1's committee reconstruction.
1133
+ const swappable = [];
1134
+ for(let k = 0; k < shuffled.length; k++){
1135
+ if (!shuffled[k].signature.isEmpty() && k !== proposerIndex) {
1136
+ swappable.push(k);
1137
+ }
1138
+ }
1139
+ if (swappable.length >= 2) {
1140
+ const [i, j] = [
1141
+ swappable[0],
1142
+ swappable[1]
1143
+ ];
1144
+ [shuffled[i], shuffled[j]] = [
1145
+ shuffled[j],
1146
+ shuffled[i]
1147
+ ];
1148
+ }
1088
1149
  const signers = new CommitteeAttestationsAndSigners(attestations).getSigners();
1089
1150
  return new MaliciousCommitteeAttestationsAndSigners(shuffled, signers);
1090
1151
  }
@@ -1097,14 +1158,13 @@ _dec = trackSpan('CheckpointProposalJob.execute'), _dec1 = trackSpan('Checkpoint
1097
1158
  const failedTxData = failedTxs.map((fail)=>fail.tx);
1098
1159
  const failedTxHashes = failedTxData.map((tx)=>tx.getTxHash());
1099
1160
  this.log.verbose(`Dropping failed txs ${failedTxHashes.join(', ')}`);
1100
- await this.p2pClient.deleteTxs(failedTxHashes);
1161
+ await this.p2pClient.handleFailedExecution(failedTxHashes);
1101
1162
  }
1102
1163
  /**
1103
1164
  * Adds the proposed block to the archiver so it's available via P2P.
1104
1165
  * Gossip doesn't echo messages back to the sender, so the proposer's archiver/world-state
1105
1166
  * would never receive its own block without this explicit sync.
1106
1167
  */ async syncProposedBlockToArchiver(block) {
1107
- // TODO(palla/mbps): Change default to false once block sync is stable.
1108
1168
  if (this.config.skipPushProposedBlocksToArchiver !== false) {
1109
1169
  this.log.warn(`Skipping push of proposed block ${block.number} to archiver`, {
1110
1170
  blockNumber: block.number,
@@ -1133,15 +1193,38 @@ _dec = trackSpan('CheckpointProposalJob.execute'), _dec1 = trackSpan('Checkpoint
1133
1193
  slot: this.slot,
1134
1194
  feeAnalysisId: feeAnalysis?.id
1135
1195
  });
1136
- this.metrics.recordBlockProposalFailed('block_build_failed');
1196
+ this.metrics.recordCheckpointProposalFailed('block_build_failed');
1137
1197
  }
1138
1198
  this.publisher.clearPendingRequests();
1139
1199
  }
1200
+ /**
1201
+ * Helper to handle HA double-signing errors. Returns true if the error was handled (caller should yield).
1202
+ */ handleHASigningError(err, errorContext) {
1203
+ if (err instanceof DutyAlreadySignedError) {
1204
+ this.log.info(`${errorContext} for slot ${this.slot} already signed by another HA node, yielding`, {
1205
+ slot: this.slot,
1206
+ signedByNode: err.signedByNode
1207
+ });
1208
+ return true;
1209
+ }
1210
+ if (err instanceof SlashingProtectionError) {
1211
+ this.log.info(`${errorContext} for slot ${this.slot} blocked by slashing protection, yielding`, {
1212
+ slot: this.slot,
1213
+ existingMessageHash: err.existingMessageHash,
1214
+ attemptedMessageHash: err.attemptedMessageHash
1215
+ });
1216
+ return true;
1217
+ }
1218
+ return false;
1219
+ }
1140
1220
  /** Waits until a specific time within the current slot */ async waitUntilTimeInSlot(targetSecondsIntoSlot) {
1141
1221
  const slotStartTimestamp = this.getSlotStartBuildTimestamp();
1142
1222
  const targetTimestamp = slotStartTimestamp + targetSecondsIntoSlot;
1143
1223
  await sleepUntil(new Date(targetTimestamp * 1000), this.dateProvider.nowAsDate());
1144
1224
  }
1225
+ /** Waits the polling interval for transactions. Extracted for test overriding. */ async waitForTxsPollingInterval() {
1226
+ await sleep(TXS_POLLING_MS);
1227
+ }
1145
1228
  getSlotStartBuildTimestamp() {
1146
1229
  return getSlotStartBuildTimestamp(this.slot, this.l1Constants);
1147
1230
  }