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}