From 015129097804af23f3cb4b420c519f0e925830a2 Mon Sep 17 00:00:00 2001 From: Jimmy Chen Date: Fri, 25 Sep 2026 01:45:05 +0000 Subject: [PATCH 1/2] Fix mock engine panic in bid gossip spec tests --- .../ef_tests/src/cases/gossip_validation.rs | 30 ++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/testing/ef_tests/src/cases/gossip_validation.rs b/testing/ef_tests/src/cases/gossip_validation.rs index 30eeb1977ca..8d6ee6ca6d4 100644 --- a/testing/ef_tests/src/cases/gossip_validation.rs +++ b/testing/ef_tests/src/cases/gossip_validation.rs @@ -10,7 +10,12 @@ use beacon_chain::slot_clock::{SlotClock, TestingSlotClock}; use beacon_chain::test_utils::{BeaconChainHarness, EphemeralHarnessType}; use beacon_chain::{BlockError, NotifyExecutionLayer}; use bls::Signature; -use execution_layer::{PayloadStatusV1, PayloadStatusV1Status}; +use execution_layer::{ + PayloadStatusV1, PayloadStatusV1Status, + json_structures::{ + JsonForkchoiceUpdatedV1Response, JsonPayloadStatusV1, JsonPayloadStatusV1Status, + }, +}; use lighthouse_network::{Client, MessageAcceptance, MessageId, PeerId}; use network::{NetworkBeaconProcessor, NetworkMessage, ReprocessAllowance}; use serde::Deserialize; @@ -234,6 +239,29 @@ impl GossipTester { let (harness, initial_block_index) = Self::build_harness(case, spec.clone(), &blocks, genesis_time, current_time_ms)?; + if case.meta.topic == Topic::ExecutionPayloadBid { + // Bid fixtures provide CL state and synthetic execution hashes, not an execution + // chain. Bypass the mock block generator when updating the cached head. + harness + .mock_execution_layer + .as_ref() + .expect("mock execution layer is configured") + .server + .ctx + .hook + .lock() + .set_forkchoice_updated_hook(Box::new(|state, payload_attributes| { + assert!(payload_attributes.is_none()); + Some(JsonForkchoiceUpdatedV1Response { + payload_status: JsonPayloadStatusV1 { + status: JsonPayloadStatusV1Status::Valid, + latest_valid_hash: Some(state.head_block_hash), + validation_error: None, + }, + payload_id: None, + }) + })); + } let (network_beacon_processor, network_rx) = NetworkBeaconProcessor::null_from_harness_with_network_receiver(&harness); From 379c1677d86143ab53fca19cd614652965b76655 Mon Sep 17 00:00:00 2001 From: Jimmy Chen Date: Fri, 25 Sep 2026 01:52:46 +0000 Subject: [PATCH 2/2] Limit mock fork-choice responses to setup payloads --- .../ef_tests/src/cases/gossip_validation.rs | 43 ++++++------------- 1 file changed, 14 insertions(+), 29 deletions(-) diff --git a/testing/ef_tests/src/cases/gossip_validation.rs b/testing/ef_tests/src/cases/gossip_validation.rs index 8d6ee6ca6d4..56cca59269b 100644 --- a/testing/ef_tests/src/cases/gossip_validation.rs +++ b/testing/ef_tests/src/cases/gossip_validation.rs @@ -10,12 +10,7 @@ use beacon_chain::slot_clock::{SlotClock, TestingSlotClock}; use beacon_chain::test_utils::{BeaconChainHarness, EphemeralHarnessType}; use beacon_chain::{BlockError, NotifyExecutionLayer}; use bls::Signature; -use execution_layer::{ - PayloadStatusV1, PayloadStatusV1Status, - json_structures::{ - JsonForkchoiceUpdatedV1Response, JsonPayloadStatusV1, JsonPayloadStatusV1Status, - }, -}; +use execution_layer::{PayloadStatusV1, PayloadStatusV1Status}; use lighthouse_network::{Client, MessageAcceptance, MessageId, PeerId}; use network::{NetworkBeaconProcessor, NetworkMessage, ReprocessAllowance}; use serde::Deserialize; @@ -239,29 +234,6 @@ impl GossipTester { let (harness, initial_block_index) = Self::build_harness(case, spec.clone(), &blocks, genesis_time, current_time_ms)?; - if case.meta.topic == Topic::ExecutionPayloadBid { - // Bid fixtures provide CL state and synthetic execution hashes, not an execution - // chain. Bypass the mock block generator when updating the cached head. - harness - .mock_execution_layer - .as_ref() - .expect("mock execution layer is configured") - .server - .ctx - .hook - .lock() - .set_forkchoice_updated_hook(Box::new(|state, payload_attributes| { - assert!(payload_attributes.is_none()); - Some(JsonForkchoiceUpdatedV1Response { - payload_status: JsonPayloadStatusV1 { - status: JsonPayloadStatusV1Status::Valid, - latest_valid_hash: Some(state.head_block_hash), - validation_error: None, - }, - payload_id: None, - }) - })); - } let (network_beacon_processor, network_rx) = NetworkBeaconProcessor::null_from_harness_with_network_receiver(&harness); @@ -992,6 +964,19 @@ impl GossipTester { "failed to mark setup payload for block {block_root:?} as received: {e:?}" )) })?; + // Setup payloads are treated as valid without executing them in the mock EL. + if let Some(mock_execution_layer) = self.harness.mock_execution_layer.as_ref() { + let block_hash = execution_payload.block_hash; + mock_execution_layer.server.set_fcu_payload_status( + block_hash, + PayloadStatusV1 { + status: PayloadStatusV1Status::Valid, + latest_valid_hash: Some(block_hash), + validation_error: None, + inclusion_list_satisfied: None, + }, + ); + } Ok(()) }