reth_network_p2p/headers/
client.rs
1use crate::{download::DownloadClient, error::PeerRequestResult, priority::Priority};
2use alloy_consensus::Header;
3use alloy_eips::BlockHashOrNumber;
4use futures::{Future, FutureExt};
5pub use reth_eth_wire_types::{BlockHeaders, HeadersDirection};
6use reth_primitives_traits::BlockHeader;
7use std::{
8 fmt::Debug,
9 pin::Pin,
10 task::{ready, Context, Poll},
11};
12
13#[derive(Clone, Debug)]
16pub struct HeadersRequest {
17 pub start: BlockHashOrNumber,
19 pub limit: u64,
21 pub direction: HeadersDirection,
23}
24
25impl HeadersRequest {
26 pub const fn one(start: BlockHashOrNumber) -> Self {
31 Self { direction: HeadersDirection::Rising, limit: 1, start }
32 }
33
34 pub const fn rising(start: BlockHashOrNumber, limit: u64) -> Self {
40 Self { direction: HeadersDirection::Rising, limit, start }
41 }
42
43 pub const fn falling(start: BlockHashOrNumber, limit: u64) -> Self {
49 Self { direction: HeadersDirection::Falling, limit, start }
50 }
51}
52
53pub type HeadersFut<H = Header> =
55 Pin<Box<dyn Future<Output = PeerRequestResult<Vec<H>>> + Send + Sync>>;
56
57#[auto_impl::auto_impl(&, Arc, Box)]
59pub trait HeadersClient: DownloadClient {
60 type Header: BlockHeader;
62 type Output: Future<Output = PeerRequestResult<Vec<Self::Header>>> + Sync + Send + Unpin;
64
65 fn get_headers(&self, request: HeadersRequest) -> Self::Output {
68 self.get_headers_with_priority(request, Priority::Normal)
69 }
70
71 fn get_headers_with_priority(
74 &self,
75 request: HeadersRequest,
76 priority: Priority,
77 ) -> Self::Output;
78
79 fn get_header(&self, start: BlockHashOrNumber) -> SingleHeaderRequest<Self::Output> {
81 self.get_header_with_priority(start, Priority::Normal)
82 }
83
84 fn get_header_with_priority(
86 &self,
87 start: BlockHashOrNumber,
88 priority: Priority,
89 ) -> SingleHeaderRequest<Self::Output> {
90 let req = HeadersRequest::one(start);
91 let fut = self.get_headers_with_priority(req, priority);
92 SingleHeaderRequest { fut }
93 }
94}
95
96#[derive(Debug)]
100#[must_use = "futures do nothing unless polled"]
101pub struct SingleHeaderRequest<Fut> {
102 fut: Fut,
103}
104
105impl<Fut, H> Future for SingleHeaderRequest<Fut>
106where
107 Fut: Future<Output = PeerRequestResult<Vec<H>>> + Sync + Send + Unpin,
108{
109 type Output = PeerRequestResult<Option<H>>;
110
111 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
112 let resp = ready!(self.get_mut().fut.poll_unpin(cx));
113 let resp = resp.map(|res| res.map(|headers| headers.into_iter().next()));
114 Poll::Ready(resp)
115 }
116}