reth_network_p2p/bodies/
client.rs
1use std::{
2 pin::Pin,
3 task::{ready, Context, Poll},
4};
5
6use crate::{download::DownloadClient, error::PeerRequestResult, priority::Priority};
7use alloy_primitives::B256;
8use futures::{Future, FutureExt};
9use reth_primitives_traits::BlockBody;
10
11pub type BodiesFut<B = reth_ethereum_primitives::BlockBody> =
13 Pin<Box<dyn Future<Output = PeerRequestResult<Vec<B>>> + Send + Sync>>;
14
15#[auto_impl::auto_impl(&, Arc, Box)]
17pub trait BodiesClient: DownloadClient {
18 type Body: BlockBody;
20 type Output: Future<Output = PeerRequestResult<Vec<Self::Body>>> + Sync + Send + Unpin;
22
23 fn get_block_bodies(&self, hashes: Vec<B256>) -> Self::Output {
25 self.get_block_bodies_with_priority(hashes, Priority::Normal)
26 }
27
28 fn get_block_bodies_with_priority(&self, hashes: Vec<B256>, priority: Priority)
30 -> Self::Output;
31
32 fn get_block_body(&self, hash: B256) -> SingleBodyRequest<Self::Output> {
34 self.get_block_body_with_priority(hash, Priority::Normal)
35 }
36
37 fn get_block_body_with_priority(
39 &self,
40 hash: B256,
41 priority: Priority,
42 ) -> SingleBodyRequest<Self::Output> {
43 let fut = self.get_block_bodies_with_priority(vec![hash], priority);
44 SingleBodyRequest { fut }
45 }
46}
47
48#[derive(Debug)]
50#[must_use = "futures do nothing unless polled"]
51pub struct SingleBodyRequest<Fut> {
52 fut: Fut,
53}
54
55impl<Fut, B> Future for SingleBodyRequest<Fut>
56where
57 Fut: Future<Output = PeerRequestResult<Vec<B>>> + Sync + Send + Unpin,
58{
59 type Output = PeerRequestResult<Option<B>>;
60
61 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
62 let resp = ready!(self.get_mut().fut.poll_unpin(cx));
63 let resp = resp.map(|res| res.map(|bodies| bodies.into_iter().next()));
64 Poll::Ready(resp)
65 }
66}