reth_rpc_eth_api/helpers/
receipt.rs1use std::sync::Arc;
5
6use crate::{EthApiTypes, RpcNodeCoreExt, RpcReceipt};
7use alloy_consensus::{transaction::TransactionMeta, TxReceipt};
8use futures::Future;
9use reth_primitives_traits::{Recovered, RecoveredBlock};
10use reth_rpc_convert::{transaction::ConvertReceiptInput, RpcConvert};
11use reth_rpc_eth_types::{
12 error::FromEthApiError, utils::calculate_gas_used_and_next_log_index, EthApiError,
13};
14use reth_storage_api::{ProviderBlock, ProviderReceipt, ProviderTx};
15
16pub trait LoadReceipt:
20 EthApiTypes<RpcConvert: RpcConvert<Primitives = Self::Primitives>> + RpcNodeCoreExt + Send + Sync
21{
22 fn build_transaction_receipt(
26 &self,
27 tx: Recovered<ProviderTx<Self::Provider>>,
28 meta: TransactionMeta,
29 receipt: ProviderReceipt<Self::Provider>,
30 all_receipts: Option<Arc<Vec<ProviderReceipt<Self::Provider>>>>,
31 block: Option<Arc<RecoveredBlock<ProviderBlock<Self::Provider>>>>,
32 ) -> impl Future<Output = Result<RpcReceipt<Self::NetworkTypes>, Self::Error>> + Send {
33 async move {
34 let hash = meta.block_hash;
35 let (block, all_receipts) = match (block, all_receipts) {
36 (Some(block), Some(all_receipts)) => (Some(block), all_receipts),
37 (Some(block), None) => {
38 let all_receipts = self
39 .cache()
40 .get_receipts(hash)
41 .await
42 .map_err(Self::Error::from_eth_err)?
43 .ok_or(EthApiError::HeaderNotFound(hash.into()))?;
44 (Some(block), all_receipts)
45 }
46 (None, Some(all_receipts)) => {
47 let block = self
48 .cache()
49 .get_maybe_block(hash)
50 .await
51 .map_err(Self::Error::from_eth_err)?;
52 (block, all_receipts)
53 }
54 (None, None) => {
55 let (all_receipts, block) = self
56 .cache()
57 .get_receipts_and_maybe_block(hash)
58 .await
59 .map_err(Self::Error::from_eth_err)?
60 .ok_or(EthApiError::HeaderNotFound(hash.into()))?;
61 (block, all_receipts)
62 }
63 };
64
65 let (gas_used, next_log_index) =
66 calculate_gas_used_and_next_log_index(meta.index, &all_receipts);
67
68 let inputs = vec![ConvertReceiptInput {
69 tx: tx.as_recovered_ref(),
70 gas_used: receipt.cumulative_gas_used() - gas_used,
71 receipt,
72 next_log_index,
73 meta,
74 }];
75 let mut receipts = match block {
76 Some(block) => {
77 self.converter().convert_receipts_with_block(inputs, block.sealed_block())
78 }
79 None => self.converter().convert_receipts(inputs),
80 }?;
81
82 Ok(receipts.pop().unwrap())
83 }
84 }
85}