reth_rpc_eth_api/helpers/
receipt.rs1use crate::{EthApiTypes, RpcNodeCoreExt, RpcReceipt};
5use alloy_consensus::{transaction::TransactionMeta, TxReceipt};
6use futures::Future;
7use reth_primitives_traits::SignerRecoverable;
8use reth_rpc_convert::{transaction::ConvertReceiptInput, RpcConvert};
9use reth_rpc_eth_types::{error::FromEthApiError, EthApiError};
10use reth_storage_api::{ProviderReceipt, ProviderTx};
11use std::borrow::Cow;
12
13pub trait LoadReceipt:
17 EthApiTypes<
18 RpcConvert: RpcConvert<
19 Primitives = Self::Primitives,
20 Error = Self::Error,
21 Network = Self::NetworkTypes,
22 >,
23 Error: FromEthApiError,
24 > + RpcNodeCoreExt
25 + Send
26 + Sync
27{
28 fn build_transaction_receipt(
30 &self,
31 tx: ProviderTx<Self::Provider>,
32 meta: TransactionMeta,
33 receipt: ProviderReceipt<Self::Provider>,
34 ) -> impl Future<Output = Result<RpcReceipt<Self::NetworkTypes>, Self::Error>> + Send {
35 async move {
36 let hash = meta.block_hash;
37 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
45 let mut gas_used = 0;
46 let mut next_log_index = 0;
47
48 if meta.index > 0 {
49 for receipt in all_receipts.iter().take(meta.index as usize) {
50 gas_used = receipt.cumulative_gas_used();
51 next_log_index += receipt.logs().len();
52 }
53 }
54
55 Ok(self
56 .tx_resp_builder()
57 .convert_receipts(vec![ConvertReceiptInput {
58 tx: tx
59 .try_into_recovered_unchecked()
60 .map_err(Self::Error::from_eth_err)?
61 .as_recovered_ref(),
62 gas_used: receipt.cumulative_gas_used() - gas_used,
63 receipt: Cow::Owned(receipt),
64 next_log_index,
65 meta,
66 }])?
67 .pop()
68 .unwrap())
69 }
70 }
71}