reth_primitives_traits/block/body.rs
1//! Block body abstraction.
2
3use crate::{
4 BlockHeader, FullSignedTx, InMemorySize, MaybeSerde, MaybeSerdeBincodeCompat, SignedTransaction,
5};
6use alloc::{fmt, vec::Vec};
7use alloy_consensus::Transaction;
8use alloy_eips::{eip2718::Encodable2718, eip4895::Withdrawals};
9use alloy_primitives::{Bytes, B256};
10
11/// Helper trait that unifies all behaviour required by transaction to support full node operations.
12pub trait FullBlockBody: BlockBody<Transaction: FullSignedTx> {}
13
14impl<T> FullBlockBody for T where T: BlockBody<Transaction: FullSignedTx> {}
15
16/// Abstraction for block's body.
17pub trait BlockBody:
18 Send
19 + Sync
20 + Unpin
21 + Clone
22 + Default
23 + fmt::Debug
24 + PartialEq
25 + Eq
26 + alloy_rlp::Encodable
27 + alloy_rlp::Decodable
28 + InMemorySize
29 + MaybeSerde
30 + MaybeSerdeBincodeCompat
31 + 'static
32{
33 /// Ordered list of signed transactions as committed in block.
34 type Transaction: SignedTransaction;
35
36 /// Ommer header type.
37 type OmmerHeader: BlockHeader;
38
39 /// Returns reference to transactions in block.
40 fn transactions(&self) -> &[Self::Transaction];
41
42 /// Consume the block body and return a [`Vec`] of transactions.
43 fn into_transactions(self) -> Vec<Self::Transaction>;
44
45 /// Calculate the transaction root for the block body.
46 fn calculate_tx_root(&self) -> B256 {
47 alloy_consensus::proofs::calculate_transaction_root(self.transactions())
48 }
49
50 /// Returns block withdrawals if any.
51 fn withdrawals(&self) -> Option<&Withdrawals>;
52
53 /// Calculate the withdrawals root for the block body.
54 ///
55 /// Returns `None` if there are no withdrawals in the block.
56 fn calculate_withdrawals_root(&self) -> Option<B256> {
57 self.withdrawals().map(|withdrawals| {
58 alloy_consensus::proofs::calculate_withdrawals_root(withdrawals.as_slice())
59 })
60 }
61
62 /// Returns block ommers if any.
63 fn ommers(&self) -> Option<&[Self::OmmerHeader]>;
64
65 /// Calculate the ommers root for the block body.
66 ///
67 /// Returns `None` if there are no ommers in the block.
68 fn calculate_ommers_root(&self) -> Option<B256> {
69 self.ommers().map(alloy_consensus::proofs::calculate_ommers_root)
70 }
71
72 /// Calculates the total blob gas used by _all_ EIP-4844 transactions in the block.
73 fn blob_gas_used(&self) -> u64 {
74 self.transactions().iter().filter_map(|tx| tx.blob_gas_used()).sum()
75 }
76
77 /// Returns an iterator over all blob versioned hashes in the block body.
78 fn blob_versioned_hashes_iter(&self) -> impl Iterator<Item = &B256> + '_ {
79 self.transactions().iter().filter_map(|tx| tx.blob_versioned_hashes()).flatten()
80 }
81
82 /// Returns an iterator over the encoded 2718 transactions.
83 ///
84 /// This is also known as `raw transactions`.
85 ///
86 /// See also [`Encodable2718`].
87 #[doc(alias = "raw_transactions_iter")]
88 fn encoded_2718_transactions_iter(&self) -> impl Iterator<Item = Vec<u8>> + '_ {
89 self.transactions().iter().map(|tx| tx.encoded_2718())
90 }
91
92 /// Returns a vector of encoded 2718 transactions.
93 ///
94 /// This is also known as `raw transactions`.
95 ///
96 /// See also [`Encodable2718`].
97 #[doc(alias = "raw_transactions")]
98 fn encoded_2718_transactions(&self) -> Vec<Bytes> {
99 self.encoded_2718_transactions_iter().map(Into::into).collect()
100 }
101}