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}