diff --git a/book/cli/reth/node.md b/book/cli/reth/node.md index f5f780af1f..5ac65259f8 100644 --- a/book/cli/reth/node.md +++ b/book/cli/reth/node.md @@ -337,6 +337,11 @@ RPC: [default: ] + --rpc.max-trace-filter-blocks + Maximum number of blocks for `trace_filter` requests + + [default: 100] + --rpc.max-blocks-per-filter Maximum number of blocks that could be scanned per filter request. (0 = entire chain) diff --git a/crates/node/core/src/args/rpc_server.rs b/crates/node/core/src/args/rpc_server.rs index fe9b80cec4..b5eb63b926 100644 --- a/crates/node/core/src/args/rpc_server.rs +++ b/crates/node/core/src/args/rpc_server.rs @@ -145,6 +145,10 @@ pub struct RpcServerArgs { #[arg(long = "rpc.max-tracing-requests", alias = "rpc-max-tracing-requests", value_name = "COUNT", default_value_t = constants::default_max_tracing_requests())] pub rpc_max_tracing_requests: usize, + /// Maximum number of blocks for `trace_filter` requests. + #[arg(long = "rpc.max-trace-filter-blocks", alias = "rpc-max-trace-filter-blocks", value_name = "COUNT", default_value_t = constants::DEFAULT_MAX_TRACE_FILTER_BLOCKS)] + pub rpc_max_trace_filter_blocks: u64, + /// Maximum number of blocks that could be scanned per filter request. (0 = entire chain) #[arg(long = "rpc.max-blocks-per-filter", alias = "rpc-max-blocks-per-filter", value_name = "COUNT", default_value_t = ZeroAsNoneU64::new(constants::DEFAULT_MAX_BLOCKS_PER_FILTER))] pub rpc_max_blocks_per_filter: ZeroAsNoneU64, @@ -323,6 +327,7 @@ impl Default for RpcServerArgs { rpc_max_subscriptions_per_connection: RPC_DEFAULT_MAX_SUBS_PER_CONN.into(), rpc_max_connections: RPC_DEFAULT_MAX_CONNECTIONS.into(), rpc_max_tracing_requests: constants::default_max_tracing_requests(), + rpc_max_trace_filter_blocks: constants::DEFAULT_MAX_TRACE_FILTER_BLOCKS, rpc_max_blocks_per_filter: constants::DEFAULT_MAX_BLOCKS_PER_FILTER.into(), rpc_max_logs_per_response: (constants::DEFAULT_MAX_LOGS_PER_RESPONSE as u64).into(), rpc_gas_cap: constants::gas_oracle::RPC_DEFAULT_GAS_CAP, diff --git a/crates/rpc/rpc-builder/src/config.rs b/crates/rpc/rpc-builder/src/config.rs index ccb822bf66..ed879d0474 100644 --- a/crates/rpc/rpc-builder/src/config.rs +++ b/crates/rpc/rpc-builder/src/config.rs @@ -95,6 +95,7 @@ impl RethRpcServerConfig for RpcServerArgs { fn eth_config(&self) -> EthConfig { EthConfig::default() .max_tracing_requests(self.rpc_max_tracing_requests) + .max_trace_filter_blocks(self.rpc_max_trace_filter_blocks) .max_blocks_per_filter(self.rpc_max_blocks_per_filter.unwrap_or_max()) .max_logs_per_response(self.rpc_max_logs_per_response.unwrap_or_max() as usize) .eth_proof_window(self.rpc_eth_proof_window) diff --git a/crates/rpc/rpc-builder/src/lib.rs b/crates/rpc/rpc-builder/src/lib.rs index da20e1b8b4..6d6983d405 100644 --- a/crates/rpc/rpc-builder/src/lib.rs +++ b/crates/rpc/rpc-builder/src/lib.rs @@ -767,6 +767,8 @@ pub struct RpcRegistryInner< blocking_pool_guard: BlockingTaskGuard, /// Contains the [Methods] of a module modules: HashMap, + /// eth config settings + eth_config: EthConfig, } // === impl RpcRegistryInner === @@ -817,6 +819,7 @@ where modules: Default::default(), blocking_pool_guard, block_executor, + eth_config: config.eth, } } } @@ -1046,7 +1049,7 @@ where where EthApi: TraceExt, { - TraceApi::new(self.eth_api().clone(), self.blocking_pool_guard.clone()) + TraceApi::new(self.eth_api().clone(), self.blocking_pool_guard.clone(), self.eth_config) } /// Instantiates [`EthBundle`] Api @@ -1221,11 +1224,13 @@ where RethRpcModule::Net => { NetApi::new(self.network.clone(), eth_api.clone()).into_rpc().into() } - RethRpcModule::Trace => { - TraceApi::new(eth_api.clone(), self.blocking_pool_guard.clone()) - .into_rpc() - .into() - } + RethRpcModule::Trace => TraceApi::new( + eth_api.clone(), + self.blocking_pool_guard.clone(), + self.eth_config, + ) + .into_rpc() + .into(), RethRpcModule::Web3 => Web3Api::new(self.network.clone()).into_rpc().into(), RethRpcModule::Txpool => TxPoolApi::new( self.eth.api.pool().clone(), diff --git a/crates/rpc/rpc-eth-types/src/builder/config.rs b/crates/rpc/rpc-eth-types/src/builder/config.rs index 532c107720..6503e83f2e 100644 --- a/crates/rpc/rpc-eth-types/src/builder/config.rs +++ b/crates/rpc/rpc-eth-types/src/builder/config.rs @@ -7,7 +7,8 @@ use crate::{ }; use reth_rpc_server_types::constants::{ default_max_tracing_requests, DEFAULT_ETH_PROOF_WINDOW, DEFAULT_MAX_BLOCKS_PER_FILTER, - DEFAULT_MAX_LOGS_PER_RESPONSE, DEFAULT_MAX_SIMULATE_BLOCKS, DEFAULT_PROOF_PERMITS, + DEFAULT_MAX_LOGS_PER_RESPONSE, DEFAULT_MAX_SIMULATE_BLOCKS, DEFAULT_MAX_TRACE_FILTER_BLOCKS, + DEFAULT_PROOF_PERMITS, }; use serde::{Deserialize, Serialize}; @@ -25,6 +26,8 @@ pub struct EthConfig { pub eth_proof_window: u64, /// The maximum number of tracing calls that can be executed in concurrently. pub max_tracing_requests: usize, + /// Maximum number of blocks for `trace_filter` requests. + pub max_trace_filter_blocks: u64, /// Maximum number of blocks that could be scanned per filter request in `eth_getLogs` calls. pub max_blocks_per_filter: u64, /// Maximum number of logs that can be returned in a single response in `eth_getLogs` calls. @@ -61,6 +64,7 @@ impl Default for EthConfig { gas_oracle: GasPriceOracleConfig::default(), eth_proof_window: DEFAULT_ETH_PROOF_WINDOW, max_tracing_requests: default_max_tracing_requests(), + max_trace_filter_blocks: DEFAULT_MAX_TRACE_FILTER_BLOCKS, max_blocks_per_filter: DEFAULT_MAX_BLOCKS_PER_FILTER, max_logs_per_response: DEFAULT_MAX_LOGS_PER_RESPONSE, rpc_gas_cap: RPC_DEFAULT_GAS_CAP.into(), @@ -97,6 +101,12 @@ impl EthConfig { self } + /// Configures the maximum number of blocks for `trace_filter` requests + pub const fn max_trace_filter_blocks(mut self, max_blocks: u64) -> Self { + self.max_trace_filter_blocks = max_blocks; + self + } + /// Configures the maximum number of logs per response pub const fn max_logs_per_response(mut self, max_logs: usize) -> Self { self.max_logs_per_response = max_logs; diff --git a/crates/rpc/rpc-server-types/src/constants.rs b/crates/rpc/rpc-server-types/src/constants.rs index 38f720a3da..a30405d95d 100644 --- a/crates/rpc/rpc-server-types/src/constants.rs +++ b/crates/rpc/rpc-server-types/src/constants.rs @@ -15,6 +15,9 @@ pub const DEFAULT_MAX_BLOCKS_PER_FILTER: u64 = 100_000; /// The default maximum of logs in a single response. pub const DEFAULT_MAX_LOGS_PER_RESPONSE: usize = 20_000; +/// The default maximum number of blocks for `trace_filter` requests. +pub const DEFAULT_MAX_TRACE_FILTER_BLOCKS: u64 = 100; + /// The default maximum number tracing requests we're allowing concurrently. /// Tracing is mostly CPU bound so we're limiting the number of concurrent requests to something /// lower that the number of cores, in order to minimize the impact on the rest of the system. diff --git a/crates/rpc/rpc/src/trace.rs b/crates/rpc/rpc/src/trace.rs index 143d6bc25a..f483160d64 100644 --- a/crates/rpc/rpc/src/trace.rs +++ b/crates/rpc/rpc/src/trace.rs @@ -22,7 +22,7 @@ use reth_provider::{BlockNumReader, BlockReader, ChainSpecProvider}; use reth_revm::{database::StateProviderDatabase, db::CacheDB}; use reth_rpc_api::TraceApiServer; use reth_rpc_eth_api::{helpers::TraceExt, FromEthApiError, RpcNodeCore}; -use reth_rpc_eth_types::{error::EthApiError, utils::recover_raw_transaction}; +use reth_rpc_eth_types::{error::EthApiError, utils::recover_raw_transaction, EthConfig}; use reth_tasks::pool::BlockingTaskGuard; use reth_transaction_pool::{PoolPooledTx, PoolTransaction, TransactionPool}; use revm::DatabaseCommit; @@ -44,8 +44,12 @@ pub struct TraceApi { impl TraceApi { /// Create a new instance of the [`TraceApi`] - pub fn new(eth_api: Eth, blocking_task_guard: BlockingTaskGuard) -> Self { - let inner = Arc::new(TraceApiInner { eth_api, blocking_task_guard }); + pub fn new( + eth_api: Eth, + blocking_task_guard: BlockingTaskGuard, + eth_config: EthConfig, + ) -> Self { + let inner = Arc::new(TraceApiInner { eth_api, blocking_task_guard, eth_config }); Self { inner } } @@ -257,7 +261,7 @@ where // ensure that the range is not too large, since we need to fetch all blocks in the range let distance = end.saturating_sub(start); - if distance > 100 { + if distance > self.inner.eth_config.max_trace_filter_blocks { return Err(EthApiError::InvalidParams( "Block range too large; currently limited to 100 blocks".to_string(), ) @@ -685,6 +689,8 @@ struct TraceApiInner { eth_api: Eth, // restrict the number of concurrent calls to `trace_*` blocking_task_guard: BlockingTaskGuard, + // eth config settings + eth_config: EthConfig, } /// Helper to construct a [`LocalizedTransactionTrace`] that describes a reward to the block