diff --git a/crates/net/network/src/eth_requests.rs b/crates/net/network/src/eth_requests.rs index ed9f8ab0892..a954c321d3e 100644 --- a/crates/net/network/src/eth_requests.rs +++ b/crates/net/network/src/eth_requests.rs @@ -46,6 +46,11 @@ pub const MAX_HEADERS_SERVE: usize = 1024; /// `SOFT_RESPONSE_LIMIT`. pub const MAX_BODIES_SERVE: usize = 1024; +/// Maximum number of block access lists to serve. +/// +/// Used to limit lookups. +pub const MAX_BLOCK_ACCESS_LISTS_SERVE: usize = 1024; + /// Maximum size of replies to data retrievals: 2MB pub const SOFT_RESPONSE_LIMIT: usize = 2 * 1024 * 1024; @@ -323,9 +328,11 @@ where fn on_block_access_lists_request( &self, _peer_id: PeerId, - request: GetBlockAccessLists, + mut request: GetBlockAccessLists, response: oneshot::Sender>, ) { + request.0.truncate(MAX_BLOCK_ACCESS_LISTS_SERVE); + let limit = GetBlockAccessListLimit::ResponseSizeSoftLimit(SOFT_RESPONSE_LIMIT); let access_lists = self .client diff --git a/crates/net/network/tests/it/requests.rs b/crates/net/network/tests/it/requests.rs index 6cca06bb1cb..ce5d57cfe4b 100644 --- a/crates/net/network/tests/it/requests.rs +++ b/crates/net/network/tests/it/requests.rs @@ -7,7 +7,7 @@ use rand::Rng; use reth_eth_wire::{BlockAccessLists, EthVersion, GetBlockAccessLists, HeadersDirection}; use reth_ethereum_primitives::Block; use reth_network::{ - eth_requests::SOFT_RESPONSE_LIMIT, + eth_requests::{MAX_BLOCK_ACCESS_LISTS_SERVE, SOFT_RESPONSE_LIMIT}, test_utils::{NetworkEventStream, PeerConfig, Testnet, TestnetHandle}, BlockDownloaderProvider, NetworkEventListenerProvider, }; @@ -607,6 +607,26 @@ async fn test_eth71_get_block_access_lists_empty_request() { assert_eq!(response, BlockAccessLists(Vec::new())); } +// Ensures BAL responses are capped at MAX_BLOCK_ACCESS_LISTS_SERVE entries. +#[tokio::test(flavor = "multi_thread")] +async fn test_eth71_get_block_access_lists_caps_count() { + reth_tracing::init_test_tracing(); + let (net, bal_store) = spawn_eth71_bal_testnet().await; + + // Request more hashes than the count cap. + let request_count = MAX_BLOCK_ACCESS_LISTS_SERVE + 100; + let hashes: Vec = (0..request_count).map(|_| B256::random()).collect(); + + // Insert one BAL so the store isn't entirely empty (not strictly needed, + // but keeps the test path closer to real usage). + let bal = Bytes::from_static(&[0xc1, 0x01]); + bal_store.insert(hashes[0], 1, bal).unwrap(); + + let response = request_block_access_lists(&net, hashes).await; + + assert_eq!(response.0.len(), MAX_BLOCK_ACCESS_LISTS_SERVE); +} + // Ensures the fetch client can request BALs through an eth/71 peer. #[tokio::test(flavor = "multi_thread")] async fn test_eth71_fetch_client_get_block_access_lists() {