22
33use crate :: {
44 budget:: DEFAULT_BUDGET_TRY_DRAIN_DOWNLOADERS , metered_poll_nested_stream_with_budget,
5- metrics:: EthRequestHandlerMetrics , transform:: header:: HeaderTransform ,
5+ metrics:: EthRequestHandlerMetrics , transform:: header:: HeaderResponseTransform ,
66} ;
77use alloy_consensus:: { BlockHeader , ReceiptWithBloom } ;
88use alloy_eips:: BlockHashOrNumber ;
99use alloy_rlp:: Encodable ;
10- use futures:: StreamExt ;
10+ use futures:: { future :: join_all , StreamExt } ;
1111use reth_eth_wire:: {
1212 BlockBodies , BlockHeaders , EthNetworkPrimitives , GetBlockBodies , GetBlockHeaders , GetNodeData ,
1313 GetReceipts , HeadersDirection , NetworkPrimitives , NodeData , Receipts , Receipts69 ,
@@ -20,6 +20,7 @@ use reth_storage_api::{BlockReader, HeaderProvider};
2020use std:: {
2121 future:: Future ,
2222 pin:: Pin ,
23+ sync:: Arc ,
2324 task:: { Context , Poll } ,
2425 time:: Duration ,
2526} ;
@@ -54,15 +55,15 @@ pub const SOFT_RESPONSE_LIMIT: usize = 2 * 1024 * 1024;
5455#[ must_use = "Manager does nothing unless polled." ]
5556pub struct EthRequestHandler < C , N : NetworkPrimitives = EthNetworkPrimitives > {
5657 /// The client type that can interact with the chain.
57- client : C ,
58+ client : Arc < C > ,
5859 /// Used for reporting peers.
5960 // TODO use to report spammers
6061 #[ expect( dead_code) ]
6162 peers : PeersHandle ,
6263 /// Incoming request from the [`NetworkManager`](crate::NetworkManager).
6364 incoming_requests : ReceiverStream < IncomingEthRequest < N > > ,
6465 /// The header transform to apply to the headers before sending to peers.
65- header_transform : Option < Box < dyn HeaderTransform < N :: BlockHeader > > > ,
66+ header_transform : Option < Arc < dyn HeaderResponseTransform < N :: BlockHeader > > > ,
6667 /// Metrics for the eth request handler.
6768 metrics : EthRequestHandlerMetrics ,
6869}
@@ -74,10 +75,10 @@ impl<C, N: NetworkPrimitives> EthRequestHandler<C, N> {
7475 client : C ,
7576 peers : PeersHandle ,
7677 incoming : Receiver < IncomingEthRequest < N > > ,
77- header_transform : Option < Box < dyn HeaderTransform < N :: BlockHeader > > > ,
78+ header_transform : Option < Arc < dyn HeaderResponseTransform < N :: BlockHeader > > > ,
7879 ) -> Self {
7980 Self {
80- client,
81+ client : Arc :: new ( client ) ,
8182 peers,
8283 incoming_requests : ReceiverStream :: new ( incoming) ,
8384 header_transform,
@@ -89,20 +90,22 @@ impl<C, N: NetworkPrimitives> EthRequestHandler<C, N> {
8990impl < C , N > EthRequestHandler < C , N >
9091where
9192 N : NetworkPrimitives ,
92- C : BlockReader < Header = N :: BlockHeader > ,
93+ C : BlockReader < Header = N :: BlockHeader > + ' static ,
9394{
9495 /// Returns the list of requested headers
95- fn get_headers_response ( & self , request : GetBlockHeaders ) -> Vec < C :: Header > {
96+ async fn get_headers_response (
97+ client : Arc < C > ,
98+ header_transform : Option < Arc < dyn HeaderResponseTransform < N :: BlockHeader > > > ,
99+ request : GetBlockHeaders ,
100+ ) -> Vec < C :: Header > {
96101 let GetBlockHeaders { start_block, limit, skip, direction } = request;
97102
98103 let mut headers = Vec :: new ( ) ;
99104
100105 let mut block: BlockHashOrNumber = match start_block {
101106 BlockHashOrNumber :: Hash ( start) => start. into ( ) ,
102107 BlockHashOrNumber :: Number ( num) => {
103- let Some ( hash) = self . client . block_hash ( num) . unwrap_or_default ( ) else {
104- return headers
105- } ;
108+ let Some ( hash) = client. block_hash ( num) . unwrap_or_default ( ) else { return headers } ;
106109 hash. into ( )
107110 }
108111 } ;
@@ -111,7 +114,7 @@ where
111114 let mut total_bytes = 0 ;
112115
113116 for _ in 0 ..limit {
114- if let Some ( header) = self . client . header_by_hash_or_number ( block) . unwrap_or_default ( ) {
117+ if let Some ( header) = client. header_by_hash_or_number ( block) . unwrap_or_default ( ) {
115118 let number = header. number ( ) ;
116119 let parent_hash = header. parent_hash ( ) ;
117120
@@ -153,8 +156,8 @@ where
153156 }
154157
155158 // TODO: remove this once we deprecated l2geth
156- if let Some ( ref header_transform) = self . header_transform {
157- headers = headers. into_iter ( ) . map ( |h| header_transform. map ( h) ) . collect ( )
159+ if let Some ( ref header_transform) = header_transform {
160+ return join_all ( headers. into_iter ( ) . map ( |h| header_transform. map ( h) ) ) . await ;
158161 }
159162
160163 headers
@@ -165,10 +168,14 @@ where
165168 _peer_id : PeerId ,
166169 request : GetBlockHeaders ,
167170 response : oneshot:: Sender < RequestResult < BlockHeaders < C :: Header > > > ,
168- ) {
171+ ) -> impl Future < Output = ( ) > + ' static {
169172 self . metrics . eth_headers_requests_received_total . increment ( 1 ) ;
170- let headers = self . get_headers_response ( request) ;
171- let _ = response. send ( Ok ( BlockHeaders ( headers) ) ) ;
173+ let client = self . client . clone ( ) ;
174+ let header_transform = self . header_transform . clone ( ) ;
175+ async move {
176+ let headers = Self :: get_headers_response ( client, header_transform, request) . await ;
177+ let _ = response. send ( Ok ( BlockHeaders ( headers) ) ) ;
178+ }
172179 }
173180
174181 fn on_bodies_request (
@@ -267,7 +274,8 @@ where
267274 N : NetworkPrimitives ,
268275 C : BlockReader < Block = N :: Block , Receipt = N :: Receipt >
269276 + HeaderProvider < Header = N :: BlockHeader >
270- + Unpin ,
277+ + Unpin
278+ + ' static ,
271279{
272280 type Output = ( ) ;
273281
@@ -284,7 +292,8 @@ where
284292 |incoming| {
285293 match incoming {
286294 IncomingEthRequest :: GetBlockHeaders { peer_id, request, response } => {
287- this. on_headers_request( peer_id, request, response)
295+ let future = this. on_headers_request( peer_id, request, response) ;
296+ tokio:: spawn( future) ;
288297 }
289298 IncomingEthRequest :: GetBlockBodies { peer_id, request, response } => {
290299 this. on_bodies_request( peer_id, request, response)
0 commit comments