reth_primitives_traits/block/
body.rs1use crate::{
4 transaction::signed::RecoveryError, BlockHeader, FullSignedTx, InMemorySize, MaybeSerde,
5 MaybeSerdeBincodeCompat, SignedTransaction,
6};
7use alloc::{fmt, vec::Vec};
8use alloy_consensus::{Transaction, Typed2718};
9use alloy_eips::{eip2718::Encodable2718, eip4895::Withdrawals};
10use alloy_primitives::{Address, Bytes, B256};
11
12pub trait FullBlockBody: BlockBody<Transaction: FullSignedTx> + MaybeSerdeBincodeCompat {}
14
15impl<T> FullBlockBody for T where T: BlockBody<Transaction: FullSignedTx> + MaybeSerdeBincodeCompat {}
16
17pub trait BlockBody:
22 Send
23 + Sync
24 + Unpin
25 + Clone
26 + Default
27 + fmt::Debug
28 + PartialEq
29 + Eq
30 + alloy_rlp::Encodable
31 + alloy_rlp::Decodable
32 + InMemorySize
33 + MaybeSerde
34 + 'static
35{
36 type Transaction: SignedTransaction;
38
39 type OmmerHeader: BlockHeader;
41
42 fn transactions(&self) -> &[Self::Transaction];
44
45 fn into_ethereum_body(self)
56 -> alloy_consensus::BlockBody<Self::Transaction, Self::OmmerHeader>;
57
58 fn transactions_iter(&self) -> impl Iterator<Item = &Self::Transaction> + '_ {
60 self.transactions().iter()
61 }
62
63 fn transaction_by_hash(&self, hash: &B256) -> Option<&Self::Transaction> {
67 self.transactions_iter().find(|tx| tx.tx_hash() == hash)
68 }
69
70 fn contains_transaction(&self, hash: &B256) -> bool {
74 self.transaction_by_hash(hash).is_some()
75 }
76
77 fn clone_transactions(&self) -> Vec<Self::Transaction> {
81 self.transactions().to_vec()
82 }
83
84 fn transaction_hashes_iter(&self) -> impl Iterator<Item = &B256> + '_ {
86 self.transactions_iter().map(|tx| tx.tx_hash())
87 }
88
89 fn transaction_count(&self) -> usize {
91 self.transactions().len()
92 }
93
94 fn into_transactions(self) -> Vec<Self::Transaction>;
96
97 fn contains_transaction_type(&self, tx_type: u8) -> bool {
99 self.transactions_iter().any(|tx| tx.is_type(tx_type))
100 }
101
102 fn calculate_tx_root(&self) -> B256 {
104 alloy_consensus::proofs::calculate_transaction_root(self.transactions())
105 }
106
107 fn withdrawals(&self) -> Option<&Withdrawals>;
109
110 fn calculate_withdrawals_root(&self) -> Option<B256> {
114 self.withdrawals().map(|withdrawals| {
115 alloy_consensus::proofs::calculate_withdrawals_root(withdrawals.as_slice())
116 })
117 }
118
119 fn ommers(&self) -> Option<&[Self::OmmerHeader]>;
121
122 fn calculate_ommers_root(&self) -> Option<B256> {
126 self.ommers().map(alloy_consensus::proofs::calculate_ommers_root)
127 }
128
129 fn blob_gas_used(&self) -> u64 {
131 self.transactions_iter().filter_map(|tx| tx.blob_gas_used()).sum()
132 }
133
134 fn blob_versioned_hashes_iter(&self) -> impl Iterator<Item = &B256> + '_ {
136 self.transactions_iter().filter_map(|tx| tx.blob_versioned_hashes()).flatten()
137 }
138
139 #[doc(alias = "raw_transactions_iter")]
145 fn encoded_2718_transactions_iter(&self) -> impl Iterator<Item = Vec<u8>> + '_ {
146 self.transactions_iter().map(|tx| tx.encoded_2718())
147 }
148
149 #[doc(alias = "raw_transactions")]
155 fn encoded_2718_transactions(&self) -> Vec<Bytes> {
156 self.encoded_2718_transactions_iter().map(Into::into).collect()
157 }
158
159 fn recover_signers(&self) -> Result<Vec<Address>, RecoveryError>
161 where
162 Self::Transaction: SignedTransaction,
163 {
164 crate::transaction::recover::recover_signers(self.transactions())
165 }
166
167 fn try_recover_signers(&self) -> Result<Vec<Address>, RecoveryError>
171 where
172 Self::Transaction: SignedTransaction,
173 {
174 self.recover_signers()
175 }
176
177 fn recover_signers_unchecked(&self) -> Result<Vec<Address>, RecoveryError>
182 where
183 Self::Transaction: SignedTransaction,
184 {
185 crate::transaction::recover::recover_signers_unchecked(self.transactions())
186 }
187
188 fn try_recover_signers_unchecked(&self) -> Result<Vec<Address>, RecoveryError>
193 where
194 Self::Transaction: SignedTransaction,
195 {
196 self.recover_signers_unchecked()
197 }
198}
199
200impl<T, H> BlockBody for alloy_consensus::BlockBody<T, H>
201where
202 T: SignedTransaction,
203 H: BlockHeader,
204{
205 type Transaction = T;
206 type OmmerHeader = H;
207
208 fn transactions(&self) -> &[Self::Transaction] {
209 &self.transactions
210 }
211
212 fn into_ethereum_body(self) -> Self {
213 self
214 }
215
216 fn into_transactions(self) -> Vec<Self::Transaction> {
217 self.transactions
218 }
219
220 fn withdrawals(&self) -> Option<&Withdrawals> {
221 self.withdrawals.as_ref()
222 }
223
224 fn ommers(&self) -> Option<&[Self::OmmerHeader]> {
225 Some(&self.ommers)
226 }
227}
228
229pub type BodyTx<N> = <N as BlockBody>::Transaction;
232
233pub type BodyOmmer<N> = <N as BlockBody>::OmmerHeader;