From c13d0258974ba116838f48c35c8fe9012993ea46 Mon Sep 17 00:00:00 2001 From: Soubhik Singha Mahapatra <160333583+Soubhik-10@users.noreply.github.com> Date: Wed, 26 Mar 2025 22:52:06 +0530 Subject: [PATCH] Made --rpc.gascap support "max" (#15272) --- crates/node/core/src/args/rpc_server.rs | 4 +- crates/node/core/src/args/types.rs | 59 +++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 1 deletion(-) diff --git a/crates/node/core/src/args/rpc_server.rs b/crates/node/core/src/args/rpc_server.rs index b5eb63b926..7357aeee8b 100644 --- a/crates/node/core/src/args/rpc_server.rs +++ b/crates/node/core/src/args/rpc_server.rs @@ -21,6 +21,8 @@ use crate::args::{ GasPriceOracleArgs, RpcStateCacheArgs, }; +use super::types::MaxOr; + /// Default max number of subscriptions per connection. pub(crate) const RPC_DEFAULT_MAX_SUBS_PER_CONN: u32 = 1024; @@ -162,7 +164,7 @@ pub struct RpcServerArgs { long = "rpc.gascap", alias = "rpc-gascap", value_name = "GAS_CAP", - value_parser = RangedU64ValueParser::::new().range(1..), + value_parser = MaxOr::new(RangedU64ValueParser::::new().range(1..)), default_value_t = constants::gas_oracle::RPC_DEFAULT_GAS_CAP )] pub rpc_gas_cap: u64, diff --git a/crates/node/core/src/args/types.rs b/crates/node/core/src/args/types.rs index 4e1d3e08cf..3c66ed297a 100644 --- a/crates/node/core/src/args/types.rs +++ b/crates/node/core/src/args/types.rs @@ -95,9 +95,56 @@ macro_rules! max_values { max_values!(MaxU32, u32); max_values!(MaxU64, u64); +/// A helper type that supports parsing max or delegates to another parser +#[derive(Debug, Clone)] +pub struct MaxOr { + /// The inner parser + inner: T, +} + +impl MaxOr +where + T: clap::builder::TypedValueParser, + T::Value: Into, +{ + /// Creates a new instance with the given inner parser + pub fn new(inner: T) -> Self { + Self { inner } + } +} + +impl clap::builder::TypedValueParser for MaxOr +where + T: clap::builder::TypedValueParser, + T::Value: Into, +{ + type Value = u64; + + fn parse_ref( + &self, + cmd: &clap::Command, + arg: Option<&clap::Arg>, + value: &std::ffi::OsStr, + ) -> Result { + if value.to_str().map(|s| s.eq_ignore_ascii_case("max")).unwrap_or(false) { + Ok(u64::MAX) + } else { + self.inner.parse_ref(cmd, arg, value).map(Into::into) + } + } +} + #[cfg(test)] mod tests { use super::*; + use clap::Parser; + + /// A test command that uses the `MaxOr` parser + #[derive(Parser, Debug)] + struct NodeCommand { + #[arg(long, value_parser = MaxOr::new(clap::value_parser!(u64)))] + max_value: u64, + } #[test] fn test_zero_parse() { @@ -116,4 +163,16 @@ mod tests { let expected = ZeroAsNoneU64(None); assert_eq!(ZeroAsNoneU64::from(original), expected); } + + #[test] + fn parse_max_value() { + let cmd: NodeCommand = NodeCommand::try_parse_from(["reth", "--max-value", "max"]).unwrap(); + assert_eq!(cmd.max_value, u64::MAX); + + let cmd: NodeCommand = NodeCommand::try_parse_from(["reth", "--max-value", "42"]).unwrap(); + assert_eq!(cmd.max_value, 42); + + let result = NodeCommand::try_parse_from(["reth", "--max-value", "invalid"]); + assert!(result.is_err()); + } }