From 247be8c6aa1d473226edae465a5f37286ee9d46d Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Mon, 5 Aug 2024 12:22:04 +0200 Subject: [PATCH] feat: add api bindings for eth_simulateV1 (#10050) --- crates/rpc/rpc-eth-api/src/core.rs | 29 ++++++++++++++++++---- crates/rpc/rpc-eth-api/src/helpers/call.rs | 16 ++++++++++-- 2 files changed, 38 insertions(+), 7 deletions(-) diff --git a/crates/rpc/rpc-eth-api/src/core.rs b/crates/rpc/rpc-eth-api/src/core.rs index 4f90e1686e..ba9d75fa29 100644 --- a/crates/rpc/rpc-eth-api/src/core.rs +++ b/crates/rpc/rpc-eth-api/src/core.rs @@ -1,6 +1,10 @@ //! Implementation of the [`jsonrpsee`] generated [`EthApiServer`] trait. Handles RPC requests for //! the `eth_` namespace. +use crate::helpers::{ + transaction::UpdateRawTxForwarder, EthApiSpec, EthBlocks, EthCall, EthFees, EthState, + EthTransactions, FullEthApi, +}; use alloy_dyn_abi::TypedData; use jsonrpsee::{core::RpcResult, proc_macros::rpc}; use reth_primitives::{ @@ -9,6 +13,7 @@ use reth_primitives::{ use reth_rpc_server_types::{result::internal_rpc_err, ToRpcResult}; use reth_rpc_types::{ serde_helpers::JsonStorageKey, + simulate::{SimBlock, SimulatedBlock}, state::{EvmOverrides, StateOverride}, AnyTransactionReceipt, BlockOverrides, Bundle, EIP1186AccountProofResponse, EthCallResponse, FeeHistory, Header, Index, RichBlock, StateContext, SyncStatus, Transaction, @@ -16,11 +21,6 @@ use reth_rpc_types::{ }; use tracing::trace; -use crate::helpers::{ - transaction::UpdateRawTxForwarder, EthApiSpec, EthBlocks, EthCall, EthFees, EthState, - EthTransactions, FullEthApi, -}; - /// Helper trait, unifies functionality that must be supported to implement all RPC methods for /// server. pub trait FullEthApiServer: EthApiServer + FullEthApi + UpdateRawTxForwarder + Clone {} @@ -192,6 +192,15 @@ pub trait EthApi { #[method(name = "getHeaderByHash")] async fn header_by_hash(&self, hash: B256) -> RpcResult>; + /// `eth_simulateV1` executes an arbitrary number of transactions on top of the requested state. + /// The transactions are packed into individual blocks. Overrides can be provided. + #[method(name = "simulateV1")] + async fn simulate_v1( + &self, + opts: SimBlock, + block_number: Option, + ) -> RpcResult>; + /// Executes a new message call immediately without creating a transaction on the block chain. #[method(name = "call")] async fn call( @@ -566,6 +575,16 @@ where Ok(EthBlocks::rpc_block_header(self, hash.into()).await?) } + /// Handler for: `eth_simulateV1` + async fn simulate_v1( + &self, + opts: SimBlock, + block_number: Option, + ) -> RpcResult> { + trace!(target: "rpc::eth", ?block_number, "Serving eth_simulateV1"); + Ok(EthCall::simulate_v1(self, opts, block_number).await?) + } + /// Handler for: `eth_call` async fn call( &self, diff --git a/crates/rpc/rpc-eth-api/src/helpers/call.rs b/crates/rpc/rpc-eth-api/src/helpers/call.rs index 9280154b8f..5ed42ec1ec 100644 --- a/crates/rpc/rpc-eth-api/src/helpers/call.rs +++ b/crates/rpc/rpc-eth-api/src/helpers/call.rs @@ -1,6 +1,7 @@ //! Loads a pending block from database. Helper trait for `eth_` transaction, call and trace RPC //! methods. +use crate::{AsEthApiError, FromEthApiError, FromEvmError, IntoEthApiError}; use futures::Future; use reth_evm::{ConfigureEvm, ConfigureEvmEnv}; use reth_primitives::{ @@ -26,6 +27,7 @@ use reth_rpc_server_types::constants::gas_oracle::{ CALL_STIPEND_GAS, ESTIMATE_GAS_ERROR_RATIO, MIN_TRANSACTION_GAS, }; use reth_rpc_types::{ + simulate::{SimBlock, SimulatedBlock}, state::{EvmOverrides, StateOverride}, BlockId, Bundle, EthCallResponse, StateContext, TransactionInfo, TransactionRequest, }; @@ -33,8 +35,6 @@ use revm::{Database, DatabaseCommit}; use revm_inspectors::access_list::AccessListInspector; use tracing::trace; -use crate::{AsEthApiError, FromEthApiError, FromEvmError, IntoEthApiError}; - use super::{LoadBlock, LoadPendingBlock, LoadState, LoadTransaction, SpawnBlocking, Trace}; /// Execution related functions for the [`EthApiServer`](crate::EthApiServer) trait in @@ -50,6 +50,18 @@ pub trait EthCall: Call + LoadPendingBlock { Call::estimate_gas_at(self, request, at, state_override) } + /// `eth_simulateV1` executes an arbitrary number of transactions on top of the requested state. + /// The transactions are packed into individual blocks. Overrides can be provided. + /// + /// See also: + fn simulate_v1( + &self, + _opts: SimBlock, + _block_number: Option, + ) -> impl Future, Self::Error>> + Send { + async move { Err(EthApiError::Unsupported("eth_simulateV1 is not supported.").into()) } + } + /// Executes the call request (`eth_call`) and returns the output fn call( &self,