From 62c016660fcdb9089064fd14ae48a1a61c5169db Mon Sep 17 00:00:00 2001 From: Daniel Knopik <107140945+dknopik@users.noreply.github.com> Date: Wed, 1 Apr 2026 02:58:49 +0200 Subject: [PATCH] Emit SSE: `execution_payload` (#9065) Emit `execution_payload` on successful import of an execution payload. Co-Authored-By: Daniel Knopik --- .../payload_envelope_verification/import.rs | 25 +++++++++++++++---- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/beacon_node/beacon_chain/src/payload_envelope_verification/import.rs b/beacon_node/beacon_chain/src/payload_envelope_verification/import.rs index 2ee315e559..bae848c3c1 100644 --- a/beacon_node/beacon_chain/src/payload_envelope_verification/import.rs +++ b/beacon_node/beacon_chain/src/payload_envelope_verification/import.rs @@ -1,11 +1,12 @@ use std::sync::Arc; use std::time::Duration; +use eth2::types::{EventKind, SseExecutionPayload}; use fork_choice::PayloadVerificationStatus; use slot_clock::SlotClock; use store::StoreOp; use tracing::{debug, error, info, info_span, instrument, warn}; -use types::{BeaconState, BlockImportSource, Hash256, Slot}; +use types::{BeaconState, BlockImportSource, Hash256, SignedExecutionPayloadEnvelope}; use super::{ AvailableEnvelope, AvailableExecutedEnvelope, EnvelopeError, EnvelopeImportData, @@ -225,7 +226,7 @@ impl BeaconChain { signed_envelope: AvailableEnvelope, block_root: Hash256, state: BeaconState, - _payload_verification_status: PayloadVerificationStatus, + payload_verification_status: PayloadVerificationStatus, ) -> Result { // Everything in this initial section is on the hot path for processing the envelope. // Take an upgradable read lock on fork choice so we can check if this block has already @@ -317,8 +318,9 @@ impl BeaconChain { metrics::stop_timer(db_write_timer); self.import_envelope_update_metrics_and_events( + signed_envelope, block_root, - signed_envelope.slot(), + payload_verification_status, envelope_time_imported, ); @@ -327,10 +329,12 @@ impl BeaconChain { fn import_envelope_update_metrics_and_events( &self, + signed_envelope: Arc>, block_root: Hash256, - envelope_slot: Slot, + payload_verification_status: PayloadVerificationStatus, envelope_time_imported: Duration, ) { + let envelope_slot = signed_envelope.slot(); let envelope_delay_total = get_slot_delay_ms(envelope_time_imported, envelope_slot, &self.slot_clock); @@ -349,6 +353,17 @@ impl BeaconChain { ); } - // TODO(gloas) emit SSE event for envelope import (similar to SseBlock for blocks). + if let Some(event_handler) = self.event_handler.as_ref() + && event_handler.has_execution_payload_subscribers() + { + event_handler.register(EventKind::ExecutionPayload(SseExecutionPayload { + slot: envelope_slot, + builder_index: signed_envelope.message.builder_index, + block_hash: signed_envelope.block_hash(), + block_root, + state_root: signed_envelope.message.state_root, + execution_optimistic: payload_verification_status.is_optimistic(), + })); + } } }