From ddff03d26f269c773e3774e0eaf1b327bd254e8b Mon Sep 17 00:00:00 2001 From: Michael Sproul Date: Wed, 1 Apr 2026 16:42:49 +1100 Subject: [PATCH] Store parent_payload_hash in ProtoNode --- consensus/fork_choice/src/fork_choice.rs | 1 + consensus/proto_array/src/proto_array.rs | 4 +++- consensus/proto_array/src/proto_array_fork_choice.rs | 5 +++-- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/consensus/fork_choice/src/fork_choice.rs b/consensus/fork_choice/src/fork_choice.rs index 1f5b2cf1b0..7e189b0a1b 100644 --- a/consensus/fork_choice/src/fork_choice.rs +++ b/consensus/fork_choice/src/fork_choice.rs @@ -1138,6 +1138,7 @@ where } // index == 1 (payload_present) requires the block's payload to have been received. + // TODO(gloas): could optimise by adding `payload_received` to `Block` if index == 1 && !self .proto_array diff --git a/consensus/proto_array/src/proto_array.rs b/consensus/proto_array/src/proto_array.rs index 256cb48c77..412e217bf8 100644 --- a/consensus/proto_array/src/proto_array.rs +++ b/consensus/proto_array/src/proto_array.rs @@ -143,6 +143,8 @@ pub struct ProtoNode { pub full_payload_weight: u64, #[superstruct(only(V29), partial_getter(copy))] pub execution_payload_block_hash: ExecutionBlockHash, + #[superstruct(only(V29), partial_getter(copy))] + pub execution_payload_parent_hash: ExecutionBlockHash, /// Equivalent to spec's `block_timeliness[root][ATTESTATION_TIMELINESS_INDEX]`. #[superstruct(only(V29), partial_getter(copy))] pub block_timeliness_attestation_threshold: bool, @@ -181,7 +183,6 @@ pub struct ProtoNode { impl ProtoNode { /// Generic version of spec's `parent_payload_status` that works for pre-Gloas nodes by /// considering their parents Empty. - /// Pre-Gloas nodes have no ePBS, default to Empty. pub fn get_parent_payload_status(&self) -> PayloadStatus { self.parent_payload_status().unwrap_or(PayloadStatus::Empty) } @@ -620,6 +621,7 @@ impl ProtoArray { empty_payload_weight: 0, full_payload_weight: 0, execution_payload_block_hash, + execution_payload_parent_hash, // Per spec `get_forkchoice_store`: the anchor block's PTC votes are // initialized to all-True, ensuring `is_payload_timely` and // `is_payload_data_available` return true for the anchor. diff --git a/consensus/proto_array/src/proto_array_fork_choice.rs b/consensus/proto_array/src/proto_array_fork_choice.rs index f6427ba863..72440b83b8 100644 --- a/consensus/proto_array/src/proto_array_fork_choice.rs +++ b/consensus/proto_array/src/proto_array_fork_choice.rs @@ -1030,7 +1030,7 @@ impl ProtoArrayForkChoice { .unwrap_or_else(|_| ExecutionStatus::irrelevant()), unrealized_justified_checkpoint: block.unrealized_justified_checkpoint(), unrealized_finalized_checkpoint: block.unrealized_finalized_checkpoint(), - execution_payload_parent_hash: None, + execution_payload_parent_hash: block.execution_payload_parent_hash().ok(), execution_payload_block_hash: block.execution_payload_block_hash().ok(), proposer_index: block.proposer_index().ok(), }) @@ -1047,7 +1047,8 @@ impl ProtoArrayForkChoice { } /// Returns whether the execution payload for a block has been received. - /// Returns `false` for pre-GLOAS (V17) nodes or unknown blocks. + /// + /// Returns `false` for pre-Gloas (V17) nodes or unknown blocks. pub fn is_payload_received(&self, block_root: &Hash256) -> bool { self.get_proto_node(block_root) .and_then(|node| node.payload_received().ok())