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::{LogData, 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.iter().map(|log| log.size()).sum::<usize>()
78 }
79}
80
81impl InMemorySize for LogData {
82 fn size(&self) -> usize {
83 self.data.len() + core::mem::size_of_val(self.topics())
84 }
85}
86
87impl<T: InMemorySize> InMemorySize for Log<T> {
88 fn size(&self) -> usize {
89 core::mem::size_of_val(&self.address) + self.data.size()
90 }
91}
92
93impl<T: InMemorySize> InMemorySize for EthereumTxEnvelope<T> {
94 fn size(&self) -> usize {
95 match self {
96 Self::Legacy(tx) => tx.size(),
97 Self::Eip2930(tx) => tx.size(),
98 Self::Eip1559(tx) => tx.size(),
99 Self::Eip4844(tx) => tx.size(),
100 Self::Eip7702(tx) => tx.size(),
101 }
102 }
103}
104
105impl<T: InMemorySize, H: InMemorySize> InMemorySize for alloy_consensus::BlockBody<T, H> {
106 #[inline]
108 fn size(&self) -> usize {
109 self.transactions.iter().map(T::size).sum::<usize>() +
110 self.ommers.iter().map(H::size).sum::<usize>() +
111 self.withdrawals
112 .as_ref()
113 .map_or(core::mem::size_of::<Option<Withdrawals>>(), Withdrawals::total_size)
114 }
115}
116
117impl<T: InMemorySize, H: InMemorySize> InMemorySize for alloy_consensus::Block<T, H> {
118 #[inline]
119 fn size(&self) -> usize {
120 self.header.size() + self.body.size()
121 }
122}
123
124impl<T: InMemorySize> InMemorySize for Vec<T> {
125 fn size(&self) -> usize {
126 self.iter().map(T::size).sum::<usize>()
128 }
129}
130
131impl InMemorySize for u64 {
132 fn size(&self) -> usize {
133 core::mem::size_of::<Self>()
134 }
135}
136
137#[cfg(feature = "op")]
139mod op {
140 use super::*;
141
142 impl InMemorySize for op_alloy_consensus::OpDepositReceipt {
143 fn size(&self) -> usize {
144 let Self { inner, deposit_nonce, deposit_receipt_version } = self;
145 inner.size() +
146 core::mem::size_of_val(deposit_nonce) +
147 core::mem::size_of_val(deposit_receipt_version)
148 }
149 }
150
151 impl InMemorySize for op_alloy_consensus::OpTypedTransaction {
152 fn size(&self) -> usize {
153 match self {
154 Self::Legacy(tx) => tx.size(),
155 Self::Eip2930(tx) => tx.size(),
156 Self::Eip1559(tx) => tx.size(),
157 Self::Eip7702(tx) => tx.size(),
158 Self::Deposit(tx) => tx.size(),
159 }
160 }
161 }
162
163 impl InMemorySize for op_alloy_consensus::OpPooledTransaction {
164 fn size(&self) -> usize {
165 match self {
166 Self::Legacy(tx) => tx.size(),
167 Self::Eip2930(tx) => tx.size(),
168 Self::Eip1559(tx) => tx.size(),
169 Self::Eip7702(tx) => tx.size(),
170 }
171 }
172 }
173
174 impl InMemorySize for op_alloy_consensus::OpTxEnvelope {
175 fn size(&self) -> usize {
176 match self {
177 Self::Legacy(tx) => tx.size(),
178 Self::Eip2930(tx) => tx.size(),
179 Self::Eip1559(tx) => tx.size(),
180 Self::Eip7702(tx) => tx.size(),
181 Self::Deposit(tx) => tx.size(),
182 }
183 }
184 }
185}
186#[cfg(test)]
187mod tests {
188 use super::*;
189
190 #[test]
192 fn no_in_memory_no_recursion() {
193 fn assert_no_recursion<T: InMemorySize + Default>() {
194 let _ = T::default().size();
195 }
196 assert_no_recursion::<Header>();
197 assert_no_recursion::<TxLegacy>();
198 assert_no_recursion::<TxEip2930>();
199 assert_no_recursion::<TxEip1559>();
200 assert_no_recursion::<TxEip7702>();
201 assert_no_recursion::<TxEip4844>();
202 }
203}