Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: make rpc gas cap configurable #3458

Merged
32 changes: 31 additions & 1 deletion bin/reth/src/args/rpc_server_args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@

use crate::args::GasPriceOracleArgs;
use clap::{
builder::{PossibleValue, TypedValueParser},
builder::{PossibleValue, RangedU64ValueParser, TypedValueParser},
Arg, Args, Command,
};
use futures::TryFutureExt;
use reth_network_api::{NetworkInfo, Peers};
use reth_primitives::constants::ETHEREUM_BLOCK_GAS_LIMIT;
use reth_provider::{
BlockReaderIdExt, CanonStateSubscriptions, ChainSpecProvider, EvmEnvProvider, HeaderProvider,
StateProviderFactory,
Expand Down Expand Up @@ -48,6 +49,9 @@ pub(crate) const RPC_DEFAULT_MAX_CONNECTIONS: u32 = 100;
/// Default number of incoming connections.
pub(crate) const RPC_DEFAULT_MAX_TRACING_REQUESTS: u32 = 25;

/// Default max gas limit for `eth_call` and call tracing RPC methods.
pub(crate) const RPC_DEFAULT_GAS_CAP: u64 = ETHEREUM_BLOCK_GAS_LIMIT;

/// Parameters for configuring the rpc more granularity via CLI
#[derive(Debug, Args, PartialEq, Eq, Default)]
#[command(next_help_heading = "RPC")]
Expand Down Expand Up @@ -132,6 +136,16 @@ pub struct RpcServerArgs {
#[arg(long, value_name = "COUNT", default_value_t = RPC_DEFAULT_MAX_TRACING_REQUESTS)]
pub rpc_max_tracing_requests: u32,

/// Maximum gas limit for `eth_call` and call tracing RPC methods.
#[arg(
long,
alias = "rpc.gascap",
value_name = "GAS_CAP",
value_parser = RangedU64ValueParser::<u64>::new().range(1..),
default_value_t = RPC_DEFAULT_GAS_CAP
)]
pub rpc_gas_cap: u64,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Next, to be able to use this parameter in EVM, we need to pass it to the RPC implementations in the same way as we do with max_log_per_response in EthFilter:

self.config.eth.max_logs_per_response,

So:

  1. Add rpc_gas_cap to EthConfig.
  2. Pass EthConfig.rpc_gas_cap to EthApi, DebugApi and TraceApi.
  3. Pass the gas cap to prepare_call_env via new function argument.


/// Gas price oracle configuration.
#[clap(flatten)]
pub gas_price_oracle: GasPriceOracleArgs,
Expand Down Expand Up @@ -174,6 +188,7 @@ impl RpcServerArgs {
pub fn eth_config(&self) -> EthConfig {
EthConfig::default()
.max_tracing_requests(self.rpc_max_tracing_requests)
.rpc_gas_cap(self.rpc_gas_cap)
.gpo_config(self.gas_price_oracle_config())
}

Expand Down Expand Up @@ -495,6 +510,21 @@ mod tests {
args: T,
}

#[test]
fn test_rpc_gas_cap() {
let args = CommandParser::<RpcServerArgs>::parse_from(["reth"]).args;
let config = args.eth_config();
assert_eq!(config.rpc_gas_cap, RPC_DEFAULT_GAS_CAP);

let args =
CommandParser::<RpcServerArgs>::parse_from(["reth", "--rpc.gascap", "1000"]).args;
let config = args.eth_config();
assert_eq!(config.rpc_gas_cap, 1000);

let args = CommandParser::<RpcServerArgs>::try_parse_from(["reth", "--rpc.gascap", "0"]);
assert!(args.is_err());
}

#[test]
fn test_rpc_server_args_parser() {
let args =
Expand Down
3 changes: 3 additions & 0 deletions book/cli/node.md
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,9 @@ Gas Price Oracle:
The percentile of gas prices to use for the estimate

[default: 60]

--rpc.gascap
Maximum gas limit for `eth_call` and call tracing RPC methods

--block-cache-len <BLOCK_CACHE_LEN>
Maximum number of block cache entries
Expand Down
2 changes: 2 additions & 0 deletions crates/rpc/rpc-builder/src/auth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use crate::{
constants,
error::{RpcError, ServerKind},
eth::DEFAULT_MAX_LOGS_PER_RESPONSE,
EthConfig,
};
use hyper::header::AUTHORIZATION;
pub use jsonrpsee::server::ServerBuilder;
Expand Down Expand Up @@ -61,6 +62,7 @@ where
network,
eth_cache.clone(),
gas_oracle,
EthConfig::default().rpc_gas_cap,
Box::new(executor.clone()),
);
let eth_filter = EthFilter::new(
Expand Down
10 changes: 10 additions & 0 deletions crates/rpc/rpc-builder/src/eth.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use reth_primitives::constants::ETHEREUM_BLOCK_GAS_LIMIT;
use reth_rpc::{
eth::{
cache::{EthStateCache, EthStateCacheConfig},
Expand Down Expand Up @@ -37,6 +38,8 @@ pub struct EthConfig {
pub max_tracing_requests: u32,
/// Maximum number of logs that can be returned in a single response in `eth_getLogs` calls.
pub max_logs_per_response: usize,
/// Maximum gas limit for `eth_call` and call tracing RPC methods.
pub rpc_gas_cap: u64,
}

impl Default for EthConfig {
Expand All @@ -46,6 +49,7 @@ impl Default for EthConfig {
gas_oracle: GasPriceOracleConfig::default(),
max_tracing_requests: DEFAULT_MAX_TRACING_REQUESTS,
max_logs_per_response: DEFAULT_MAX_LOGS_PER_RESPONSE,
rpc_gas_cap: ETHEREUM_BLOCK_GAS_LIMIT,
}
}
}
Expand Down Expand Up @@ -74,4 +78,10 @@ impl EthConfig {
self.max_logs_per_response = max_logs;
self
}

/// Configures the maximum gas limit for `eth_call` and call tracing RPC methods
pub fn rpc_gas_cap(mut self, rpc_gas_cap: u64) -> Self {
self.rpc_gas_cap = rpc_gas_cap;
self
}
}
1 change: 1 addition & 0 deletions crates/rpc/rpc-builder/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -967,6 +967,7 @@ where
self.network.clone(),
cache.clone(),
gas_oracle,
self.config.eth.rpc_gas_cap,
executor.clone(),
);
let filter = EthFilter::new(
Expand Down
12 changes: 12 additions & 0 deletions crates/rpc/rpc/src/eth/api/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,13 +83,15 @@ where
network: Network,
eth_cache: EthStateCache,
gas_oracle: GasPriceOracle<Provider>,
gas_cap: u64,
) -> Self {
Self::with_spawner(
provider,
pool,
network,
eth_cache,
gas_oracle,
gas_cap,
Box::<TokioTaskExecutor>::default(),
)
}
Expand All @@ -101,6 +103,7 @@ where
network: Network,
eth_cache: EthStateCache,
gas_oracle: GasPriceOracle<Provider>,
gas_cap: u64,
task_spawner: Box<dyn TaskSpawner>,
) -> Self {
// get the block number of the latest block
Expand All @@ -118,6 +121,7 @@ where
signers: Default::default(),
eth_cache,
gas_oracle,
gas_cap,
starting_block: U256::from(latest_block),
task_spawner,
pending_block: Default::default(),
Expand Down Expand Up @@ -155,6 +159,12 @@ where
&self.inner.gas_oracle
}

/// Returns the configured gas limit cap for `eth_call` and tracing related calls
#[allow(unused)]
pub(crate) fn gas_cap(&self) -> u64 {
self.inner.gas_cap
}

/// Returns the inner `Provider`
pub fn provider(&self) -> &Provider {
&self.inner.provider
Expand Down Expand Up @@ -354,6 +364,8 @@ struct EthApiInner<Provider, Pool, Network> {
eth_cache: EthStateCache,
/// The async gas oracle frontend for gas price suggestions
gas_oracle: GasPriceOracle<Provider>,
/// Maximum gas limit for `eth_call` and call tracing RPC methods.
gas_cap: u64,
/// The block number at which the node started
starting_block: U256,
/// The type that can spawn tasks which would otherwise block.
Expand Down
5 changes: 3 additions & 2 deletions crates/rpc/rpc/src/eth/api/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -398,8 +398,8 @@ mod tests {
use reth_interfaces::test_utils::{generators, generators::Rng};
use reth_network_api::noop::NoopNetwork;
use reth_primitives::{
basefee::calculate_next_block_base_fee, Block, BlockNumberOrTag, Header, TransactionSigned,
H256, U256,
basefee::calculate_next_block_base_fee, constants::ETHEREUM_BLOCK_GAS_LIMIT, Block,
BlockNumberOrTag, Header, TransactionSigned, H256, U256,
};
use reth_provider::{
test_utils::{MockEthProvider, NoopProvider},
Expand Down Expand Up @@ -427,6 +427,7 @@ mod tests {
NoopNetwork::default(),
cache.clone(),
GasPriceOracle::new(provider, Default::default(), cache),
ETHEREUM_BLOCK_GAS_LIMIT,
)
}

Expand Down
4 changes: 3 additions & 1 deletion crates/rpc/rpc/src/eth/api/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ where
mod tests {
use super::*;
use crate::eth::{cache::EthStateCache, gas_oracle::GasPriceOracle};
use reth_primitives::{StorageKey, StorageValue};
use reth_primitives::{constants::ETHEREUM_BLOCK_GAS_LIMIT, StorageKey, StorageValue};
use reth_provider::test_utils::{ExtendedAccount, MockEthProvider, NoopProvider};
use reth_transaction_pool::test_utils::testing_pool;
use std::collections::HashMap;
Expand All @@ -164,6 +164,7 @@ mod tests {
(),
cache.clone(),
GasPriceOracle::new(NoopProvider::default(), Default::default(), cache),
ETHEREUM_BLOCK_GAS_LIMIT,
);
let address = Address::random();
let storage = eth_api.storage_at(address, U256::ZERO.into(), None).unwrap();
Expand All @@ -184,6 +185,7 @@ mod tests {
(),
cache.clone(),
GasPriceOracle::new(mock_provider, Default::default(), cache),
ETHEREUM_BLOCK_GAS_LIMIT,
);

let storage_key: U256 = storage_key.into();
Expand Down
3 changes: 2 additions & 1 deletion crates/rpc/rpc/src/eth/api/transactions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -872,7 +872,7 @@ mod tests {
EthApi,
};
use reth_network_api::noop::NoopNetwork;
use reth_primitives::{hex_literal::hex, Bytes};
use reth_primitives::{constants::ETHEREUM_BLOCK_GAS_LIMIT, hex_literal::hex, Bytes};
use reth_provider::test_utils::NoopProvider;
use reth_transaction_pool::{test_utils::testing_pool, TransactionPool};

Expand All @@ -890,6 +890,7 @@ mod tests {
noop_network_provider,
cache.clone(),
GasPriceOracle::new(noop_provider, Default::default(), cache),
ETHEREUM_BLOCK_GAS_LIMIT,
);

// https://etherscan.io/tx/0xa694b71e6c128a2ed8e2e0f6770bddbe52e3bb8f10e8472f9a79ab81497a8b5d
Expand Down