reth_primitives_traits/
size.rs1use alloc::vec::Vec;
2use alloy_consensus::{
3 transaction::TxEip4844Sidecar, EthereumTxEnvelope, Header, TxEip1559, TxEip2930, TxEip4844,
4 TxEip4844Variant, TxEip4844WithSidecar, TxEip7702, TxLegacy, TxType,
5};
6use alloy_eips::eip4895::Withdrawals;
7use alloy_primitives::{Signature, TxHash, B256};
8use revm_primitives::Log;
9
10#[auto_impl::auto_impl(&, Arc, Box)]
12pub trait InMemorySize {
13 fn size(&self) -> usize;
15}
16
17impl<T: InMemorySize> InMemorySize for alloy_consensus::Signed<T> {
18 fn size(&self) -> usize {
19 T::size(self.tx()) + self.signature().size() + core::mem::size_of::<B256>()
20 }
21}
22
23macro_rules! impl_in_mem_size_size_of {
25 ($($ty:ty),*) => {
26 $(
27 impl InMemorySize for $ty {
28 #[inline]
29 fn size(&self) -> usize {
30 core::mem::size_of::<Self>()
31 }
32 }
33 )*
34 };
35}
36
37impl_in_mem_size_size_of!(Signature, TxHash, TxType);
38
39macro_rules! impl_in_mem_size {
41 ($($ty:ty),*) => {
42 $(
43 impl InMemorySize for $ty {
44 #[inline]
45 fn size(&self) -> usize {
46 Self::size(self)
47 }
48 }
49 )*
50 };
51}
52
53impl_in_mem_size!(Header, TxLegacy, TxEip2930, TxEip1559, TxEip7702, TxEip4844);
54
55impl<T: TxEip4844Sidecar> InMemorySize for TxEip4844Variant<T> {
56 #[inline]
57 fn size(&self) -> usize {
58 Self::size(self)
59 }
60}
61
62impl<T: TxEip4844Sidecar> InMemorySize for TxEip4844WithSidecar<T> {
63 #[inline]
64 fn size(&self) -> usize {
65 Self::size(self)
66 }
67}
68
69#[cfg(feature = "op")]
70impl_in_mem_size_size_of!(op_alloy_consensus::OpTxType);
71
72impl InMemorySize for alloy_consensus::Receipt {
73 fn size(&self) -> usize {
74 let Self { status, cumulative_gas_used, logs } = self;
75 core::mem::size_of_val(status) +
76 core::mem::size_of_val(cumulative_gas_used) +
77 logs.capacity() * core::mem::size_of::<Log>()
78 }
79}
80
81impl<T: InMemorySize> InMemorySize for EthereumTxEnvelope<T> {
82 fn size(&self) -> usize {
83 match self {
84 Self::Legacy(tx) => tx.size(),
85 Self::Eip2930(tx) => tx.size(),
86 Self::Eip1559(tx) => tx.size(),
87 Self::Eip4844(tx) => tx.size(),
88 Self::Eip7702(tx) => tx.size(),
89 }
90 }
91}
92
93impl<T: InMemorySize, H: InMemorySize> InMemorySize for alloy_consensus::BlockBody<T, H> {
94 #[inline]
96 fn size(&self) -> usize {
97 self.transactions.iter().map(T::size).sum::<usize>() +
98 self.transactions.capacity() * core::mem::size_of::<T>() +
99 self.ommers.iter().map(H::size).sum::<usize>() +
100 self.ommers.capacity() * core::mem::size_of::<Header>() +
101 self.withdrawals
102 .as_ref()
103 .map_or(core::mem::size_of::<Option<Withdrawals>>(), Withdrawals::total_size)
104 }
105}
106
107impl<T: InMemorySize, H: InMemorySize> InMemorySize for alloy_consensus::Block<T, H> {
108 #[inline]
109 fn size(&self) -> usize {
110 self.header.size() + self.body.size()
111 }
112}
113
114impl<T: InMemorySize> InMemorySize for Vec<T> {
115 fn size(&self) -> usize {
116 self.iter().map(T::size).sum::<usize>()
118 }
119}
120
121impl InMemorySize for u64 {
122 fn size(&self) -> usize {
123 core::mem::size_of::<Self>()
124 }
125}
126
127#[cfg(feature = "op")]
129mod op {
130 use super::*;
131
132 impl InMemorySize for op_alloy_consensus::OpDepositReceipt {
133 fn size(&self) -> usize {
134 let Self { inner, deposit_nonce, deposit_receipt_version } = self;
135 inner.size() +
136 core::mem::size_of_val(deposit_nonce) +
137 core::mem::size_of_val(deposit_receipt_version)
138 }
139 }
140
141 impl InMemorySize for op_alloy_consensus::OpTypedTransaction {
142 fn size(&self) -> usize {
143 match self {
144 Self::Legacy(tx) => tx.size(),
145 Self::Eip2930(tx) => tx.size(),
146 Self::Eip1559(tx) => tx.size(),
147 Self::Eip7702(tx) => tx.size(),
148 Self::Deposit(tx) => tx.size(),
149 }
150 }
151 }
152
153 impl InMemorySize for op_alloy_consensus::OpPooledTransaction {
154 fn size(&self) -> usize {
155 match self {
156 Self::Legacy(tx) => tx.size(),
157 Self::Eip2930(tx) => tx.size(),
158 Self::Eip1559(tx) => tx.size(),
159 Self::Eip7702(tx) => tx.size(),
160 }
161 }
162 }
163
164 impl InMemorySize for op_alloy_consensus::OpTxEnvelope {
165 fn size(&self) -> usize {
166 match self {
167 Self::Legacy(tx) => tx.size(),
168 Self::Eip2930(tx) => tx.size(),
169 Self::Eip1559(tx) => tx.size(),
170 Self::Eip7702(tx) => tx.size(),
171 Self::Deposit(tx) => tx.size(),
172 }
173 }
174 }
175}
176#[cfg(test)]
177mod tests {
178 use super::*;
179
180 #[test]
182 fn no_in_memory_no_recursion() {
183 fn assert_no_recursion<T: InMemorySize + Default>() {
184 let _ = T::default().size();
185 }
186 assert_no_recursion::<Header>();
187 assert_no_recursion::<TxLegacy>();
188 assert_no_recursion::<TxEip2930>();
189 assert_no_recursion::<TxEip1559>();
190 assert_no_recursion::<TxEip7702>();
191 assert_no_recursion::<TxEip4844>();
192 }
193}