mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 10:59:55 +00:00
feat(rpc): limit block_range by 100_000 per eth_getLogs request (#5243)
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de> Co-authored-by: Alexey Shekhirin <a.shekhirin@gmail.com>
This commit is contained in:
@ -31,7 +31,7 @@ pub use stage_args::StageEnum;
|
||||
mod gas_price_oracle_args;
|
||||
pub use gas_price_oracle_args::GasPriceOracleArgs;
|
||||
|
||||
/// TxPoolArgs for congiguring the transaction pool
|
||||
/// TxPoolArgs for configuring the transaction pool
|
||||
mod txpool_args;
|
||||
pub use txpool_args::TxPoolArgs;
|
||||
|
||||
@ -44,3 +44,5 @@ mod pruning_args;
|
||||
pub use pruning_args::PruningArgs;
|
||||
|
||||
pub mod utils;
|
||||
|
||||
pub mod types;
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
//! clap [Args](clap::Args) for RPC related arguments.
|
||||
|
||||
use crate::{
|
||||
args::GasPriceOracleArgs,
|
||||
args::{types::ZeroAsNone, GasPriceOracleArgs},
|
||||
cli::{
|
||||
components::{RethNodeComponents, RethRpcComponents, RethRpcServerHandles},
|
||||
config::RethRpcConfig,
|
||||
@ -140,9 +140,13 @@ pub struct RpcServerArgs {
|
||||
#[arg(long, value_name = "COUNT", default_value_t = constants::DEFAULT_MAX_TRACING_REQUESTS)]
|
||||
pub rpc_max_tracing_requests: u32,
|
||||
|
||||
/// Maximum number of logs that can be returned in a single response.
|
||||
#[arg(long, value_name = "COUNT", default_value_t = constants::DEFAULT_MAX_LOGS_PER_RESPONSE)]
|
||||
pub rpc_max_logs_per_response: usize,
|
||||
/// Maximum number of blocks that could be scanned per filter request. (0 = entire chain)
|
||||
#[arg(long, value_name = "COUNT", default_value_t = ZeroAsNone::new(constants::DEFAULT_MAX_BLOCKS_PER_FILTER))]
|
||||
pub rpc_max_blocks_per_filter: ZeroAsNone,
|
||||
|
||||
/// Maximum number of logs that can be returned in a single response. (0 = no limit)
|
||||
#[arg(long, value_name = "COUNT", default_value_t = ZeroAsNone::new(constants::DEFAULT_MAX_LOGS_PER_RESPONSE as u64))]
|
||||
pub rpc_max_logs_per_response: ZeroAsNone,
|
||||
|
||||
/// Maximum gas limit for `eth_call` and call tracing RPC methods.
|
||||
#[arg(
|
||||
@ -326,7 +330,8 @@ impl RethRpcConfig for RpcServerArgs {
|
||||
fn eth_config(&self) -> EthConfig {
|
||||
EthConfig::default()
|
||||
.max_tracing_requests(self.rpc_max_tracing_requests)
|
||||
.max_logs_per_response(self.rpc_max_logs_per_response)
|
||||
.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)
|
||||
.rpc_gas_cap(self.rpc_gas_cap)
|
||||
.gpo_config(self.gas_price_oracle_config())
|
||||
}
|
||||
@ -598,4 +603,36 @@ mod tests {
|
||||
);
|
||||
assert_eq!(config.ipc_endpoint().unwrap().path(), constants::DEFAULT_IPC_ENDPOINT);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_zero_filter_limits() {
|
||||
let args = CommandParser::<RpcServerArgs>::parse_from([
|
||||
"reth",
|
||||
"--rpc-max-blocks-per-filter",
|
||||
"0",
|
||||
"--rpc-max-logs-per-response",
|
||||
"0",
|
||||
])
|
||||
.args;
|
||||
|
||||
let config = args.eth_config().filter_config();
|
||||
assert_eq!(config.max_blocks_per_filter, Some(u64::MAX));
|
||||
assert_eq!(config.max_logs_per_response, Some(usize::MAX));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_custom_filter_limits() {
|
||||
let args = CommandParser::<RpcServerArgs>::parse_from([
|
||||
"reth",
|
||||
"--rpc-max-blocks-per-filter",
|
||||
"100",
|
||||
"--rpc-max-logs-per-response",
|
||||
"200",
|
||||
])
|
||||
.args;
|
||||
|
||||
let config = args.eth_config().filter_config();
|
||||
assert_eq!(config.max_blocks_per_filter, Some(100));
|
||||
assert_eq!(config.max_logs_per_response, Some(200));
|
||||
}
|
||||
}
|
||||
|
||||
49
bin/reth/src/args/types.rs
Normal file
49
bin/reth/src/args/types.rs
Normal file
@ -0,0 +1,49 @@
|
||||
//! Additional helper types for CLI parsing.
|
||||
|
||||
use std::{fmt, str::FromStr};
|
||||
|
||||
/// A helper type that maps `0` to `None` when parsing CLI arguments.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub struct ZeroAsNone(pub Option<u64>);
|
||||
|
||||
impl ZeroAsNone {
|
||||
/// Returns the inner value.
|
||||
pub const fn new(value: u64) -> Self {
|
||||
Self(Some(value))
|
||||
}
|
||||
|
||||
/// Returns the inner value or `u64::MAX` if `None`.
|
||||
pub fn unwrap_or_max(self) -> u64 {
|
||||
self.0.unwrap_or(u64::MAX)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for ZeroAsNone {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self.0 {
|
||||
Some(value) => write!(f, "{}", value),
|
||||
None => write!(f, "0"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for ZeroAsNone {
|
||||
type Err = std::num::ParseIntError;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
let value = s.parse::<u64>()?;
|
||||
Ok(Self(if value == 0 { None } else { Some(value) }))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_zero_parse() {
|
||||
let val = "0".parse::<ZeroAsNone>().unwrap();
|
||||
assert_eq!(val, ZeroAsNone(None));
|
||||
assert_eq!(val.unwrap_or_max(), u64::MAX);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user