Skip to content

Conversation

@spalladino
Copy link
Contributor

@spalladino spalladino commented Dec 5, 2025

Summary

This PR refactors the sequencer to propose checkpoints instead of individual blocks, enabling multi-block checkpoint proposals. The sequencer now builds multiple blocks within a slot and packages them into a single checkpoint for L1 publication.

Yes, this text was written by Claude

Environment Variables

New

  • SEQ_BLOCK_DURATION_MS: Duration per block in milliseconds when building multiple blocks per slot. If undefined (default), builds a single block per slot using the full slot duration.
  • SEQ_BUILD_CHECKPOINT_IF_EMPTY: Whether to build and publish an empty checkpoint when there are no txs (defaults to true).

Changed

  • SEQ_MAX_L1_TX_INCLUSION_TIME_INTO_SLOT changed to SEQ_L1_PUBLISHING_TIME_ALLOWANCE_IN_SLOT: Aka "the dead zone". Renamed to better reflect its purpose of how much time (in seconds) we allow in the slot for publishing the L1 tx (defaults to 1 L1 slot).
  • SEQ_TX_POLLING_INTERVAL_MS changed to SEQ_POLLING_INTERVAL_MS: This is the polling for the sequencer loop, unrelated to polling for txs.

Architecture Changes

Main Sequencer

Sequencer now focuses on orchestration and state management by delegating checkpoint proposal logic to a job-like class. It now manages lifecycle of checkpoint proposal jobs and handles checkpoint invalidation.

CheckpointProposalJob (new)

Extracted checkpoint proposal logic into a dedicated, self-contained job that manages the full lifecycle of building and proposing a checkpoint. Handles block building loop, attestation collection, L1 publishing, and P2P broadcasting.

CheckpointVoter (new)

Handles voting for slashing and governance proposals, called from both the main sequencer and the proposal job.

SequencerPublisher

Updated the publisher to work with Checkpoints as opposed to Blocks.

CheckpointsBuilder (new)

Emulates the old BlockBuilder but for checkpoints, managing checkpoint-level state, and orchestrating building multiple blocks within a checkpoint. Builds on top of the LightweightCheckpointBuilder.

Miscellaneous Changes

Disposable Interface

MerkleTreeWriteOperations, GuardedMerkleTree, and HintingDbSource now implement a Disposable interface for proper resource cleanup.

Global Variables

Introduced a CheckpointGlobalVariables for checkpoint-level constants, separating block-level and checkpoint-level variables.

Sequencer Config

All sequencer config defaults are now in a single DefaultSequencerConfig object, and the Sequencer works with a config type with most entries defined.

Placeholders

Validator Client

Block proposals currently create dummy checkpoint proposals, and checkpoint proposal creation needs to be distinguished from block proposals.

Archiver & World State Sync

Provisional blocks are not yet sent to archiver and world state, actual sync mechanism to be wired once available.

P2P Broadcasting

Checkpoint proposals and provisional blocks use placeholder P2P API, needs wiring to new P2P protocol once available.

Pending Work

  1. Timetable fixes: Review timing for new states and fix timing calculations.
  2. Checkpoint invalidation: Implement proper checkpoint invalidation (currently invalidates blocks)
  3. Checkpoint number computation: Derive proper checkpoint numbers (currently assumes checkpoint number is the same as block number)
  4. Block builder cleanup: Remove old block builder in favor of CheckpointsBuilder
  5. Metrics review: Audit all metrics for checkpoint-level tracking
  6. Re-enable disabled tests: Fix and restore checkpoint proposal failure tests and multi-block checkpoint tests

@spalladino spalladino force-pushed the palla/sequencer-multiple-blocks branch 2 times, most recently from 0f4ef07 to 6c17d6c Compare December 11, 2025 17:59
@spalladino spalladino added the ci-no-fail-fast Sets NO_FAIL_FAST in the CI so the run is not aborted on the first failure label Dec 11, 2025
@spalladino spalladino marked this pull request as ready for review December 11, 2025 18:08
@spalladino spalladino force-pushed the palla/sequencer-multiple-blocks branch 5 times, most recently from 2249b20 to e6c739f Compare December 13, 2025 02:10
...booleanConfigHelper(DefaultSequencerConfig.shuffleAttestationOrdering),
},
blockDurationMs: {
env: 'SEQ_BLOCK_DURATION_MS',
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be more intuitive to configure a 'num blocks per slot' instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair. I wanted to be more explicit, since block duration is not just slot_duration / num_blocks. It also depends on the SEQ_L1_PUBLISHING_TIME_ALLOWANCE_IN_SLOT below, plus some constant overheads, plus how late we actually started building (affected by sync time). This ultimately relates to the big TODO I have on the timetable.

env: 'SEQ_MAX_L1_TX_INCLUSION_TIME_INTO_SLOT',
description: 'How many seconds into an L1 slot we can still send a tx and get it mined.',
l1PublishingTime: {
env: 'SEQ_L1_PUBLISHING_TIME_ALLOWANCE_IN_SLOT',
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this not have a default?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Default depends on whether we're running on Anvil or a real network, same as the old env var it replaced

return await this.db.close();
}

async [Symbol.dispose](): Promise<void> {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lovely!

@spalladino spalladino force-pushed the palla/sequencer-multiple-blocks branch 5 times, most recently from e7f1686 to eed0404 Compare December 16, 2025 22:21
Copy link
Collaborator

@PhilWindle PhilWindle left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a fantastic PR, thanks @spalladino .

I have a couple of questions but we follow up separately. I don't want to hold this up or we will get merge conflicts. I also want to get this running on next ASAP.

@spalladino spalladino force-pushed the palla/sequencer-multiple-blocks branch from f1339ca to 4ed9f7e Compare December 22, 2025 13:10
@spalladino spalladino added this pull request to the merge queue Dec 22, 2025
Merged via the queue into next with commit d3be5a7 Dec 22, 2025
15 checks passed
@spalladino spalladino deleted the palla/sequencer-multiple-blocks branch December 22, 2025 15:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci-no-fail-fast Sets NO_FAIL_FAST in the CI so the run is not aborted on the first failure

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants