Skip to content

feat: add preconfirmation support#3005

Open
fridrik01 wants to merge 13 commits intopreconf-devfrom
add-preconf-support
Open

feat: add preconfirmation support#3005
fridrik01 wants to merge 13 commits intopreconf-devfrom
add-preconf-support

Conversation

@fridrik01
Copy link
Contributor

@fridrik01 fridrik01 commented Dec 11, 2025

Context

This PR implements the beacon-kit portion of the preconfirmation system which significantly reduces transaction inclusion latency for users who opt into the preconfirmation network.

Berachain's standard block time is ~2 seconds. The preconfirmation system provides a fast path where a sequencer emits partial blocks (flashblocks) every ~200ms (not implemented in this PR), which are then finalized when the full block is proposed through CometBFT consensus. If any component fails, the chain seamlessly falls back to normal block building.

Design

The preconfirmation network consists of a sequencer and a set of whitelisted validators. Each runs beacon-kit with different roles:

  • Sequencer Mode:

    • Runs on the sequencer node alongside the block-building execution client
    • When processing a finalized block at slot N, looks up the proposer for slot N+1
    • If the next proposer is whitelisted, triggers an optimistic forkchoiceUpdate to begin payload construction early
    • Exposes an HTTP API (/eth/v1/preconf/payload) where validators fetch their pre-built payloads
    • Authenticates validators using per-validator JWT secrets
  • Validator Mode (whitelisted):

    • Runs on validators participating in the preconfirmation network
    • When it's time to propose, fetches the payload from the sequencer instead of building locally
    • Validates the payload by calling newPayload on the local execution client
    • Falls back to local block building if:
      • Sequencer is unreachable or times out
      • Sequencer returns an error (e.g., payload not ready)
      • Received payload fails local validation
  • Validator Mode (not in whitelist):

    • Validators not in the whitelist build blocks locally as normal
    • The preconfirmation system is transparent to them and no configuration changes required

Robustness: Race Condition Handling

The optimistic payload build is triggered from ProcessProposal in a background goroutine. This introduces two race conditions that are handled by:

  1. Payload fetch before build completes: Validators may request a payload from the sequencer before the goroutine has finished the FCU and cached the payload ID. GetPayloadBySlot retries up to 5 times (50ms intervals, 250ms max) on ErrPayloadIDNotFound (cache miss) or ErrUnknownPayload (EL still building).
  2. ProcessProposal skipped: CometBFT may skip ProcessProposal entirely if a proposal arrives after the propose timeout (the block goes directly to FinalizeBlock). An optimisticBuildTriggered atomic flag tracks whether ProcessProposal triggered a build. If FinalizeBlock finds the flag unset, sequencerFinalizeOptimisticBuild triggers the build as a fallback.

Kurtosis Devnet

The kurtosis devnet config (kurtosis/beaconkit-preconf.yaml) sets up a multi-node network with a dedicated sequencer:

  • Sequencer reth node configured with --sequencer-enabled, flashblock WebSocket (port 8548), and a signing key
  • Flashblock monitor service that connects to the sequencer's flashblock WS and logs incoming flashblocks in real time
  • Sequencer node runs in reth sequencer mode with ports exposed for both the preconf API (9090) and flashblock streaming (8548)
  • Preconf RPC node configured with --flashblocks-url to consume the sequencer's flashblock stream. This node serves standard JSON-RPC with. flashblock-aware state

Test Plan

  1. Checkout branch sequencer-dev from feat: add sequencer/rpc mode for flashblock preconfirmations bera-reth#214 locally and run make docker-build-local in the bera-reth directory

  2. Run make start-devnet-preconf to start local kurtosis devnet

  3. View flashblock-monitor container logs and you should see flashblocks produced every 200ms

Outstanding Issues

  • Reth OOM under high tx load: Running 16 tx-fuzz instances causes all reth nodes to OOM within ~15 minutes (2 GB limit). Geth nodes remain stable under the same load. Current workaround: run 1 tx-fuzz instance.
  • Validate sequencerFinalizeOptimisticBuild fallback: I haven't been able to get this to happen locally after introducing this fallback, though it happened a few times before.
  • Identify why we have multiple flashblocks with no txs (they come in bursts).

@fridrik01 fridrik01 self-assigned this Dec 11, 2025
@fridrik01 fridrik01 changed the title Add preconf support Add initial preconf support Dec 11, 2025
@codecov
Copy link

codecov bot commented Dec 11, 2025

Codecov Report

❌ Patch coverage is 30.86233% with 457 lines in your changes missing coverage. Please review.
✅ Project coverage is 61.50%. Comparing base (b193bed) to head (3e32cca).

Files with missing lines Patch % Lines
beacon/preconf/client.go 0.00% 97 Missing ⚠️
beacon/preconf/server.go 50.32% 67 Missing and 10 partials ⚠️
payload/builder/payload.go 0.00% 52 Missing ⚠️
cli/flags/flags.go 0.00% 40 Missing ⚠️
beacon/blockchain/process_proposal.go 32.00% 32 Missing and 2 partials ⚠️
beacon/preconf/loader.go 55.00% 18 Missing and 9 partials ⚠️
node-core/components/preconf.go 22.85% 27 Missing ⚠️
node-core/components/preconf_server.go 23.52% 26 Missing ⚠️
beacon/blockchain/finalize_block.go 4.16% 21 Missing and 2 partials ⚠️
node-core/components/preconf_client.go 29.62% 19 Missing ⚠️
... and 5 more
Additional details and impacted files

Impacted file tree graph

@@               Coverage Diff               @@
##           preconf-dev    #3005      +/-   ##
===============================================
- Coverage        62.69%   61.50%   -1.19%     
===============================================
  Files              357      366       +9     
  Lines            17226    17862     +636     
===============================================
+ Hits             10799    10986     +187     
- Misses            5572     5998     +426     
- Partials           855      878      +23     
Files with missing lines Coverage Δ
beacon/blockchain/service.go 80.70% <100.00%> (+0.70%) ⬆️
beacon/preconf/config.go 100.00% <100.00%> (ø)
beacon/validator/service.go 100.00% <100.00%> (ø)
config/config.go 81.81% <100.00%> (+0.42%) ⬆️
node-core/components/chain_service.go 100.00% <100.00%> (ø)
node-core/components/validator_service.go 100.00% <100.00%> (ø)
beacon/preconf/whitelist.go 75.00% <75.00%> (ø)
cmd/beacond/defaults.go 0.00% <0.00%> (ø)
node-core/components/service_registry.go 88.88% <25.00%> (-11.12%) ⬇️
beacon/preconf/types.go 60.00% <60.00%> (ø)
... and 11 more

... and 2 files with indirect coverage changes

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

@fridrik01 fridrik01 changed the title Add initial preconf support Add initial preconf support (config + FCU) Dec 11, 2025
@fridrik01 fridrik01 force-pushed the add-preconf-support branch from 89cd61e to 92b8c7f Compare January 27, 2026 17:10
@fridrik01 fridrik01 changed the title Add initial preconf support (config + FCU) feat: add preconfirmation support Jan 27, 2026
@fridrik01 fridrik01 requested a review from calbera January 27, 2026 17:35
@fridrik01 fridrik01 marked this pull request as ready for review January 27, 2026 21:13
@fridrik01 fridrik01 requested a review from a team as a code owner January 27, 2026 21:13
Copilot AI review requested due to automatic review settings February 11, 2026 15:00
Copy link
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

Implements beacon-kit support for a preconfirmation flow, adding a sequencer-side HTTP payload server plus validator-side fetching/fallback, and wiring this through config/DI and Kurtosis/e2e scaffolding.

Changes:

  • Add beacon/preconf module (config, whitelist/JWT loading, HTTP server, HTTP client) and integrate it into validator and blockchain optimistic-building logic.
  • Extend configuration + CLI flags + templates to enable preconf modes (sequencer vs validator fetching).
  • Add Kurtosis + e2e support for spinning up a preconf devnet and validating basic behavior/fallback.

Reviewed changes

Copilot reviewed 45 out of 45 changed files in this pull request and generated 13 comments.

Show a summary per file
File Description
testing/simulated/components.go Includes preconf providers in simulated test component wiring.
testing/e2e/suite/suite.go Adds helper to remove a Kurtosis service via Starlark to simulate outages.
testing/e2e/suite/options.go Adds suite option to run e2e with preconf-enabled config.
testing/e2e/suite/logs.go Adds Kurtosis service log collection helpers for assertions.
testing/e2e/e2e_preconf_test.go Adds an e2e_preconf test validating serving/fetching and fallback behavior.
testing/e2e/config/defaults.go Adds PreconfE2ETestConfig for preconf-enabled e2e runs.
testing/e2e/config/config.go Extends e2e config schema with PreconfConfig.
scripts/build/testing.mk Adds make test-e2e-preconf targets.
payload/builder/payload.go Adds PayloadBuilder.GetPayloadBySlot for serving cached payloads to validators.
payload/builder/interfaces.go Renames cache interface arg names to reflect “blockRoot” semantics.
node-core/components/validator_service.go Injects preconf client/whitelist into validator service.
node-core/components/service_registry.go Registers preconf server (sequencer mode) in service registry.
node-core/components/preconf_server.go Depinject provider for preconf HTTP server.
node-core/components/preconf_client.go Depinject provider for preconf HTTP client.
node-core/components/preconf.go Depinject provider for loading/constructing the preconf whitelist.
node-core/components/chain_service.go Injects preconf config/whitelist into blockchain service.
kurtosis/src/services/sequencer/launcher.star Adds launcher for a dedicated sequencer EL service (bera-sequencer).
kurtosis/src/services/flashblock-monitor/launcher.star Adds a simple websocat-based flashblock monitor service.
kurtosis/src/preconf/config.star Generates whitelist/JWT artifacts and preconf CLI flags for devnet.
kurtosis/src/nodes/nodes.star Adds parsing support for a dedicated sequencer node.
kurtosis/src/nodes/execution/reth/config.star Adds reth sequencer-mode args + flashblock WS port wiring.
kurtosis/src/nodes/execution/execution.star Enables sequencer-mode configuration for dedicated sequencer node.
kurtosis/src/nodes/consensus/beacond/node.star Adds support for appending preconf flags to beacond start command.
kurtosis/src/nodes/consensus/beacond/launcher.star Wires preconf artifacts/env into CL node configs; adjusts genesis ceremony return shape.
kurtosis/main.star Adds preconf args handling; deploys dedicated sequencer node when enabled; launches related services.
kurtosis/beaconkit-preconf.yaml Adds Kurtosis args file to run a preconf-enabled devnet (with sequencer_node).
kurtosis/Makefile Adds targets to start/stop/remove a preconf devnet.
config/template/template.go Adds TOML template section for [beacon-kit.preconf].
config/config.go Adds preconf config to global node config defaults and struct.
cmd/beacond/defaults.go Adds preconf providers to default component list.
cli/flags/flags.go Adds CLI flags for preconf config.
beacon/validator/service.go Extends validator service to hold preconf cfg/client/whitelist.
beacon/validator/block_builder.go Attempts sequencer fetch before local build when configured/whitelisted.
beacon/preconf/whitelist.go Adds whitelist interface + implementation.
beacon/preconf/types.go Defines request/response types and envelope conversion helpers.
beacon/preconf/server_test.go Adds unit tests for server auth/method handling.
beacon/preconf/server.go Implements JWT-authenticated preconf payload server endpoint.
beacon/preconf/loader_test.go Adds unit tests for whitelist/JWT loader helpers.
beacon/preconf/loader.go Implements whitelist/JWT secret file loaders.
beacon/preconf/config.go Adds preconf config struct + defaults + helper predicates.
beacon/preconf/client.go Implements HTTP client for fetching payloads from sequencer.
beacon/blockchain/service.go Adds preconf cfg/whitelist + optimistic-build trigger tracking to blockchain service.
beacon/blockchain/process_proposal.go Adds sequencer-mode proposer detection + optimistic build triggering based on whitelist.
beacon/blockchain/payload_test.go Updates blockchain tests to pass new constructor args.
beacon/blockchain/finalize_block.go Adds FinalizeBlock fallback to trigger optimistic build when ProcessProposal is skipped.

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

@fridrik01 fridrik01 changed the base branch from main to preconf-dev February 25, 2026 15:12
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.

3 participants