reth_primitives_traits/block/
body.rs
1use 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()).map_err(|_| RecoveryError)
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;