reth_rpc_types_compat/
block.rs

1//! Compatibility functions for rpc `Block` type.
2
3use crate::transaction::TransactionCompat;
4use alloy_consensus::{transaction::Recovered, BlockBody, BlockHeader, Sealable};
5use alloy_primitives::U256;
6use alloy_rpc_types_eth::{
7    Block, BlockTransactions, BlockTransactionsKind, Header, TransactionInfo,
8};
9use reth_primitives_traits::{
10    Block as BlockTrait, BlockBody as BlockBodyTrait, RecoveredBlock, SignedTransaction,
11};
12
13/// Converts the given primitive block into a [`Block`] response with the given
14/// [`BlockTransactionsKind`]
15///
16/// If a `block_hash` is provided, then this is used, otherwise the block hash is computed.
17#[expect(clippy::type_complexity)]
18pub fn from_block<T, B>(
19    block: RecoveredBlock<B>,
20    kind: BlockTransactionsKind,
21    tx_resp_builder: &T,
22) -> Result<Block<T::Transaction, Header<B::Header>>, T::Error>
23where
24    T: TransactionCompat<<<B as BlockTrait>::Body as BlockBodyTrait>::Transaction>,
25    B: BlockTrait,
26{
27    match kind {
28        BlockTransactionsKind::Hashes => Ok(from_block_with_tx_hashes::<T::Transaction, B>(block)),
29        BlockTransactionsKind::Full => from_block_full::<T, B>(block, tx_resp_builder),
30    }
31}
32
33/// Create a new [`Block`] response from a [`RecoveredBlock`], using the
34/// total difficulty to populate its field in the rpc response.
35///
36/// This will populate the `transactions` field with only the hashes of the transactions in the
37/// block: [`BlockTransactions::Hashes`]
38pub fn from_block_with_tx_hashes<T, B>(block: RecoveredBlock<B>) -> Block<T, Header<B::Header>>
39where
40    B: BlockTrait,
41{
42    let transactions = block.body().transaction_hashes_iter().copied().collect();
43    let rlp_length = block.rlp_length();
44    let (header, body) = block.into_sealed_block().split_sealed_header_body();
45    let BlockBody { ommers, withdrawals, .. } = body.into_ethereum_body();
46
47    let transactions = BlockTransactions::Hashes(transactions);
48    let uncles = ommers.into_iter().map(|h| h.hash_slow()).collect();
49    let header = Header::from_consensus(header.into(), None, Some(U256::from(rlp_length)));
50
51    Block { header, uncles, transactions, withdrawals }
52}
53
54/// Create a new [`Block`] response from a [`RecoveredBlock`], using the
55/// total difficulty to populate its field in the rpc response.
56///
57/// This will populate the `transactions` field with the _full_
58/// [`TransactionCompat::Transaction`] objects: [`BlockTransactions::Full`]
59#[expect(clippy::type_complexity)]
60pub fn from_block_full<T, B>(
61    block: RecoveredBlock<B>,
62    tx_resp_builder: &T,
63) -> Result<Block<T::Transaction, Header<B::Header>>, T::Error>
64where
65    T: TransactionCompat<<<B as BlockTrait>::Body as BlockBodyTrait>::Transaction>,
66    B: BlockTrait,
67{
68    let block_number = block.header().number();
69    let base_fee = block.header().base_fee_per_gas();
70    let block_length = block.rlp_length();
71    let block_hash = Some(block.hash());
72
73    let (block, senders) = block.split_sealed();
74    let (header, body) = block.split_sealed_header_body();
75    let BlockBody { transactions, ommers, withdrawals } = body.into_ethereum_body();
76
77    let transactions = transactions
78        .into_iter()
79        .zip(senders)
80        .enumerate()
81        .map(|(idx, (tx, sender))| {
82            let tx_info = TransactionInfo {
83                hash: Some(*tx.tx_hash()),
84                block_hash,
85                block_number: Some(block_number),
86                base_fee,
87                index: Some(idx as u64),
88            };
89
90            tx_resp_builder.fill(Recovered::new_unchecked(tx, sender), tx_info)
91        })
92        .collect::<Result<Vec<_>, T::Error>>()?;
93
94    let transactions = BlockTransactions::Full(transactions);
95    let uncles = ommers.into_iter().map(|h| h.hash_slow()).collect();
96    let header = Header::from_consensus(header.into(), None, Some(U256::from(block_length)));
97
98    let block = Block { header, uncles, transactions, withdrawals };
99
100    Ok(block)
101}