@aztec/sequencer-client 0.0.1-commit.c7c42ec → 0.0.1-commit.d1f2d6c

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 (71) hide show
  1. package/dest/client/sequencer-client.d.ts +4 -5
  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-metrics.d.ts +1 -1
  13. package/dest/publisher/sequencer-publisher-metrics.d.ts.map +1 -1
  14. package/dest/publisher/sequencer-publisher-metrics.js +15 -86
  15. package/dest/publisher/sequencer-publisher.d.ts +17 -16
  16. package/dest/publisher/sequencer-publisher.d.ts.map +1 -1
  17. package/dest/publisher/sequencer-publisher.js +442 -49
  18. package/dest/sequencer/checkpoint_proposal_job.d.ts +14 -9
  19. package/dest/sequencer/checkpoint_proposal_job.d.ts.map +1 -1
  20. package/dest/sequencer/checkpoint_proposal_job.js +561 -39
  21. package/dest/sequencer/checkpoint_voter.d.ts +3 -2
  22. package/dest/sequencer/checkpoint_voter.d.ts.map +1 -1
  23. package/dest/sequencer/checkpoint_voter.js +34 -10
  24. package/dest/sequencer/index.d.ts +1 -3
  25. package/dest/sequencer/index.d.ts.map +1 -1
  26. package/dest/sequencer/index.js +0 -2
  27. package/dest/sequencer/metrics.d.ts +3 -3
  28. package/dest/sequencer/metrics.d.ts.map +1 -1
  29. package/dest/sequencer/metrics.js +30 -121
  30. package/dest/sequencer/sequencer.d.ts +25 -15
  31. package/dest/sequencer/sequencer.d.ts.map +1 -1
  32. package/dest/sequencer/sequencer.js +486 -42
  33. package/dest/test/index.d.ts +2 -3
  34. package/dest/test/index.d.ts.map +1 -1
  35. package/dest/test/mock_checkpoint_builder.d.ts +19 -10
  36. package/dest/test/mock_checkpoint_builder.d.ts.map +1 -1
  37. package/dest/test/mock_checkpoint_builder.js +32 -3
  38. package/dest/test/utils.d.ts +13 -9
  39. package/dest/test/utils.d.ts.map +1 -1
  40. package/dest/test/utils.js +26 -17
  41. package/package.json +30 -28
  42. package/src/client/sequencer-client.ts +3 -4
  43. package/src/config.ts +5 -0
  44. package/src/global_variable_builder/global_builder.ts +13 -13
  45. package/src/index.ts +1 -9
  46. package/src/publisher/sequencer-publisher-metrics.ts +14 -70
  47. package/src/publisher/sequencer-publisher.ts +84 -73
  48. package/src/sequencer/checkpoint_proposal_job.ts +195 -58
  49. package/src/sequencer/checkpoint_voter.ts +32 -7
  50. package/src/sequencer/index.ts +0 -2
  51. package/src/sequencer/metrics.ts +23 -131
  52. package/src/sequencer/sequencer.ts +124 -41
  53. package/src/test/index.ts +1 -2
  54. package/src/test/mock_checkpoint_builder.ts +70 -22
  55. package/src/test/utils.ts +55 -28
  56. package/dest/sequencer/block_builder.d.ts +0 -26
  57. package/dest/sequencer/block_builder.d.ts.map +0 -1
  58. package/dest/sequencer/block_builder.js +0 -129
  59. package/dest/sequencer/checkpoint_builder.d.ts +0 -63
  60. package/dest/sequencer/checkpoint_builder.d.ts.map +0 -1
  61. package/dest/sequencer/checkpoint_builder.js +0 -131
  62. package/dest/tx_validator/nullifier_cache.d.ts +0 -14
  63. package/dest/tx_validator/nullifier_cache.d.ts.map +0 -1
  64. package/dest/tx_validator/nullifier_cache.js +0 -24
  65. package/dest/tx_validator/tx_validator_factory.d.ts +0 -18
  66. package/dest/tx_validator/tx_validator_factory.d.ts.map +0 -1
  67. package/dest/tx_validator/tx_validator_factory.js +0 -53
  68. package/src/sequencer/block_builder.ts +0 -217
  69. package/src/sequencer/checkpoint_builder.ts +0 -217
  70. package/src/tx_validator/nullifier_cache.ts +0 -30
  71. package/src/tx_validator/tx_validator_factory.ts +0 -133
@@ -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) {
@@ -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,6 +139,8 @@ 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(
@@ -167,6 +169,7 @@ export class SequencerPublisher {
167
169
 
168
170
  const telemetry = deps.telemetry ?? getTelemetryClient();
169
171
  this.metrics = deps.metrics ?? new SequencerPublisherMetrics(telemetry, 'SequencerPublisher');
172
+ this.tracer = telemetry.getTracer('SequencerPublisher');
170
173
  this.l1TxUtils = deps.l1TxUtils;
171
174
 
172
175
  this.rollupContract = deps.rollupContract;
@@ -296,6 +299,7 @@ export class SequencerPublisher {
296
299
  * - a receipt and errorMsg if it failed on L1
297
300
  * - undefined if no valid requests are found OR the tx failed to send.
298
301
  */
302
+ @trackSpan('SequencerPublisher.sendRequests')
299
303
  public async sendRequests() {
300
304
  const requestsToProcess = [...this.requests];
301
305
  this.requests = [];
@@ -413,17 +417,14 @@ export class SequencerPublisher {
413
417
  public canProposeAtNextEthBlock(
414
418
  tipArchive: Fr,
415
419
  msgSender: EthAddress,
416
- opts: { forcePendingBlockNumber?: BlockNumber } = {},
420
+ opts: { forcePendingCheckpointNumber?: CheckpointNumber } = {},
417
421
  ) {
418
422
  // TODO: #14291 - should loop through multiple keys to check if any of them can propose
419
423
  const ignoredErrors = ['SlotAlreadyInChain', 'InvalidProposer', 'InvalidArchive'];
420
424
 
421
425
  return this.rollupContract
422
426
  .canProposeAtNextEthBlock(tipArchive.toBuffer(), msgSender.toString(), Number(this.ethereumSlotDuration), {
423
- forcePendingCheckpointNumber:
424
- opts.forcePendingBlockNumber !== undefined
425
- ? CheckpointNumber.fromBlockNumber(opts.forcePendingBlockNumber)
426
- : undefined,
427
+ forcePendingCheckpointNumber: opts.forcePendingCheckpointNumber,
427
428
  })
428
429
  .catch(err => {
429
430
  if (err instanceof FormattedViemError && ignoredErrors.find(e => err.message.includes(e))) {
@@ -442,10 +443,11 @@ export class SequencerPublisher {
442
443
  * It will throw if the block header is invalid.
443
444
  * @param header - The block header to validate
444
445
  */
446
+ @trackSpan('SequencerPublisher.validateBlockHeader')
445
447
  public async validateBlockHeader(
446
448
  header: CheckpointHeader,
447
- opts?: { forcePendingBlockNumber: BlockNumber | undefined },
448
- ) {
449
+ opts?: { forcePendingCheckpointNumber: CheckpointNumber | undefined },
450
+ ): Promise<void> {
449
451
  const flags = { ignoreDA: true, ignoreSignatures: true };
450
452
 
451
453
  const args = [
@@ -454,17 +456,13 @@ export class SequencerPublisher {
454
456
  [], // no signers
455
457
  Signature.empty().toViemSignature(),
456
458
  `0x${'0'.repeat(64)}`, // 32 empty bytes
457
- header.contentCommitment.blobsHash.toString(),
459
+ header.blobsHash.toString(),
458
460
  flags,
459
461
  ] as const;
460
462
 
461
463
  const ts = BigInt((await this.l1TxUtils.getBlock()).timestamp + this.ethereumSlotDuration);
462
- const optsForcePendingCheckpointNumber =
463
- opts?.forcePendingBlockNumber !== undefined
464
- ? CheckpointNumber.fromBlockNumber(opts.forcePendingBlockNumber)
465
- : undefined;
466
464
  const stateOverrides = await this.rollupContract.makePendingCheckpointNumberOverride(
467
- optsForcePendingCheckpointNumber,
465
+ opts?.forcePendingCheckpointNumber,
468
466
  );
469
467
  let balance = 0n;
470
468
  if (this.config.fishermanMode) {
@@ -492,77 +490,90 @@ export class SequencerPublisher {
492
490
  }
493
491
 
494
492
  /**
495
- * Simulate making a call to invalidate a block with invalid attestations. Returns undefined if no need to invalidate.
496
- * @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)
497
495
  */
498
- public async simulateInvalidateBlock(
499
- validationResult: ValidateBlockResult,
500
- ): Promise<InvalidateBlockRequest | undefined> {
496
+ public async simulateInvalidateCheckpoint(
497
+ validationResult: ValidateCheckpointResult,
498
+ ): Promise<InvalidateCheckpointRequest | undefined> {
501
499
  if (validationResult.valid) {
502
500
  return undefined;
503
501
  }
504
502
 
505
- const { reason, block } = validationResult;
506
- const blockNumber = block.blockNumber;
507
- const logData = { ...block, reason };
503
+ const { reason, checkpoint } = validationResult;
504
+ const checkpointNumber = checkpoint.checkpointNumber;
505
+ const logData = { ...checkpoint, reason };
508
506
 
509
- const currentBlockNumber = await this.rollupContract.getCheckpointNumber();
510
- if (currentBlockNumber < validationResult.block.blockNumber) {
507
+ const currentCheckpointNumber = await this.rollupContract.getCheckpointNumber();
508
+ if (currentCheckpointNumber < checkpointNumber) {
511
509
  this.log.verbose(
512
- `Skipping block ${blockNumber} invalidation since it has already been removed from the pending chain`,
513
- { currentBlockNumber, ...logData },
510
+ `Skipping checkpoint ${checkpointNumber} invalidation since it has already been removed from the pending chain`,
511
+ { currentCheckpointNumber, ...logData },
514
512
  );
515
513
  return undefined;
516
514
  }
517
515
 
518
- const request = this.buildInvalidateBlockRequest(validationResult);
519
- 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 });
520
518
 
521
519
  try {
522
520
  const { gasUsed } = await this.l1TxUtils.simulate(request, undefined, undefined, ErrorsAbi);
523
- 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
+ });
524
526
 
525
- 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
+ };
526
534
  } catch (err) {
527
535
  const viemError = formatViemError(err);
528
536
 
529
- // If the error is due to the block not being in the pending chain, and it was indeed removed by someone else,
530
- // 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.
531
539
  if (viemError.message?.includes('Rollup__BlockNotInPendingChain')) {
532
540
  this.log.verbose(
533
- `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`,
534
542
  { ...logData, request, error: viemError.message },
535
543
  );
536
- const latestPendingBlockNumber = await this.rollupContract.getCheckpointNumber();
537
- if (latestPendingBlockNumber < blockNumber) {
538
- 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 });
539
547
  return undefined;
540
548
  } else {
541
549
  this.log.error(
542
- `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`,
543
551
  viemError,
544
552
  logData,
545
553
  );
546
- throw new Error(`Failed to simulate invalidate block ${blockNumber} while it is still in pending chain`, {
547
- cause: viemError,
548
- });
554
+ throw new Error(
555
+ `Failed to simulate invalidate checkpoint ${checkpointNumber} while it is still in pending chain`,
556
+ {
557
+ cause: viemError,
558
+ },
559
+ );
549
560
  }
550
561
  }
551
562
 
552
- // Otherwise, throw. We cannot build the next block if we cannot invalidate the previous one.
553
- this.log.error(`Simulation for invalidate block ${blockNumber} failed`, viemError, logData);
554
- 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 });
555
566
  }
556
567
  }
557
568
 
558
- private buildInvalidateBlockRequest(validationResult: ValidateBlockResult) {
569
+ private buildInvalidateCheckpointRequest(validationResult: ValidateCheckpointResult) {
559
570
  if (validationResult.valid) {
560
- throw new Error('Cannot invalidate a valid block');
571
+ throw new Error('Cannot invalidate a valid checkpoint');
561
572
  }
562
573
 
563
- const { block, committee, reason } = validationResult;
564
- const logData = { ...block, reason };
565
- 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);
566
577
 
567
578
  const attestationsAndSigners = new CommitteeAttestationsAndSigners(
568
579
  validationResult.attestations,
@@ -570,14 +581,14 @@ export class SequencerPublisher {
570
581
 
571
582
  if (reason === 'invalid-attestation') {
572
583
  return this.rollupContract.buildInvalidateBadAttestationRequest(
573
- CheckpointNumber.fromBlockNumber(block.blockNumber),
584
+ checkpoint.checkpointNumber,
574
585
  attestationsAndSigners,
575
586
  committee,
576
587
  validationResult.invalidIndex,
577
588
  );
578
589
  } else if (reason === 'insufficient-attestations') {
579
590
  return this.rollupContract.buildInvalidateInsufficientAttestationsRequest(
580
- CheckpointNumber.fromBlockNumber(block.blockNumber),
591
+ checkpoint.checkpointNumber,
581
592
  attestationsAndSigners,
582
593
  committee,
583
594
  );
@@ -588,11 +599,12 @@ export class SequencerPublisher {
588
599
  }
589
600
 
590
601
  /** Simulates `propose` to make sure that the checkpoint is valid for submission */
602
+ @trackSpan('SequencerPublisher.validateCheckpointForSubmission')
591
603
  public async validateCheckpointForSubmission(
592
604
  checkpoint: Checkpoint,
593
605
  attestationsAndSigners: CommitteeAttestationsAndSigners,
594
606
  attestationsAndSignersSignature: Signature,
595
- options: { forcePendingBlockNumber?: BlockNumber }, // TODO(palla/mbps): Should this be forcePendingCheckpointNumber?
607
+ options: { forcePendingCheckpointNumber?: CheckpointNumber },
596
608
  ): Promise<bigint> {
597
609
  const ts = BigInt((await this.l1TxUtils.getBlock()).timestamp + this.ethereumSlotDuration);
598
610
 
@@ -891,7 +903,7 @@ export class SequencerPublisher {
891
903
  checkpoint: Checkpoint,
892
904
  attestationsAndSigners: CommitteeAttestationsAndSigners,
893
905
  attestationsAndSignersSignature: Signature,
894
- opts: { txTimeoutAt?: Date; forcePendingBlockNumber?: BlockNumber } = {},
906
+ opts: { txTimeoutAt?: Date; forcePendingCheckpointNumber?: CheckpointNumber } = {},
895
907
  ): Promise<void> {
896
908
  const checkpointHeader = checkpoint.header;
897
909
 
@@ -924,7 +936,7 @@ export class SequencerPublisher {
924
936
  this.log.error(`Checkpoint validation failed. ${err instanceof Error ? err.message : 'No error message'}`, err, {
925
937
  ...checkpoint.getStats(),
926
938
  slotNumber: checkpoint.header.slotNumber,
927
- forcePendingBlockNumber: opts.forcePendingBlockNumber,
939
+ forcePendingCheckpointNumber: opts.forcePendingCheckpointNumber,
928
940
  });
929
941
  throw err;
930
942
  }
@@ -933,7 +945,10 @@ export class SequencerPublisher {
933
945
  await this.addProposeTx(checkpoint, proposeTxArgs, opts, ts);
934
946
  }
935
947
 
936
- public enqueueInvalidateBlock(request: InvalidateBlockRequest | undefined, opts: { txTimeoutAt?: Date } = {}) {
948
+ public enqueueInvalidateCheckpoint(
949
+ request: InvalidateCheckpointRequest | undefined,
950
+ opts: { txTimeoutAt?: Date } = {},
951
+ ) {
937
952
  if (!request) {
938
953
  return;
939
954
  }
@@ -941,9 +956,9 @@ export class SequencerPublisher {
941
956
  // We issued the simulation against the rollup contract, so we need to account for the overhead of the multicall3
942
957
  const gasLimit = this.l1TxUtils.bumpGasLimit(BigInt(Math.ceil((Number(request.gasUsed) * 64) / 63)));
943
958
 
944
- const { gasUsed, blockNumber } = request;
945
- const logData = { gasUsed, blockNumber, gasLimit, opts };
946
- 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);
947
962
  this.addRequest({
948
963
  action: `invalidate-by-${request.reason}`,
949
964
  request: request.request,
@@ -956,9 +971,9 @@ export class SequencerPublisher {
956
971
  result.receipt.status === 'success' &&
957
972
  tryExtractEvent(result.receipt.logs, this.rollupContract.address, RollupAbi, 'CheckpointInvalidated');
958
973
  if (!success) {
959
- this.log.warn(`Invalidate block ${request.blockNumber} failed`, { ...result, ...logData });
974
+ this.log.warn(`Invalidate checkpoint ${request.checkpointNumber} failed`, { ...result, ...logData });
960
975
  } else {
961
- this.log.info(`Invalidate block ${request.blockNumber} succeeded`, { ...result, ...logData });
976
+ this.log.info(`Invalidate checkpoint ${request.checkpointNumber} succeeded`, { ...result, ...logData });
962
977
  }
963
978
  return !!success;
964
979
  },
@@ -1037,7 +1052,7 @@ export class SequencerPublisher {
1037
1052
  private async prepareProposeTx(
1038
1053
  encodedData: L1ProcessArgs,
1039
1054
  timestamp: bigint,
1040
- options: { forcePendingBlockNumber?: BlockNumber },
1055
+ options: { forcePendingCheckpointNumber?: CheckpointNumber },
1041
1056
  ) {
1042
1057
  const kzg = Blob.getViemKzgInstance();
1043
1058
  const blobInput = getPrefixedEthBlobCommitments(encodedData.blobs);
@@ -1118,7 +1133,7 @@ export class SequencerPublisher {
1118
1133
  `0x${string}`,
1119
1134
  ],
1120
1135
  timestamp: bigint,
1121
- options: { forcePendingBlockNumber?: BlockNumber },
1136
+ options: { forcePendingCheckpointNumber?: CheckpointNumber },
1122
1137
  ) {
1123
1138
  const rollupData = encodeFunctionData({
1124
1139
  abi: RollupAbi,
@@ -1127,13 +1142,9 @@ export class SequencerPublisher {
1127
1142
  });
1128
1143
 
1129
1144
  // override the pending checkpoint number if requested
1130
- const optsForcePendingCheckpointNumber =
1131
- options.forcePendingBlockNumber !== undefined
1132
- ? CheckpointNumber.fromBlockNumber(options.forcePendingBlockNumber)
1133
- : undefined;
1134
1145
  const forcePendingCheckpointNumberStateDiff = (
1135
- optsForcePendingCheckpointNumber !== undefined
1136
- ? await this.rollupContract.makePendingCheckpointNumberOverride(optsForcePendingCheckpointNumber)
1146
+ options.forcePendingCheckpointNumber !== undefined
1147
+ ? await this.rollupContract.makePendingCheckpointNumberOverride(options.forcePendingCheckpointNumber)
1137
1148
  : []
1138
1149
  ).flatMap(override => override.stateDiff ?? []);
1139
1150
 
@@ -1197,7 +1208,7 @@ export class SequencerPublisher {
1197
1208
  private async addProposeTx(
1198
1209
  checkpoint: Checkpoint,
1199
1210
  encodedData: L1ProcessArgs,
1200
- opts: { txTimeoutAt?: Date; forcePendingBlockNumber?: BlockNumber } = {},
1211
+ opts: { txTimeoutAt?: Date; forcePendingCheckpointNumber?: CheckpointNumber } = {},
1201
1212
  timestamp: bigint,
1202
1213
  ): Promise<void> {
1203
1214
  const slot = checkpoint.header.slotNumber;