Skip to content

feat(flashblocks): Cache recent flashblocks#19786

Merged
mattsse merged 6 commits intoparadigmxyz:mainfrom
0x00101010:flashblock-cache
Nov 24, 2025
Merged

feat(flashblocks): Cache recent flashblocks#19786
mattsse merged 6 commits intoparadigmxyz:mainfrom
0x00101010:flashblock-cache

Conversation

@0x00101010
Copy link
Contributor

@0x00101010 0x00101010 commented Nov 16, 2025

Rework FlashBlock: Introduce SequenceManager and Improve Architecture

Closes: #18373

Reviewer Notes:

  1. Best reviewed by commit, high level changes summarized below.
  2. Tested on both base & uni sepolia for both chain follow and catch up scenario.

Base Sepolia:
image

Unichain Sepolia:
image

Summary

This PR introduces a major refactoring of the flashblock system, implementing a SequenceManager to handle
sequence caching and intelligent block building selection. The changes improve the system's ability to handle
both 1-second and 2-second block times, with and without sequencer-provided state roots.

Key Changes

1. Introduce SequenceManager (cache.rs)

Added SequenceManager to centralize sequence management with:

  • Ring buffer caching: Maintains last 3 completed sequences for efficient state_root computation
  • Intelligent build selection: Chooses optimal sequence for building based on parent hash and timestamp
  • State root computation management: Configurable compute_state_root flag for different block time
    scenarios
  • Double-broadcast strategy: Broadcasts sequences immediately (without state_root) and re-broadcasts after
    build completion (with state_root)

Benefits:

  • Enables execution cache reuse across blocks during catch-up scenarios
  • Supports both 1s blocks (state_root provided by sequencer) and 2s blocks (computed locally)
  • Clean separation between pending sequences and cached sequences

2. Simplify FlashBlockPendingSequence (sequence.rs)

Removed PreparedFlashblock type and streamlined the pending sequence implementation:

  • Single responsibility: manage ordered flashblock accumulation
  • Added SequenceExecutionOutcome to store computed state_root and block_hash
  • Improved validation and error handling
  • 48 comprehensive tests covering all edge cases and invariants

3. Rework FlashBlockService (service.rs)

Major improvements to the service loop:

  • Integrated SequenceManager: Replaces ad-hoc sequence handling
  • Tokio select-based event loop: Properly awaits on build jobs OR incoming flashblocks (no busy-waiting)
  • Efficient flashblock batching: Processes all immediately available flashblocks before triggering builds
  • Removed Stream trait: Simplified loop logic by removing unnecessary abstraction
  • Removed CanonicalChainTip listener: Not needed with new architecture

Event Loop:

  1. Build job completion → process results, update cache, broadcast pending block
  2. New flashblock arrival → batch process, attempt build if conditions met

4. Rework FlashBlockConsensusClient (consensus.rs)

Simplified consensus client logic:

  • Clean separation of submit_new_payload and submit_forkchoice_update
  • Smart handling of state_root availability:
    • With state_root: Submit both engine_newPayload and engine_forkChoiceUpdated
    • Without state_root: Skip engine_newPayload, only submit FCU with parent_hash
  • 14 comprehensive tests covering all consensus scenarios

5. Enhanced Test Infrastructure (test_utils.rs)

Improved TestFlashBlockFactory with:

  • Configurable block time support (with_block_time())
  • Builder pattern for flashblock creation
  • Helpers for creating sequential flashblocks (flashblock_after(), flashblock_for_next_block())
  • State root configuration

Architecture Improvements

Before

FlashBlockService
├── Manual sequence tracking
├── No caching
├── Stream-based loop (complex)
└── CanonicalChainTip listener

After

FlashBlockService
├── SequenceManager (centralized)
│ ├── Pending sequence
│ └── Ring buffer cache (last 3 sequences)
├── Tokio select loop (clean)
├── Efficient batching
└── Smart build selection

Block Time Scenarios

1-Second Blocks (State Root Provided)

  • Sequencer provides state_root in flashblocks
  • Service validates and forwards to consensus client
  • No local state_root computation needed
  • Fast block progression

2-Second Blocks (State Root Computed)

  • Sequencer provides B256::ZERO for state_root
  • Service computes state_root when building on local tip
  • Execution cache reuse from ring buffer
  • Consensus client receives state_root from execution outcome

Testing

Test Coverage

  • cache.rs: 48 tests - sequence management, caching, buildability logic
  • consensus.rs: 14 tests - payload submission, FCU behavior, conversion logic
  • service.rs: Tests added for batching and event loop behavior

Key Test Scenarios

  • ✅ 2s block with no state_root provided
  • ✅ 1s block with state_root provided
  • ✅ Flashblock batching
  • ✅ Sequence finalization and caching
  • ✅ State root computation
  • ✅ Cache eviction (ring buffer)
  • ✅ OpExecutionData conversion with/without state_root
  • ✅ Multiple blocks in sequence

@github-project-automation github-project-automation bot moved this to Backlog in Reth Tracker Nov 16, 2025
@0x00101010 0x00101010 force-pushed the flashblock-cache branch 2 times, most recently from fdca217 to 0c51485 Compare November 17, 2025 04:49
@0x00101010 0x00101010 marked this pull request as ready for review November 17, 2025 05:04
Copy link
Collaborator

@mattsse mattsse left a comment

Choose a reason for hiding this comment

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

cool,

all of this looks great

I only have last suggestion re the PreparedFlashblock, because we can cache all of the raw -> WithEncoded conversions of previous blocks, so that we only need to recover the new transactions per flashblock

Comment on lines -272 to -278
#[derive(Debug)]
struct PreparedFlashBlock<T> {
/// The prepared transactions, ready for execution
txs: Vec<WithEncoded<Recovered<T>>>,
/// The tracked flashblock
block: FlashBlock,
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

we should add this back because I believe rn we're re-recovering the entire block per flashblock in

https://github.com/paradigmxyz/reth/blob/main/crates/optimism/flashblocks/src/cache.rs#L177-L177

recovery is fairly expensive and we can avoid doing all of this for the previous flashblocks in the block

Copy link
Contributor Author

@0x00101010 0x00101010 Nov 23, 2025

Choose a reason for hiding this comment

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

Done.

Chose to not revive PreparedFlashBlock and instead do recovery inside SequenceMananger.

After the caching change, we also need recovered transactions for FlashBlockCompleteSequence as well, so the choices are:

  1. Keep the original way of storing PreparedFlashBlock in both FlashBlockPendingSequence and FlashBlockCompleteSequence, but any changes to FlashBlockCompleteSequence would be breaking lots of interfaces like FlashBlockListener, FlashBlockConsensClient, etc
  2. Revert to the old way of just having FlashBlockPendingSequence use PreparedFlashBlock, however, it still leaves us caching the recovered txs in SequenceManager
  3. Just have SequenceManager handle it all.

Opting for 3 due to:

  1. Keeping FlashBlockPendingSequence simple to just be a data container
  2. all the tx recovering, building related logic is handled by SequenceManager, keep it consistent
  3. Keep interfaces clean without unnecessary trait bounds

@github-project-automation github-project-automation bot moved this from Backlog to In Progress in Reth Tracker Nov 21, 2025
@mattsse mattsse added C-enhancement New feature or request A-op-reth Related to Optimism and op-reth labels Nov 21, 2025
Francis Li added 5 commits November 21, 2025 15:14
1. Use SequenceManager to manage pending and cached blocks
2. Remove Stream trait implementation and simplify loop logic
3. Remove CanonicalChainTip listening, it's not needed
Comment on lines +159 to +160
// Batch process all other immediately available flashblocks
while let Some(result) = self.incoming_flashblock_rx.next().now_or_never().flatten() {
Copy link
Collaborator

Choose a reason for hiding this comment

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

this makes sense

@mattsse mattsse enabled auto-merge November 24, 2025 17:49
@mattsse mattsse added this pull request to the merge queue Nov 24, 2025
Merged via the queue into paradigmxyz:main with commit 118fd3b Nov 24, 2025
43 checks passed
@github-project-automation github-project-automation bot moved this from In Progress to Done in Reth Tracker Nov 24, 2025
sieniven pushed a commit to okx/reth that referenced this pull request Dec 10, 2025
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
Vui-Chee added a commit to okx/reth that referenced this pull request Dec 11, 2025
* dev:
  chore: Update cargo deps (#65)
  feat(flashblock): Enable eth_getTransactionByHash support for flashblock (paradigmxyz#19954)
  feat(flashblocks): Cache recent flashblocks (paradigmxyz#19786)
  feat(flashblock): improve state root calculation condition (paradigmxyz#19667)
  feat(flashblocks): add metrics for current block and index (paradigmxyz#19712)
  refactor(flashblock): Move all flashblocks related data structure to op-alloy (paradigmxyz#19608)
  chore: add target: flashblock for all flashblock related traces (paradigmxyz#19656)
  feat(metrics): implement RAII-based block timing with Prometheus support (#60)
  Fix fmt (#62)
sieniven pushed a commit to okx/reth that referenced this pull request Dec 11, 2025
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
theochap pushed a commit to ethereum-optimism/optimism that referenced this pull request Jan 22, 2026
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
theochap pushed a commit to ethereum-optimism/optimism that referenced this pull request Feb 11, 2026
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-op-reth Related to Optimism and op-reth C-enhancement New feature or request

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

cache recent flashblock sequences

2 participants