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 clone_transactions(&self) -> Vec<Self::Transaction> {
74        self.transactions().to_vec()
75    }
76
77    fn transaction_hashes_iter(&self) -> impl Iterator<Item = &B256> + '_ {
79        self.transactions_iter().map(|tx| tx.tx_hash())
80    }
81
82    fn transaction_count(&self) -> usize {
84        self.transactions().len()
85    }
86
87    fn into_transactions(self) -> Vec<Self::Transaction>;
89
90    fn contains_transaction_type(&self, tx_type: u8) -> bool {
92        self.transactions_iter().any(|tx| tx.is_type(tx_type))
93    }
94
95    fn calculate_tx_root(&self) -> B256 {
97        alloy_consensus::proofs::calculate_transaction_root(self.transactions())
98    }
99
100    fn withdrawals(&self) -> Option<&Withdrawals>;
102
103    fn calculate_withdrawals_root(&self) -> Option<B256> {
107        self.withdrawals().map(|withdrawals| {
108            alloy_consensus::proofs::calculate_withdrawals_root(withdrawals.as_slice())
109        })
110    }
111
112    fn ommers(&self) -> Option<&[Self::OmmerHeader]>;
114
115    fn calculate_ommers_root(&self) -> Option<B256> {
119        self.ommers().map(alloy_consensus::proofs::calculate_ommers_root)
120    }
121
122    fn blob_gas_used(&self) -> u64 {
124        self.transactions_iter().filter_map(|tx| tx.blob_gas_used()).sum()
125    }
126
127    fn blob_versioned_hashes_iter(&self) -> impl Iterator<Item = &B256> + '_ {
129        self.transactions_iter().filter_map(|tx| tx.blob_versioned_hashes()).flatten()
130    }
131
132    #[doc(alias = "raw_transactions_iter")]
138    fn encoded_2718_transactions_iter(&self) -> impl Iterator<Item = Vec<u8>> + '_ {
139        self.transactions_iter().map(|tx| tx.encoded_2718())
140    }
141
142    #[doc(alias = "raw_transactions")]
148    fn encoded_2718_transactions(&self) -> Vec<Bytes> {
149        self.encoded_2718_transactions_iter().map(Into::into).collect()
150    }
151
152    fn recover_signers(&self) -> Result<Vec<Address>, RecoveryError>
154    where
155        Self::Transaction: SignedTransaction,
156    {
157        crate::transaction::recover::recover_signers(self.transactions())
158    }
159
160    fn try_recover_signers(&self) -> Result<Vec<Address>, RecoveryError>
164    where
165        Self::Transaction: SignedTransaction,
166    {
167        self.recover_signers()
168    }
169
170    fn recover_signers_unchecked(&self) -> Result<Vec<Address>, RecoveryError>
175    where
176        Self::Transaction: SignedTransaction,
177    {
178        crate::transaction::recover::recover_signers_unchecked(self.transactions())
179    }
180
181    fn try_recover_signers_unchecked(&self) -> Result<Vec<Address>, RecoveryError>
186    where
187        Self::Transaction: SignedTransaction,
188    {
189        self.recover_signers_unchecked()
190    }
191}
192
193impl<T, H> BlockBody for alloy_consensus::BlockBody<T, H>
194where
195    T: SignedTransaction,
196    H: BlockHeader,
197{
198    type Transaction = T;
199    type OmmerHeader = H;
200
201    fn transactions(&self) -> &[Self::Transaction] {
202        &self.transactions
203    }
204
205    fn into_ethereum_body(self) -> Self {
206        self
207    }
208
209    fn into_transactions(self) -> Vec<Self::Transaction> {
210        self.transactions
211    }
212
213    fn withdrawals(&self) -> Option<&Withdrawals> {
214        self.withdrawals.as_ref()
215    }
216
217    fn ommers(&self) -> Option<&[Self::OmmerHeader]> {
218        Some(&self.ommers)
219    }
220}
221
222pub type BodyTx<N> = <N as BlockBody>::Transaction;
225
226pub type BodyOmmer<N> = <N as BlockBody>::OmmerHeader;