@aztec/sequencer-client 0.0.1-commit.03f7ef2 → 0.0.1-commit.0b941701

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 (74) hide show
  1. package/dest/client/sequencer-client.d.ts +5 -6
  2. package/dest/client/sequencer-client.d.ts.map +1 -1
  3. package/dest/config.d.ts +1 -1
  4. package/dest/config.d.ts.map +1 -1
  5. package/dest/config.js +6 -1
  6. package/dest/global_variable_builder/global_builder.d.ts +4 -4
  7. package/dest/global_variable_builder/global_builder.d.ts.map +1 -1
  8. package/dest/global_variable_builder/global_builder.js +13 -13
  9. package/dest/index.d.ts +2 -3
  10. package/dest/index.d.ts.map +1 -1
  11. package/dest/index.js +1 -2
  12. package/dest/publisher/sequencer-publisher-factory.d.ts +2 -2
  13. package/dest/publisher/sequencer-publisher-factory.d.ts.map +1 -1
  14. package/dest/publisher/sequencer-publisher-metrics.d.ts +1 -1
  15. package/dest/publisher/sequencer-publisher-metrics.d.ts.map +1 -1
  16. package/dest/publisher/sequencer-publisher-metrics.js +15 -86
  17. package/dest/publisher/sequencer-publisher.d.ts +19 -18
  18. package/dest/publisher/sequencer-publisher.d.ts.map +1 -1
  19. package/dest/publisher/sequencer-publisher.js +443 -53
  20. package/dest/sequencer/checkpoint_proposal_job.d.ts +14 -9
  21. package/dest/sequencer/checkpoint_proposal_job.d.ts.map +1 -1
  22. package/dest/sequencer/checkpoint_proposal_job.js +565 -40
  23. package/dest/sequencer/checkpoint_voter.d.ts +3 -2
  24. package/dest/sequencer/checkpoint_voter.d.ts.map +1 -1
  25. package/dest/sequencer/checkpoint_voter.js +34 -10
  26. package/dest/sequencer/index.d.ts +1 -3
  27. package/dest/sequencer/index.d.ts.map +1 -1
  28. package/dest/sequencer/index.js +0 -2
  29. package/dest/sequencer/metrics.d.ts +3 -3
  30. package/dest/sequencer/metrics.d.ts.map +1 -1
  31. package/dest/sequencer/metrics.js +30 -121
  32. package/dest/sequencer/sequencer.d.ts +25 -15
  33. package/dest/sequencer/sequencer.d.ts.map +1 -1
  34. package/dest/sequencer/sequencer.js +486 -42
  35. package/dest/test/index.d.ts +2 -3
  36. package/dest/test/index.d.ts.map +1 -1
  37. package/dest/test/mock_checkpoint_builder.d.ts +23 -11
  38. package/dest/test/mock_checkpoint_builder.d.ts.map +1 -1
  39. package/dest/test/mock_checkpoint_builder.js +50 -7
  40. package/dest/test/utils.d.ts +13 -9
  41. package/dest/test/utils.d.ts.map +1 -1
  42. package/dest/test/utils.js +26 -17
  43. package/package.json +30 -28
  44. package/src/client/sequencer-client.ts +4 -5
  45. package/src/config.ts +5 -0
  46. package/src/global_variable_builder/global_builder.ts +13 -13
  47. package/src/index.ts +1 -9
  48. package/src/publisher/sequencer-publisher-factory.ts +1 -1
  49. package/src/publisher/sequencer-publisher-metrics.ts +14 -70
  50. package/src/publisher/sequencer-publisher.ts +87 -77
  51. package/src/sequencer/checkpoint_proposal_job.ts +201 -59
  52. package/src/sequencer/checkpoint_voter.ts +32 -7
  53. package/src/sequencer/index.ts +0 -2
  54. package/src/sequencer/metrics.ts +23 -131
  55. package/src/sequencer/sequencer.ts +124 -41
  56. package/src/test/index.ts +1 -2
  57. package/src/test/mock_checkpoint_builder.ts +92 -28
  58. package/src/test/utils.ts +55 -28
  59. package/dest/sequencer/block_builder.d.ts +0 -26
  60. package/dest/sequencer/block_builder.d.ts.map +0 -1
  61. package/dest/sequencer/block_builder.js +0 -129
  62. package/dest/sequencer/checkpoint_builder.d.ts +0 -63
  63. package/dest/sequencer/checkpoint_builder.d.ts.map +0 -1
  64. package/dest/sequencer/checkpoint_builder.js +0 -131
  65. package/dest/tx_validator/nullifier_cache.d.ts +0 -14
  66. package/dest/tx_validator/nullifier_cache.d.ts.map +0 -1
  67. package/dest/tx_validator/nullifier_cache.js +0 -24
  68. package/dest/tx_validator/tx_validator_factory.d.ts +0 -18
  69. package/dest/tx_validator/tx_validator_factory.d.ts.map +0 -1
  70. package/dest/tx_validator/tx_validator_factory.js +0 -53
  71. package/src/sequencer/block_builder.ts +0 -217
  72. package/src/sequencer/checkpoint_builder.ts +0 -217
  73. package/src/tx_validator/nullifier_cache.ts +0 -30
  74. package/src/tx_validator/tx_validator_factory.ts +0 -133
@@ -23,7 +23,7 @@ import { createPublicClient, fallback, http } from 'viem';
23
23
  */
24
24
  export class GlobalVariableBuilder implements GlobalVariableBuilderInterface {
25
25
  private log = createLogger('sequencer:global_variable_builder');
26
- private currentBaseFees: Promise<GasFees> = Promise.resolve(new GasFees(0, 0));
26
+ private currentMinFees: Promise<GasFees> = Promise.resolve(new GasFees(0, 0));
27
27
  private currentL1BlockNumber: bigint | undefined = undefined;
28
28
 
29
29
  private readonly rollupContract: RollupContract;
@@ -61,34 +61,34 @@ export class GlobalVariableBuilder implements GlobalVariableBuilderInterface {
61
61
  }
62
62
 
63
63
  /**
64
- * Computes the "current" base fees, e.g., the price that you currently should pay to get include in the next block
65
- * @returns Base fees for the next block
64
+ * Computes the "current" min fees, e.g., the price that you currently should pay to get include in the next block
65
+ * @returns Min fees for the next block
66
66
  */
67
- private async computeCurrentBaseFees(): Promise<GasFees> {
67
+ private async computeCurrentMinFees(): Promise<GasFees> {
68
68
  // Since this might be called in the middle of a slot where a block might have been published,
69
69
  // we need to fetch the last block written, and estimate the earliest timestamp for the next block.
70
70
  // The timestamp of that last block will act as a lower bound for the next block.
71
71
 
72
- const lastBlock = await this.rollupContract.getPendingCheckpoint();
72
+ const lastCheckpoint = await this.rollupContract.getPendingCheckpoint();
73
73
  const earliestTimestamp = await this.rollupContract.getTimestampForSlot(
74
- SlotNumber.fromBigInt(lastBlock.slotNumber + 1n),
74
+ SlotNumber.fromBigInt(BigInt(lastCheckpoint.slotNumber) + 1n),
75
75
  );
76
76
  const nextEthTimestamp = BigInt((await this.publicClient.getBlock()).timestamp + BigInt(this.ethereumSlotDuration));
77
77
  const timestamp = earliestTimestamp > nextEthTimestamp ? earliestTimestamp : nextEthTimestamp;
78
78
 
79
- return new GasFees(0, await this.rollupContract.getManaBaseFeeAt(timestamp, true));
79
+ return new GasFees(0, await this.rollupContract.getManaMinFeeAt(timestamp, true));
80
80
  }
81
81
 
82
- public async getCurrentBaseFees(): Promise<GasFees> {
82
+ public async getCurrentMinFees(): Promise<GasFees> {
83
83
  // Get the current block number
84
84
  const blockNumber = await this.publicClient.getBlockNumber();
85
85
 
86
- // If the L1 block number has changed then chain a new promise to get the current base fees
86
+ // If the L1 block number has changed then chain a new promise to get the current min fees
87
87
  if (this.currentL1BlockNumber === undefined || blockNumber > this.currentL1BlockNumber) {
88
88
  this.currentL1BlockNumber = blockNumber;
89
- this.currentBaseFees = this.currentBaseFees.then(() => this.computeCurrentBaseFees());
89
+ this.currentMinFees = this.currentMinFees.then(() => this.computeCurrentMinFees());
90
90
  }
91
- return this.currentBaseFees;
91
+ return this.currentMinFees;
92
92
  }
93
93
 
94
94
  /**
@@ -128,9 +128,9 @@ export class GlobalVariableBuilder implements GlobalVariableBuilderInterface {
128
128
  l1GenesisTime: this.l1GenesisTime,
129
129
  });
130
130
 
131
- // We can skip much of the logic in getCurrentBaseFees since it we already check that we are not within a slot elsewhere.
131
+ // We can skip much of the logic in getCurrentMinFees since it we already check that we are not within a slot elsewhere.
132
132
  // TODO(palla/mbps): Can we use a cached value here?
133
- const gasFees = new GasFees(0, await this.rollupContract.getManaBaseFeeAt(timestamp, true));
133
+ const gasFees = new GasFees(0, await this.rollupContract.getManaMinFeeAt(timestamp, true));
134
134
 
135
135
  return { chainId, version, slotNumber, timestamp, coinbase, feeRecipient, gasFees };
136
136
  }
package/src/index.ts CHANGED
@@ -1,15 +1,7 @@
1
1
  export * from './client/index.js';
2
2
  export * from './config.js';
3
3
  export * from './publisher/index.js';
4
- export {
5
- FullNodeBlockBuilder as BlockBuilder,
6
- FullNodeCheckpointsBuilder as CheckpointsBuilder,
7
- CheckpointBuilder,
8
- Sequencer,
9
- SequencerState,
10
- type SequencerEvents,
11
- } from './sequencer/index.js';
12
- export * from './tx_validator/tx_validator_factory.js';
4
+ export { Sequencer, SequencerState, type SequencerEvents } from './sequencer/index.js';
13
5
 
14
6
  // Used by the node to simulate public parts of transactions. Should these be moved to a shared library?
15
7
  // ISSUE(#9832)
@@ -33,7 +33,7 @@ export class SequencerPublisherFactory {
33
33
  private deps: {
34
34
  telemetry: TelemetryClient;
35
35
  publisherManager: PublisherManager<L1TxUtilsWithBlobs>;
36
- blobClient?: BlobClientInterface;
36
+ blobClient: BlobClientInterface;
37
37
  dateProvider: DateProvider;
38
38
  epochCache: EpochCache;
39
39
  rollupContract: RollupContract;
@@ -7,7 +7,6 @@ import {
7
7
  Metrics,
8
8
  type TelemetryClient,
9
9
  type UpDownCounter,
10
- ValueType,
11
10
  } from '@aztec/telemetry-client';
12
11
 
13
12
  import { formatEther } from 'viem/utils';
@@ -40,88 +39,33 @@ export class SequencerPublisherMetrics {
40
39
  ) {
41
40
  const meter = client.getMeter(name);
42
41
 
43
- this.gasPrice = meter.createHistogram(Metrics.L1_PUBLISHER_GAS_PRICE, {
44
- description: 'The gas price used for transactions',
45
- unit: 'gwei',
46
- valueType: ValueType.DOUBLE,
47
- });
42
+ this.gasPrice = meter.createHistogram(Metrics.L1_PUBLISHER_GAS_PRICE);
48
43
 
49
- this.txCount = meter.createUpDownCounter(Metrics.L1_PUBLISHER_TX_COUNT, {
50
- description: 'The number of transactions processed',
51
- });
44
+ this.txCount = meter.createUpDownCounter(Metrics.L1_PUBLISHER_TX_COUNT);
52
45
 
53
- this.txDuration = meter.createHistogram(Metrics.L1_PUBLISHER_TX_DURATION, {
54
- description: 'The duration of transaction processing',
55
- unit: 'ms',
56
- valueType: ValueType.INT,
57
- });
46
+ this.txDuration = meter.createHistogram(Metrics.L1_PUBLISHER_TX_DURATION);
58
47
 
59
- this.txGas = meter.createHistogram(Metrics.L1_PUBLISHER_TX_GAS, {
60
- description: 'The gas consumed by transactions',
61
- unit: 'gas',
62
- valueType: ValueType.INT,
63
- });
48
+ this.txGas = meter.createHistogram(Metrics.L1_PUBLISHER_TX_GAS);
64
49
 
65
- this.txCalldataSize = meter.createHistogram(Metrics.L1_PUBLISHER_TX_CALLDATA_SIZE, {
66
- description: 'The size of the calldata in transactions',
67
- unit: 'By',
68
- valueType: ValueType.INT,
69
- });
50
+ this.txCalldataSize = meter.createHistogram(Metrics.L1_PUBLISHER_TX_CALLDATA_SIZE);
70
51
 
71
- this.txCalldataGas = meter.createHistogram(Metrics.L1_PUBLISHER_TX_CALLDATA_GAS, {
72
- description: 'The gas consumed by the calldata in transactions',
73
- unit: 'gas',
74
- valueType: ValueType.INT,
75
- });
52
+ this.txCalldataGas = meter.createHistogram(Metrics.L1_PUBLISHER_TX_CALLDATA_GAS);
76
53
 
77
- this.txBlobDataGasUsed = meter.createHistogram(Metrics.L1_PUBLISHER_TX_BLOBDATA_GAS_USED, {
78
- description: 'The amount of blob gas used in transactions',
79
- unit: 'gas',
80
- valueType: ValueType.INT,
81
- });
54
+ this.txBlobDataGasUsed = meter.createHistogram(Metrics.L1_PUBLISHER_TX_BLOBDATA_GAS_USED);
82
55
 
83
- this.txBlobDataGasCost = meter.createHistogram(Metrics.L1_PUBLISHER_TX_BLOBDATA_GAS_COST, {
84
- description: 'The gas cost of blobs in transactions',
85
- unit: 'gwei',
86
- valueType: ValueType.INT,
87
- });
56
+ this.txBlobDataGasCost = meter.createHistogram(Metrics.L1_PUBLISHER_TX_BLOBDATA_GAS_COST);
88
57
 
89
- this.blobCountHistogram = meter.createHistogram(Metrics.L1_PUBLISHER_BLOB_COUNT, {
90
- description: 'Number of blobs in L1 transactions',
91
- unit: 'blobs',
92
- valueType: ValueType.INT,
93
- });
58
+ this.blobCountHistogram = meter.createHistogram(Metrics.L1_PUBLISHER_BLOB_COUNT);
94
59
 
95
- this.blobInclusionBlocksHistogram = meter.createHistogram(Metrics.L1_PUBLISHER_BLOB_INCLUSION_BLOCKS, {
96
- description: 'Number of L1 blocks between blob tx submission and inclusion',
97
- unit: 'blocks',
98
- valueType: ValueType.INT,
99
- });
60
+ this.blobInclusionBlocksHistogram = meter.createHistogram(Metrics.L1_PUBLISHER_BLOB_INCLUSION_BLOCKS);
100
61
 
101
- this.blobTxSuccessCounter = meter.createUpDownCounter(Metrics.L1_PUBLISHER_BLOB_TX_SUCCESS, {
102
- description: 'Number of successful L1 transactions with blobs',
103
- });
62
+ this.blobTxSuccessCounter = meter.createUpDownCounter(Metrics.L1_PUBLISHER_BLOB_TX_SUCCESS);
104
63
 
105
- this.blobTxFailureCounter = meter.createUpDownCounter(Metrics.L1_PUBLISHER_BLOB_TX_FAILURE, {
106
- description: 'Number of failed L1 transactions with blobs',
107
- });
64
+ this.blobTxFailureCounter = meter.createUpDownCounter(Metrics.L1_PUBLISHER_BLOB_TX_FAILURE);
108
65
 
109
- this.txTotalFee = meter.createHistogram(Metrics.L1_PUBLISHER_TX_TOTAL_FEE, {
110
- description: 'How much L1 tx costs',
111
- unit: 'eth',
112
- valueType: ValueType.DOUBLE,
113
- advice: {
114
- explicitBucketBoundaries: [
115
- 0.001, 0.002, 0.004, 0.008, 0.01, 0.02, 0.04, 0.08, 0.1, 0.2, 0.4, 0.8, 1, 1.2, 1.4, 1.8, 2,
116
- ],
117
- },
118
- });
66
+ this.txTotalFee = meter.createHistogram(Metrics.L1_PUBLISHER_TX_TOTAL_FEE);
119
67
 
120
- this.senderBalance = meter.createGauge(Metrics.L1_PUBLISHER_BALANCE, {
121
- unit: 'eth',
122
- description: 'The balance of the sender address',
123
- valueType: ValueType.DOUBLE,
124
- });
68
+ this.senderBalance = meter.createGauge(Metrics.L1_PUBLISHER_BALANCE);
125
69
  }
126
70
 
127
71
  recordFailedTx(txType: L1TxType) {
@@ -1,4 +1,4 @@
1
- import { type BlobClientInterface, createBlobClient } from '@aztec/blob-client/client';
1
+ import type { BlobClientInterface } from '@aztec/blob-client/client';
2
2
  import { Blob, getBlobsPerL1Block, getPrefixedEthBlobCommitments } from '@aztec/blob-lib';
3
3
  import type { EpochCache } from '@aztec/epoch-cache';
4
4
  import type { L1ContractsConfig } from '@aztec/ethereum/config';
@@ -25,7 +25,7 @@ import type { L1TxUtilsWithBlobs } from '@aztec/ethereum/l1-tx-utils-with-blobs'
25
25
  import { FormattedViemError, formatViemError, tryExtractEvent } from '@aztec/ethereum/utils';
26
26
  import { sumBigint } from '@aztec/foundation/bigint';
27
27
  import { toHex as toPaddedHex } from '@aztec/foundation/bigint-buffer';
28
- import { BlockNumber, CheckpointNumber, SlotNumber } from '@aztec/foundation/branded-types';
28
+ import { CheckpointNumber, SlotNumber } from '@aztec/foundation/branded-types';
29
29
  import { pick } from '@aztec/foundation/collection';
30
30
  import type { Fr } from '@aztec/foundation/curves/bn254';
31
31
  import { EthAddress } from '@aztec/foundation/eth-address';
@@ -35,12 +35,12 @@ import { bufferToHex } from '@aztec/foundation/string';
35
35
  import { DateProvider, Timer } from '@aztec/foundation/timer';
36
36
  import { EmpireBaseAbi, ErrorsAbi, RollupAbi } from '@aztec/l1-artifacts';
37
37
  import { type ProposerSlashAction, encodeSlashConsensusVotes } from '@aztec/slasher';
38
- import { CommitteeAttestationsAndSigners, type ValidateBlockResult } from '@aztec/stdlib/block';
38
+ import { CommitteeAttestationsAndSigners, type ValidateCheckpointResult } from '@aztec/stdlib/block';
39
39
  import type { Checkpoint } from '@aztec/stdlib/checkpoint';
40
40
  import { SlashFactoryContract } from '@aztec/stdlib/l1-contracts';
41
41
  import type { CheckpointHeader } from '@aztec/stdlib/rollup';
42
42
  import type { L1PublishCheckpointStats } from '@aztec/stdlib/stats';
43
- import { type TelemetryClient, getTelemetryClient } from '@aztec/telemetry-client';
43
+ import { type TelemetryClient, type Tracer, getTelemetryClient, trackSpan } from '@aztec/telemetry-client';
44
44
 
45
45
  import { type StateOverride, type TransactionReceipt, type TypedDataDefinition, encodeFunctionData, toHex } from 'viem';
46
46
 
@@ -80,12 +80,12 @@ type GovernanceSignalAction = Extract<Action, 'governance-signal' | 'empire-slas
80
80
  // Sorting for actions such that invalidations go before proposals, and proposals go before votes
81
81
  export const compareActions = (a: Action, b: Action) => Actions.indexOf(a) - Actions.indexOf(b);
82
82
 
83
- export type InvalidateBlockRequest = {
83
+ export type InvalidateCheckpointRequest = {
84
84
  request: L1TxRequest;
85
85
  reason: 'invalid-attestation' | 'insufficient-attestations';
86
86
  gasUsed: bigint;
87
- blockNumber: BlockNumber;
88
- forcePendingBlockNumber: BlockNumber;
87
+ checkpointNumber: CheckpointNumber;
88
+ forcePendingCheckpointNumber: CheckpointNumber;
89
89
  };
90
90
 
91
91
  interface RequestWithExpiry {
@@ -139,13 +139,15 @@ export class SequencerPublisher {
139
139
  public slashingProposerContract: EmpireSlashingProposerContract | TallySlashingProposerContract | undefined;
140
140
  public slashFactoryContract: SlashFactoryContract;
141
141
 
142
+ public readonly tracer: Tracer;
143
+
142
144
  protected requests: RequestWithExpiry[] = [];
143
145
 
144
146
  constructor(
145
147
  private config: TxSenderConfig & PublisherConfig & Pick<L1ContractsConfig, 'ethereumSlotDuration'>,
146
148
  deps: {
147
149
  telemetry?: TelemetryClient;
148
- blobClient?: BlobClientInterface;
150
+ blobClient: BlobClientInterface;
149
151
  l1TxUtils: L1TxUtilsWithBlobs;
150
152
  rollupContract: RollupContract;
151
153
  slashingProposerContract: EmpireSlashingProposerContract | TallySlashingProposerContract | undefined;
@@ -163,11 +165,11 @@ export class SequencerPublisher {
163
165
  this.epochCache = deps.epochCache;
164
166
  this.lastActions = deps.lastActions;
165
167
 
166
- this.blobClient =
167
- deps.blobClient ?? createBlobClient(config, { logger: createLogger('sequencer:blob-client:client') });
168
+ this.blobClient = deps.blobClient;
168
169
 
169
170
  const telemetry = deps.telemetry ?? getTelemetryClient();
170
171
  this.metrics = deps.metrics ?? new SequencerPublisherMetrics(telemetry, 'SequencerPublisher');
172
+ this.tracer = telemetry.getTracer('SequencerPublisher');
171
173
  this.l1TxUtils = deps.l1TxUtils;
172
174
 
173
175
  this.rollupContract = deps.rollupContract;
@@ -297,6 +299,7 @@ export class SequencerPublisher {
297
299
  * - a receipt and errorMsg if it failed on L1
298
300
  * - undefined if no valid requests are found OR the tx failed to send.
299
301
  */
302
+ @trackSpan('SequencerPublisher.sendRequests')
300
303
  public async sendRequests() {
301
304
  const requestsToProcess = [...this.requests];
302
305
  this.requests = [];
@@ -414,17 +417,14 @@ export class SequencerPublisher {
414
417
  public canProposeAtNextEthBlock(
415
418
  tipArchive: Fr,
416
419
  msgSender: EthAddress,
417
- opts: { forcePendingBlockNumber?: BlockNumber } = {},
420
+ opts: { forcePendingCheckpointNumber?: CheckpointNumber } = {},
418
421
  ) {
419
422
  // TODO: #14291 - should loop through multiple keys to check if any of them can propose
420
423
  const ignoredErrors = ['SlotAlreadyInChain', 'InvalidProposer', 'InvalidArchive'];
421
424
 
422
425
  return this.rollupContract
423
426
  .canProposeAtNextEthBlock(tipArchive.toBuffer(), msgSender.toString(), Number(this.ethereumSlotDuration), {
424
- forcePendingCheckpointNumber:
425
- opts.forcePendingBlockNumber !== undefined
426
- ? CheckpointNumber.fromBlockNumber(opts.forcePendingBlockNumber)
427
- : undefined,
427
+ forcePendingCheckpointNumber: opts.forcePendingCheckpointNumber,
428
428
  })
429
429
  .catch(err => {
430
430
  if (err instanceof FormattedViemError && ignoredErrors.find(e => err.message.includes(e))) {
@@ -443,10 +443,11 @@ export class SequencerPublisher {
443
443
  * It will throw if the block header is invalid.
444
444
  * @param header - The block header to validate
445
445
  */
446
+ @trackSpan('SequencerPublisher.validateBlockHeader')
446
447
  public async validateBlockHeader(
447
448
  header: CheckpointHeader,
448
- opts?: { forcePendingBlockNumber: BlockNumber | undefined },
449
- ) {
449
+ opts?: { forcePendingCheckpointNumber: CheckpointNumber | undefined },
450
+ ): Promise<void> {
450
451
  const flags = { ignoreDA: true, ignoreSignatures: true };
451
452
 
452
453
  const args = [
@@ -455,17 +456,13 @@ export class SequencerPublisher {
455
456
  [], // no signers
456
457
  Signature.empty().toViemSignature(),
457
458
  `0x${'0'.repeat(64)}`, // 32 empty bytes
458
- header.contentCommitment.blobsHash.toString(),
459
+ header.blobsHash.toString(),
459
460
  flags,
460
461
  ] as const;
461
462
 
462
463
  const ts = BigInt((await this.l1TxUtils.getBlock()).timestamp + this.ethereumSlotDuration);
463
- const optsForcePendingCheckpointNumber =
464
- opts?.forcePendingBlockNumber !== undefined
465
- ? CheckpointNumber.fromBlockNumber(opts.forcePendingBlockNumber)
466
- : undefined;
467
464
  const stateOverrides = await this.rollupContract.makePendingCheckpointNumberOverride(
468
- optsForcePendingCheckpointNumber,
465
+ opts?.forcePendingCheckpointNumber,
469
466
  );
470
467
  let balance = 0n;
471
468
  if (this.config.fishermanMode) {
@@ -493,77 +490,90 @@ export class SequencerPublisher {
493
490
  }
494
491
 
495
492
  /**
496
- * Simulate making a call to invalidate a block with invalid attestations. Returns undefined if no need to invalidate.
497
- * @param block - The block to invalidate and the criteria for invalidation (as returned by the archiver)
493
+ * Simulate making a call to invalidate a checkpoint with invalid attestations. Returns undefined if no need to invalidate.
494
+ * @param validationResult - The validation result indicating which checkpoint to invalidate (as returned by the archiver)
498
495
  */
499
- public async simulateInvalidateBlock(
500
- validationResult: ValidateBlockResult,
501
- ): Promise<InvalidateBlockRequest | undefined> {
496
+ public async simulateInvalidateCheckpoint(
497
+ validationResult: ValidateCheckpointResult,
498
+ ): Promise<InvalidateCheckpointRequest | undefined> {
502
499
  if (validationResult.valid) {
503
500
  return undefined;
504
501
  }
505
502
 
506
- const { reason, block } = validationResult;
507
- const blockNumber = block.blockNumber;
508
- const logData = { ...block, reason };
503
+ const { reason, checkpoint } = validationResult;
504
+ const checkpointNumber = checkpoint.checkpointNumber;
505
+ const logData = { ...checkpoint, reason };
509
506
 
510
- const currentBlockNumber = await this.rollupContract.getCheckpointNumber();
511
- if (currentBlockNumber < validationResult.block.blockNumber) {
507
+ const currentCheckpointNumber = await this.rollupContract.getCheckpointNumber();
508
+ if (currentCheckpointNumber < checkpointNumber) {
512
509
  this.log.verbose(
513
- `Skipping block ${blockNumber} invalidation since it has already been removed from the pending chain`,
514
- { currentBlockNumber, ...logData },
510
+ `Skipping checkpoint ${checkpointNumber} invalidation since it has already been removed from the pending chain`,
511
+ { currentCheckpointNumber, ...logData },
515
512
  );
516
513
  return undefined;
517
514
  }
518
515
 
519
- const request = this.buildInvalidateBlockRequest(validationResult);
520
- this.log.debug(`Simulating invalidate block ${blockNumber}`, { ...logData, request });
516
+ const request = this.buildInvalidateCheckpointRequest(validationResult);
517
+ this.log.debug(`Simulating invalidate checkpoint ${checkpointNumber}`, { ...logData, request });
521
518
 
522
519
  try {
523
520
  const { gasUsed } = await this.l1TxUtils.simulate(request, undefined, undefined, ErrorsAbi);
524
- this.log.verbose(`Simulation for invalidate block ${blockNumber} succeeded`, { ...logData, request, gasUsed });
521
+ this.log.verbose(`Simulation for invalidate checkpoint ${checkpointNumber} succeeded`, {
522
+ ...logData,
523
+ request,
524
+ gasUsed,
525
+ });
525
526
 
526
- return { request, gasUsed, blockNumber, forcePendingBlockNumber: BlockNumber(blockNumber - 1), reason };
527
+ return {
528
+ request,
529
+ gasUsed,
530
+ checkpointNumber,
531
+ forcePendingCheckpointNumber: CheckpointNumber(checkpointNumber - 1),
532
+ reason,
533
+ };
527
534
  } catch (err) {
528
535
  const viemError = formatViemError(err);
529
536
 
530
- // If the error is due to the block not being in the pending chain, and it was indeed removed by someone else,
531
- // we can safely ignore it and return undefined so we go ahead with block building.
537
+ // If the error is due to the checkpoint not being in the pending chain, and it was indeed removed by someone else,
538
+ // we can safely ignore it and return undefined so we go ahead with checkpoint building.
532
539
  if (viemError.message?.includes('Rollup__BlockNotInPendingChain')) {
533
540
  this.log.verbose(
534
- `Simulation for invalidate block ${blockNumber} failed due to block not being in pending chain`,
541
+ `Simulation for invalidate checkpoint ${checkpointNumber} failed due to checkpoint not being in pending chain`,
535
542
  { ...logData, request, error: viemError.message },
536
543
  );
537
- const latestPendingBlockNumber = await this.rollupContract.getCheckpointNumber();
538
- if (latestPendingBlockNumber < blockNumber) {
539
- this.log.verbose(`Block number ${blockNumber} has already been invalidated`, { ...logData });
544
+ const latestPendingCheckpointNumber = await this.rollupContract.getCheckpointNumber();
545
+ if (latestPendingCheckpointNumber < checkpointNumber) {
546
+ this.log.verbose(`Checkpoint ${checkpointNumber} has already been invalidated`, { ...logData });
540
547
  return undefined;
541
548
  } else {
542
549
  this.log.error(
543
- `Simulation for invalidate ${blockNumber} failed and it is still in pending chain`,
550
+ `Simulation for invalidate checkpoint ${checkpointNumber} failed and it is still in pending chain`,
544
551
  viemError,
545
552
  logData,
546
553
  );
547
- throw new Error(`Failed to simulate invalidate block ${blockNumber} while it is still in pending chain`, {
548
- cause: viemError,
549
- });
554
+ throw new Error(
555
+ `Failed to simulate invalidate checkpoint ${checkpointNumber} while it is still in pending chain`,
556
+ {
557
+ cause: viemError,
558
+ },
559
+ );
550
560
  }
551
561
  }
552
562
 
553
- // Otherwise, throw. We cannot build the next block if we cannot invalidate the previous one.
554
- this.log.error(`Simulation for invalidate block ${blockNumber} failed`, viemError, logData);
555
- throw new Error(`Failed to simulate invalidate block ${blockNumber}`, { cause: viemError });
563
+ // Otherwise, throw. We cannot build the next checkpoint if we cannot invalidate the previous one.
564
+ this.log.error(`Simulation for invalidate checkpoint ${checkpointNumber} failed`, viemError, logData);
565
+ throw new Error(`Failed to simulate invalidate checkpoint ${checkpointNumber}`, { cause: viemError });
556
566
  }
557
567
  }
558
568
 
559
- private buildInvalidateBlockRequest(validationResult: ValidateBlockResult) {
569
+ private buildInvalidateCheckpointRequest(validationResult: ValidateCheckpointResult) {
560
570
  if (validationResult.valid) {
561
- throw new Error('Cannot invalidate a valid block');
571
+ throw new Error('Cannot invalidate a valid checkpoint');
562
572
  }
563
573
 
564
- const { block, committee, reason } = validationResult;
565
- const logData = { ...block, reason };
566
- this.log.debug(`Simulating invalidate block ${block.blockNumber}`, logData);
574
+ const { checkpoint, committee, reason } = validationResult;
575
+ const logData = { ...checkpoint, reason };
576
+ this.log.debug(`Building invalidate checkpoint ${checkpoint.checkpointNumber} request`, logData);
567
577
 
568
578
  const attestationsAndSigners = new CommitteeAttestationsAndSigners(
569
579
  validationResult.attestations,
@@ -571,14 +581,14 @@ export class SequencerPublisher {
571
581
 
572
582
  if (reason === 'invalid-attestation') {
573
583
  return this.rollupContract.buildInvalidateBadAttestationRequest(
574
- CheckpointNumber.fromBlockNumber(block.blockNumber),
584
+ checkpoint.checkpointNumber,
575
585
  attestationsAndSigners,
576
586
  committee,
577
587
  validationResult.invalidIndex,
578
588
  );
579
589
  } else if (reason === 'insufficient-attestations') {
580
590
  return this.rollupContract.buildInvalidateInsufficientAttestationsRequest(
581
- CheckpointNumber.fromBlockNumber(block.blockNumber),
591
+ checkpoint.checkpointNumber,
582
592
  attestationsAndSigners,
583
593
  committee,
584
594
  );
@@ -589,11 +599,12 @@ export class SequencerPublisher {
589
599
  }
590
600
 
591
601
  /** Simulates `propose` to make sure that the checkpoint is valid for submission */
602
+ @trackSpan('SequencerPublisher.validateCheckpointForSubmission')
592
603
  public async validateCheckpointForSubmission(
593
604
  checkpoint: Checkpoint,
594
605
  attestationsAndSigners: CommitteeAttestationsAndSigners,
595
606
  attestationsAndSignersSignature: Signature,
596
- options: { forcePendingBlockNumber?: BlockNumber }, // TODO(palla/mbps): Should this be forcePendingCheckpointNumber?
607
+ options: { forcePendingCheckpointNumber?: CheckpointNumber },
597
608
  ): Promise<bigint> {
598
609
  const ts = BigInt((await this.l1TxUtils.getBlock()).timestamp + this.ethereumSlotDuration);
599
610
 
@@ -892,7 +903,7 @@ export class SequencerPublisher {
892
903
  checkpoint: Checkpoint,
893
904
  attestationsAndSigners: CommitteeAttestationsAndSigners,
894
905
  attestationsAndSignersSignature: Signature,
895
- opts: { txTimeoutAt?: Date; forcePendingBlockNumber?: BlockNumber } = {},
906
+ opts: { txTimeoutAt?: Date; forcePendingCheckpointNumber?: CheckpointNumber } = {},
896
907
  ): Promise<void> {
897
908
  const checkpointHeader = checkpoint.header;
898
909
 
@@ -925,7 +936,7 @@ export class SequencerPublisher {
925
936
  this.log.error(`Checkpoint validation failed. ${err instanceof Error ? err.message : 'No error message'}`, err, {
926
937
  ...checkpoint.getStats(),
927
938
  slotNumber: checkpoint.header.slotNumber,
928
- forcePendingBlockNumber: opts.forcePendingBlockNumber,
939
+ forcePendingCheckpointNumber: opts.forcePendingCheckpointNumber,
929
940
  });
930
941
  throw err;
931
942
  }
@@ -934,7 +945,10 @@ export class SequencerPublisher {
934
945
  await this.addProposeTx(checkpoint, proposeTxArgs, opts, ts);
935
946
  }
936
947
 
937
- public enqueueInvalidateBlock(request: InvalidateBlockRequest | undefined, opts: { txTimeoutAt?: Date } = {}) {
948
+ public enqueueInvalidateCheckpoint(
949
+ request: InvalidateCheckpointRequest | undefined,
950
+ opts: { txTimeoutAt?: Date } = {},
951
+ ) {
938
952
  if (!request) {
939
953
  return;
940
954
  }
@@ -942,9 +956,9 @@ export class SequencerPublisher {
942
956
  // We issued the simulation against the rollup contract, so we need to account for the overhead of the multicall3
943
957
  const gasLimit = this.l1TxUtils.bumpGasLimit(BigInt(Math.ceil((Number(request.gasUsed) * 64) / 63)));
944
958
 
945
- const { gasUsed, blockNumber } = request;
946
- const logData = { gasUsed, blockNumber, gasLimit, opts };
947
- this.log.verbose(`Enqueuing invalidate block request`, logData);
959
+ const { gasUsed, checkpointNumber } = request;
960
+ const logData = { gasUsed, checkpointNumber, gasLimit, opts };
961
+ this.log.verbose(`Enqueuing invalidate checkpoint request`, logData);
948
962
  this.addRequest({
949
963
  action: `invalidate-by-${request.reason}`,
950
964
  request: request.request,
@@ -957,9 +971,9 @@ export class SequencerPublisher {
957
971
  result.receipt.status === 'success' &&
958
972
  tryExtractEvent(result.receipt.logs, this.rollupContract.address, RollupAbi, 'CheckpointInvalidated');
959
973
  if (!success) {
960
- this.log.warn(`Invalidate block ${request.blockNumber} failed`, { ...result, ...logData });
974
+ this.log.warn(`Invalidate checkpoint ${request.checkpointNumber} failed`, { ...result, ...logData });
961
975
  } else {
962
- this.log.info(`Invalidate block ${request.blockNumber} succeeded`, { ...result, ...logData });
976
+ this.log.info(`Invalidate checkpoint ${request.checkpointNumber} succeeded`, { ...result, ...logData });
963
977
  }
964
978
  return !!success;
965
979
  },
@@ -1038,7 +1052,7 @@ export class SequencerPublisher {
1038
1052
  private async prepareProposeTx(
1039
1053
  encodedData: L1ProcessArgs,
1040
1054
  timestamp: bigint,
1041
- options: { forcePendingBlockNumber?: BlockNumber },
1055
+ options: { forcePendingCheckpointNumber?: CheckpointNumber },
1042
1056
  ) {
1043
1057
  const kzg = Blob.getViemKzgInstance();
1044
1058
  const blobInput = getPrefixedEthBlobCommitments(encodedData.blobs);
@@ -1119,7 +1133,7 @@ export class SequencerPublisher {
1119
1133
  `0x${string}`,
1120
1134
  ],
1121
1135
  timestamp: bigint,
1122
- options: { forcePendingBlockNumber?: BlockNumber },
1136
+ options: { forcePendingCheckpointNumber?: CheckpointNumber },
1123
1137
  ) {
1124
1138
  const rollupData = encodeFunctionData({
1125
1139
  abi: RollupAbi,
@@ -1128,13 +1142,9 @@ export class SequencerPublisher {
1128
1142
  });
1129
1143
 
1130
1144
  // override the pending checkpoint number if requested
1131
- const optsForcePendingCheckpointNumber =
1132
- options.forcePendingBlockNumber !== undefined
1133
- ? CheckpointNumber.fromBlockNumber(options.forcePendingBlockNumber)
1134
- : undefined;
1135
1145
  const forcePendingCheckpointNumberStateDiff = (
1136
- optsForcePendingCheckpointNumber !== undefined
1137
- ? await this.rollupContract.makePendingCheckpointNumberOverride(optsForcePendingCheckpointNumber)
1146
+ options.forcePendingCheckpointNumber !== undefined
1147
+ ? await this.rollupContract.makePendingCheckpointNumberOverride(options.forcePendingCheckpointNumber)
1138
1148
  : []
1139
1149
  ).flatMap(override => override.stateDiff ?? []);
1140
1150
 
@@ -1198,7 +1208,7 @@ export class SequencerPublisher {
1198
1208
  private async addProposeTx(
1199
1209
  checkpoint: Checkpoint,
1200
1210
  encodedData: L1ProcessArgs,
1201
- opts: { txTimeoutAt?: Date; forcePendingBlockNumber?: BlockNumber } = {},
1211
+ opts: { txTimeoutAt?: Date; forcePendingCheckpointNumber?: CheckpointNumber } = {},
1202
1212
  timestamp: bigint,
1203
1213
  ): Promise<void> {
1204
1214
  const slot = checkpoint.header.slotNumber;