feat: make trace_filter block range configurable (#14939)

Co-authored-by: Dan Cline <6798349+Rjected@users.noreply.github.com>
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
This commit is contained in:
Steven
2025-03-14 05:52:19 -06:00
committed by GitHub
parent 5f55448941
commit 89e3e5529f
7 changed files with 46 additions and 11 deletions

View File

@@ -337,6 +337,11 @@ RPC:
[default: <NUM CPU CORES-2>]
--rpc.max-trace-filter-blocks <COUNT>
Maximum number of blocks for `trace_filter` requests
[default: 100]
--rpc.max-blocks-per-filter <COUNT>
Maximum number of blocks that could be scanned per filter request. (0 = entire chain)

View File

@@ -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,

View File

@@ -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)

View File

@@ -767,6 +767,8 @@ pub struct RpcRegistryInner<
blocking_pool_guard: BlockingTaskGuard,
/// Contains the [Methods] of a module
modules: HashMap<RethRpcModule, Methods>,
/// 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(),

View File

@@ -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;

View File

@@ -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.

View File

@@ -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<Eth> {
impl<Eth> TraceApi<Eth> {
/// 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> {
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