Skip to content

Commit

Permalink
Fix Block Root Calculation post-Deneb
Browse files Browse the repository at this point in the history
  • Loading branch information
ethDreamer committed Jul 24, 2023
1 parent 2ce8a0e commit 2b3adbe
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 17 deletions.
8 changes: 2 additions & 6 deletions beacon_node/beacon_chain/src/execution_payload.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,6 @@ impl<T: BeaconChainTypes> PayloadNotifier<T> {
)
.map_err(BlockError::PerBlockProcessingError)?;

let payload = block_message.execution_payload()?;

match notify_execution_layer {
NotifyExecutionLayer::No if chain.config.optimistic_finalized_sync => {
// Verify the block hash here in Lighthouse and immediately mark the block as
Expand All @@ -89,13 +87,11 @@ impl<T: BeaconChainTypes> PayloadNotifier<T> {
.as_ref()
.ok_or(ExecutionPayloadError::NoExecutionConnection)?;

if let Err(e) =
execution_layer.verify_payload_block_hash(payload.execution_payload_ref())
{
if let Err(e) = execution_layer.verify_payload_block_hash(block_message) {
warn!(
chain.log,
"Falling back to slow block hash verification";
"block_number" => payload.block_number(),
"block_number" => ?block_message.execution_payload().map(|payload| payload.block_number()),
"info" => "you can silence this warning with --disable-optimistic-finalized-sync",
"error" => ?e,
);
Expand Down
29 changes: 23 additions & 6 deletions beacon_node/execution_layer/src/block_hash.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ use ethers_core::utils::rlp::RlpStream;
use keccak_hash::KECCAK_EMPTY_LIST_RLP;
use triehash::ordered_trie_root;
use types::{
map_execution_block_header_fields_except_withdrawals, Address, EthSpec, ExecutionBlockHash,
ExecutionBlockHeader, ExecutionPayloadRef, Hash256, Hash64, Uint256,
map_execution_block_header_fields_except_withdrawals, Address, BeaconBlockRef, EthSpec,
ExecutionBlockHash, ExecutionBlockHeader, ExecutionPayloadRef, Hash256, Hash64, Uint256,
};

impl<T: EthSpec> ExecutionLayer<T> {
Expand All @@ -18,6 +18,7 @@ impl<T: EthSpec> ExecutionLayer<T> {
/// transactions.
pub fn calculate_execution_block_hash(
payload: ExecutionPayloadRef<T>,
parent_beacon_block_root: Hash256,
) -> (ExecutionBlockHash, Hash256) {
// Calculate the transactions root.
// We're currently using a deprecated Parity library for this. We should move to a
Expand All @@ -40,14 +41,20 @@ impl<T: EthSpec> ExecutionLayer<T> {
let rlp_data_gas_used = payload.data_gas_used().ok();
let rlp_excess_data_gas = payload.excess_data_gas().ok();

// Calculate parent beacon block root (post-Deneb).
let rlp_parent_beacon_block_root = rlp_excess_data_gas
.as_ref()
.map(|_| parent_beacon_block_root);

// Construct the block header.
let exec_block_header = ExecutionBlockHeader::from_payload(
payload,
KECCAK_EMPTY_LIST_RLP.as_fixed_bytes().into(),
rlp_transactions_root,
rlp_withdrawals_root,
rlp_data_gas_used.copied(),
rlp_excess_data_gas.copied(),
rlp_data_gas_used,
rlp_excess_data_gas,
rlp_parent_beacon_block_root,
);

// Hash the RLP encoding of the block header.
Expand All @@ -61,10 +68,14 @@ impl<T: EthSpec> ExecutionLayer<T> {
/// Verify `payload.block_hash` locally within Lighthouse.
///
/// No remote calls to the execution client will be made, so this is quite a cheap check.
pub fn verify_payload_block_hash(&self, payload: ExecutionPayloadRef<T>) -> Result<(), Error> {
pub fn verify_payload_block_hash(&self, block: BeaconBlockRef<T>) -> Result<(), Error> {
let payload = block.execution_payload()?.execution_payload_ref();
let parent_beacon_block_root = block.parent_root();

let _timer = metrics::start_timer(&metrics::EXECUTION_LAYER_VERIFY_BLOCK_HASH);

let (header_hash, rlp_transactions_root) = Self::calculate_execution_block_hash(payload);
let (header_hash, rlp_transactions_root) =
Self::calculate_execution_block_hash(payload, parent_beacon_block_root);

if header_hash != payload.block_hash() {
return Err(Error::BlockHashMismatch {
Expand Down Expand Up @@ -105,6 +116,9 @@ pub fn rlp_encode_block_header(header: &ExecutionBlockHeader) -> Vec<u8> {
if let Some(excess_data_gas) = &header.excess_data_gas {
rlp_header_stream.append(excess_data_gas);
}
if let Some(parent_beacon_block_root) = &header.parent_beacon_block_root {
rlp_header_stream.append(parent_beacon_block_root);
}
rlp_header_stream.finalize_unbounded_list();
rlp_header_stream.out().into()
}
Expand Down Expand Up @@ -153,6 +167,7 @@ mod test {
withdrawals_root: None,
data_gas_used: None,
excess_data_gas: None,
parent_beacon_block_root: None,
};
let expected_rlp = "f90200a0e0a94a7a3c9617401586b1a27025d2d9671332d22d540e0af72b069170380f2aa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794ba5e000000000000000000000000000000000000a0ec3c94b18b8a1cff7d60f8d258ec723312932928626b4c9355eb4ab3568ec7f7a050f738580ed699f0469702c7ccc63ed2e51bc034be9479b7bff4e68dee84accfa029b0562f7140574dd0d50dee8a271b22e1a0a7b78fca58f7c60370d8317ba2a9b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830200000188016345785d8a00008301553482079e42a0000000000000000000000000000000000000000000000000000000000000000088000000000000000082036b";
let expected_hash =
Expand Down Expand Up @@ -183,6 +198,7 @@ mod test {
withdrawals_root: None,
data_gas_used: None,
excess_data_gas: None,
parent_beacon_block_root: None,
};
let expected_rlp = "f901fda0927ca537f06c783a3a2635b8805eef1c8c2124f7444ad4a3389898dd832f2dbea01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794ba5e000000000000000000000000000000000000a0e97859b065bd8dbbb4519c7cb935024de2484c2b7f881181b4360492f0b06b82a050f738580ed699f0469702c7ccc63ed2e51bc034be9479b7bff4e68dee84accfa029b0562f7140574dd0d50dee8a271b22e1a0a7b78fca58f7c60370d8317ba2a9b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800188016345785d8a00008301553482079e42a0000000000000000000000000000000000000000000000000000000000002000088000000000000000082036b";
let expected_hash =
Expand Down Expand Up @@ -214,6 +230,7 @@ mod test {
withdrawals_root: None,
data_gas_used: None,
excess_data_gas: None,
parent_beacon_block_root: None,
};
let expected_hash =
Hash256::from_str("6da69709cd5a34079b6604d29cd78fc01dacd7c6268980057ad92a2bede87351")
Expand Down
6 changes: 5 additions & 1 deletion consensus/types/src/execution_block_header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ use metastruct::metastruct;
#[metastruct(mappings(map_execution_block_header_fields_except_withdrawals(exclude(
withdrawals_root,
data_gas_used,
excess_data_gas
excess_data_gas,
parent_beacon_block_root
)),))]
pub struct ExecutionBlockHeader {
pub parent_hash: Hash256,
Expand All @@ -49,6 +50,7 @@ pub struct ExecutionBlockHeader {
pub withdrawals_root: Option<Hash256>,
pub data_gas_used: Option<u64>,
pub excess_data_gas: Option<u64>,
pub parent_beacon_block_root: Option<Hash256>,
}

impl ExecutionBlockHeader {
Expand All @@ -59,6 +61,7 @@ impl ExecutionBlockHeader {
rlp_withdrawals_root: Option<Hash256>,
rlp_data_gas_used: Option<u64>,
rlp_excess_data_gas: Option<u64>,
rlp_parent_beacon_block_root: Option<Hash256>,
) -> Self {
// Most of these field mappings are defined in EIP-3675 except for `mixHash`, which is
// defined in EIP-4399.
Expand All @@ -82,6 +85,7 @@ impl ExecutionBlockHeader {
withdrawals_root: rlp_withdrawals_root,
data_gas_used: rlp_data_gas_used,
excess_data_gas: rlp_excess_data_gas,
parent_beacon_block_root: rlp_parent_beacon_block_root,
}
}
}
6 changes: 2 additions & 4 deletions consensus/types/src/execution_payload.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,13 +83,11 @@ pub struct ExecutionPayload<T: EthSpec> {
pub transactions: Transactions<T>,
#[superstruct(only(Capella, Deneb))]
pub withdrawals: Withdrawals<T>,
#[superstruct(only(Deneb))]
#[superstruct(only(Deneb), partial_getter(copy))]
#[serde(with = "serde_utils::quoted_u64")]
#[superstruct(getter(copy))]
pub data_gas_used: u64,
#[superstruct(only(Deneb))]
#[superstruct(only(Deneb), partial_getter(copy))]
#[serde(with = "serde_utils::quoted_u64")]
#[superstruct(getter(copy))]
pub excess_data_gas: u64,
}

Expand Down

0 comments on commit 2b3adbe

Please sign in to comment.