reth_rpc_types_compat/
block.rs
1use 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#[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
33pub 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#[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}