From a39980a6f6f04c65617280e936ad24dd40bec5f5 Mon Sep 17 00:00:00 2001 From: Arsenii Kulikov Date: Sat, 1 Feb 2025 02:05:09 +0400 Subject: [PATCH] feat: generalize Block impls (#14133) --- crates/net/network/tests/it/requests.rs | 2 +- crates/optimism/evm/src/l1.rs | 2 +- crates/optimism/rpc/src/eth/receipt.rs | 4 +-- crates/payload/builder/src/test_utils.rs | 2 +- crates/primitives-traits/src/block/body.rs | 7 ++-- crates/primitives-traits/src/block/mod.rs | 11 +++--- .../src/header/test_utils.rs | 3 +- crates/primitives-traits/src/size.rs | 6 ++-- crates/primitives/src/block.rs | 5 +-- crates/rpc/rpc-builder/tests/it/auth.rs | 2 +- .../provider/src/providers/database/chain.rs | 10 +++--- crates/storage/storage-api/src/chain.rs | 34 +++++++++++-------- 12 files changed, 49 insertions(+), 39 deletions(-) diff --git a/crates/net/network/tests/it/requests.rs b/crates/net/network/tests/it/requests.rs index 0dd38c959..000745dc3 100644 --- a/crates/net/network/tests/it/requests.rs +++ b/crates/net/network/tests/it/requests.rs @@ -64,7 +64,7 @@ async fn test_get_body() { for _ in 0..100 { // Set a new random block to the mock storage and request it via the network let block_hash = rng.gen(); - let mut block = Block::default(); + let mut block: Block = Block::default(); block.body.transactions.push(rng_transaction(&mut rng)); mock_provider.add_block(block_hash, block.clone()); diff --git a/crates/optimism/evm/src/l1.rs b/crates/optimism/evm/src/l1.rs index 129c4c35d..9b8658357 100644 --- a/crates/optimism/evm/src/l1.rs +++ b/crates/optimism/evm/src/l1.rs @@ -352,7 +352,7 @@ mod tests { const TX: [u8; 251] = hex!("7ef8f8a0a539eb753df3b13b7e386e147d45822b67cb908c9ddc5618e3dbaa22ed00850b94deaddeaddeaddeaddeaddeaddeaddeaddead00019442000000000000000000000000000000000000158080830f424080b8a4440a5e2000000558000c5fc50000000000000000000000006605a89f00000000012a10d90000000000000000000000000000000000000000000000000000000af39ac3270000000000000000000000000000000000000000000000000000000d5ea528d24e582fa68786f080069bdbfe06a43f8e67bfd31b8e4d8a8837ba41da9a82a54a0000000000000000000000006887246668a3b87f54deb3b94ba47a6f63f32985"); let tx = OpTransactionSigned::decode_2718(&mut TX.as_slice()).unwrap(); - let block = Block { + let block: Block = Block { body: BlockBody { transactions: vec![tx], ..Default::default() }, ..Default::default() }; diff --git a/crates/optimism/rpc/src/eth/receipt.rs b/crates/optimism/rpc/src/eth/receipt.rs index 2bb08e22e..2ea10e1cb 100644 --- a/crates/optimism/rpc/src/eth/receipt.rs +++ b/crates/optimism/rpc/src/eth/receipt.rs @@ -293,7 +293,7 @@ mod test { OpTransactionSigned::decode_2718(&mut TX_1_OP_MAINNET_BLOCK_124665056.as_slice()) .unwrap(); - let block = Block { + let block: Block = Block { body: BlockBody { transactions: [tx_0, tx_1.clone()].to_vec(), ..Default::default() }, ..Default::default() }; @@ -359,7 +359,7 @@ mod test { let system = hex!("7ef8f8a0389e292420bcbf9330741f72074e39562a09ff5a00fd22e4e9eee7e34b81bca494deaddeaddeaddeaddeaddeaddeaddeaddead00019442000000000000000000000000000000000000158080830f424080b8a4440a5e20000008dd00101c120000000000000004000000006721035b00000000014189960000000000000000000000000000000000000000000000000000000349b4dcdc000000000000000000000000000000000000000000000000000000004ef9325cc5991ce750960f636ca2ffbb6e209bb3ba91412f21dd78c14ff154d1930f1f9a0000000000000000000000005050f69a9786f081509234f1a7f4684b5e5b76c9"); let tx_0 = OpTransactionSigned::decode_2718(&mut &system[..]).unwrap(); - let block = Block { + let block: alloy_consensus::Block = Block { body: BlockBody { transactions: vec![tx_0], ..Default::default() }, ..Default::default() }; diff --git a/crates/payload/builder/src/test_utils.rs b/crates/payload/builder/src/test_utils.rs index 835d94265..8276b5e95 100644 --- a/crates/payload/builder/src/test_utils.rs +++ b/crates/payload/builder/src/test_utils.rs @@ -88,7 +88,7 @@ impl PayloadJob for TestPayloadJob { fn best_payload(&self) -> Result { Ok(EthBuiltPayload::new( self.attr.payload_id(), - Arc::new(Block::default().seal_slow()), + Arc::new(Block::<_>::default().seal_slow()), U256::ZERO, Some(Default::default()), )) diff --git a/crates/primitives-traits/src/block/body.rs b/crates/primitives-traits/src/block/body.rs index 783480c02..0cb323bf5 100644 --- a/crates/primitives-traits/src/block/body.rs +++ b/crates/primitives-traits/src/block/body.rs @@ -5,7 +5,7 @@ use crate::{ MaybeSerdeBincodeCompat, SignedTransaction, }; use alloc::{fmt, vec::Vec}; -use alloy_consensus::{Header, Transaction, Typed2718}; +use alloy_consensus::{Transaction, Typed2718}; use alloy_eips::{eip2718::Encodable2718, eip4895::Withdrawals}; use alloy_primitives::{Address, Bytes, B256}; @@ -177,12 +177,13 @@ pub trait BlockBody: } } -impl BlockBody for alloy_consensus::BlockBody +impl BlockBody for alloy_consensus::BlockBody where T: SignedTransaction, + H: BlockHeader, { type Transaction = T; - type OmmerHeader = Header; + type OmmerHeader = H; fn transactions(&self) -> &[Self::Transaction] { &self.transactions diff --git a/crates/primitives-traits/src/block/mod.rs b/crates/primitives-traits/src/block/mod.rs index 464d5080f..4ef1e3b19 100644 --- a/crates/primitives-traits/src/block/mod.rs +++ b/crates/primitives-traits/src/block/mod.rs @@ -11,7 +11,6 @@ pub mod error; pub mod header; use alloc::{fmt, vec::Vec}; -use alloy_consensus::Header; use alloy_primitives::{Address, B256}; use alloy_rlp::{Decodable, Encodable}; @@ -178,12 +177,13 @@ pub trait Block: } } -impl Block for alloy_consensus::Block +impl Block for alloy_consensus::Block where T: SignedTransaction, + H: BlockHeader, { - type Header = Header; - type Body = alloy_consensus::BlockBody; + type Header = H; + type Body = alloy_consensus::BlockBody; fn new(header: Self::Header, body: Self::Body) -> Self { Self { header, body } @@ -238,9 +238,10 @@ pub trait TestBlock: Block { } #[cfg(any(test, feature = "test-utils"))] -impl TestBlock for alloy_consensus::Block +impl TestBlock for alloy_consensus::Block where T: SignedTransaction, + H: crate::test_utils::TestHeader, { fn body_mut(&mut self) -> &mut Self::Body { &mut self.body diff --git a/crates/primitives-traits/src/header/test_utils.rs b/crates/primitives-traits/src/header/test_utils.rs index 58237fbca..893f43235 100644 --- a/crates/primitives-traits/src/header/test_utils.rs +++ b/crates/primitives-traits/src/header/test_utils.rs @@ -1,5 +1,6 @@ //! Test utilities for the block header. +use crate::BlockHeader; use alloy_consensus::Header; use alloy_primitives::{BlockHash, BlockNumber, B256, U256}; use proptest::{arbitrary::any, prop_compose}; @@ -8,7 +9,7 @@ use proptest_arbitrary_interop::arb; /// A helper trait for [`Header`]s that allows for mutable access to the headers values. /// /// This allows for modifying the header for testing purposes. -pub trait TestHeader { +pub trait TestHeader: BlockHeader { /// Updates the parent block hash. fn set_parent_hash(&mut self, hash: BlockHash); diff --git a/crates/primitives-traits/src/size.rs b/crates/primitives-traits/src/size.rs index 5a03d7a58..ad858c904 100644 --- a/crates/primitives-traits/src/size.rs +++ b/crates/primitives-traits/src/size.rs @@ -84,13 +84,13 @@ impl InMemorySize for PooledTransaction { } } -impl InMemorySize for alloy_consensus::BlockBody { +impl InMemorySize for alloy_consensus::BlockBody { /// Calculates a heuristic for the in-memory size of the block body #[inline] fn size(&self) -> usize { self.transactions.iter().map(T::size).sum::() + self.transactions.capacity() * core::mem::size_of::() + - self.ommers.iter().map(Header::size).sum::() + + self.ommers.iter().map(H::size).sum::() + self.ommers.capacity() * core::mem::size_of::
() + self.withdrawals .as_ref() @@ -98,7 +98,7 @@ impl InMemorySize for alloy_consensus::BlockBody { } } -impl InMemorySize for alloy_consensus::Block { +impl InMemorySize for alloy_consensus::Block { #[inline] fn size(&self) -> usize { self.header.size() + self.body.size() diff --git a/crates/primitives/src/block.rs b/crates/primitives/src/block.rs index 3ea6da42d..78066b352 100644 --- a/crates/primitives/src/block.rs +++ b/crates/primitives/src/block.rs @@ -1,3 +1,4 @@ +use alloy_consensus::Header; use reth_ethereum_primitives::TransactionSigned; #[cfg(any(test, feature = "arbitrary"))] pub use reth_primitives_traits::test_utils::{generate_valid_header, valid_header_strategy}; @@ -5,12 +6,12 @@ pub use reth_primitives_traits::test_utils::{generate_valid_header, valid_header /// Ethereum full block. /// /// Withdrawals can be optionally included at the end of the RLP encoded message. -pub type Block = alloy_consensus::Block; +pub type Block = alloy_consensus::Block; /// A response to `GetBlockBodies`, containing bodies if any bodies were found. /// /// Withdrawals can be optionally included at the end of the RLP encoded message. -pub type BlockBody = alloy_consensus::BlockBody; +pub type BlockBody = alloy_consensus::BlockBody; /// Ethereum sealed block type pub type SealedBlock = reth_primitives_traits::block::SealedBlock; diff --git a/crates/rpc/rpc-builder/tests/it/auth.rs b/crates/rpc/rpc-builder/tests/it/auth.rs index 381b48dad..2ff0a60fd 100644 --- a/crates/rpc/rpc-builder/tests/it/auth.rs +++ b/crates/rpc/rpc-builder/tests/it/auth.rs @@ -19,7 +19,7 @@ async fn test_basic_engine_calls(client: &C) where C: ClientT + SubscriptionClientT + Sync + EngineApiClient, { - let block = Block::default().seal_slow(); + let block = Block::<_>::default().seal_slow(); EngineApiClient::new_payload_v1(client, block_to_payload_v1(block.clone())).await; EngineApiClient::new_payload_v2( client, diff --git a/crates/storage/provider/src/providers/database/chain.rs b/crates/storage/provider/src/providers/database/chain.rs index b20741784..3f0201efb 100644 --- a/crates/storage/provider/src/providers/database/chain.rs +++ b/crates/storage/provider/src/providers/database/chain.rs @@ -1,6 +1,7 @@ use crate::{providers::NodeTypesForProvider, DatabaseProvider}; use reth_db::transaction::{DbTx, DbTxMut}; use reth_node_types::{FullNodePrimitives, FullSignedTx}; +use reth_primitives_traits::FullBlockHeader; use reth_storage_api::{ChainStorageReader, ChainStorageWriter, EthStorage}; /// Trait that provides access to implementations of [`ChainStorage`] @@ -18,13 +19,14 @@ pub trait ChainStorage: Send + Sync { Types: NodeTypesForProvider; } -impl ChainStorage for EthStorage +impl ChainStorage for EthStorage where T: FullSignedTx, + H: FullBlockHeader, N: FullNodePrimitives< - Block = reth_primitives::Block, - BlockHeader = alloy_consensus::Header, - BlockBody = reth_primitives::BlockBody, + Block = reth_primitives::Block, + BlockHeader = H, + BlockBody = reth_primitives::BlockBody, SignedTx = T, >, { diff --git a/crates/storage/storage-api/src/chain.rs b/crates/storage/storage-api/src/chain.rs index cb2b38dc7..4a77c4a06 100644 --- a/crates/storage/storage-api/src/chain.rs +++ b/crates/storage/storage-api/src/chain.rs @@ -10,7 +10,9 @@ use reth_db::{ DbTxUnwindExt, }; use reth_primitives::TransactionSigned; -use reth_primitives_traits::{Block, BlockBody, FullNodePrimitives, SignedTransaction}; +use reth_primitives_traits::{ + Block, BlockBody, FullBlockHeader, FullNodePrimitives, SignedTransaction, +}; use reth_storage_errors::provider::ProviderResult; /// Trait that implements how block bodies are written to the storage. @@ -81,26 +83,28 @@ impl ChainStorageReader(std::marker::PhantomData); +pub struct EthStorage(std::marker::PhantomData<(T, H)>); -impl Default for EthStorage { +impl Default for EthStorage { fn default() -> Self { Self(Default::default()) } } -impl BlockBodyWriter> for EthStorage +impl BlockBodyWriter> + for EthStorage where Provider: DBProvider, T: SignedTransaction, + H: FullBlockHeader, { fn write_block_bodies( &self, provider: &Provider, - bodies: Vec<(u64, Option>)>, + bodies: Vec<(u64, Option>)>, _write_to: StorageLocation, ) -> ProviderResult<()> { - let mut ommers_cursor = provider.tx_ref().cursor_write::()?; + let mut ommers_cursor = provider.tx_ref().cursor_write::>()?; let mut withdrawals_cursor = provider.tx_ref().cursor_write::()?; @@ -137,14 +141,14 @@ where } } -impl BlockBodyReader for EthStorage +impl BlockBodyReader for EthStorage where - Provider: DBProvider - + ChainSpecProvider - + OmmersProvider
, + Provider: + DBProvider + ChainSpecProvider + OmmersProvider
, T: SignedTransaction, + H: FullBlockHeader, { - type Block = reth_primitives::Block; + type Block = reth_primitives::Block; fn read_block_bodies( &self, @@ -161,19 +165,19 @@ where for (header, transactions) in inputs { // If we are past shanghai, then all blocks should have a withdrawal list, // even if empty - let withdrawals = if chain_spec.is_shanghai_active_at_timestamp(header.timestamp) { + let withdrawals = if chain_spec.is_shanghai_active_at_timestamp(header.timestamp()) { withdrawals_cursor - .seek_exact(header.number)? + .seek_exact(header.number())? .map(|(_, w)| w.withdrawals) .unwrap_or_default() .into() } else { None }; - let ommers = if chain_spec.final_paris_total_difficulty(header.number).is_some() { + let ommers = if chain_spec.final_paris_total_difficulty(header.number()).is_some() { Vec::new() } else { - provider.ommers(header.number.into())?.unwrap_or_default() + provider.ommers(header.number().into())?.unwrap_or_default() }; bodies.push(reth_primitives::BlockBody { transactions, ommers, withdrawals });