@aztec/sequencer-client 0.0.1-commit.6230efd → 0.0.1-commit.64b6bbb

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 (76) 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/client/sequencer-client.js +1 -1
  4. package/dest/config.d.ts +1 -2
  5. package/dest/config.d.ts.map +1 -1
  6. package/dest/config.js +10 -9
  7. package/dest/global_variable_builder/global_builder.d.ts +4 -4
  8. package/dest/global_variable_builder/global_builder.d.ts.map +1 -1
  9. package/dest/global_variable_builder/global_builder.js +13 -13
  10. package/dest/index.d.ts +2 -3
  11. package/dest/index.d.ts.map +1 -1
  12. package/dest/index.js +1 -2
  13. package/dest/publisher/sequencer-publisher-metrics.d.ts +1 -1
  14. package/dest/publisher/sequencer-publisher-metrics.d.ts.map +1 -1
  15. package/dest/publisher/sequencer-publisher-metrics.js +23 -86
  16. package/dest/publisher/sequencer-publisher.d.ts +17 -17
  17. package/dest/publisher/sequencer-publisher.d.ts.map +1 -1
  18. package/dest/publisher/sequencer-publisher.js +481 -67
  19. package/dest/sequencer/checkpoint_proposal_job.d.ts +40 -12
  20. package/dest/sequencer/checkpoint_proposal_job.d.ts.map +1 -1
  21. package/dest/sequencer/checkpoint_proposal_job.js +606 -57
  22. package/dest/sequencer/checkpoint_voter.d.ts +3 -2
  23. package/dest/sequencer/checkpoint_voter.d.ts.map +1 -1
  24. package/dest/sequencer/checkpoint_voter.js +34 -10
  25. package/dest/sequencer/index.d.ts +1 -3
  26. package/dest/sequencer/index.d.ts.map +1 -1
  27. package/dest/sequencer/index.js +0 -2
  28. package/dest/sequencer/metrics.d.ts +4 -4
  29. package/dest/sequencer/metrics.d.ts.map +1 -1
  30. package/dest/sequencer/metrics.js +48 -129
  31. package/dest/sequencer/sequencer.d.ts +27 -15
  32. package/dest/sequencer/sequencer.d.ts.map +1 -1
  33. package/dest/sequencer/sequencer.js +492 -43
  34. package/dest/sequencer/timetable.d.ts +1 -4
  35. package/dest/sequencer/timetable.d.ts.map +1 -1
  36. package/dest/sequencer/timetable.js +1 -4
  37. package/dest/test/index.d.ts +2 -3
  38. package/dest/test/index.d.ts.map +1 -1
  39. package/dest/test/mock_checkpoint_builder.d.ts +23 -11
  40. package/dest/test/mock_checkpoint_builder.d.ts.map +1 -1
  41. package/dest/test/mock_checkpoint_builder.js +50 -9
  42. package/dest/test/utils.d.ts +13 -9
  43. package/dest/test/utils.d.ts.map +1 -1
  44. package/dest/test/utils.js +26 -17
  45. package/package.json +30 -28
  46. package/src/client/sequencer-client.ts +4 -5
  47. package/src/config.ts +14 -11
  48. package/src/global_variable_builder/global_builder.ts +13 -13
  49. package/src/index.ts +1 -9
  50. package/src/publisher/sequencer-publisher-metrics.ts +17 -69
  51. package/src/publisher/sequencer-publisher.ts +118 -91
  52. package/src/sequencer/checkpoint_proposal_job.ts +258 -87
  53. package/src/sequencer/checkpoint_voter.ts +32 -7
  54. package/src/sequencer/index.ts +0 -2
  55. package/src/sequencer/metrics.ts +48 -138
  56. package/src/sequencer/sequencer.ts +133 -43
  57. package/src/sequencer/timetable.ts +6 -5
  58. package/src/test/index.ts +1 -2
  59. package/src/test/mock_checkpoint_builder.ts +91 -29
  60. package/src/test/utils.ts +55 -28
  61. package/dest/sequencer/block_builder.d.ts +0 -26
  62. package/dest/sequencer/block_builder.d.ts.map +0 -1
  63. package/dest/sequencer/block_builder.js +0 -129
  64. package/dest/sequencer/checkpoint_builder.d.ts +0 -63
  65. package/dest/sequencer/checkpoint_builder.d.ts.map +0 -1
  66. package/dest/sequencer/checkpoint_builder.js +0 -131
  67. package/dest/tx_validator/nullifier_cache.d.ts +0 -14
  68. package/dest/tx_validator/nullifier_cache.d.ts.map +0 -1
  69. package/dest/tx_validator/nullifier_cache.js +0 -24
  70. package/dest/tx_validator/tx_validator_factory.d.ts +0 -18
  71. package/dest/tx_validator/tx_validator_factory.d.ts.map +0 -1
  72. package/dest/tx_validator/tx_validator_factory.js +0 -53
  73. package/src/sequencer/block_builder.ts +0 -217
  74. package/src/sequencer/checkpoint_builder.ts +0 -217
  75. package/src/tx_validator/nullifier_cache.ts +0 -30
  76. package/src/tx_validator/tx_validator_factory.ts +0 -133
@@ -12,7 +12,7 @@ import type { DateProvider } from '@aztec/foundation/timer';
12
12
  import type { TypedEventEmitter } from '@aztec/foundation/types';
13
13
  import type { P2P } from '@aztec/p2p';
14
14
  import type { SlasherClientInterface } from '@aztec/slasher';
15
- import type { L2BlockNew, L2BlockSource, ValidateBlockResult } from '@aztec/stdlib/block';
15
+ import type { L2Block, L2BlockSink, L2BlockSource, ValidateCheckpointResult } from '@aztec/stdlib/block';
16
16
  import type { Checkpoint } from '@aztec/stdlib/checkpoint';
17
17
  import { getSlotAtTimestamp, getSlotStartBuildTimestamp } from '@aztec/stdlib/epoch-helpers';
18
18
  import {
@@ -24,16 +24,15 @@ import {
24
24
  import type { L1ToL2MessageSource } from '@aztec/stdlib/messaging';
25
25
  import { pickFromSchema } from '@aztec/stdlib/schemas';
26
26
  import { MerkleTreeId } from '@aztec/stdlib/trees';
27
- import { type TelemetryClient, type Tracer, getTelemetryClient, trackSpan } from '@aztec/telemetry-client';
28
- import type { ValidatorClient } from '@aztec/validator-client';
27
+ import { Attributes, type TelemetryClient, type Tracer, getTelemetryClient, trackSpan } from '@aztec/telemetry-client';
28
+ import { FullNodeCheckpointsBuilder, type ValidatorClient } from '@aztec/validator-client';
29
29
 
30
30
  import EventEmitter from 'node:events';
31
31
 
32
32
  import { DefaultSequencerConfig } from '../config.js';
33
33
  import type { GlobalVariableBuilder } from '../global_variable_builder/global_builder.js';
34
34
  import type { SequencerPublisherFactory } from '../publisher/sequencer-publisher-factory.js';
35
- import type { InvalidateBlockRequest, SequencerPublisher } from '../publisher/sequencer-publisher.js';
36
- import { FullNodeCheckpointsBuilder } from './checkpoint_builder.js';
35
+ import type { InvalidateCheckpointRequest, SequencerPublisher } from '../publisher/sequencer-publisher.js';
37
36
  import { CheckpointProposalJob } from './checkpoint_proposal_job.js';
38
37
  import { CheckpointVoter } from './checkpoint_voter.js';
39
38
  import { SequencerInterruptedError, SequencerTooSlowError } from './errors.js';
@@ -58,8 +57,11 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
58
57
  private state = SequencerState.STOPPED;
59
58
  private metrics: SequencerMetrics;
60
59
 
61
- /** The last slot for which we attempted to vote when sync failed, to prevent duplicate attempts. */
62
- private lastSlotForVoteWhenSyncFailed: SlotNumber | undefined;
60
+ /** The last slot for which we attempted to perform our voting duties with degraded block production */
61
+ private lastSlotForFallbackVote: SlotNumber | undefined;
62
+
63
+ /** The last slot for which we logged "no committee" warning, to avoid spam */
64
+ private lastSlotForNoCommitteeWarning: SlotNumber | undefined;
63
65
 
64
66
  /** The last slot for which we triggered a checkpoint proposal job, to prevent duplicate attempts. */
65
67
  private lastSlotForCheckpointProposalJob: SlotNumber | undefined;
@@ -91,7 +93,7 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
91
93
  protected p2pClient: P2P,
92
94
  protected worldState: WorldStateSynchronizer,
93
95
  protected slasherClient: SlasherClientInterface | undefined,
94
- protected l2BlockSource: L2BlockSource,
96
+ protected l2BlockSource: L2BlockSource & L2BlockSink,
95
97
  protected l1ToL2MessageSource: L1ToL2MessageSource,
96
98
  protected checkpointsBuilder: FullNodeCheckpointsBuilder,
97
99
  protected l1Constants: SequencerRollupConstants,
@@ -160,7 +162,6 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
160
162
  this.log.info('Stopped sequencer');
161
163
  }
162
164
 
163
- @trackSpan('Sequencer.work')
164
165
  /** Main sequencer loop with a try/catch */
165
166
  protected async safeWork() {
166
167
  try {
@@ -198,12 +199,13 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
198
199
  * - Collect attestations for the final block
199
200
  * - Submit checkpoint
200
201
  */
202
+ @trackSpan('Sequencer.work')
201
203
  protected async work() {
202
204
  this.setState(SequencerState.SYNCHRONIZING, undefined);
203
205
  const { slot, ts, now, epoch } = this.epochCache.getEpochAndSlotInNextL1Slot();
204
206
 
205
207
  // Check if we are synced and it's our slot, grab a publisher, check previous block invalidation, etc
206
- const checkpointProposalJob = await this.prepareCheckpointProposal(slot, ts, now);
208
+ const checkpointProposalJob = await this.prepareCheckpointProposal(epoch, slot, ts, now);
207
209
  if (!checkpointProposalJob) {
208
210
  return;
209
211
  }
@@ -233,7 +235,9 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
233
235
  * This is the initial step in the main loop.
234
236
  * @returns CheckpointProposalJob if successful, undefined if we are not yet synced or are not the proposer.
235
237
  */
238
+ @trackSpan('Sequencer.prepareCheckpointProposal')
236
239
  private async prepareCheckpointProposal(
240
+ epoch: EpochNumber,
237
241
  slot: SlotNumber,
238
242
  ts: bigint,
239
243
  now: bigint,
@@ -263,8 +267,27 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
263
267
  return undefined;
264
268
  }
265
269
 
266
- // TODO(palla/mbps): Compute proper checkpoint number
267
- const checkpointNumber = CheckpointNumber.fromBlockNumber(BlockNumber(syncedTo.blockNumber + 1));
270
+ // If escape hatch is open for this epoch, do not start checkpoint proposal work and do not attempt invalidations.
271
+ // Still perform governance/slashing voting (as proposer) once per slot.
272
+ const isEscapeHatchOpen = await this.epochCache.isEscapeHatchOpen(epoch);
273
+
274
+ if (isEscapeHatchOpen) {
275
+ this.setState(SequencerState.PROPOSER_CHECK, slot);
276
+ const [canPropose, proposer] = await this.checkCanPropose(slot);
277
+ if (canPropose) {
278
+ await this.tryVoteWhenEscapeHatchOpen({ slot, proposer });
279
+ } else {
280
+ this.log.trace(`Escape hatch open but we are not proposer, skipping vote-only actions`, {
281
+ slot,
282
+ epoch,
283
+ proposer,
284
+ });
285
+ }
286
+ return undefined;
287
+ }
288
+
289
+ // Next checkpoint follows from the last synced one
290
+ const checkpointNumber = CheckpointNumber(syncedTo.checkpointNumber + 1);
268
291
 
269
292
  const logCtx = {
270
293
  now,
@@ -280,9 +303,9 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
280
303
  this.setState(SequencerState.PROPOSER_CHECK, slot);
281
304
  const [canPropose, proposer] = await this.checkCanPropose(slot);
282
305
 
283
- // If we are not a proposer check if we should invalidate a invalid block, and bail
306
+ // If we are not a proposer check if we should invalidate an invalid checkpoint, and bail
284
307
  if (!canPropose) {
285
- await this.considerInvalidatingBlock(syncedTo, slot);
308
+ await this.considerInvalidatingCheckpoint(syncedTo, slot);
286
309
  return undefined;
287
310
  }
288
311
 
@@ -312,15 +335,14 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
312
335
  }
313
336
 
314
337
  // Prepare invalidation request if the pending chain is invalid (returns undefined if no need)
315
- // TODO(palla/mbps): We need to invalidate checkpoints, not blocks
316
- const invalidateBlock = await publisher.simulateInvalidateBlock(syncedTo.pendingChainValidationStatus);
338
+ const invalidateCheckpoint = await publisher.simulateInvalidateCheckpoint(syncedTo.pendingChainValidationStatus);
317
339
 
318
340
  // Check with the rollup contract if we can indeed propose at the next L2 slot. This check should not fail
319
341
  // if all the previous checks are good, but we do it just in case.
320
342
  const canProposeCheck = await publisher.canProposeAtNextEthBlock(
321
343
  syncedTo.archive,
322
344
  proposer ?? EthAddress.ZERO,
323
- invalidateBlock,
345
+ invalidateCheckpoint,
324
346
  );
325
347
 
326
348
  if (canProposeCheck === undefined) {
@@ -354,43 +376,49 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
354
376
  }
355
377
 
356
378
  this.lastSlotForCheckpointProposalJob = slot;
379
+ await this.p2pClient.prepareForSlot(slot);
357
380
  this.log.info(`Preparing checkpoint proposal ${checkpointNumber} at slot ${slot}`, { ...logCtx, proposer });
358
381
 
359
382
  // Create and return the checkpoint proposal job
360
383
  return this.createCheckpointProposalJob(
384
+ epoch,
361
385
  slot,
362
386
  checkpointNumber,
363
387
  syncedTo.blockNumber,
364
388
  proposer,
365
389
  publisher,
366
390
  attestorAddress,
367
- invalidateBlock,
391
+ invalidateCheckpoint,
368
392
  );
369
393
  }
370
394
 
371
395
  protected createCheckpointProposalJob(
396
+ epoch: EpochNumber,
372
397
  slot: SlotNumber,
373
398
  checkpointNumber: CheckpointNumber,
374
399
  syncedToBlockNumber: BlockNumber,
375
400
  proposer: EthAddress | undefined,
376
401
  publisher: SequencerPublisher,
377
402
  attestorAddress: EthAddress,
378
- invalidateBlock: InvalidateBlockRequest | undefined,
403
+ invalidateCheckpoint: InvalidateCheckpointRequest | undefined,
379
404
  ): CheckpointProposalJob {
380
405
  return new CheckpointProposalJob(
406
+ epoch,
381
407
  slot,
382
408
  checkpointNumber,
383
409
  syncedToBlockNumber,
384
410
  proposer,
385
411
  publisher,
386
412
  attestorAddress,
387
- invalidateBlock,
413
+ invalidateCheckpoint,
388
414
  this.validatorClient,
389
415
  this.globalsBuilder,
390
416
  this.p2pClient,
391
417
  this.worldState,
392
418
  this.l1ToL2MessageSource,
419
+ this.l2BlockSource,
393
420
  this.checkpointsBuilder,
421
+ this.l2BlockSource,
394
422
  this.l1Constants,
395
423
  this.config,
396
424
  this.timetable,
@@ -400,7 +428,8 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
400
428
  this.metrics,
401
429
  this,
402
430
  this.setState.bind(this),
403
- this.log,
431
+ this.tracer,
432
+ this.log.getBindings(),
404
433
  );
405
434
  }
406
435
 
@@ -469,9 +498,9 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
469
498
  number: syncSummary.latestBlockNumber,
470
499
  hash: syncSummary.latestBlockHash,
471
500
  })),
472
- this.l2BlockSource.getL2Tips().then(t => t.latest),
501
+ this.l2BlockSource.getL2Tips().then(t => t.proposed),
473
502
  this.p2pClient.getStatus().then(p2p => p2p.syncedToL2Block),
474
- this.l1ToL2MessageSource.getL2Tips().then(t => t.latest),
503
+ this.l1ToL2MessageSource.getL2Tips().then(t => t.proposed),
475
504
  this.l2BlockSource.getPendingChainValidationStatus(),
476
505
  ] as const);
477
506
 
@@ -479,6 +508,7 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
479
508
 
480
509
  // Handle zero as a special case, since the block hash won't match across services if we're changing the prefilled data for the genesis block,
481
510
  // as the world state can compute the new genesis block hash, but other components use the hardcoded constant.
511
+ // TODO(palla/mbps): Fix the above. All components should be able to handle dynamic genesis block hashes.
482
512
  const result =
483
513
  (l2BlockSource.number === 0 && worldState.number === 0 && p2p.number === 0 && l1ToL2MessageSource.number === 0) ||
484
514
  (worldState.hash === l2BlockSource.hash &&
@@ -494,10 +524,16 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
494
524
  const blockNumber = worldState.number;
495
525
  if (blockNumber < INITIAL_L2_BLOCK_NUM) {
496
526
  const archive = new Fr((await this.worldState.getCommitted().getTreeInfo(MerkleTreeId.ARCHIVE)).root);
497
- return { blockNumber: BlockNumber(INITIAL_L2_BLOCK_NUM - 1), archive, l1Timestamp, pendingChainValidationStatus };
527
+ return {
528
+ checkpointNumber: CheckpointNumber.ZERO,
529
+ blockNumber: BlockNumber.ZERO,
530
+ archive,
531
+ l1Timestamp,
532
+ pendingChainValidationStatus,
533
+ };
498
534
  }
499
535
 
500
- const block = await this.l2BlockSource.getL2BlockNew(blockNumber);
536
+ const block = await this.l2BlockSource.getL2Block(blockNumber);
501
537
  if (!block) {
502
538
  // this shouldn't really happen because a moment ago we checked that all components were in sync
503
539
  this.log.error(`Failed to get L2 block ${blockNumber} from the archiver with all components in sync`);
@@ -507,6 +543,7 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
507
543
  return {
508
544
  block,
509
545
  blockNumber: block.number,
546
+ checkpointNumber: block.checkpointNumber,
510
547
  archive: block.archive.root,
511
548
  l1Timestamp,
512
549
  pendingChainValidationStatus,
@@ -524,7 +561,10 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
524
561
  proposer = await this.epochCache.getProposerAttesterAddressInSlot(slot);
525
562
  } catch (e) {
526
563
  if (e instanceof NoCommitteeError) {
527
- this.log.warn(`Cannot propose at next L2 slot ${slot} since the committee does not exist on L1`);
564
+ if (this.lastSlotForNoCommitteeWarning !== slot) {
565
+ this.lastSlotForNoCommitteeWarning = slot;
566
+ this.log.warn(`Cannot propose at next L2 slot ${slot} since the committee does not exist on L1`);
567
+ }
528
568
  return [false, undefined];
529
569
  }
530
570
  this.log.error(`Error getting proposer for slot ${slot}`, e);
@@ -555,11 +595,12 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
555
595
  * Tries to vote on slashing actions and governance when the sync check fails but we're past the max time for initializing a proposal.
556
596
  * This allows the sequencer to participate in governance/slashing votes even when it cannot build blocks.
557
597
  */
598
+ @trackSpan('Seqeuencer.tryVoteWhenSyncFails', ({ slot }) => ({ [Attributes.SLOT_NUMBER]: slot }))
558
599
  protected async tryVoteWhenSyncFails(args: { slot: SlotNumber; ts: bigint }): Promise<void> {
559
600
  const { slot } = args;
560
601
 
561
602
  // Prevent duplicate attempts in the same slot
562
- if (this.lastSlotForVoteWhenSyncFailed === slot) {
603
+ if (this.lastSlotForFallbackVote === slot) {
563
604
  this.log.trace(`Already attempted to vote in slot ${slot} (skipping)`);
564
605
  return;
565
606
  }
@@ -591,7 +632,7 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
591
632
  }
592
633
 
593
634
  // Mark this slot as attempted
594
- this.lastSlotForVoteWhenSyncFailed = slot;
635
+ this.lastSlotForFallbackVote = slot;
595
636
 
596
637
  // Get a publisher for voting
597
638
  const { attestorAddress, publisher } = await this.publisherFactory.create(proposer);
@@ -625,13 +666,61 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
625
666
  await publisher.sendRequests();
626
667
  }
627
668
 
669
+ /**
670
+ * Tries to vote on slashing actions and governance proposals when escape hatch is open.
671
+ * This allows the sequencer to participate in voting without performing checkpoint proposal work.
672
+ */
673
+ @trackSpan('Sequencer.tryVoteWhenEscapeHatchOpen', ({ slot }) => ({ [Attributes.SLOT_NUMBER]: slot }))
674
+ protected async tryVoteWhenEscapeHatchOpen(args: {
675
+ slot: SlotNumber;
676
+ proposer: EthAddress | undefined;
677
+ }): Promise<void> {
678
+ const { slot, proposer } = args;
679
+
680
+ // Prevent duplicate attempts in the same slot
681
+ if (this.lastSlotForFallbackVote === slot) {
682
+ this.log.trace(`Already attempted to vote in slot ${slot} (escape hatch open, skipping)`);
683
+ return;
684
+ }
685
+
686
+ // Mark this slot as attempted
687
+ this.lastSlotForFallbackVote = slot;
688
+
689
+ const { attestorAddress, publisher } = await this.publisherFactory.create(proposer);
690
+
691
+ this.log.debug(`Escape hatch open for slot ${slot}, attempting vote-only actions`, { slot, attestorAddress });
692
+
693
+ const voter = new CheckpointVoter(
694
+ slot,
695
+ publisher,
696
+ attestorAddress,
697
+ this.validatorClient,
698
+ this.slasherClient,
699
+ this.l1Constants,
700
+ this.config,
701
+ this.metrics,
702
+ this.log,
703
+ );
704
+
705
+ const votesPromises = voter.enqueueVotes();
706
+ const votes = await Promise.all(votesPromises);
707
+
708
+ if (votes.every(p => !p)) {
709
+ this.log.debug(`No votes to enqueue for slot ${slot} (escape hatch open)`);
710
+ return;
711
+ }
712
+
713
+ this.log.info(`Voting in slot ${slot} (escape hatch open)`, { slot });
714
+ await publisher.sendRequests();
715
+ }
716
+
628
717
  /**
629
718
  * Considers invalidating a block if the pending chain is invalid. Depends on how long the invalid block
630
719
  * has been there without being invalidated and whether the sequencer is in the committee or not. We always
631
720
  * have the proposer try to invalidate, but if they fail, the sequencers in the committee are expected to try,
632
721
  * and if they fail, any sequencer will try as well.
633
722
  */
634
- protected async considerInvalidatingBlock(
723
+ protected async considerInvalidatingCheckpoint(
635
724
  syncedTo: SequencerSyncCheckResult,
636
725
  currentSlot: SlotNumber,
637
726
  ): Promise<void> {
@@ -640,18 +729,18 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
640
729
  return;
641
730
  }
642
731
 
643
- const invalidBlockNumber = pendingChainValidationStatus.block.blockNumber;
644
- const invalidBlockTimestamp = pendingChainValidationStatus.block.timestamp;
645
- const timeSinceChainInvalid = this.dateProvider.nowInSeconds() - Number(invalidBlockTimestamp);
732
+ const invalidCheckpointNumber = pendingChainValidationStatus.checkpoint.checkpointNumber;
733
+ const invalidCheckpointTimestamp = pendingChainValidationStatus.checkpoint.timestamp;
734
+ const timeSinceChainInvalid = this.dateProvider.nowInSeconds() - Number(invalidCheckpointTimestamp);
646
735
  const ourValidatorAddresses = this.validatorClient.getValidatorAddresses();
647
736
 
648
737
  const { secondsBeforeInvalidatingBlockAsCommitteeMember, secondsBeforeInvalidatingBlockAsNonCommitteeMember } =
649
738
  this.config;
650
739
 
651
740
  const logData = {
652
- invalidL1Timestamp: invalidBlockTimestamp,
741
+ invalidL1Timestamp: invalidCheckpointTimestamp,
653
742
  l1Timestamp,
654
- invalidBlock: pendingChainValidationStatus.block,
743
+ invalidCheckpoint: pendingChainValidationStatus.checkpoint,
655
744
  secondsBeforeInvalidatingBlockAsCommitteeMember,
656
745
  secondsBeforeInvalidatingBlockAsNonCommitteeMember,
657
746
  ourValidatorAddresses,
@@ -697,25 +786,25 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
697
786
 
698
787
  const { publisher } = await this.publisherFactory.create(validatorToUse);
699
788
 
700
- const invalidateBlock = await publisher.simulateInvalidateBlock(pendingChainValidationStatus);
701
- if (!invalidateBlock) {
702
- this.log.warn(`Failed to simulate invalidate block`, logData);
789
+ const invalidateCheckpoint = await publisher.simulateInvalidateCheckpoint(pendingChainValidationStatus);
790
+ if (!invalidateCheckpoint) {
791
+ this.log.warn(`Failed to simulate invalidate checkpoint`, logData);
703
792
  return;
704
793
  }
705
794
 
706
795
  this.log.info(
707
796
  invalidateAsCommitteeMember
708
- ? `Invalidating block ${invalidBlockNumber} as committee member`
709
- : `Invalidating block ${invalidBlockNumber} as non-committee member`,
797
+ ? `Invalidating checkpoint ${invalidCheckpointNumber} as committee member`
798
+ : `Invalidating checkpoint ${invalidCheckpointNumber} as non-committee member`,
710
799
  logData,
711
800
  );
712
801
 
713
- publisher.enqueueInvalidateBlock(invalidateBlock);
802
+ publisher.enqueueInvalidateCheckpoint(invalidateCheckpoint);
714
803
 
715
804
  if (!this.config.fishermanMode) {
716
805
  await publisher.sendRequests();
717
806
  } else {
718
- this.log.info('Invalidating block in fisherman mode, clearing pending requests');
807
+ this.log.info('Invalidating checkpoint in fisherman mode, clearing pending requests');
719
808
  publisher.clearPendingRequests();
720
809
  }
721
810
  }
@@ -788,9 +877,10 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
788
877
  }
789
878
 
790
879
  type SequencerSyncCheckResult = {
791
- block?: L2BlockNew;
880
+ block?: L2Block;
881
+ checkpointNumber: CheckpointNumber;
792
882
  blockNumber: BlockNumber;
793
883
  archive: Fr;
794
884
  l1Timestamp: bigint;
795
- pendingChainValidationStatus: ValidateBlockResult;
885
+ pendingChainValidationStatus: ValidateCheckpointResult;
796
886
  };
@@ -1,14 +1,15 @@
1
1
  import { createLogger } from '@aztec/aztec.js/log';
2
+ import {
3
+ CHECKPOINT_ASSEMBLE_TIME,
4
+ CHECKPOINT_INITIALIZATION_TIME,
5
+ DEFAULT_P2P_PROPAGATION_TIME,
6
+ MIN_EXECUTION_TIME,
7
+ } from '@aztec/stdlib/timetable';
2
8
 
3
- import { DEFAULT_ATTESTATION_PROPAGATION_TIME as DEFAULT_P2P_PROPAGATION_TIME } from '../config.js';
4
9
  import { SequencerTooSlowError } from './errors.js';
5
10
  import type { SequencerMetrics } from './metrics.js';
6
11
  import { SequencerState } from './utils.js';
7
12
 
8
- export const MIN_EXECUTION_TIME = 2;
9
- export const CHECKPOINT_INITIALIZATION_TIME = 1;
10
- export const CHECKPOINT_ASSEMBLE_TIME = 1;
11
-
12
13
  export class SequencerTimetable {
13
14
  /**
14
15
  * How late into the slot can we be to start working. Computed as the total time needed for assembling and publishing a block,
package/src/test/index.ts CHANGED
@@ -1,12 +1,11 @@
1
1
  import type { L1TxUtilsWithBlobs } from '@aztec/ethereum/l1-tx-utils-with-blobs';
2
2
  import type { PublisherManager } from '@aztec/ethereum/publisher-manager';
3
3
  import type { PublicProcessorFactory } from '@aztec/simulator/server';
4
- import type { ValidatorClient } from '@aztec/validator-client';
4
+ import type { FullNodeCheckpointsBuilder, ValidatorClient } from '@aztec/validator-client';
5
5
 
6
6
  import { SequencerClient } from '../client/sequencer-client.js';
7
7
  import type { SequencerPublisherFactory } from '../publisher/sequencer-publisher-factory.js';
8
8
  import type { SequencerPublisher } from '../publisher/sequencer-publisher.js';
9
- import type { FullNodeCheckpointsBuilder } from '../sequencer/checkpoint_builder.js';
10
9
  import { Sequencer } from '../sequencer/sequencer.js';
11
10
  import type { SequencerTimetable } from '../sequencer/timetable.js';
12
11