reth_storage_api/
receipts.rs

1use crate::BlockIdReader;
2use alloy_eips::{BlockHashOrNumber, BlockId, BlockNumberOrTag};
3use alloy_primitives::{TxHash, TxNumber};
4use reth_primitives_traits::Receipt;
5use reth_storage_errors::provider::ProviderResult;
6use std::ops::RangeBounds;
7
8/// A helper type alias to access [`ReceiptProvider::Receipt`].
9pub type ProviderReceipt<P> = <P as ReceiptProvider>::Receipt;
10
11/// Client trait for fetching receipt data.
12#[auto_impl::auto_impl(&, Arc)]
13pub trait ReceiptProvider: Send + Sync {
14    /// The receipt type.
15    type Receipt: Receipt;
16
17    /// Get receipt by transaction number
18    ///
19    /// Returns `None` if the transaction is not found.
20    fn receipt(&self, id: TxNumber) -> ProviderResult<Option<Self::Receipt>>;
21
22    /// Get receipt by transaction hash.
23    ///
24    /// Returns `None` if the transaction is not found.
25    fn receipt_by_hash(&self, hash: TxHash) -> ProviderResult<Option<Self::Receipt>>;
26
27    /// Get receipts by block num or hash.
28    ///
29    /// Returns `None` if the block is not found.
30    fn receipts_by_block(
31        &self,
32        block: BlockHashOrNumber,
33    ) -> ProviderResult<Option<Vec<Self::Receipt>>>;
34
35    /// Get receipts by tx range.
36    fn receipts_by_tx_range(
37        &self,
38        range: impl RangeBounds<TxNumber>,
39    ) -> ProviderResult<Vec<Self::Receipt>>;
40}
41
42/// Trait extension for `ReceiptProvider`, for types that implement `BlockId` conversion.
43///
44/// The `Receipt` trait should be implemented on types that can retrieve receipts from either
45/// a block number or hash. However, it might be desirable to fetch receipts from a `BlockId` type,
46/// which can be a number, hash, or tag such as `BlockNumberOrTag::Safe`.
47///
48/// Resolving tags requires keeping track of block hashes or block numbers associated with the tag,
49/// so this trait can only be implemented for types that implement `BlockIdReader`. The
50/// `BlockIdReader` methods should be used to resolve `BlockId`s to block numbers or hashes, and
51/// retrieving the receipts should be done using the type's `ReceiptProvider` methods.
52pub trait ReceiptProviderIdExt: ReceiptProvider + BlockIdReader {
53    /// Get receipt by block id
54    fn receipts_by_block_id(&self, block: BlockId) -> ProviderResult<Option<Vec<Self::Receipt>>> {
55        let id = match block {
56            BlockId::Hash(hash) => BlockHashOrNumber::Hash(hash.block_hash),
57            BlockId::Number(num_tag) => {
58                if let Some(num) = self.convert_block_number(num_tag)? {
59                    BlockHashOrNumber::Number(num)
60                } else {
61                    return Ok(None)
62                }
63            }
64        };
65
66        self.receipts_by_block(id)
67    }
68
69    /// Returns the block with the matching `BlockId` from the database.
70    ///
71    /// Returns `None` if block is not found.
72    fn receipts_by_number_or_tag(
73        &self,
74        number_or_tag: BlockNumberOrTag,
75    ) -> ProviderResult<Option<Vec<Self::Receipt>>> {
76        self.receipts_by_block_id(number_or_tag.into())
77    }
78}