Fix block hash computation

This commit is contained in:
Pawan Dhananjay
2024-11-06 19:11:07 -08:00
parent 2aaf9b5dbe
commit 27ce1a08d9
6 changed files with 83 additions and 42 deletions

View File

@@ -52,9 +52,11 @@ pub struct ExecutionBlockHeader {
pub blob_gas_used: Option<u64>,
pub excess_blob_gas: Option<u64>,
pub parent_beacon_block_root: Option<Hash256>,
pub requests_root: Option<Hash256>,
}
impl ExecutionBlockHeader {
#[allow(clippy::too_many_arguments)]
pub fn from_payload<E: EthSpec>(
payload: ExecutionPayloadRef<E>,
rlp_empty_list_root: Hash256,
@@ -63,6 +65,7 @@ impl ExecutionBlockHeader {
rlp_blob_gas_used: Option<u64>,
rlp_excess_blob_gas: Option<u64>,
rlp_parent_beacon_block_root: Option<Hash256>,
rlp_requests_root: Option<Hash256>,
) -> Self {
// Most of these field mappings are defined in EIP-3675 except for `mixHash`, which is
// defined in EIP-4399.
@@ -87,6 +90,7 @@ impl ExecutionBlockHeader {
blob_gas_used: rlp_blob_gas_used,
excess_blob_gas: rlp_excess_blob_gas,
parent_beacon_block_root: rlp_parent_beacon_block_root,
requests_root: rlp_requests_root,
}
}
}
@@ -114,6 +118,7 @@ pub struct EncodableExecutionBlockHeader<'a> {
pub blob_gas_used: Option<u64>,
pub excess_blob_gas: Option<u64>,
pub parent_beacon_block_root: Option<&'a [u8]>,
pub requests_root: Option<&'a [u8]>,
}
impl<'a> From<&'a ExecutionBlockHeader> for EncodableExecutionBlockHeader<'a> {
@@ -139,6 +144,7 @@ impl<'a> From<&'a ExecutionBlockHeader> for EncodableExecutionBlockHeader<'a> {
blob_gas_used: header.blob_gas_used,
excess_blob_gas: header.excess_blob_gas,
parent_beacon_block_root: None,
requests_root: None,
};
if let Some(withdrawals_root) = &header.withdrawals_root {
encodable.withdrawals_root = Some(withdrawals_root.as_slice());
@@ -146,6 +152,9 @@ impl<'a> From<&'a ExecutionBlockHeader> for EncodableExecutionBlockHeader<'a> {
if let Some(parent_beacon_block_root) = &header.parent_beacon_block_root {
encodable.parent_beacon_block_root = Some(parent_beacon_block_root.as_slice())
}
if let Some(requests_root) = &header.requests_root {
encodable.requests_root = Some(requests_root.as_slice())
}
encodable
}
}

View File

@@ -1,7 +1,8 @@
use crate::test_utils::TestRandom;
use crate::{ConsolidationRequest, DepositRequest, EthSpec, WithdrawalRequest};
use crate::{ConsolidationRequest, DepositRequest, EthSpec, Hash256, WithdrawalRequest};
use alloy_primitives::Bytes;
use derivative::Derivative;
use ethereum_hashing::{DynamicContext, Sha256Context};
use serde::{Deserialize, Serialize};
use ssz::Encode;
use ssz_derive::{Decode, Encode};
@@ -47,6 +48,43 @@ impl<E: EthSpec> ExecutionRequests<E> {
let consolidation_bytes = Bytes::from(self.consolidations.as_ssz_bytes());
vec![deposit_bytes, withdrawal_bytes, consolidation_bytes]
}
/// Generate the execution layer `requests_hash` based on EIP-7685.
///
/// `sha256(sha256(requests_0) ++ sha256(requests_1) ++ ...)`
pub fn requests_hash(&self) -> Hash256 {
let mut hasher = DynamicContext::new();
for (i, request) in self.get_execution_requests_list().iter().enumerate() {
let mut request_hasher = DynamicContext::new();
request_hasher.update(&[i as u8]);
request_hasher.update(request);
let request_hash = request_hasher.finalize();
hasher.update(&request_hash);
}
hasher.finalize().into()
}
}
/// This is used to index into the `execution_requests` array.
#[derive(Debug, Copy, Clone)]
pub enum RequestPrefix {
Deposit,
Withdrawal,
Consolidation,
}
impl RequestPrefix {
pub fn from_prefix(prefix: u8) -> Option<Self> {
match prefix {
0 => Some(Self::Deposit),
1 => Some(Self::Withdrawal),
2 => Some(Self::Consolidation),
_ => None,
}
}
}
#[cfg(test)]

View File

@@ -170,7 +170,7 @@ pub use crate::execution_payload_header::{
ExecutionPayloadHeaderDeneb, ExecutionPayloadHeaderElectra, ExecutionPayloadHeaderRef,
ExecutionPayloadHeaderRefMut,
};
pub use crate::execution_requests::ExecutionRequests;
pub use crate::execution_requests::{ExecutionRequests, RequestPrefix};
pub use crate::fork::Fork;
pub use crate::fork_context::ForkContext;
pub use crate::fork_data::ForkData;