From aff72c2b36ca69c98c9a1f3494278dfd6b87bf27 Mon Sep 17 00:00:00 2001 From: julio4 <30329843+julio4@users.noreply.github.com> Date: Thu, 11 Jun 2026 23:56:00 +0900 Subject: [PATCH] fix: warn-only payload-channel sends + publish ordering parity in continuous mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In continuous mode, `publish_candidate` was treating a full `built_fb_payload_tx` channel as a fatal error via `?`, which killed the entire payload job whenever the payload handler stalled (e.g. on a slow p2p peer). The per-trigger path in `notify_built_payload` has always treated the same condition as warn-and-continue. This fix replaces the fatal `try_send` / partial-warn pattern with a call to the existing `notify_built_payload` (widened to `pub(crate)`) and corrects the publish ordering to match the old path: ws publish → send_replace → notify_built_payload → timing metric. The now-dead `built_fb_payload_tx` and `built_payload_tx` accessor methods are removed; all callers are consolidated into `notify_built_payload`. --- .../op-rbuilder/src/builder/continuous/publish.rs | 15 +++------------ crates/op-rbuilder/src/builder/payload.rs | 10 +--------- 2 files changed, 4 insertions(+), 21 deletions(-) diff --git a/crates/op-rbuilder/src/builder/continuous/publish.rs b/crates/op-rbuilder/src/builder/continuous/publish.rs index d82d4130..091fc2ce 100644 --- a/crates/op-rbuilder/src/builder/continuous/publish.rs +++ b/crates/op-rbuilder/src/builder/continuous/publish.rs @@ -25,7 +25,7 @@ use reth_node_api::PayloadBuilderError; use reth_optimism_node::OpBuiltPayload; use std::{ops::ControlFlow, time::Instant}; use tokio::sync::watch; -use tracing::{debug, info, metadata::Level, span, warn}; +use tracing::{debug, info, metadata::Level, span}; // === Per-interval publishing and advancement ================= // @@ -123,20 +123,11 @@ where .ws_pub() .publish(fb_payload_delta) .map_err(PayloadBuilderError::other)?; + best_payload_tx.send_replace(Some(new_payload.clone())); + self.notify_built_payload(new_payload.clone()); let slot_offset_ms = compute_slot_offset_ms(ctx.attributes().timestamp(), self.config().block_time); record_flashblock_publish_timing(candidate.fb_state.flashblock_index(), slot_offset_ms); - self.built_fb_payload_tx() - .try_send(new_payload.clone()) - .map_err(PayloadBuilderError::other)?; - if let Err(e) = self.built_payload_tx().try_send(new_payload.clone()) { - warn!( - target: "payload_builder", - error = %e, - "Failed to send updated payload" - ); - } - best_payload_tx.send_replace(Some(new_payload.clone())); Ok(flashblock_byte_size) } diff --git a/crates/op-rbuilder/src/builder/payload.rs b/crates/op-rbuilder/src/builder/payload.rs index a5d4f2a8..3c8bf7af 100644 --- a/crates/op-rbuilder/src/builder/payload.rs +++ b/crates/op-rbuilder/src/builder/payload.rs @@ -315,14 +315,6 @@ impl OpPayloadBuilderInner { &self.client } - pub(crate) fn built_fb_payload_tx(&self) -> &mpsc::Sender { - &self.built_fb_payload_tx - } - - pub(crate) fn built_payload_tx(&self) -> &mpsc::Sender { - &self.built_payload_tx - } - pub(crate) fn ws_pub(&self) -> &WebSocketPublisher { &self.ws_pub } @@ -1020,7 +1012,7 @@ where }) } - fn notify_built_payload(&self, payload: OpBuiltPayload) { + pub(crate) fn notify_built_payload(&self, payload: OpBuiltPayload) { if let Err(e) = self.built_fb_payload_tx.try_send(payload.clone()) { warn!( target: "payload_builder",