reth_primitives_traits/
size.rs

1use alloy_consensus::{
2    Header, TxEip1559, TxEip2930, TxEip4844, TxEip7702, TxLegacy, TxSeismic, TxType,
3};
4use alloy_primitives::{PrimitiveSignature as Signature, TxHash};
5use revm_primitives::Log;
6
7/// Trait for calculating a heuristic for the in-memory size of a struct.
8#[auto_impl::auto_impl(&, Arc, Box)]
9pub trait InMemorySize {
10    /// Returns a heuristic for the in-memory size of a struct.
11    fn size(&self) -> usize;
12}
13
14impl<T: InMemorySize> InMemorySize for alloy_consensus::Signed<T> {
15    fn size(&self) -> usize {
16        T::size(self.tx()) + self.signature().size() + self.hash().size()
17    }
18}
19
20/// Implement `InMemorySize` for a type with `size_of`
21macro_rules! impl_in_mem_size_size_of {
22    ($($ty:ty),*) => {
23        $(
24            impl InMemorySize for $ty {
25                #[inline]
26                fn size(&self) -> usize {
27                    core::mem::size_of::<Self>()
28                }
29            }
30        )*
31    };
32}
33
34impl_in_mem_size_size_of!(Signature, TxHash, TxType);
35
36/// Implement `InMemorySize` for a type with a native `size` method.
37macro_rules! impl_in_mem_size {
38    ($($ty:ty),*) => {
39        $(
40            impl InMemorySize for $ty {
41                #[inline]
42                fn size(&self) -> usize {
43                   Self::size(self)
44                }
45            }
46        )*
47    };
48}
49
50impl_in_mem_size!(Header, TxLegacy, TxEip2930, TxEip1559, TxEip7702, TxEip4844, TxSeismic);
51
52#[cfg(feature = "op")]
53impl_in_mem_size_size_of!(op_alloy_consensus::OpTxType);
54
55impl InMemorySize for alloy_consensus::Receipt {
56    fn size(&self) -> usize {
57        let Self { status, cumulative_gas_used, logs } = self;
58        core::mem::size_of_val(status) +
59            core::mem::size_of_val(cumulative_gas_used) +
60            logs.capacity() * core::mem::size_of::<Log>()
61    }
62}
63
64#[cfg(feature = "op")]
65impl InMemorySize for op_alloy_consensus::OpDepositReceipt {
66    fn size(&self) -> usize {
67        let Self { inner, deposit_nonce, deposit_receipt_version } = self;
68        inner.size() +
69            core::mem::size_of_val(deposit_nonce) +
70            core::mem::size_of_val(deposit_receipt_version)
71    }
72}
73
74#[cfg(feature = "op")]
75impl InMemorySize for op_alloy_consensus::OpTypedTransaction {
76    fn size(&self) -> usize {
77        match self {
78            Self::Legacy(tx) => tx.size(),
79            Self::Eip2930(tx) => tx.size(),
80            Self::Eip1559(tx) => tx.size(),
81            Self::Eip7702(tx) => tx.size(),
82            Self::Deposit(tx) => tx.size(),
83        }
84    }
85}
86
87#[cfg(test)]
88mod tests {
89    use super::*;
90
91    // ensures we don't have any recursion in the `InMemorySize` impls
92    #[test]
93    fn no_in_memory_no_recursion() {
94        fn assert_no_recursion<T: InMemorySize + Default>() {
95            let _ = T::default().size();
96        }
97        assert_no_recursion::<Header>();
98        assert_no_recursion::<TxLegacy>();
99        assert_no_recursion::<TxEip2930>();
100        assert_no_recursion::<TxEip1559>();
101        assert_no_recursion::<TxEip7702>();
102        assert_no_recursion::<TxEip4844>();
103    }
104}