diff --git a/consensus/fork_choice/src/fork_choice.rs b/consensus/fork_choice/src/fork_choice.rs index 19a9bc3b64..aa1c03685e 100644 --- a/consensus/fork_choice/src/fork_choice.rs +++ b/consensus/fork_choice/src/fork_choice.rs @@ -134,6 +134,7 @@ impl ResetPayloadStatuses { #[derive(Debug)] pub enum InvalidBlock { UnknownParent(Hash256), + ParentPayloadNotVerified(Hash256), FutureSlot { current_slot: Slot, block_slot: Slot, @@ -818,6 +819,19 @@ where .get_block(&block.parent_root()) .ok_or_else(|| Error::InvalidBlock(InvalidBlock::UnknownParent(block.parent_root())))?; + // If the block builds on a full payload envelope, the envelope must be known. + if let Some(parent_block_hash) = parent_block.execution_payload_block_hash { + let builds_on_full = block + .body() + .signed_execution_payload_bid() + .is_ok_and(|bid| bid.message.parent_block_hash == parent_block_hash); + if builds_on_full && !self.is_payload_received(&block.parent_root()) { + return Err(Error::InvalidBlock(InvalidBlock::ParentPayloadNotVerified( + block.parent_root(), + ))); + } + } + // Blocks cannot be in the future. If they are, their consideration must be delayed until // they are in the past. //