From 00804191ff434034f757003c3026ba3b66dc5a36 Mon Sep 17 00:00:00 2001 From: Aditya Pandey Date: Thu, 30 Nov 2023 17:16:44 +0530 Subject: [PATCH] Add stateOverrides-to-estimate-gas-call (#5604) --- crates/rpc/rpc-api/src/eth.rs | 1 + crates/rpc/rpc-builder/tests/it/http.rs | 2 +- crates/rpc/rpc/src/eth/api/call.rs | 21 ++++++++++++++++----- crates/rpc/rpc/src/eth/api/server.rs | 2 ++ crates/rpc/rpc/src/eth/api/transactions.rs | 1 + crates/rpc/rpc/src/eth/revm_utils.rs | 5 ++++- 6 files changed, 25 insertions(+), 7 deletions(-) diff --git a/crates/rpc/rpc-api/src/eth.rs b/crates/rpc/rpc-api/src/eth.rs index 01aa8fa0c..c301864ee 100644 --- a/crates/rpc/rpc-api/src/eth.rs +++ b/crates/rpc/rpc-api/src/eth.rs @@ -190,6 +190,7 @@ pub trait EthApi { &self, request: CallRequest, block_number: Option, + state_override: Option, ) -> RpcResult; /// Returns the current price per gas in wei. diff --git a/crates/rpc/rpc-builder/tests/it/http.rs b/crates/rpc/rpc-builder/tests/it/http.rs index ffe39b766..dd86a0a14 100644 --- a/crates/rpc/rpc-builder/tests/it/http.rs +++ b/crates/rpc/rpc-builder/tests/it/http.rs @@ -160,7 +160,7 @@ where EthApiClient::create_access_list(client, call_request.clone(), Some(block_number.into())) .await .unwrap(); - EthApiClient::estimate_gas(client, call_request.clone(), Some(block_number.into())) + EthApiClient::estimate_gas(client, call_request.clone(), Some(block_number.into()), None) .await .unwrap(); EthApiClient::call(client, call_request.clone(), Some(block_number.into()), None, None) diff --git a/crates/rpc/rpc/src/eth/api/call.rs b/crates/rpc/rpc/src/eth/api/call.rs index a90d64ecc..0ae826de7 100644 --- a/crates/rpc/rpc/src/eth/api/call.rs +++ b/crates/rpc/rpc/src/eth/api/call.rs @@ -4,8 +4,9 @@ use crate::{ eth::{ error::{ensure_success, EthApiError, EthResult, RevertError, RpcInvalidTransactionError}, revm_utils::{ - build_call_evm_env, caller_gas_allowance, cap_tx_gas_limit_with_caller_allowance, - get_precompiles, inspect, prepare_call_env, transact, EvmOverrides, + apply_state_overrides, build_call_evm_env, caller_gas_allowance, + cap_tx_gas_limit_with_caller_allowance, get_precompiles, inspect, prepare_call_env, + transact, EvmOverrides, }, EthTransactions, }, @@ -41,12 +42,17 @@ where Network: NetworkInfo + Send + Sync + 'static, { /// Estimate gas needed for execution of the `request` at the [BlockId]. - pub async fn estimate_gas_at(&self, request: CallRequest, at: BlockId) -> EthResult { + pub async fn estimate_gas_at( + &self, + request: CallRequest, + at: BlockId, + state_override: Option, + ) -> EthResult { let (cfg, block_env, at) = self.evm_env_at(at).await?; self.on_blocking_task(|this| async move { let state = this.state_at(at)?; - this.estimate_gas_with(cfg, block_env, request, state) + this.estimate_gas_with(cfg, block_env, request, state, state_override) }) .await } @@ -171,6 +177,7 @@ where block: BlockEnv, request: CallRequest, state: S, + state_override: Option, ) -> EthResult where S: StateProvider, @@ -197,6 +204,10 @@ where let mut env = build_call_evm_env(cfg, block, request)?; let mut db = CacheDB::new(StateProviderDatabase::new(state)); + if let Some(state_override) = state_override { + // apply state overrides + apply_state_overrides(state_override, &mut db)?; + } // if the request is a simple transfer we can optimize if env.tx.data.is_empty() { if let TransactTo::Call(to) = env.tx.transact_to { @@ -409,7 +420,7 @@ where // calculate the gas used using the access list request.access_list = Some(access_list.clone()); - let gas_used = self.estimate_gas_with(env.cfg, env.block, request, db.db.state())?; + let gas_used = self.estimate_gas_with(env.cfg, env.block, request, db.db.state(), None)?; Ok(AccessListWithGasUsed { access_list, gas_used }) } diff --git a/crates/rpc/rpc/src/eth/api/server.rs b/crates/rpc/rpc/src/eth/api/server.rs index c63de87e7..6d20f7912 100644 --- a/crates/rpc/rpc/src/eth/api/server.rs +++ b/crates/rpc/rpc/src/eth/api/server.rs @@ -266,12 +266,14 @@ where &self, request: CallRequest, block_number: Option, + state_override: Option, ) -> Result { trace!(target: "rpc::eth", ?request, ?block_number, "Serving eth_estimateGas"); Ok(self .estimate_gas_at( request, block_number.unwrap_or(BlockId::Number(BlockNumberOrTag::Latest)), + state_override, ) .await?) } diff --git a/crates/rpc/rpc/src/eth/api/transactions.rs b/crates/rpc/rpc/src/eth/api/transactions.rs index 93577db24..d6d1a80c5 100644 --- a/crates/rpc/rpc/src/eth/api/transactions.rs +++ b/crates/rpc/rpc/src/eth/api/transactions.rs @@ -530,6 +530,7 @@ where max_fee_per_blob_gas: None, }, BlockId::Number(BlockNumberOrTag::Pending), + None, ) .await?; let gas_limit = estimated_gas; diff --git a/crates/rpc/rpc/src/eth/revm_utils.rs b/crates/rpc/rpc/src/eth/revm_utils.rs index 4393272fc..8d016ec6b 100644 --- a/crates/rpc/rpc/src/eth/revm_utils.rs +++ b/crates/rpc/rpc/src/eth/revm_utils.rs @@ -520,7 +520,10 @@ fn apply_block_overrides(overrides: BlockOverrides, env: &mut BlockEnv) { } /// Applies the given state overrides (a set of [AccountOverride]) to the [CacheDB]. -fn apply_state_overrides(overrides: StateOverride, db: &mut CacheDB) -> EthResult<()> +pub(crate) fn apply_state_overrides( + overrides: StateOverride, + db: &mut CacheDB, +) -> EthResult<()> where DB: DatabaseRef, EthApiError: From<::Error>,