Skip to content

refactor: remove non-pipelining sequencer code path#23665

Merged
spalladino merged 6 commits into
merge-train/spartanfrom
spl/only-pipelining
Jun 1, 2026
Merged

refactor: remove non-pipelining sequencer code path#23665
spalladino merged 6 commits into
merge-train/spartanfrom
spl/only-pipelining

Conversation

@spalladino

@spalladino spalladino commented May 29, 2026

Copy link
Copy Markdown
Contributor

Motivation

Proposer pipelining (the proposer builds for slot + 1 while in slot, defers checkpoint finalization to the next slot, and builds on the locally-gossiped proposed parent checkpoint) was gated behind SEQ_ENABLE_PROPOSER_PIPELINING. Production already runs with it on and every non-trivial e2e suite opts in, so the dual on/off code path was dead weight — a duplicated timing model and if (isPipelining) branches scattered across the sequencer, validator, and p2p stack. This makes pipelining the only behavior of the production sequencer and removes the toggle.

Fixes A-912
Fixes A-971

Approach

Removed the enableProposerPipelining config / SEQ_ENABLE_PROPOSER_PIPELINING env var everywhere and dropped every isProposerPipeliningEnabled() / pipeliningOffset() check, collapsing each to the pipelining branch (the EpochCache now always applies PROPOSER_PIPELINING_SLOT_OFFSET). The checkpoint timing model was consolidated to a single pipelined model. The test-only AutomineSequencer is preserved — it is selected by the separate useAutomineSequencer flag, publishes synchronously in-slot, and is the one remaining caller of the non-pipelined getPreviousCheckpointOutHashes branch. Checks for whether a proposed checkpoint exists (hasProposedCheckpoint / proposedCheckpointData) are kept.

Changes

  • stdlib: deleted pipelining-config.ts; consolidated timetable to a single CheckpointTimingModel (removed StandardCheckpointTimingModel and the pipelining option from createCheckpointTimingModel / calculateMaxBlocksPerSlot); kept the pipeliningEnabled param on getPreviousCheckpointOutHashes for automine, with new dedicated unit coverage.
  • foundation / archiver / sequencer-client / epoch-cache (config): removed the env-var registry entry and the PipelineConfig merges.
  • epoch-cache: removed isProposerPipeliningEnabled() / pipeliningOffset(); getTargetSlot / getTargetEpochAndSlotInNextL1Slot / getTargetAndNextSlot always apply the offset.
  • sequencer-client: collapsed the sequencer / checkpoint-proposal-job / publisher branches to the pipelining path; SequencerTimetable no longer takes a pipelining flag; AutomineSequencer untouched (boundary comment added).
  • validator-client / p2p: collapsed proposal-handler, p2p-client, and clock-tolerance branches; deleted the orphaned waitForBlockSourceSync and the now-dead block_source_not_synced reason.
  • p2p gossipsub: maxBlocksPerSlot now uses the pipelined timing model (a higher value), consistent with the always-pipelining sequencer.
  • end-to-end (tests): dropped the flag from PIPELINING_SETUP_OPTS / AUTOMINE_E2E_OPTS and ~40 test sites; setup.ts allows empty checkpoints unconditionally.
  • spartan / docs / aztec-up / docker-compose: removed the env var from infra, and added a migration note.
  • Also includes the benchmark pipelining-setup migration cherry-picked from test: migrate benchmarks to pipelining setup #23647.

Note: SEQ_ENABLE_PROPOSER_PIPELINING is a breaking change for node operators — see the migration note. Labeled ci-no-fail-fast to survey the full suite.

@spalladino spalladino requested review from a team and charlielye as code owners May 29, 2026 04:17
@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 May 29, 2026
@spalladino spalladino removed request for a team and charlielye May 29, 2026 15:04
@spalladino spalladino force-pushed the spl/only-pipelining branch 2 times, most recently from 293ba4e to 63a747d Compare May 29, 2026 19:58
Proposer pipelining (build for slot+1, defer finalization to the next
slot, build on the locally-proposed parent checkpoint) is now the only
behavior of the production sequencer. Removes the SEQ_ENABLE_PROPOSER_PIPELINING
env var / enableProposerPipelining config and every isProposerPipeliningEnabled()
and pipeliningOffset() check, collapsing each to the pipelining path. The
EpochCache always applies PROPOSER_PIPELINING_SLOT_OFFSET.

The checkpoint timing model is consolidated to a single pipelined model
(StandardCheckpointTimingModel deleted; the pipelining selector removed from
createCheckpointTimingModel / calculateMaxBlocksPerSlot). Gossipsub
maxBlocksPerSlot rises accordingly, now consistent with the always-pipelining
sequencer.

The test-only AutomineSequencer is preserved: it is selected by the separate
useAutomineSequencer flag, publishes synchronously in-slot via sendRequests, and
keeps passing pipeliningEnabled: false to getPreviousCheckpointOutHashes (the one
retained parameter, with dedicated unit coverage).

Checks for whether a proposed checkpoint exists (hasProposedCheckpoint,
proposedCheckpointData) are kept.

BREAKING CHANGE: SEQ_ENABLE_PROPOSER_PIPELINING removed; pipelining is always on.

Also includes the benchmark pipelining-setup migration from #23647.
Rebased onto merge-train/spartan. Resolved the proposal_handler conflict (the
own-proposal branch no longer re-pushes the proposed checkpoint, since the
sequencer's checkpoint proposal job already does) and collapsed the
isProposerPipeliningEnabled() guard the base branch newly added to
syncProposedCheckpointToArchiver (pipelining is always on now).

The refactor dropped the archiver's 'pipeliningOffset() === 0' guard on
pruneOrphanProposedBlocks and hardcoded the offset, so the prune now runs
unconditionally. The default e2e setup uses the non-pipelined automine
sequencer, which publishes each checkpoint in-slot via two awaited archiver
calls (addBlock then addProposedCheckpoint); the orphan prune raced between
them, deleting the block before its checkpoint attached. Block 1 never landed
and the whole e2e suite timed out in setup. Gate the prune behind a new
enableOrphanProposedBlockPruning archiver flag, set false for the automine
sequencer, restoring the pre-refactor behavior.
Collapse the missed getSlotContextInNextL1Slot branch to always apply
PROPOSER_PIPELINING_SLOT_OFFSET (it still called the removed
isProposerPipeliningEnabled(), breaking the build and crashing the work
loop), and drop the stale enableProposerPipelining flag from
epochs_partial_proof_multi_root.test.ts (removed from the config types).
@spalladino spalladino force-pushed the spl/only-pipelining branch from 63a747d to 5de117d Compare June 1, 2026 14:36
The env var was introduced in v5 (unreleased), so removing it requires no
migration from v4 — there is no released version that ever exposed it.
- Build a pipelined job by default (targetSlot = slotNumber + offset) so the suite
  exercises the production slot shape, and add assertions that the target slot is
  threaded through the checkpoint constants, attestation signing, and L1 submission.
- Mock the parent-checkpoint sync lookups in the top-level beforeEach so the
  always-pipelined submission path no longer spins in a real-clock retryUntil; this
  cuts the suite from ~250s to ~3s (the three attestation tests dropped from ~80s each).
- Add a build-slot reservation assertion to the validator re-execution budget test so
  it checks the README guarantee, not just the permissive target-slot spillover deadline.
- Rename the overflow test to describe its actual behavior (continues in the next
  sub-slot rather than skipping one).
The proposer now always builds for targetSlot = buildSlot + PROPOSER_PIPELINING_SLOT_OFFSET
(getSlotContextInNextL1Slot no longer branches on a pipelining flag), but the test mocks still
modelled targetSlot == buildSlot: the proposed block, canProposeAt, and the slasher/governance
vote-slot assertions all used the build slot, so the proposer check bailed with
'Expected slot 2 but got 1' and 13 cases failed. Set newSlotNumber to the target slot
(buildSlot + offset) so the block and canProposeAt report the target, and update the vote-slot
assertions accordingly. The dead getTargetSlot / getTargetEpochAndSlotInNextL1Slot mocks (the
sequencer derives the target from getEpochAndSlotInNextL1Slot) are realigned for clarity.
@spalladino spalladino enabled auto-merge (squash) June 1, 2026 15:55
@spalladino spalladino merged commit cc194e1 into merge-train/spartan Jun 1, 2026
20 checks passed
@spalladino spalladino deleted the spl/only-pipelining branch June 1, 2026 16:18
danielntmd pushed a commit to danielntmd/aztec-packages that referenced this pull request Jun 4, 2026
BEGIN_COMMIT_OVERRIDE
chore: deploy next-net and reuse contracts (AztecProtocol#23761)
chore: turn on autoscaling (AztecProtocol#23706)
chore: rename staging-public to staging (AztecProtocol#23767)
chore(p2p): use sync hash for tx validation hashing (AztecProtocol#23768)
test(e2e): wait warmup slots in slashing tests (AztecProtocol#23719)
feat(api)!: make getTxReceipt the single tx-lookup API (AztecProtocol#23660)
fix: cap cloned n_tps fees within sponsored FPC balance (AztecProtocol#23770)
fix: protect HA validator Postgres from cluster scale-down (AztecProtocol#23772)
refactor: remove non-pipelining sequencer code path (AztecProtocol#23665)
feat(archiver): add getL2ToL1MembershipWitness node RPC (AztecProtocol#23646)
fix(p2p)!: revamp BLOCK_TXS validations (AztecProtocol#23778)
chore: name the bots (AztecProtocol#23795)
fix(e2e): ensure BBSync init (AztecProtocol#23793)
fix(p2p)!: fix BLOCK_TXS response under proposer equivocation (AztecProtocol#23786)
fix: reconnect L1 port-forward after epoch-boundary sleep in n_tps_prove
(AztecProtocol#23800)
chore: add empty vscode settings for yarn-project (AztecProtocol#23808)
fix(sequencer): only warn about missing proposed checkpoint once overdue
(AztecProtocol#23807)
fix: refresh n_tps fee quotes during sustained benchmark (AztecProtocol#23797)
fix(sequencer): enforce build-frame deadlines and align
attestation/publish windows (AztecProtocol#23776)
END_COMMIT_OVERRIDE
spalladino added a commit that referenced this pull request Jun 4, 2026
## Motivation

`v5-next` was cut from `next` at cbc99df (Jun 1), so PRs merged to
`merge-train/spartan` after the cut never flowed into it. This backports
all of them (authored by @spalladino and @fcarreiro) to keep v5-next
current with the spartan train.

## Approach

Each PR is cherry-picked from its squashed merge commit on
`merge-train/spartan`, in merge order, preserving the original commit
message and PR number — one commit per backported PR. All 11 applied
cleanly with no conflicts; patches are identical to the originals
(verified via `git patch-id`), and `bootstrap.sh build yarn-project`
passes on the result. Labeled `ci-no-squash` to preserve the per-PR
commits.

## Backported PRs

- #23768 — chore(p2p): use sync hash for tx validation hashing
- #23719 — test(e2e): wait warmup slots in slashing tests
- #23660 — feat(api)!: make getTxReceipt the single tx-lookup API
- #23665 — refactor: remove non-pipelining sequencer code path
- #23646 — feat(archiver): add getL2ToL1MembershipWitness node RPC
- #23778 — fix(p2p)!: revamp BLOCK_TXS validations
- #23786 — fix(p2p)!: fix BLOCK_TXS response under proposer equivocation
- #23808 — chore: add empty vscode settings for yarn-project
- #23807 — fix(sequencer): only warn about missing proposed checkpoint
once overdue
- #23776 — fix(sequencer): enforce build-frame deadlines and align
attestation/publish windows
- #23818 — chore(p2p): BlockTxsRequest comment

Note #23660, #23778, and #23786 are breaking changes (node RPC +
tx-effect db format, and p2p wire format respectively), as they were on
`next`.
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.

2 participants