chore: use 50M default gas limit for calls in rpc (#3812)

This commit is contained in:
Matthias Seitz
2023-07-17 18:31:25 +02:00
committed by GitHub
parent eb32fd3c6d
commit 01e1344cc1
8 changed files with 40 additions and 17 deletions

View File

@ -7,7 +7,6 @@ use clap::{
}; };
use futures::TryFutureExt; use futures::TryFutureExt;
use reth_network_api::{NetworkInfo, Peers}; use reth_network_api::{NetworkInfo, Peers};
use reth_primitives::constants::ETHEREUM_BLOCK_GAS_LIMIT;
use reth_provider::{ use reth_provider::{
BlockReaderIdExt, CanonStateSubscriptions, ChainSpecProvider, EvmEnvProvider, HeaderProvider, BlockReaderIdExt, CanonStateSubscriptions, ChainSpecProvider, EvmEnvProvider, HeaderProvider,
StateProviderFactory, StateProviderFactory,
@ -24,6 +23,7 @@ use reth_rpc::{
use reth_rpc_builder::{ use reth_rpc_builder::{
auth::{AuthServerConfig, AuthServerHandle}, auth::{AuthServerConfig, AuthServerHandle},
constants, constants,
constants::RPC_DEFAULT_GAS_CAP,
error::RpcError, error::RpcError,
EthConfig, IpcServerBuilder, RethRpcModule, RpcModuleBuilder, RpcModuleConfig, EthConfig, IpcServerBuilder, RethRpcModule, RpcModuleBuilder, RpcModuleConfig,
RpcModuleSelection, RpcServerConfig, RpcServerHandle, ServerBuilder, TransportRpcModuleConfig, RpcModuleSelection, RpcServerConfig, RpcServerHandle, ServerBuilder, TransportRpcModuleConfig,
@ -49,9 +49,6 @@ pub(crate) const RPC_DEFAULT_MAX_CONNECTIONS: u32 = 100;
/// Default number of incoming connections. /// Default number of incoming connections.
pub(crate) const RPC_DEFAULT_MAX_TRACING_REQUESTS: u32 = 25; 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 /// Parameters for configuring the rpc more granularity via CLI
#[derive(Debug, Args, PartialEq, Eq, Default)] #[derive(Debug, Args, PartialEq, Eq, Default)]
#[command(next_help_heading = "RPC")] #[command(next_help_heading = "RPC")]

View File

@ -7,6 +7,13 @@ pub const DEFAULT_WS_RPC_PORT: u16 = 8546;
/// The default port for the auth server. /// The default port for the auth server.
pub const DEFAULT_AUTH_PORT: u16 = 8551; pub const DEFAULT_AUTH_PORT: u16 = 8551;
/// The default gas limit for eth_call and adjacent calls.
///
/// This is different from the default to regular 30M block gas limit
/// [ETHEREUM_BLOCK_GAS_LIMIT](reth_primitives::constants::ETHEREUM_BLOCK_GAS_LIMIT) to allow for
/// more complex calls.
pub const RPC_DEFAULT_GAS_CAP: u64 = 50_000_000;
/// The default IPC endpoint /// The default IPC endpoint
#[cfg(windows)] #[cfg(windows)]
pub const DEFAULT_IPC_ENDPOINT: &str = r"\\.\pipe\reth.ipc"; pub const DEFAULT_IPC_ENDPOINT: &str = r"\\.\pipe\reth.ipc";

View File

@ -1,4 +1,4 @@
use reth_primitives::constants::ETHEREUM_BLOCK_GAS_LIMIT; use crate::constants::RPC_DEFAULT_GAS_CAP;
use reth_rpc::{ use reth_rpc::{
eth::{ eth::{
cache::{EthStateCache, EthStateCacheConfig}, cache::{EthStateCache, EthStateCacheConfig},
@ -38,7 +38,9 @@ pub struct EthConfig {
pub max_tracing_requests: u32, pub max_tracing_requests: u32,
/// Maximum number of logs that can be returned in a single response in `eth_getLogs` calls. /// Maximum number of logs that can be returned in a single response in `eth_getLogs` calls.
pub max_logs_per_response: usize, pub max_logs_per_response: usize,
/// Maximum gas limit for `eth_call` and call tracing RPC methods. /// Gas limit for `eth_call` and call tracing RPC methods.
///
/// Defaults to [RPC_DEFAULT_GAS_CAP]
pub rpc_gas_cap: u64, pub rpc_gas_cap: u64,
} }
@ -49,7 +51,7 @@ impl Default for EthConfig {
gas_oracle: GasPriceOracleConfig::default(), gas_oracle: GasPriceOracleConfig::default(),
max_tracing_requests: DEFAULT_MAX_TRACING_REQUESTS, max_tracing_requests: DEFAULT_MAX_TRACING_REQUESTS,
max_logs_per_response: DEFAULT_MAX_LOGS_PER_RESPONSE, max_logs_per_response: DEFAULT_MAX_LOGS_PER_RESPONSE,
rpc_gas_cap: ETHEREUM_BLOCK_GAS_LIMIT, rpc_gas_cap: RPC_DEFAULT_GAS_CAP,
} }
} }
} }

View File

@ -319,7 +319,14 @@ where
let state = self.inner.eth_api.state_at(at)?; let state = self.inner.eth_api.state_at(at)?;
let mut db = SubState::new(State::new(state)); let mut db = SubState::new(State::new(state));
let has_state_overrides = overrides.has_state(); let has_state_overrides = overrides.has_state();
let env = prepare_call_env(cfg, block_env, call, &mut db, overrides)?; let env = prepare_call_env(
cfg,
block_env,
call,
self.inner.eth_api.call_gas_limit(),
&mut db,
overrides,
)?;
// If the caller provided state overrides we need to clone the DB so the js // If the caller provided state overrides we need to clone the DB so the js
// service has access these modifications // service has access these modifications

View File

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

View File

@ -43,6 +43,9 @@ pub(crate) type StateCacheDB<'r> = CacheDB<State<StateProviderBox<'r>>>;
/// Commonly used transaction related functions for the [EthApi] type in the `eth_` namespace /// Commonly used transaction related functions for the [EthApi] type in the `eth_` namespace
#[async_trait::async_trait] #[async_trait::async_trait]
pub trait EthTransactions: Send + Sync { pub trait EthTransactions: Send + Sync {
/// Returns default gas limit to use for `eth_call` and tracing RPC methods.
fn call_gas_limit(&self) -> u64;
/// Returns the state at the given [BlockId] /// Returns the state at the given [BlockId]
fn state_at(&self, at: BlockId) -> EthResult<StateProviderBox<'_>>; fn state_at(&self, at: BlockId) -> EthResult<StateProviderBox<'_>>;
@ -226,6 +229,10 @@ where
Provider: BlockReaderIdExt + StateProviderFactory + EvmEnvProvider + 'static, Provider: BlockReaderIdExt + StateProviderFactory + EvmEnvProvider + 'static,
Network: NetworkInfo + Send + Sync + 'static, Network: NetworkInfo + Send + Sync + 'static,
{ {
fn call_gas_limit(&self) -> u64 {
self.inner.gas_cap
}
fn state_at(&self, at: BlockId) -> EthResult<StateProviderBox<'_>> { fn state_at(&self, at: BlockId) -> EthResult<StateProviderBox<'_>> {
self.state_at_block_id(at) self.state_at_block_id(at)
} }
@ -480,7 +487,8 @@ where
let state = self.state_at(at)?; let state = self.state_at(at)?;
let mut db = SubState::new(State::new(state)); let mut db = SubState::new(State::new(state));
let env = prepare_call_env(cfg, block_env, request, &mut db, overrides)?; let env =
prepare_call_env(cfg, block_env, request, self.call_gas_limit(), &mut db, overrides)?;
f(db, env) f(db, env)
} }
@ -520,7 +528,8 @@ where
let state = self.state_at(at)?; let state = self.state_at(at)?;
let mut db = SubState::new(State::new(state)); let mut db = SubState::new(State::new(state));
let env = prepare_call_env(cfg, block_env, request, &mut db, overrides)?; let env =
prepare_call_env(cfg, block_env, request, self.call_gas_limit(), &mut db, overrides)?;
inspect_and_return_db(db, env, inspector) inspect_and_return_db(db, env, inspector)
} }

View File

@ -2,8 +2,7 @@
use crate::eth::error::{EthApiError, EthResult, RpcInvalidTransactionError}; use crate::eth::error::{EthApiError, EthResult, RpcInvalidTransactionError};
use reth_primitives::{ use reth_primitives::{
constants::ETHEREUM_BLOCK_GAS_LIMIT, AccessList, Address, TransactionSigned, AccessList, Address, TransactionSigned, TransactionSignedEcRecovered, TxHash, H256, U256,
TransactionSignedEcRecovered, TxHash, H256, U256,
}; };
use reth_revm::env::{fill_tx_env, fill_tx_env_with_recovered}; use reth_revm::env::{fill_tx_env, fill_tx_env_with_recovered};
use reth_rpc_types::{ use reth_rpc_types::{
@ -203,6 +202,7 @@ pub(crate) fn prepare_call_env<DB>(
mut cfg: CfgEnv, mut cfg: CfgEnv,
block: BlockEnv, block: BlockEnv,
request: CallRequest, request: CallRequest,
gas_limit: u64,
db: &mut CacheDB<DB>, db: &mut CacheDB<DB>,
overrides: EvmOverrides, overrides: EvmOverrides,
) -> EthResult<Env> ) -> EthResult<Env>
@ -247,10 +247,10 @@ where
// If no gas price is specified, use maximum allowed gas limit. The reason for this is // If no gas price is specified, use maximum allowed gas limit. The reason for this is
// that both Erigon and Geth use pre-configured gas cap even if it's possible // that both Erigon and Geth use pre-configured gas cap even if it's possible
// to derive the gas limit from the block: // to derive the gas limit from the block:
// https://github.com/ledgerwatch/erigon/blob/eae2d9a79cb70dbe30b3a6b79c436872e4605458/cmd/rpcdaemon/commands/trace_adhoc.go#L956 // <https://github.com/ledgerwatch/erigon/blob/eae2d9a79cb70dbe30b3a6b79c436872e4605458/cmd/rpcdaemon/commands/trace_adhoc.go#L956
// https://github.com/ledgerwatch/erigon/blob/eae2d9a79cb70dbe30b3a6b79c436872e4605458/eth/ethconfig/config.go#L94 // https://github.com/ledgerwatch/erigon/blob/eae2d9a79cb70dbe30b3a6b79c436872e4605458/eth/ethconfig/config.go#L94>
trace!(target: "rpc::eth::call", ?env, "Applying gas limit cap as the maximum gas limit"); trace!(target: "rpc::eth::call", ?env, "Applying gas limit cap as the maximum gas limit");
env.tx.gas_limit = ETHEREUM_BLOCK_GAS_LIMIT; env.tx.gas_limit = gas_limit;
} }
} }

View File

@ -191,6 +191,7 @@ where
let (cfg, block_env, at) = self.inner.eth_api.evm_env_at(at).await?; let (cfg, block_env, at) = self.inner.eth_api.evm_env_at(at).await?;
self.on_blocking_task(|this| async move { self.on_blocking_task(|this| async move {
let gas_limit = this.inner.eth_api.call_gas_limit();
// execute all transactions on top of each other and record the traces // execute all transactions on top of each other and record the traces
this.inner.eth_api.with_state_at_block(at, move |state| { this.inner.eth_api.with_state_at_block(at, move |state| {
let mut results = Vec::with_capacity(calls.len()); let mut results = Vec::with_capacity(calls.len());
@ -203,6 +204,7 @@ where
cfg.clone(), cfg.clone(),
block_env.clone(), block_env.clone(),
call, call,
gas_limit,
&mut db, &mut db,
Default::default(), Default::default(),
)?; )?;