From c0544ed7e1fe804556da6aa53fc47ba9e125b171 Mon Sep 17 00:00:00 2001 From: Thomas Coratger <60488569+tcoratger@users.noreply.github.com> Date: Mon, 31 Jul 2023 16:36:13 +0200 Subject: [PATCH] feat(p2p): Add `GetReceipts` eth handler implementation (#3959) --- crates/net/network/src/eth_requests.rs | 54 ++++++++++++++++++++++++-- 1 file changed, 51 insertions(+), 3 deletions(-) diff --git a/crates/net/network/src/eth_requests.rs b/crates/net/network/src/eth_requests.rs index 7cb4db72b37b..10b53f61701b 100644 --- a/crates/net/network/src/eth_requests.rs +++ b/crates/net/network/src/eth_requests.rs @@ -8,7 +8,7 @@ use reth_eth_wire::{ }; use reth_interfaces::p2p::error::RequestResult; use reth_primitives::{BlockBody, BlockHashOrNumber, Header, HeadersDirection, PeerId}; -use reth_provider::{BlockReader, HeaderProvider}; +use reth_provider::{BlockReader, HeaderProvider, ReceiptProvider}; use std::{ borrow::Borrow, future::Future, @@ -21,6 +21,11 @@ use tokio_stream::wrappers::ReceiverStream; // Limits: +/// Maximum number of receipts to serve. +/// +/// Used to limit lookups. +const MAX_RECEIPTS_SERVE: usize = 1024; + /// Maximum number of block headers to serve. /// /// Used to limit lookups. @@ -32,6 +37,9 @@ const MAX_HEADERS_SERVE: usize = 1024; /// SOFT_RESPONSE_LIMIT. const MAX_BODIES_SERVE: usize = 1024; +/// Estimated size in bytes of an RLP encoded receipt. +const APPROX_RECEIPT_SIZE: usize = 24 * 1024; + /// Estimated size in bytes of an RLP encoded body. // TODO: check 24kb blocksize assumption const APPROX_BODY_SIZE: usize = 24 * 1024; @@ -70,7 +78,7 @@ impl EthRequestHandler { impl EthRequestHandler where - C: BlockReader + HeaderProvider, + C: BlockReader + HeaderProvider + ReceiptProvider, { /// Returns the list of requested headers fn get_headers_response(&self, request: GetBlockHeaders) -> Vec
{ @@ -185,6 +193,44 @@ where let _ = response.send(Ok(BlockBodies(bodies))); } + + fn on_receipts_request( + &mut self, + _peer_id: PeerId, + request: GetReceipts, + response: oneshot::Sender>, + ) { + let mut receipts = Vec::new(); + + let mut total_bytes = APPROX_RECEIPT_SIZE; + + for hash in request.0 { + if let Some(receipts_by_block) = + self.client.receipts_by_block(BlockHashOrNumber::Hash(hash)).unwrap_or_default() + { + receipts.push( + receipts_by_block + .into_iter() + .map(|receipt| receipt.with_bloom()) + .collect::>(), + ); + + total_bytes += APPROX_RECEIPT_SIZE; + + if total_bytes > SOFT_RESPONSE_LIMIT { + break + } + + if receipts.len() >= MAX_RECEIPTS_SERVE { + break + } + } else { + break + } + } + + let _ = response.send(Ok(Receipts(receipts))); + } } /// An endless future. @@ -211,7 +257,9 @@ where this.on_bodies_request(peer_id, request, response) } IncomingEthRequest::GetNodeData { .. } => {} - IncomingEthRequest::GetReceipts { .. } => {} + IncomingEthRequest::GetReceipts { peer_id, request, response } => { + this.on_receipts_request(peer_id, request, response) + } }, } }