From 0f8bce346fd32b68503fb4897e962fdd4936adeb Mon Sep 17 00:00:00 2001 From: snowmead Date: Mon, 14 Apr 2025 13:20:18 -0400 Subject: [PATCH 1/2] validate max block range in eth_getLogs RPC --- client/rpc/src/eth/filter.rs | 10 ++++++++++ template/node/src/eth.rs | 4 ++++ template/node/src/rpc/eth.rs | 4 ++++ template/node/src/service.rs | 2 ++ 4 files changed, 20 insertions(+) diff --git a/client/rpc/src/eth/filter.rs b/client/rpc/src/eth/filter.rs index 30c7ae71dc..e25ef35d4c 100644 --- a/client/rpc/src/eth/filter.rs +++ b/client/rpc/src/eth/filter.rs @@ -50,6 +50,7 @@ pub struct EthFilter { filter_pool: FilterPool, max_stored_filters: usize, max_past_logs: u32, + max_block_range: u32, block_data_cache: Arc>, _marker: PhantomData, } @@ -62,6 +63,7 @@ impl EthFilter { filter_pool: FilterPool, max_stored_filters: usize, max_past_logs: u32, + max_block_range: u32, block_data_cache: Arc>, ) -> Self { Self { @@ -71,6 +73,7 @@ impl EthFilter { filter_pool, max_stored_filters, max_past_logs, + max_block_range, block_data_cache, _marker: PhantomData, } @@ -507,6 +510,13 @@ where .map(|s| s.unique_saturated_into()) .unwrap_or(best_number); + if current_number - from_number > self.max_block_range.into() { + return Err(internal_err(format!( + "block range is too wide (maximum {})", + self.max_block_range + ))); + } + if backend.is_indexed() { let _ = filter_range_logs_indexed( client.as_ref(), diff --git a/template/node/src/eth.rs b/template/node/src/eth.rs index b48e8d7300..aa2f47aab0 100644 --- a/template/node/src/eth.rs +++ b/template/node/src/eth.rs @@ -46,6 +46,10 @@ pub struct EthConfiguration { #[arg(long, default_value = "10000")] pub max_past_logs: u32, + /// Maximum block range to query logs from. + #[arg(long, default_value = "1024")] + pub max_block_range: u32, + /// Maximum fee history cache size. #[arg(long, default_value = "2048")] pub fee_history_limit: u64, diff --git a/template/node/src/rpc/eth.rs b/template/node/src/rpc/eth.rs index 59f956b69d..d01863f692 100644 --- a/template/node/src/rpc/eth.rs +++ b/template/node/src/rpc/eth.rs @@ -53,6 +53,8 @@ pub struct EthDeps { pub filter_pool: Option, /// Maximum number of logs in a query. pub max_past_logs: u32, + /// Maximum block range for eth_getLogs. + pub max_block_range: u32, /// Fee history cache. pub fee_history_cache: FeeHistoryCache, /// Maximum fee history cache size. @@ -115,6 +117,7 @@ where block_data_cache, filter_pool, max_past_logs, + max_block_range, fee_history_cache, fee_history_cache_limit, execute_gas_limit_multiplier, @@ -159,6 +162,7 @@ where filter_pool, 500_usize, // max stored filters max_past_logs, + max_block_range, block_data_cache.clone(), ) .into_rpc(), diff --git a/template/node/src/service.rs b/template/node/src/service.rs index 93bfa96101..d4caa97d52 100644 --- a/template/node/src/service.rs +++ b/template/node/src/service.rs @@ -411,6 +411,7 @@ where let is_authority = role.is_authority(); let enable_dev_signer = eth_config.enable_dev_signer; let max_past_logs = eth_config.max_past_logs; + let max_block_range = eth_config.max_block_range; let execute_gas_limit_multiplier = eth_config.execute_gas_limit_multiplier; let filter_pool = filter_pool.clone(); let frontier_backend = frontier_backend.clone(); @@ -457,6 +458,7 @@ where block_data_cache: block_data_cache.clone(), filter_pool: filter_pool.clone(), max_past_logs, + max_block_range, fee_history_cache: fee_history_cache.clone(), fee_history_cache_limit, execute_gas_limit_multiplier, From f3ab5792b99b8fae059bfcc3629cd781dd133a99 Mon Sep 17 00:00:00 2001 From: snowmead Date: Mon, 14 Apr 2025 13:50:27 -0400 Subject: [PATCH 2/2] amend saturating sub --- client/rpc/src/eth/filter.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/client/rpc/src/eth/filter.rs b/client/rpc/src/eth/filter.rs index e25ef35d4c..fb04078901 100644 --- a/client/rpc/src/eth/filter.rs +++ b/client/rpc/src/eth/filter.rs @@ -510,7 +510,8 @@ where .map(|s| s.unique_saturated_into()) .unwrap_or(best_number); - if current_number - from_number > self.max_block_range.into() { + let block_range = current_number.saturating_sub(from_number); + if block_range > self.max_block_range.into() { return Err(internal_err(format!( "block range is too wide (maximum {})", self.max_block_range