diff --git a/beacon_node/beacon_chain/src/beacon_chain.rs b/beacon_node/beacon_chain/src/beacon_chain.rs index 9ba8f24cbe7..4c7f314d870 100644 --- a/beacon_node/beacon_chain/src/beacon_chain.rs +++ b/beacon_node/beacon_chain/src/beacon_chain.rs @@ -197,6 +197,9 @@ pub enum ProduceBlockVerification { pub struct PrePayloadAttributes { pub proposer_index: u64, pub prev_randao: Hash256, + /// The parent block number is not part of the payload attributes sent to the EL, but *is* + /// sent to builders via SSE. + pub parent_block_number: u64, } /// Define whether a forkchoiceUpdate needs to be checked for an override (`Yes`) or has already @@ -3866,16 +3869,21 @@ impl BeaconChain { proposer as u64 }; - // Get the `prev_randao` value. - let prev_randao = if proposer_head == parent_block_root { - cached_head.parent_random() + // Get the `prev_randao` and parent block number. + let head_block_number = cached_head.head_block_number()?; + let (prev_randao, parent_block_number) = if proposer_head == parent_block_root { + ( + cached_head.parent_random()?, + head_block_number.saturating_sub(1), + ) } else { - cached_head.head_random() - }?; + (cached_head.head_random()?, head_block_number) + }; Ok(Some(PrePayloadAttributes { proposer_index, prev_randao, + parent_block_number, })) } @@ -4865,6 +4873,7 @@ impl BeaconChain { proposal_slot: prepare_slot, proposer_index: proposer, parent_block_root: head_root, + parent_block_number: pre_payload_attributes.parent_block_number, parent_block_hash: forkchoice_update_params.head_hash.unwrap_or_default(), payload_attributes: payload_attributes.into(), }, diff --git a/beacon_node/beacon_chain/src/canonical_head.rs b/beacon_node/beacon_chain/src/canonical_head.rs index 19eddf60263..24c06680d49 100644 --- a/beacon_node/beacon_chain/src/canonical_head.rs +++ b/beacon_node/beacon_chain/src/canonical_head.rs @@ -167,6 +167,17 @@ impl CachedHead { .map(|payload| payload.prev_randao()) } + /// Returns the execution block number of the block at the head of the chain. + /// + /// Returns an error if the chain is prior to Bellatrix. + pub fn head_block_number(&self) -> Result { + self.snapshot + .beacon_block + .message() + .execution_payload() + .map(|payload| payload.block_number()) + } + /// Returns the active validator count for the current epoch of the head state. /// /// Should only return `None` if the caches have not been built on the head state (this should diff --git a/beacon_node/execution_layer/src/lib.rs b/beacon_node/execution_layer/src/lib.rs index b7aa4dc05ee..60bc6278a0e 100644 --- a/beacon_node/execution_layer/src/lib.rs +++ b/beacon_node/execution_layer/src/lib.rs @@ -47,7 +47,7 @@ use types::{ mod block_hash; mod engine_api; -mod engines; +pub mod engines; mod keccak; mod metrics; pub mod payload_cache; diff --git a/common/eth2/src/types.rs b/common/eth2/src/types.rs index b4218c361a3..175c7db7867 100644 --- a/common/eth2/src/types.rs +++ b/common/eth2/src/types.rs @@ -921,6 +921,8 @@ pub struct SseExtendedPayloadAttributesGeneric { #[serde(with = "eth2_serde_utils::quoted_u64")] pub proposer_index: u64, pub parent_block_root: Hash256, + #[serde(with = "eth2_serde_utils::quoted_u64")] + pub parent_block_number: u64, pub parent_block_hash: ExecutionBlockHash, pub payload_attributes: T, } @@ -958,6 +960,7 @@ impl ForkVersionDeserialize for SseExtendedPayloadAttributes { proposal_slot: helper.proposal_slot, proposer_index: helper.proposer_index, parent_block_root: helper.parent_block_root, + parent_block_number: helper.parent_block_number, parent_block_hash: helper.parent_block_hash, payload_attributes: SsePayloadAttributes::deserialize_by_fork::( helper.payload_attributes,