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}