use crate::{ chainspec::HlChainSpec, node::{ primitives::TransactionSigned, rpc::{HlEthApi, HlNodeCore}, HlBlock, HlPrimitives, }, }; use alloy_consensus::{BlockHeader, ReceiptEnvelope, TxType}; use alloy_primitives::B256; use reth::{ api::NodeTypes, builder::FullNodeComponents, primitives::{Receipt, SealedHeader, TransactionMeta}, providers::{BlockReaderIdExt, ProviderHeader, ReceiptProvider, TransactionsProvider}, rpc::{ eth::EthApiTypes, server_types::eth::{ error::FromEvmError, receipt::build_receipt, EthApiError, EthReceiptBuilder, PendingBlock, }, types::{BlockId, TransactionReceipt}, }, transaction_pool::{PoolTransaction, TransactionPool}, }; use reth_chainspec::{EthChainSpec, EthereumHardforks}; use reth_evm::{ConfigureEvm, NextBlockEnvAttributes}; use reth_primitives_traits::BlockBody as _; use reth_provider::{ BlockReader, ChainSpecProvider, HeaderProvider, ProviderBlock, ProviderReceipt, ProviderTx, StateProviderFactory, }; use reth_rpc_eth_api::{ helpers::{EthBlocks, LoadBlock, LoadPendingBlock, LoadReceipt, SpawnBlocking}, types::RpcTypes, FromEthApiError, RpcNodeCore, RpcNodeCoreExt, RpcReceipt, }; impl EthBlocks for HlEthApi where Self: LoadBlock< Error = EthApiError, NetworkTypes: RpcTypes, Provider: BlockReader, >, N: HlNodeCore + HeaderProvider>, { async fn block_receipts( &self, block_id: BlockId, ) -> Result>>, Self::Error> where Self: LoadReceipt, { if let Some((block, receipts)) = self.load_block_and_receipts(block_id).await? { let block_number = block.number(); let base_fee = block.base_fee_per_gas(); let block_hash = block.hash(); let excess_blob_gas = block.excess_blob_gas(); let timestamp = block.timestamp(); let blob_params = self.provider().chain_spec().blob_params_at_timestamp(timestamp); return block .body() .transactions() .iter() .zip(receipts.iter()) .enumerate() .map(|(idx, (tx, receipt))| { let meta = TransactionMeta { tx_hash: *tx.0.tx_hash(), index: idx as u64, block_hash, block_number, base_fee, excess_blob_gas, timestamp, }; EthReceiptBuilder::new(&tx.0, meta, receipt, &receipts, blob_params) .map(|builder| builder.build()) }) .collect::, Self::Error>>() .map(Some); } Ok(None) } } impl LoadBlock for HlEthApi where Self: LoadPendingBlock + SpawnBlocking + RpcNodeCoreExt< Pool: TransactionPool< Transaction: PoolTransaction>, >, >, N: HlNodeCore, { } impl LoadPendingBlock for HlEthApi where Self: SpawnBlocking + EthApiTypes< NetworkTypes: RpcTypes< Header = alloy_rpc_types_eth::Header>, >, Error: FromEvmError, >, N: RpcNodeCore< Provider: BlockReaderIdExt< Transaction = TransactionSigned, Block = HlBlock, Receipt = Receipt, Header = alloy_consensus::Header, > + ChainSpecProvider + StateProviderFactory, Pool: TransactionPool>>, Evm: ConfigureEvm, >, { #[inline] fn pending_block( &self, ) -> &tokio::sync::Mutex< Option, ProviderReceipt>>, > { self.inner.eth_api.pending_block() } fn next_env_attributes( &self, parent: &SealedHeader>, ) -> Result<::NextBlockEnvCtx, Self::Error> { Ok(NextBlockEnvAttributes { timestamp: parent.timestamp().saturating_add(12), suggested_fee_recipient: parent.beneficiary(), prev_randao: B256::random(), gas_limit: parent.gas_limit(), parent_beacon_block_root: parent.parent_beacon_block_root(), withdrawals: None, }) } } impl LoadReceipt for HlEthApi where Self: Send + Sync, N: FullNodeComponents>, Self::Provider: TransactionsProvider + ReceiptProvider, { async fn build_transaction_receipt( &self, tx: TransactionSigned, meta: TransactionMeta, receipt: Receipt, ) -> Result, Self::Error> { let hash = meta.block_hash; // get all receipts for the block let all_receipts = self .cache() .get_receipts(hash) .await .map_err(Self::Error::from_eth_err)? .ok_or(EthApiError::HeaderNotFound(hash.into()))?; let blob_params = self.provider().chain_spec().blob_params_at_timestamp(meta.timestamp); build_receipt(&tx, meta, &receipt, &all_receipts, blob_params, |receipt_with_bloom| { match receipt.tx_type { TxType::Legacy => ReceiptEnvelope::Legacy(receipt_with_bloom), TxType::Eip2930 => ReceiptEnvelope::Eip2930(receipt_with_bloom), TxType::Eip1559 => ReceiptEnvelope::Eip1559(receipt_with_bloom), TxType::Eip4844 => ReceiptEnvelope::Eip4844(receipt_with_bloom), TxType::Eip7702 => ReceiptEnvelope::Eip7702(receipt_with_bloom), } }) } }