Skip to content

feat(preconf): rebuild sequencer payload on consensus round change to keep flashblocks flowing#3068

Merged
fridrik01 merged 4 commits intopreconf-devfrom
round-change-rebuild
Apr 7, 2026
Merged

feat(preconf): rebuild sequencer payload on consensus round change to keep flashblocks flowing#3068
fridrik01 merged 4 commits intopreconf-devfrom
round-change-rebuild

Conversation

@fridrik01
Copy link
Copy Markdown
Contributor

@fridrik01 fridrik01 commented Mar 27, 2026

When consensus goes to multiple rounds, the sequencer only builds a payload and emits flashblocks for round 0. If round 0 times out and a new proposer is selected, no fresh flashblocks are produced for any subsequent rounds. RPC nodes continue serving stale round-0 state, and the new proposer receives the same cached payload with no new transactions.

Detecting the round change in ProcessProposal is too late. By that point the new proposer has already fetched and proposed. There is also no round information in the ABCI PrepareProposalRequest or ProcessProposalRequest.

This PR aims to circumvent this by subscribing to CometBFT's local EventNewRound message through its message bus on the sequencer. This event should fires before the new proposer enters PrepareProposal, giving the sequencer enough time to invalidate the stale payload cache and trigger a fresh optimistic build with up-to-date transactions.

Note that no bera-reth changes should be needed because when a new index-0 flashblock arrives with a different payload ID, the RPC node's flashblock service discards the stale round-0 sequence and starts tracking the new one.

Test plan

The following e2e test stops a single validator to trigger a multi round and verifies that cometbft on sequencer sent a new round message and that flashblocks were emitted for round1:

go test -timeout 200s -tags e2e,bls12381,test ./testing/e2e/preconf/. -v -run TestPreconfE2ESuite/TestRoundChangeRebuild

@fridrik01 fridrik01 self-assigned this Mar 27, 2026
@fridrik01 fridrik01 requested review from bar-bera and calbera March 27, 2026 09:53
@fridrik01 fridrik01 force-pushed the round-change-rebuild branch 2 times, most recently from 9146c51 to bb1e57b Compare March 27, 2026 11:04
@fridrik01 fridrik01 marked this pull request as ready for review March 27, 2026 11:06
@fridrik01 fridrik01 requested a review from a team as a code owner March 27, 2026 11:06
Copilot AI review requested due to automatic review settings March 27, 2026 11:06
@fridrik01 fridrik01 force-pushed the round-change-rebuild branch from bb1e57b to 032b2be Compare March 27, 2026 11:11
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR addresses a preconf failure mode where, after CometBFT advances past round 0 at a given height, the sequencer continues serving a stale cached payload and stops producing fresh flashblocks. It adds a CometBFT EventNewRound subscription so the sequencer can detect round changes early, invalidate its payload cache, and trigger a fresh optimistic payload build.

Changes:

  • Subscribe to CometBFT EventNewRound after node start and route round-change events into the beacon blockchain service.
  • Add a LocalBuilder.InvalidatePayload(slot, parentBlockRoot) API and implement it in the payload builder/cache.
  • Add an e2e test that forces a multi-round scenario and asserts sequencer rebuild + flashblock monitor evidence.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
testing/e2e/preconf/round_change_test.go New e2e that induces a round change and checks for rebuild logs + flashblock rebuild evidence.
payload/builder/builder.go Adds InvalidatePayload to delete cached payload IDs for a slot/root.
node-core/components/interfaces.go Extends the node-core LocalBuilder interface with InvalidatePayload.
consensus/cometbft/service/service.go Hooks round-change subscription into CometBFT service startup.
consensus/cometbft/service/round_change.go New CometBFT event-bus subscription handler for EventNewRound.
beacon/blockchain/round_change.go New HandleRoundChange implementation to whitelist-check, invalidate cache, and rebuild payload.
beacon/blockchain/mocks/local_builder.mock.go Updates mock to include InvalidatePayload.
beacon/blockchain/interfaces.go Extends blockchain interfaces with InvalidatePayload and HandleRoundChange.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread consensus/cometbft/service/round_change.go Outdated
Comment thread beacon/blockchain/round_change.go Outdated
Comment thread consensus/cometbft/service/service.go Outdated
@fridrik01 fridrik01 force-pushed the round-change-rebuild branch from 032b2be to 5c86102 Compare March 27, 2026 15:38
@fridrik01 fridrik01 force-pushed the round-change-rebuild branch from 5c86102 to 6701b2c Compare March 27, 2026 15:46
@codecov
Copy link
Copy Markdown

codecov bot commented Mar 27, 2026

Codecov Report

❌ Patch coverage is 0% with 127 lines in your changes missing coverage. Please review.
✅ Project coverage is 58.93%. Comparing base (735d488) to head (d3a5fd3).
⚠️ Report is 33 commits behind head on preconf-dev.

Files with missing lines Patch % Lines
consensus/cometbft/service/round_change.go 0.00% 55 Missing ⚠️
beacon/blockchain/round_change.go 0.00% 53 Missing ⚠️
consensus/cometbft/service/service.go 0.00% 7 Missing ⚠️
node-core/components/cometbft_service.go 0.00% 5 Missing ⚠️
node-core/components/preconf.go 0.00% 3 Missing ⚠️
consensus/cometbft/service/options.go 0.00% 2 Missing ⚠️
payload/builder/builder.go 0.00% 2 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@               Coverage Diff               @@
##           preconf-dev    #3068      +/-   ##
===============================================
- Coverage        61.49%   58.93%   -2.57%     
===============================================
  Files              366      378      +12     
  Lines            17862    19432    +1570     
===============================================
+ Hits             10985    11452     +467     
- Misses            5999     7018    +1019     
- Partials           878      962      +84     
Files with missing lines Coverage Δ
consensus/cometbft/service/options.go 61.29% <0.00%> (-4.23%) ⬇️
payload/builder/builder.go 84.61% <0.00%> (-15.39%) ⬇️
node-core/components/preconf.go 31.03% <0.00%> (+8.17%) ⬆️
node-core/components/cometbft_service.go 0.00% <0.00%> (ø)
consensus/cometbft/service/service.go 36.36% <0.00%> (-1.14%) ⬇️
beacon/blockchain/round_change.go 0.00% <0.00%> (ø)
consensus/cometbft/service/round_change.go 0.00% <0.00%> (ø)

... and 15 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Copy Markdown
Collaborator

@bar-bera bar-bera left a comment

Choose a reason for hiding this comment

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

lgtm, just maybe we should rename the existing round_rotation_test.go to something more appropriate since now round_change_test.go tests the detection of the round ratation, while the former tests the behavior of the network under the round rotation condition. or maybe they could be merged

Copy link
Copy Markdown
Contributor

@calbera calbera left a comment

Choose a reason for hiding this comment

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

mostly makes sense, utACK.

EDIT: I see the e2e test now, but would it be possible to also send txs during this round change and observe that the newly built payload includes these new txs?

Comment thread consensus/cometbft/service/round_change.go Outdated
Comment thread beacon/blockchain/round_change.go
Comment thread consensus/cometbft/service/service.go Outdated
Comment thread consensus/cometbft/service/round_change.go Outdated
Comment thread consensus/cometbft/service/round_change.go Outdated
@fridrik01
Copy link
Copy Markdown
Contributor Author

EDIT: I see the e2e test now, but would it be possible to also send txs during this round change and observe that the newly built payload includes these new txs?

Updated the e2e test so that we start a background routine that sends txs after first payload and then verifies that at least 1 gets included in the next payload

@fridrik01 fridrik01 merged commit 57b3af8 into preconf-dev Apr 7, 2026
20 checks passed
@fridrik01 fridrik01 deleted the round-change-rebuild branch April 7, 2026 16:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants