From 9561f2860a020bc0f271786bd1bf924f7cf1bbe9 Mon Sep 17 00:00:00 2001 From: Yash Atreya <44857776+yash-atreya@users.noreply.github.com> Date: Mon, 9 Oct 2023 08:01:23 -0400 Subject: [PATCH] fix: improve eth_createAccessList (#4954) Co-authored-by: Matthias Seitz --- crates/rpc/rpc/src/eth/api/call.rs | 29 +++++++++++++++++++++++----- crates/rpc/rpc/src/eth/api/server.rs | 10 ++++------ 2 files changed, 28 insertions(+), 11 deletions(-) diff --git a/crates/rpc/rpc/src/eth/api/call.rs b/crates/rpc/rpc/src/eth/api/call.rs index c5c60ac2d..4a7445bcf 100644 --- a/crates/rpc/rpc/src/eth/api/call.rs +++ b/crates/rpc/rpc/src/eth/api/call.rs @@ -12,7 +12,7 @@ use crate::{ EthApi, }; use reth_network_api::NetworkInfo; -use reth_primitives::{AccessList, BlockId, BlockNumberOrTag, Bytes, U256}; +use reth_primitives::{AccessListWithGasUsed, BlockId, BlockNumberOrTag, Bytes, U256}; use reth_provider::{ BlockReaderIdExt, ChainSpecProvider, EvmEnvProvider, StateProvider, StateProviderFactory, }; @@ -168,7 +168,7 @@ where /// Estimates the gas usage of the `request` with the state. /// /// This will execute the [CallRequest] and find the best gas limit via binary search - fn estimate_gas_with( + pub fn estimate_gas_with( &self, mut cfg: CfgEnv, block: BlockEnv, @@ -337,11 +337,23 @@ where Ok(U256::from(highest_gas_limit)) } + /// Creates the AccessList for the `request` at the [BlockId] or latest. pub(crate) async fn create_access_list_at( + &self, + request: CallRequest, + block_number: Option, + ) -> EthResult { + self.on_blocking_task(|this| async move { + this.create_access_list_with(request, block_number).await + }) + .await + } + + async fn create_access_list_with( &self, mut request: CallRequest, at: Option, - ) -> EthResult { + ) -> EthResult { let block_id = at.unwrap_or(BlockId::Number(BlockNumberOrTag::Latest)); let (cfg, block, at) = self.evm_env_at(block_id).await?; let state = self.state_at(at)?; @@ -377,7 +389,7 @@ where let precompiles = get_precompiles(env.cfg.spec_id); let mut inspector = AccessListInspector::new(initial, from, to, precompiles); - let (result, _env) = inspect(&mut db, env, &mut inspector)?; + let (result, env) = inspect(&mut db, env, &mut inspector)?; match result.result { ExecutionResult::Halt { reason, .. } => Err(match reason { @@ -389,7 +401,14 @@ where } ExecutionResult::Success { .. } => Ok(()), }?; - Ok(inspector.into_access_list()) + + let access_list = inspector.into_access_list(); + + // 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())?; + + 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 4eb45828a..d4d867619 100644 --- a/crates/rpc/rpc/src/eth/api/server.rs +++ b/crates/rpc/rpc/src/eth/api/server.rs @@ -254,15 +254,13 @@ where /// Handler for: `eth_createAccessList` async fn create_access_list( &self, - mut request: CallRequest, + request: CallRequest, block_number: Option, ) -> Result { trace!(target: "rpc::eth", ?request, ?block_number, "Serving eth_createAccessList"); - let block_id = block_number.unwrap_or(BlockId::Number(BlockNumberOrTag::Latest)); - let access_list = self.create_access_list_at(request.clone(), block_number).await?; - request.access_list = Some(access_list.clone()); - let gas_used = self.estimate_gas_at(request, block_id).await?; - Ok(AccessListWithGasUsed { access_list, gas_used }) + let access_list_with_gas_used = self.create_access_list_at(request, block_number).await?; + + Ok(access_list_with_gas_used) } /// Handler for: `eth_estimateGas`