diff --git a/bin/reth/src/commands/debug_cmd/build_block.rs b/bin/reth/src/commands/debug_cmd/build_block.rs index 7507e8bf1..40110fe84 100644 --- a/bin/reth/src/commands/debug_cmd/build_block.rs +++ b/bin/reth/src/commands/debug_cmd/build_block.rs @@ -238,7 +238,7 @@ impl> Command { debug!(target: "reth::cli", ?block, "Built new payload"); consensus.validate_header_with_total_difficulty(block, U256::MAX)?; - consensus.validate_header(block)?; + consensus.validate_header(block.sealed_header())?; consensus.validate_block_pre_execution(block)?; let senders = block.senders().expect("sender recovery failed"); diff --git a/crates/consensus/common/src/validation.rs b/crates/consensus/common/src/validation.rs index 61251b80e..9e6a2ad90 100644 --- a/crates/consensus/common/src/validation.rs +++ b/crates/consensus/common/src/validation.rs @@ -64,8 +64,7 @@ pub fn validate_cancun_gas( ) -> Result<(), ConsensusError> { // Check that the blob gas used in the header matches the sum of the blob gas used by each // blob tx - let header_blob_gas_used = - block.header().blob_gas_used().ok_or(ConsensusError::BlobGasUsedMissing)?; + let header_blob_gas_used = block.blob_gas_used().ok_or(ConsensusError::BlobGasUsedMissing)?; let total_blob_gas = block.body().blob_gas_used(); if total_blob_gas != header_blob_gas_used { return Err(ConsensusError::BlobGasUsedDiff(GotExpected { diff --git a/crates/engine/tree/src/tree/mod.rs b/crates/engine/tree/src/tree/mod.rs index 00e314cf5..03b9f0ab5 100644 --- a/crates/engine/tree/src/tree/mod.rs +++ b/crates/engine/tree/src/tree/mod.rs @@ -1809,7 +1809,7 @@ where return Err(e) } - if let Err(e) = self.consensus.validate_header(block) { + if let Err(e) = self.consensus.validate_header(block.sealed_header()) { error!(target: "engine::tree", ?block, "Failed to validate header {}: {e}", block.hash()); return Err(e) } @@ -2248,7 +2248,9 @@ where block.parent_hash().into(), )) })?; - if let Err(e) = self.consensus.validate_header_against_parent(&block, &parent_block) { + if let Err(e) = + self.consensus.validate_header_against_parent(block.sealed_header(), &parent_block) + { warn!(target: "engine::tree", ?block, "Failed to validate header {} against parent: {e}", block.hash()); return Err(e.into()) } diff --git a/crates/primitives-traits/src/block/mod.rs b/crates/primitives-traits/src/block/mod.rs index f161ced82..85e29995f 100644 --- a/crates/primitives-traits/src/block/mod.rs +++ b/crates/primitives-traits/src/block/mod.rs @@ -93,12 +93,35 @@ where /// /// This allows for modifying the block's header and body for testing purposes. #[cfg(any(test, feature = "test-utils"))] -pub trait TestBlock: Block { +pub trait TestBlock: Block { /// Returns mutable reference to block body. fn body_mut(&mut self) -> &mut Self::Body; /// Returns mutable reference to block header. fn header_mut(&mut self) -> &mut Self::Header; + + /// Updates the block header. + fn set_header(&mut self, header: Self::Header); + + /// Updates the parent block hash. + fn set_parent_hash(&mut self, hash: alloy_primitives::BlockHash) { + crate::header::test_utils::TestHeader::set_parent_hash(self.header_mut(), hash); + } + + /// Updates the block number. + fn set_block_number(&mut self, number: alloy_primitives::BlockNumber) { + crate::header::test_utils::TestHeader::set_block_number(self.header_mut(), number); + } + + /// Updates the block state root. + fn set_state_root(&mut self, state_root: alloy_primitives::B256) { + crate::header::test_utils::TestHeader::set_state_root(self.header_mut(), state_root); + } + + /// Updates the block difficulty. + fn set_difficulty(&mut self, difficulty: alloy_primitives::U256) { + crate::header::test_utils::TestHeader::set_difficulty(self.header_mut(), difficulty); + } } #[cfg(any(test, feature = "test-utils"))] @@ -113,4 +136,8 @@ where fn header_mut(&mut self) -> &mut Self::Header { &mut self.header } + + fn set_header(&mut self, header: Self::Header) { + self.header = header + } } diff --git a/crates/primitives-traits/src/header/sealed.rs b/crates/primitives-traits/src/header/sealed.rs index 4291735a6..4b1a83fb5 100644 --- a/crates/primitives-traits/src/header/sealed.rs +++ b/crates/primitives-traits/src/header/sealed.rs @@ -138,9 +138,9 @@ where } #[cfg(any(test, feature = "test-utils"))] -impl SealedHeader { +impl SealedHeader { /// Updates the block header. - pub fn set_header(&mut self, header: Header) { + pub fn set_header(&mut self, header: H) { self.header = header } @@ -149,24 +149,29 @@ impl SealedHeader { self.hash = hash } + /// Returns a mutable reference to the header. + pub fn header_mut(&mut self) -> &mut H { + &mut self.header + } + /// Updates the parent block hash. pub fn set_parent_hash(&mut self, hash: BlockHash) { - self.header.parent_hash = hash + self.header.set_parent_hash(hash); } /// Updates the block number. pub fn set_block_number(&mut self, number: alloy_primitives::BlockNumber) { - self.header.number = number; + self.header.set_block_number(number); } /// Updates the block state root. pub fn set_state_root(&mut self, state_root: alloy_primitives::B256) { - self.header.state_root = state_root; + self.header.set_state_root(state_root); } /// Updates the block difficulty. pub fn set_difficulty(&mut self, difficulty: alloy_primitives::U256) { - self.header.difficulty = difficulty; + self.header.set_difficulty(difficulty); } } diff --git a/crates/primitives/Cargo.toml b/crates/primitives/Cargo.toml index 6937ec285..2ccaf4b0d 100644 --- a/crates/primitives/Cargo.toml +++ b/crates/primitives/Cargo.toml @@ -63,7 +63,7 @@ arbitrary = { workspace = true, features = ["derive"], optional = true } # eth reth-chainspec = { workspace = true, features = ["arbitrary"] } reth-codecs = { workspace = true, features = ["test-utils"] } -reth-primitives-traits = { workspace = true, features = ["arbitrary"] } +reth-primitives-traits = { workspace = true, features = ["arbitrary", "test-utils"] } reth-testing-utils.workspace = true reth-trie-common = { workspace = true, features = ["arbitrary"] } revm-primitives = { workspace = true, features = ["arbitrary"] } diff --git a/crates/primitives/src/block.rs b/crates/primitives/src/block.rs index 9908c0667..fd0dc0cee 100644 --- a/crates/primitives/src/block.rs +++ b/crates/primitives/src/block.rs @@ -4,7 +4,9 @@ use crate::{ }; use alloc::vec::Vec; use alloy_consensus::Header; -use alloy_eips::{eip2718::Encodable2718, eip4895::Withdrawals}; +use alloy_eips::{ + eip1898::BlockWithParent, eip2718::Encodable2718, eip4895::Withdrawals, BlockNumHash, +}; use alloy_primitives::{Address, B256}; use alloy_rlp::{Decodable, Encodable, RlpDecodable, RlpEncodable}; use derive_more::{Deref, DerefMut}; @@ -162,11 +164,9 @@ impl BlockWithSenders { /// Sealed Ethereum full block. /// /// Withdrawals can be optionally included at the end of the RLP encoded message. -#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Deref, DerefMut)] +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct SealedBlock { /// Locked block header. - #[deref] - #[deref_mut] header: SealedHeader, /// Block body. body: B, @@ -185,6 +185,11 @@ impl SealedBlock { self.header.hash() } + /// Returns reference to block header. + pub const fn header(&self) -> &H { + self.header.header() + } + /// Returns reference to block body. pub const fn body(&self) -> &B { &self.body @@ -252,6 +257,16 @@ where H: alloy_consensus::BlockHeader, B: reth_primitives_traits::BlockBody, { + /// Return the number hash tuple. + pub fn num_hash(&self) -> BlockNumHash { + BlockNumHash::new(self.number(), self.hash()) + } + + /// Return a [`BlockWithParent`] for this header. + pub fn block_with_parent(&self) -> BlockWithParent { + BlockWithParent { parent: self.parent_hash(), block: self.num_hash() } + } + /// Ensures that the transaction root in the block header is valid. /// /// The transaction root is the Keccak 256-bit hash of the root node of the trie structure @@ -388,6 +403,14 @@ where } } +impl Deref for SealedBlock { + type Target = H; + + fn deref(&self) -> &Self::Target { + self.header.header() + } +} + #[cfg(any(test, feature = "arbitrary"))] impl<'a, H, B> arbitrary::Arbitrary<'a> for SealedBlock where @@ -399,6 +422,52 @@ where } } +#[cfg(any(test, feature = "test-utils"))] +impl SealedBlock +where + H: reth_primitives_traits::test_utils::TestHeader, +{ + /// Returns a mutable reference to the header. + pub fn header_mut(&mut self) -> &mut H { + self.header.header_mut() + } + + /// Returns a mutable reference to the header. + pub fn body_mut(&mut self) -> &mut B { + &mut self.body + } + + /// Updates the block header. + pub fn set_header(&mut self, header: H) { + self.header.set_header(header) + } + + /// Updates the block hash. + pub fn set_hash(&mut self, hash: alloy_primitives::BlockHash) { + self.header.set_hash(hash); + } + + /// Updates the parent block hash. + pub fn set_parent_hash(&mut self, hash: alloy_primitives::BlockHash) { + self.header.set_parent_hash(hash); + } + + /// Updates the block number. + pub fn set_block_number(&mut self, number: alloy_primitives::BlockNumber) { + self.header.set_block_number(number); + } + + /// Updates the block state root. + pub fn set_state_root(&mut self, state_root: B256) { + self.header.set_state_root(state_root); + } + + /// Updates the block difficulty. + pub fn set_difficulty(&mut self, difficulty: alloy_primitives::U256) { + self.header.set_difficulty(difficulty); + } +} + /// A helepr trait to construct [`SealedBlock`] from a [`reth_primitives_traits::Block`]. pub type SealedBlockFor = SealedBlock< ::Header,