Skip to main content

reth_network_p2p/receipts/
client.rs

1use std::pin::Pin;
2
3use crate::{download::DownloadClient, error::PeerRequestResult, priority::Priority};
4use alloy_consensus::TxReceipt;
5use alloy_primitives::B256;
6use futures::Future;
7use reth_eth_wire_types::Receipts70;
8
9/// The receipts future type
10pub type ReceiptsFut<R = reth_ethereum_primitives::Receipt> =
11    Pin<Box<dyn Future<Output = PeerRequestResult<ReceiptsResponse<R>>> + Send + Sync>>;
12
13/// Response from a receipts request.
14///
15/// Eth/70 responses may contain an incomplete last block, indicated by
16/// [`last_block_incomplete`](Self::last_block_incomplete). The network layer forwards this flag
17/// without fetching the remaining receipts.
18///
19/// [`ReceiptsClient`] does not expose a receipt offset. Resuming an incomplete block requires a
20/// lower-level eth/70 [`GetReceipts70`](reth_eth_wire_types::GetReceipts70) request with that block
21/// first in `block_hashes` and `first_block_receipt_index` set to the number of receipts already
22/// received for it. Responses from eth/69 and older peers always set this flag to `false`.
23#[derive(Debug, Clone, PartialEq, Eq)]
24pub struct ReceiptsResponse<R> {
25    /// Receipts grouped by block, in the same order as the requested hashes.
26    pub receipts: Vec<Vec<R>>,
27    /// When `true`, the **last** block in [`receipts`](Self::receipts) was
28    /// truncated by the remote peer (eth/70 `Receipts70.last_block_incomplete`).
29    ///
30    /// The remaining receipts of that block have to be requested separately. Responses from
31    /// eth/69 and older peers always have this set to `false`.
32    pub last_block_incomplete: bool,
33}
34
35impl<R> ReceiptsResponse<R> {
36    /// Creates a complete (non-truncated) response.
37    #[inline]
38    pub const fn new(receipts: Vec<Vec<R>>) -> Self {
39        Self { receipts, last_block_incomplete: false }
40    }
41}
42
43impl<R> From<Receipts70<R>> for ReceiptsResponse<R> {
44    fn from(r70: Receipts70<R>) -> Self {
45        Self { receipts: r70.receipts, last_block_incomplete: r70.last_block_incomplete }
46    }
47}
48
49/// A client capable of downloading block receipts from peers.
50#[auto_impl::auto_impl(&, Arc, Box)]
51pub trait ReceiptsClient: DownloadClient {
52    /// The receipt type this client fetches.
53    type Receipt: TxReceipt;
54
55    /// The output of the request future for querying block receipts.
56    type Output: Future<Output = PeerRequestResult<ReceiptsResponse<Self::Receipt>>>
57        + Sync
58        + Send
59        + Unpin;
60
61    /// Fetches the receipts for the requested block hashes.
62    fn get_receipts(&self, hashes: Vec<B256>) -> Self::Output {
63        self.get_receipts_with_priority(hashes, Priority::Normal)
64    }
65
66    /// Fetches the receipts for the requested block hashes with priority.
67    fn get_receipts_with_priority(&self, hashes: Vec<B256>, priority: Priority) -> Self::Output;
68}