chore(reth_primitives): Use trait for size methods in primitive types (#12201)

Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
This commit is contained in:
Tuan Tran
2024-11-11 23:54:00 +07:00
committed by GitHub
parent 24b3e63ab3
commit eccff7d24b
16 changed files with 84 additions and 42 deletions

4
Cargo.lock generated
View File

@ -7039,6 +7039,7 @@ dependencies = [
"reth-network-p2p", "reth-network-p2p",
"reth-network-peers", "reth-network-peers",
"reth-primitives", "reth-primitives",
"reth-primitives-traits",
"reth-provider", "reth-provider",
"reth-storage-api", "reth-storage-api",
"reth-tasks", "reth-tasks",
@ -7828,6 +7829,7 @@ dependencies = [
"reth-network-peers", "reth-network-peers",
"reth-network-types", "reth-network-types",
"reth-primitives", "reth-primitives",
"reth-primitives-traits",
"reth-storage-errors", "reth-storage-errors",
"tokio", "tokio",
"tracing", "tracing",
@ -8570,6 +8572,7 @@ dependencies = [
"reth-errors", "reth-errors",
"reth-exex-types", "reth-exex-types",
"reth-metrics", "reth-metrics",
"reth-primitives-traits",
"reth-provider", "reth-provider",
"reth-prune-types", "reth-prune-types",
"reth-stages", "reth-stages",
@ -9192,6 +9195,7 @@ dependencies = [
"reth-fs-util", "reth-fs-util",
"reth-metrics", "reth-metrics",
"reth-primitives", "reth-primitives",
"reth-primitives-traits",
"reth-provider", "reth-provider",
"reth-storage-api", "reth-storage-api",
"reth-tasks", "reth-tasks",

View File

@ -18,6 +18,7 @@ reth-consensus.workspace = true
reth-network-p2p.workspace = true reth-network-p2p.workspace = true
reth-network-peers.workspace = true reth-network-peers.workspace = true
reth-primitives.workspace = true reth-primitives.workspace = true
reth-primitives-traits.workspace = true
reth-storage-api.workspace = true reth-storage-api.workspace = true
reth-tasks.workspace = true reth-tasks.workspace = true
@ -80,5 +81,6 @@ test-utils = [
"reth-chainspec/test-utils", "reth-chainspec/test-utils",
"reth-primitives/test-utils", "reth-primitives/test-utils",
"reth-db-api?/test-utils", "reth-db-api?/test-utils",
"reth-provider/test-utils" "reth-provider/test-utils",
"reth-primitives-traits/test-utils"
] ]

View File

@ -14,6 +14,7 @@ use reth_network_p2p::{
error::{DownloadError, DownloadResult}, error::{DownloadError, DownloadResult},
}; };
use reth_primitives::SealedHeader; use reth_primitives::SealedHeader;
use reth_primitives_traits::size::InMemorySize;
use reth_storage_api::HeaderProvider; use reth_storage_api::HeaderProvider;
use reth_tasks::{TaskSpawner, TokioTaskExecutor}; use reth_tasks::{TaskSpawner, TokioTaskExecutor};
use std::{ use std::{

View File

@ -9,6 +9,7 @@ use reth_network_p2p::{
}; };
use reth_network_peers::{PeerId, WithPeerId}; use reth_network_peers::{PeerId, WithPeerId};
use reth_primitives::{BlockBody, GotExpected, SealedBlock, SealedHeader}; use reth_primitives::{BlockBody, GotExpected, SealedBlock, SealedHeader};
use reth_primitives_traits::InMemorySize;
use std::{ use std::{
collections::VecDeque, collections::VecDeque,
mem, mem,

View File

@ -14,6 +14,7 @@ workspace = true
[dependencies] [dependencies]
# reth # reth
reth-primitives.workspace = true reth-primitives.workspace = true
reth-primitives-traits.workspace = true
reth-eth-wire-types.workspace = true reth-eth-wire-types.workspace = true
reth-consensus.workspace = true reth-consensus.workspace = true
reth-network-peers.workspace = true reth-network-peers.workspace = true
@ -32,7 +33,6 @@ tokio = { workspace = true, features = ["sync"] }
auto_impl.workspace = true auto_impl.workspace = true
tracing.workspace = true tracing.workspace = true
derive_more.workspace = true derive_more.workspace = true
parking_lot = { workspace = true, optional = true } parking_lot = { workspace = true, optional = true }
[dev-dependencies] [dev-dependencies]
@ -47,11 +47,13 @@ test-utils = [
"reth-consensus/test-utils", "reth-consensus/test-utils",
"parking_lot", "parking_lot",
"reth-network-types/test-utils", "reth-network-types/test-utils",
"reth-primitives/test-utils" "reth-primitives/test-utils",
"reth-primitives-traits/test-utils"
] ]
std = [ std = [
"reth-consensus/std", "reth-consensus/std",
"reth-primitives/std", "reth-primitives/std",
"alloy-eips/std", "alloy-eips/std",
"alloy-primitives/std" "alloy-primitives/std",
"reth-primitives-traits/std"
] ]

View File

@ -1,5 +1,6 @@
use alloy_primitives::{BlockNumber, U256}; use alloy_primitives::{BlockNumber, U256};
use reth_primitives::{SealedBlock, SealedHeader}; use reth_primitives::{SealedBlock, SealedHeader};
use reth_primitives_traits::InMemorySize;
/// The block response /// The block response
#[derive(PartialEq, Eq, Debug, Clone)] #[derive(PartialEq, Eq, Debug, Clone)]
@ -19,15 +20,6 @@ impl BlockResponse {
} }
} }
/// Calculates a heuristic for the in-memory size of the [`BlockResponse`].
#[inline]
pub fn size(&self) -> usize {
match self {
Self::Full(block) => SealedBlock::size(block),
Self::Empty(header) => SealedHeader::size(header),
}
}
/// Return the block number /// Return the block number
pub fn block_number(&self) -> BlockNumber { pub fn block_number(&self) -> BlockNumber {
self.header().number self.header().number
@ -41,3 +33,14 @@ impl BlockResponse {
} }
} }
} }
impl InMemorySize for BlockResponse {
/// Calculates a heuristic for the in-memory size of the [`BlockResponse`].
#[inline]
fn size(&self) -> usize {
match self {
Self::Full(block) => SealedBlock::size(block),
Self::Empty(header) => SealedHeader::size(header),
}
}
}

View File

@ -1,3 +1,5 @@
use crate::InMemorySize;
use super::Header; use super::Header;
use alloy_consensus::Sealed; use alloy_consensus::Sealed;
use alloy_eips::BlockNumHash; use alloy_eips::BlockNumHash;
@ -59,10 +61,12 @@ impl SealedHeader {
pub fn num_hash(&self) -> BlockNumHash { pub fn num_hash(&self) -> BlockNumHash {
BlockNumHash::new(self.number, self.hash) BlockNumHash::new(self.number, self.hash)
} }
}
impl InMemorySize for SealedHeader {
/// Calculates a heuristic for the in-memory size of the [`SealedHeader`]. /// Calculates a heuristic for the in-memory size of the [`SealedHeader`].
#[inline] #[inline]
pub fn size(&self) -> usize { fn size(&self) -> usize {
self.header.size() + mem::size_of::<BlockHash>() self.header.size() + mem::size_of::<BlockHash>()
} }
} }

View File

@ -73,3 +73,7 @@ pub use header::{Header, HeaderError, SealedHeader};
pub mod serde_bincode_compat { pub mod serde_bincode_compat {
pub use super::header::{serde_bincode_compat as header, serde_bincode_compat::*}; pub use super::header::{serde_bincode_compat as header, serde_bincode_compat::*};
} }
/// Heuristic size trait
pub mod size;
pub use size::InMemorySize;

View File

@ -0,0 +1,5 @@
/// Trait for calculating a heuristic for the in-memory size of a struct.
pub trait InMemorySize {
/// Returns a heuristic for the in-memory size of a struct.
fn size(&self) -> usize;
}

View File

@ -6,6 +6,7 @@ use alloy_rlp::{Decodable, Encodable, RlpDecodable, RlpEncodable};
use derive_more::{Deref, DerefMut}; use derive_more::{Deref, DerefMut};
#[cfg(any(test, feature = "arbitrary"))] #[cfg(any(test, feature = "arbitrary"))]
pub use reth_primitives_traits::test_utils::{generate_valid_header, valid_header_strategy}; pub use reth_primitives_traits::test_utils::{generate_valid_header, valid_header_strategy};
use reth_primitives_traits::InMemorySize;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
/// Ethereum full block. /// Ethereum full block.
@ -84,10 +85,12 @@ impl Block {
let senders = self.senders()?; let senders = self.senders()?;
Some(BlockWithSenders { block: self, senders }) Some(BlockWithSenders { block: self, senders })
} }
}
impl InMemorySize for Block {
/// Calculates a heuristic for the in-memory size of the [`Block`]. /// Calculates a heuristic for the in-memory size of the [`Block`].
#[inline] #[inline]
pub fn size(&self) -> usize { fn size(&self) -> usize {
self.header.size() + self.body.size() self.header.size() + self.body.size()
} }
} }
@ -376,12 +379,6 @@ impl SealedBlock {
Block { header: self.header.unseal(), body: self.body } Block { header: self.header.unseal(), body: self.body }
} }
/// Calculates a heuristic for the in-memory size of the [`SealedBlock`].
#[inline]
pub fn size(&self) -> usize {
self.header.size() + self.body.size()
}
/// Calculates the total gas used by blob transactions in the sealed block. /// Calculates the total gas used by blob transactions in the sealed block.
pub fn blob_gas_used(&self) -> u64 { pub fn blob_gas_used(&self) -> u64 {
self.blob_transactions().iter().filter_map(|tx| tx.blob_gas_used()).sum() self.blob_transactions().iter().filter_map(|tx| tx.blob_gas_used()).sum()
@ -431,6 +428,14 @@ impl SealedBlock {
} }
} }
impl InMemorySize for SealedBlock {
/// Calculates a heuristic for the in-memory size of the [`SealedBlock`].
#[inline]
fn size(&self) -> usize {
self.header.size() + self.body.size()
}
}
impl From<SealedBlock> for Block { impl From<SealedBlock> for Block {
fn from(block: SealedBlock) -> Self { fn from(block: SealedBlock) -> Self {
block.unseal() block.unseal()
@ -625,10 +630,12 @@ impl BlockBody {
pub fn transactions(&self) -> impl Iterator<Item = &TransactionSigned> + '_ { pub fn transactions(&self) -> impl Iterator<Item = &TransactionSigned> + '_ {
self.transactions.iter() self.transactions.iter()
} }
}
impl InMemorySize for BlockBody {
/// Calculates a heuristic for the in-memory size of the [`BlockBody`]. /// Calculates a heuristic for the in-memory size of the [`BlockBody`].
#[inline] #[inline]
pub fn size(&self) -> usize { fn size(&self) -> usize {
self.transactions.iter().map(TransactionSigned::size).sum::<usize>() + self.transactions.iter().map(TransactionSigned::size).sum::<usize>() +
self.transactions.capacity() * core::mem::size_of::<TransactionSigned>() + self.transactions.capacity() * core::mem::size_of::<TransactionSigned>() +
self.ommers.iter().map(Header::size).sum::<usize>() + self.ommers.iter().map(Header::size).sum::<usize>() +

View File

@ -24,6 +24,7 @@ use once_cell::sync::Lazy as LazyLock;
#[cfg(feature = "optimism")] #[cfg(feature = "optimism")]
use op_alloy_consensus::DepositTransaction; use op_alloy_consensus::DepositTransaction;
use rayon::prelude::{IntoParallelIterator, ParallelIterator}; use rayon::prelude::{IntoParallelIterator, ParallelIterator};
use reth_primitives_traits::InMemorySize;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use signature::decode_with_eip155_chain_id; use signature::decode_with_eip155_chain_id;
#[cfg(feature = "std")] #[cfg(feature = "std")]
@ -472,20 +473,6 @@ impl Transaction {
} }
} }
/// Calculates a heuristic for the in-memory size of the [Transaction].
#[inline]
pub fn size(&self) -> usize {
match self {
Self::Legacy(tx) => tx.size(),
Self::Eip2930(tx) => tx.size(),
Self::Eip1559(tx) => tx.size(),
Self::Eip4844(tx) => tx.size(),
Self::Eip7702(tx) => tx.size(),
#[cfg(feature = "optimism")]
Self::Deposit(tx) => tx.size(),
}
}
/// Returns true if the transaction is a legacy transaction. /// Returns true if the transaction is a legacy transaction.
#[inline] #[inline]
pub const fn is_legacy(&self) -> bool { pub const fn is_legacy(&self) -> bool {
@ -557,6 +544,22 @@ impl Transaction {
} }
} }
impl InMemorySize for Transaction {
/// Calculates a heuristic for the in-memory size of the [Transaction].
#[inline]
fn size(&self) -> usize {
match self {
Self::Legacy(tx) => tx.size(),
Self::Eip2930(tx) => tx.size(),
Self::Eip1559(tx) => tx.size(),
Self::Eip4844(tx) => tx.size(),
Self::Eip7702(tx) => tx.size(),
#[cfg(feature = "optimism")]
Self::Deposit(tx) => tx.size(),
}
}
}
#[cfg(any(test, feature = "reth-codec"))] #[cfg(any(test, feature = "reth-codec"))]
impl reth_codecs::Compact for Transaction { impl reth_codecs::Compact for Transaction {
// Serializes the TxType to the buffer if necessary, returning 2 bits of the type as an // Serializes the TxType to the buffer if necessary, returning 2 bits of the type as an

View File

@ -41,6 +41,7 @@ rustc-hash.workspace = true
# reth # reth
reth-db = { workspace = true, features = ["test-utils"] } reth-db = { workspace = true, features = ["test-utils"] }
reth-stages = { workspace = true, features = ["test-utils"] } reth-stages = { workspace = true, features = ["test-utils"] }
reth-primitives-traits = { workspace = true, features = ["arbitrary"] }
reth-testing-utils.workspace = true reth-testing-utils.workspace = true
reth-tracing.workspace = true reth-tracing.workspace = true

View File

@ -10,7 +10,6 @@ use reth_prune_types::{
SegmentOutput, MINIMUM_PRUNING_DISTANCE, SegmentOutput, MINIMUM_PRUNING_DISTANCE,
}; };
use tracing::{instrument, trace}; use tracing::{instrument, trace};
#[derive(Debug)] #[derive(Debug)]
pub struct ReceiptsByLogs { pub struct ReceiptsByLogs {
config: ReceiptsLogPruneConfig, config: ReceiptsLogPruneConfig,
@ -223,6 +222,7 @@ mod tests {
use assert_matches::assert_matches; use assert_matches::assert_matches;
use reth_db::tables; use reth_db::tables;
use reth_db_api::{cursor::DbCursorRO, transaction::DbTx}; use reth_db_api::{cursor::DbCursorRO, transaction::DbTx};
use reth_primitives_traits::InMemorySize;
use reth_provider::{DatabaseProviderFactory, PruneCheckpointReader, TransactionsProvider}; use reth_provider::{DatabaseProviderFactory, PruneCheckpointReader, TransactionsProvider};
use reth_prune_types::{PruneLimiter, PruneMode, PruneSegment, ReceiptsLogPruneConfig}; use reth_prune_types::{PruneLimiter, PruneMode, PruneSegment, ReceiptsLogPruneConfig};
use reth_stages::test_utils::{StorageKind, TestStageDB}; use reth_stages::test_utils::{StorageKind, TestStageDB};

View File

@ -17,6 +17,7 @@ reth-chain-state.workspace = true
reth-chainspec.workspace = true reth-chainspec.workspace = true
reth-eth-wire-types.workspace = true reth-eth-wire-types.workspace = true
reth-primitives = { workspace = true, features = ["c-kzg", "secp256k1"] } reth-primitives = { workspace = true, features = ["c-kzg", "secp256k1"] }
reth-primitives-traits.workspace = true
reth-execution-types.workspace = true reth-execution-types.workspace = true
reth-fs-util.workspace = true reth-fs-util.workspace = true
reth-storage-api.workspace = true reth-storage-api.workspace = true
@ -50,6 +51,7 @@ bitflags.workspace = true
auto_impl.workspace = true auto_impl.workspace = true
smallvec.workspace = true smallvec.workspace = true
# testing # testing
rand = { workspace = true, optional = true } rand = { workspace = true, optional = true }
paste = { workspace = true, optional = true } paste = { workspace = true, optional = true }
@ -84,7 +86,7 @@ serde = [
"parking_lot/serde", "parking_lot/serde",
"rand?/serde", "rand?/serde",
"revm/serde", "revm/serde",
"smallvec/serde" "smallvec/serde",
] ]
test-utils = [ test-utils = [
"rand", "rand",
@ -94,7 +96,8 @@ test-utils = [
"reth-chainspec/test-utils", "reth-chainspec/test-utils",
"reth-primitives/test-utils", "reth-primitives/test-utils",
"reth-provider/test-utils", "reth-provider/test-utils",
"revm/test-utils" "revm/test-utils",
"reth-primitives-traits/test-utils",
] ]
arbitrary = [ arbitrary = [
"proptest", "proptest",
@ -107,7 +110,8 @@ arbitrary = [
"alloy-primitives/arbitrary", "alloy-primitives/arbitrary",
"bitflags/arbitrary", "bitflags/arbitrary",
"revm/arbitrary", "revm/arbitrary",
"smallvec/arbitrary" "reth-primitives-traits/arbitrary",
"smallvec/arbitrary",
] ]
[[bench]] [[bench]]

View File

@ -28,7 +28,6 @@ use reth_primitives::{
transaction::TryFromRecoveredTransactionError, PooledTransactionsElementEcRecovered, transaction::TryFromRecoveredTransactionError, PooledTransactionsElementEcRecovered,
Transaction, TransactionSigned, TransactionSignedEcRecovered, TxType, Transaction, TransactionSigned, TransactionSignedEcRecovered, TxType,
}; };
use std::{ops::Range, sync::Arc, time::Instant, vec::IntoIter}; use std::{ops::Range, sync::Arc, time::Instant, vec::IntoIter};
/// A transaction pool implementation using [`MockOrdering`] for transaction ordering. /// A transaction pool implementation using [`MockOrdering`] for transaction ordering.
@ -1007,6 +1006,7 @@ impl proptest::arbitrary::Arbitrary for MockTransaction {
fn arbitrary_with(_: Self::Parameters) -> Self::Strategy { fn arbitrary_with(_: Self::Parameters) -> Self::Strategy {
use proptest::prelude::Strategy; use proptest::prelude::Strategy;
use proptest_arbitrary_interop::arb; use proptest_arbitrary_interop::arb;
use reth_primitives_traits::size::InMemorySize;
arb::<(Transaction, Address, B256)>() arb::<(Transaction, Address, B256)>()
.prop_map(|(tx, sender, tx_hash)| match &tx { .prop_map(|(tx, sender, tx_hash)| match &tx {

View File

@ -17,7 +17,8 @@ use alloy_consensus::constants::{
}; };
use alloy_eips::eip4844::MAX_BLOBS_PER_BLOCK; use alloy_eips::eip4844::MAX_BLOBS_PER_BLOCK;
use reth_chainspec::{ChainSpec, EthereumHardforks}; use reth_chainspec::{ChainSpec, EthereumHardforks};
use reth_primitives::{GotExpected, InvalidTransactionError, SealedBlock}; use reth_primitives::{InvalidTransactionError, SealedBlock};
use reth_primitives_traits::GotExpected;
use reth_storage_api::{AccountReader, StateProviderFactory}; use reth_storage_api::{AccountReader, StateProviderFactory};
use reth_tasks::TaskSpawner; use reth_tasks::TaskSpawner;
use revm::{ use revm::{