Skip to content

refactor: fan out flashblock publication#559

Open
julio4 wants to merge 1 commit into
mainfrom
refactor/flashblock-publish-bus
Open

refactor: fan out flashblock publication#559
julio4 wants to merge 1 commit into
mainfrom
refactor/flashblock-publish-bus

Conversation

@julio4

@julio4 julio4 commented Jul 17, 2026

Copy link
Copy Markdown
Member

Publication side effects (ws publish, p2p forward, engine feedback) now decoupled from the build path.
Every built payload (fallback, flashblock, continuous candidate) is sent once on a broadcast bus (fanout.rs), consumed by dedicated subscriber tasks with fanout guarantees. PayloadHandler now only handles payloads received from peers.

Changes:

  • websocket publish failure no longer aborts payload job; it's logged and isolated in the subscriber so a rollup-boost disconnect can't stop block building.
  • Slow subscribers lag (drop oldest) instead of dropping the newest send: built_*_send_failed counters from feat(observability): count dropped built-payload channel sends #555 are replaced by per-subscriber ws_publish_lagged / p2p_forward_lagged / engine_feedback_lagged counters.

Supersede / Close #518

Copilot AI review requested due to automatic review settings July 17, 2026 04:12

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

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 refactors flashblock publication so post-build side effects (websocket publish, p2p forwarding, engine feedback) are decoupled from the payload build path and handled by dedicated subscriber tasks consuming a fanout broadcast bus. This isolates transient publication failures (e.g., websocket disconnects) from aborting payload construction and replaces “send failed” counters with per-subscriber lag/drop counters.

Changes:

  • Introduces a broadcast-based fanout bus (fanout.rs) and subscriber tasks for websocket publish, p2p forward, and engine feedback.
  • Updates the builder/service wiring so built payloads are emitted once onto the bus; PayloadHandler now only processes peer-received payloads.
  • Improves slot-offset timing robustness (saturating pre-UNIX-epoch case) and adds a regression test; updates task metrics + lag counters.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
crates/op-rbuilder/src/tokio_metrics.rs Adds task monitors/recording for the new subscriber tasks.
crates/op-rbuilder/src/metrics.rs Replaces built-payload send-failure counters with per-subscriber lag/drop counters.
crates/op-rbuilder/src/builder/timing.rs Uses saturating subtraction for slot start calculation; adds test.
crates/op-rbuilder/src/builder/service.rs Wires up the fanout bus and spawns websocket/p2p/engine subscriber tasks.
crates/op-rbuilder/src/builder/payload.rs Emits FlashblockEvents onto the fanout bus instead of doing side effects inline.
crates/op-rbuilder/src/builder/payload_handler.rs Narrows responsibility to handling peer-received payloads only.
crates/op-rbuilder/src/builder/mod.rs Registers the new fanout module.
crates/op-rbuilder/src/builder/fanout.rs New fanout bus + subscribers with lag handling and targeted tests.
crates/op-rbuilder/src/builder/continuous/publish.rs Routes continuous candidate publication through the fanout bus.

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

Comment on lines +662 to +668
let _ = self.flashblock_tx.send(FlashblockEvent {
fb_payload: Arc::new(fb_payload),
built: Arc::new(payload),
attributes_timestamp_secs: config.attributes.timestamp(),
ws_eligible: !ctx.attributes().no_tx_pool,
tx_trace_total_txs: info.executed_transactions.len(),
});
Comment on lines 1048 to 1049
// After this point, all side effects are synchronous. If cancellation wins the race after
// this check, still publish the local payload so getPayload can include this flashblock.
Comment on lines +1053 to +1057
let _ = self.flashblock_tx.send(FlashblockEvent {
fb_payload: Arc::new(fb_payload),
built: Arc::new(new_payload),
attributes_timestamp_secs: ctx.attributes().timestamp(),
ws_eligible: true,
Comment on lines +120 to +126
let _ = self.flashblock_tx().send(FlashblockEvent {
fb_payload: Arc::new(fb_payload_delta.clone()),
built: Arc::new(new_payload.clone()),
attributes_timestamp_secs: ctx.attributes().timestamp(),
ws_eligible: true,
tx_trace_total_txs: candidate.info.executed_transactions.len(),
});
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.

2 participants