chore: integrate Test trait for sealed types (#13746)

This commit is contained in:
Matthias Seitz
2025-01-09 09:06:28 +01:00
committed by GitHub
parent d0684cf8bb
commit 383eb2331c
7 changed files with 119 additions and 17 deletions

View File

@ -238,7 +238,7 @@ impl<C: ChainSpecParser<ChainSpec = ChainSpec>> Command<C> {
debug!(target: "reth::cli", ?block, "Built new payload"); debug!(target: "reth::cli", ?block, "Built new payload");
consensus.validate_header_with_total_difficulty(block, U256::MAX)?; 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)?; consensus.validate_block_pre_execution(block)?;
let senders = block.senders().expect("sender recovery failed"); let senders = block.senders().expect("sender recovery failed");

View File

@ -64,8 +64,7 @@ pub fn validate_cancun_gas<H: BlockHeader, B: BlockBody>(
) -> Result<(), ConsensusError> { ) -> Result<(), ConsensusError> {
// Check that the blob gas used in the header matches the sum of the blob gas used by each // Check that the blob gas used in the header matches the sum of the blob gas used by each
// blob tx // blob tx
let header_blob_gas_used = let header_blob_gas_used = block.blob_gas_used().ok_or(ConsensusError::BlobGasUsedMissing)?;
block.header().blob_gas_used().ok_or(ConsensusError::BlobGasUsedMissing)?;
let total_blob_gas = block.body().blob_gas_used(); let total_blob_gas = block.body().blob_gas_used();
if total_blob_gas != header_blob_gas_used { if total_blob_gas != header_blob_gas_used {
return Err(ConsensusError::BlobGasUsedDiff(GotExpected { return Err(ConsensusError::BlobGasUsedDiff(GotExpected {

View File

@ -1809,7 +1809,7 @@ where
return Err(e) 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()); error!(target: "engine::tree", ?block, "Failed to validate header {}: {e}", block.hash());
return Err(e) return Err(e)
} }
@ -2248,7 +2248,9 @@ where
block.parent_hash().into(), 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()); warn!(target: "engine::tree", ?block, "Failed to validate header {} against parent: {e}", block.hash());
return Err(e.into()) return Err(e.into())
} }

View File

@ -93,12 +93,35 @@ where
/// ///
/// This allows for modifying the block's header and body for testing purposes. /// This allows for modifying the block's header and body for testing purposes.
#[cfg(any(test, feature = "test-utils"))] #[cfg(any(test, feature = "test-utils"))]
pub trait TestBlock: Block { pub trait TestBlock: Block<Header: crate::test_utils::TestHeader> {
/// Returns mutable reference to block body. /// Returns mutable reference to block body.
fn body_mut(&mut self) -> &mut Self::Body; fn body_mut(&mut self) -> &mut Self::Body;
/// Returns mutable reference to block header. /// Returns mutable reference to block header.
fn header_mut(&mut self) -> &mut Self::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"))] #[cfg(any(test, feature = "test-utils"))]
@ -113,4 +136,8 @@ where
fn header_mut(&mut self) -> &mut Self::Header { fn header_mut(&mut self) -> &mut Self::Header {
&mut self.header &mut self.header
} }
fn set_header(&mut self, header: Self::Header) {
self.header = header
}
} }

View File

@ -138,9 +138,9 @@ where
} }
#[cfg(any(test, feature = "test-utils"))] #[cfg(any(test, feature = "test-utils"))]
impl SealedHeader { impl<H: crate::test_utils::TestHeader> SealedHeader<H> {
/// Updates the block header. /// Updates the block header.
pub fn set_header(&mut self, header: Header) { pub fn set_header(&mut self, header: H) {
self.header = header self.header = header
} }
@ -149,24 +149,29 @@ impl SealedHeader {
self.hash = hash 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. /// Updates the parent block hash.
pub fn set_parent_hash(&mut self, hash: BlockHash) { pub fn set_parent_hash(&mut self, hash: BlockHash) {
self.header.parent_hash = hash self.header.set_parent_hash(hash);
} }
/// Updates the block number. /// Updates the block number.
pub fn set_block_number(&mut self, number: alloy_primitives::BlockNumber) { 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. /// Updates the block state root.
pub fn set_state_root(&mut self, state_root: alloy_primitives::B256) { 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. /// Updates the block difficulty.
pub fn set_difficulty(&mut self, difficulty: alloy_primitives::U256) { pub fn set_difficulty(&mut self, difficulty: alloy_primitives::U256) {
self.header.difficulty = difficulty; self.header.set_difficulty(difficulty);
} }
} }

View File

@ -63,7 +63,7 @@ arbitrary = { workspace = true, features = ["derive"], optional = true }
# eth # eth
reth-chainspec = { workspace = true, features = ["arbitrary"] } reth-chainspec = { workspace = true, features = ["arbitrary"] }
reth-codecs = { workspace = true, features = ["test-utils"] } 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-testing-utils.workspace = true
reth-trie-common = { workspace = true, features = ["arbitrary"] } reth-trie-common = { workspace = true, features = ["arbitrary"] }
revm-primitives = { workspace = true, features = ["arbitrary"] } revm-primitives = { workspace = true, features = ["arbitrary"] }

View File

@ -4,7 +4,9 @@ use crate::{
}; };
use alloc::vec::Vec; use alloc::vec::Vec;
use alloy_consensus::Header; 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_primitives::{Address, B256};
use alloy_rlp::{Decodable, Encodable, RlpDecodable, RlpEncodable}; use alloy_rlp::{Decodable, Encodable, RlpDecodable, RlpEncodable};
use derive_more::{Deref, DerefMut}; use derive_more::{Deref, DerefMut};
@ -162,11 +164,9 @@ impl<B: reth_primitives_traits::Block> BlockWithSenders<B> {
/// Sealed Ethereum full block. /// Sealed Ethereum full block.
/// ///
/// Withdrawals can be optionally included at the end of the RLP encoded message. /// 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<H = Header, B = BlockBody> { pub struct SealedBlock<H = Header, B = BlockBody> {
/// Locked block header. /// Locked block header.
#[deref]
#[deref_mut]
header: SealedHeader<H>, header: SealedHeader<H>,
/// Block body. /// Block body.
body: B, body: B,
@ -185,6 +185,11 @@ impl<H, B> SealedBlock<H, B> {
self.header.hash() self.header.hash()
} }
/// Returns reference to block header.
pub const fn header(&self) -> &H {
self.header.header()
}
/// Returns reference to block body. /// Returns reference to block body.
pub const fn body(&self) -> &B { pub const fn body(&self) -> &B {
&self.body &self.body
@ -252,6 +257,16 @@ where
H: alloy_consensus::BlockHeader, H: alloy_consensus::BlockHeader,
B: reth_primitives_traits::BlockBody, 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. /// 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 /// The transaction root is the Keccak 256-bit hash of the root node of the trie structure
@ -388,6 +403,14 @@ where
} }
} }
impl<H, B> Deref for SealedBlock<H, B> {
type Target = H;
fn deref(&self) -> &Self::Target {
self.header.header()
}
}
#[cfg(any(test, feature = "arbitrary"))] #[cfg(any(test, feature = "arbitrary"))]
impl<'a, H, B> arbitrary::Arbitrary<'a> for SealedBlock<H, B> impl<'a, H, B> arbitrary::Arbitrary<'a> for SealedBlock<H, B>
where where
@ -399,6 +422,52 @@ where
} }
} }
#[cfg(any(test, feature = "test-utils"))]
impl<H, B> SealedBlock<H, B>
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`]. /// A helepr trait to construct [`SealedBlock`] from a [`reth_primitives_traits::Block`].
pub type SealedBlockFor<B> = SealedBlock< pub type SealedBlockFor<B> = SealedBlock<
<B as reth_primitives_traits::Block>::Header, <B as reth_primitives_traits::Block>::Header,