Skip to content

fix(builder): Resolve bugs on upstream flashblocks timing scheduler#169

Merged
louisliu2048 merged 8 commits intomainfrom
niven/flashblocks-timing
Mar 5, 2026
Merged

fix(builder): Resolve bugs on upstream flashblocks timing scheduler#169
louisliu2048 merged 8 commits intomainfrom
niven/flashblocks-timing

Conversation

@sieniven
Copy link
Contributor

@sieniven sieniven commented Mar 4, 2026

Summary

This PR fixes all the flashblocks timing intervals logic issue that was introduced from the upstream PR flashbots/op-rbuilder#380.

  1. Biggest breaking change from the PR is that flashblock building was switched to start at the intervals calculated (first flashblock offset). This meant that the old logic of paylaod building triggered immediately on FCU is broken - reducing the throughput of the chain by a flashblock interval since the builder waits idle until the first send time (20% reduction in throughput with flashblock configuration of 200ms interval, 1s blocktime). This PR resolves this issue by reverting back to old behaviour, which is to start payload building immediately once FCU is received.

  2. The flashblock offset configuration bug, which was only applied to the first and last flashblock. This PR resolves this issue by correctly applying the offset on every flashblock interval send time.

  3. The new scheduler logic is problematic when calculating send times. This PR resolves them by:

    • reverting to the old logic of using a div_ceiling instead which aligns target_flashblock with the actual send_times vector calculated
    • Target flashblocks is calculated using original logic of remaining time / interval (remaining time = wall clock time when FCU arrives - payload timestamp) instead of the problematic configured block time / interval
    • Remove logic to append final deadline to the send vector which could result in 2 deadline timings inside send times vector if the scenario when FCU came delayed (but before payload timing)
    • Remove entire logic of truncating send time with target flashblocks
  4. Breaking change on the payload builder refactor: extract flashblock timing code and test it flashbots/op-rbuilder#380. Because the additional check to safeguard that we are not building flashblocks past our target index, this could result in the an additional flashblock to start building and never be resolved or gossiped. For example, for 1s blocktime and 200ms interval, if FCU arrives at the start of block time, on the final 5th flashblock send time, we will stop building the last flashblock (index=5) and gossip that flashblock out. However without this guard, the payload builder actually starts building the 6th flashblock (index=6), which is problematic for X Layer builder (since we resolve payload on engine_getPayload). This PR restores the original behaviour and fixes this from happening.

  5. Potentially breaking change on the new flashblocks scheduler, which changes the behaviour of the payload builder on the specific scenario that FCU arrives after exactly at or after payload timestamp. The old behaviour will use the configured block time / intervals to build that payload. However the new behaviour changes to building just 1 flashblock, which could potentially be backwards breaking. To safeguard this, the PR reverts to restore the old behaviour.

Test coverage

In addition, this PR extends the unit tests on the flashblock timing scheduler to add more comprehesive unit coverages, testing all possible scenarios to ensure flashblocks interval send times generated are correct:

  • FCU arrives on time, full block time to payload timestamp
  • FCU arrives late, less than full block time to payload timestamp
  • FCU arrives very late, exactly at payload timestamp
  • FCU arrives very late, past payload timestamp

sieniven and others added 4 commits March 3, 2026 17:36
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Replace Option<Vec<Instant>> with explicit target_flashblocks field
- Add edge-case tests for timing calculation and scheduler intervals
- Add async integration tests for scheduler run, cancellation, and token lifecycle
- Add tokio test-util dev dependency for time-paused tests

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Revert compute_remaining_time to return block_time on late FCU for
  backwards compatibility instead of returning None
- Extract from_reference constructor for deterministic test scheduling
- Add comprehensive integration tests for FCU timing scenarios, offset
  and buffer configurations, block time variations, and late FCU handling
- Remove Option wrapper from remaining_time flow

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@sieniven sieniven changed the title Niven/flashblocks timing fix(builder): Resolve bugs on upstream flashblocks timing scheduler Mar 4, 2026
sieniven and others added 3 commits March 4, 2026 14:30
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
sieniven added a commit to okx/op-rbuilder that referenced this pull request Mar 4, 2026
Cherry-pick fixes from okx/xlayer-reth#169 into op-rbuilder:

- Scheduler now sends immediate first flashblock trigger on FCU instead
  of waiting idle for the first interval offset
- Target flashblocks calculated via div_ceil(remaining_time, interval)
  instead of block_time / interval, aligning target count with send times
- Late FCU backwards compatibility: returns block_time instead of zero
  duration so payload building still proceeds normally
- Send offset correctly applied to every flashblock interval, not just
  first and last
- Simplified interval computation: removed truncation and deadline append
- Guard check prevents building flashblocks past target count
- Early return when target_flashblocks is zero
- Added 12 comprehensive async unit tests with tokio test-util

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
sieniven added a commit to okx/op-rbuilder that referenced this pull request Mar 4, 2026
)

Cherry-pick fixes from okx/xlayer-reth#169 into op-rbuilder:

- Scheduler now sends immediate first flashblock trigger on FCU instead
  of waiting idle for the first interval offset
- Target flashblocks calculated via div_ceil(remaining_time, interval)
  instead of block_time / interval, aligning target count with send times
- Late FCU backwards compatibility: returns block_time instead of zero
  duration so payload building still proceeds normally
- Send offset correctly applied to every flashblock interval, not just
  first and last
- Simplified interval computation: removed truncation and deadline append
- Guard check prevents building flashblocks past target count
- Early return when target_flashblocks is zero
- Added 12 comprehensive async unit tests with tokio test-util

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
@sieniven
Copy link
Contributor Author

sieniven commented Mar 4, 2026

Screenshot 2026-03-04 at 5 11 35 PM

ERC20 stress test with 500M block gas limit for 20+ mins, max throughput of the chain is stabilized at 10+K TPS with no drop off in throughput.

@dloghin dloghin self-requested a review March 4, 2026 11:48
Copy link
Contributor

@dloghin dloghin left a comment

Choose a reason for hiding this comment

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

lgtm

@louisliu2048 louisliu2048 merged commit db6fa36 into main Mar 5, 2026
Vui-Chee added a commit that referenced this pull request Mar 9, 2026
* main:
  Feat(chainspec): adding xlayer-devnet chainspec (#167)
  chore(builder): flatten flashblocks builder, remove unnecessary trait interfaces (#172)
  rpc: remove unnecessary trait bounds and dependencies from XlayerRpcExtApiServer impl (#171)
  fix fmt in bin/tools/gen_genesis.rs (#170)
  fix(builder): Resolve bugs on upstream flashblocks timing scheduler (#169)
  Feat(tools): Add a tool to generate a custom genesis file based on a template and existing chain data (#159)
  feat(flashblocks): Add flashblocks sequence persistence logic on RPC and sequence replay flashblock builder (#162)
  chore(builder): remove unused custom-engine-api feature flag in tests (#168)
  fix: p2p test hang due to hang on port (#165)
Vui-Chee added a commit that referenced this pull request Mar 13, 2026
* main: (25 commits)
  fix: bump quinn-proto to 0.11.14 to patch CVE-2026-31812 DoS vuln (#183)
  pre-job authorization (#193)
  fix: trigger review skill failed to ack (#192)
  feat: trigger skill review separately (#191)
  feat: add Claude skills and CLAUDE.md for AI-assisted development (#190)
  rename ext (#185)
  supply workflow for claude (#184)
  feat(builder): incremental trie cache optimization for flashblocks state root (#163)
  chore(flashblocks-rpc): migrate op-reth flashblocks into xlayer-reth (#175)
  Feat(chainspec): adding xlayer-devnet chainspec (#167)
  chore(builder): flatten flashblocks builder, remove unnecessary trait interfaces (#172)
  rpc: remove unnecessary trait bounds and dependencies from XlayerRpcExtApiServer impl (#171)
  fix fmt in bin/tools/gen_genesis.rs (#170)
  fix(builder): Resolve bugs on upstream flashblocks timing scheduler (#169)
  Feat(tools): Add a tool to generate a custom genesis file based on a template and existing chain data (#159)
  feat(flashblocks): Add flashblocks sequence persistence logic on RPC and sequence replay flashblock builder (#162)
  chore(builder): remove unused custom-engine-api feature flag in tests (#168)
  fix: p2p test hang due to hang on port (#165)
  fix: update testcontainers to v0.27.0 to remediate CVE-2025-62518 (#164)
  chore(builder): further clean up builder crate (#161)
  ...
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