From e20c52445296437dcf5d1e3add8b8759ec31c883 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Fri, 5 Apr 2024 09:26:11 +0200 Subject: [PATCH] feat: integrate evm in rpc (#7470) --- Cargo.lock | 2 +- crates/evm/src/lib.rs | 22 ++++++++++++---- crates/node-optimism/src/evm.rs | 9 +++++-- crates/revm/src/test_utils.rs | 9 ++++++- crates/rpc/rpc/Cargo.toml | 2 +- crates/rpc/rpc/src/eth/api/server.rs | 2 +- crates/rpc/rpc/src/eth/api/state.rs | 2 +- crates/rpc/rpc/src/eth/api/transactions.rs | 30 +++++----------------- examples/custom-evm/src/main.rs | 10 ++++++-- 9 files changed, 51 insertions(+), 37 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6fdaa6ed4..a91daa53a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6851,10 +6851,10 @@ dependencies = [ "reqwest", "reth-consensus-common", "reth-evm", + "reth-evm-ethereum", "reth-interfaces", "reth-metrics", "reth-network-api", - "reth-node-ethereum", "reth-primitives", "reth-provider", "reth-revm", diff --git a/crates/evm/src/lib.rs b/crates/evm/src/lib.rs index 47700260e..78dd0cb07 100644 --- a/crates/evm/src/lib.rs +++ b/crates/evm/src/lib.rs @@ -9,7 +9,7 @@ #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] use reth_primitives::{revm::env::fill_block_env, Address, ChainSpec, Header, Transaction, U256}; -use revm::{Database, Evm, EvmBuilder}; +use revm::{inspector_handle_register, Database, Evm, EvmBuilder, GetInspector}; use revm_primitives::{BlockEnv, CfgEnvWithHandlerCfg, EnvWithHandlerCfg, SpecId, TxEnv}; /// Trait for configuring the EVM for executing full blocks. @@ -42,12 +42,16 @@ pub trait ConfigureEvm: ConfigureEvmEnv { /// including the spec id. /// /// This will preserve any handler modifications - fn evm_with_env_and_inspector<'a, DB: Database + 'a, I>( + fn evm_with_env_and_inspector<'a, DB, I>( &self, db: DB, env: EnvWithHandlerCfg, inspector: I, - ) -> Evm<'a, I, DB> { + ) -> Evm<'a, I, DB> + where + DB: Database + 'a, + I: GetInspector, + { let mut evm = self.evm_with_inspector(db, inspector); evm.modify_spec_id(env.spec_id()); evm.context.evm.env = env.env; @@ -59,8 +63,16 @@ pub trait ConfigureEvm: ConfigureEvmEnv { /// Caution: This does not automatically configure the EVM with [ConfigureEvmEnv] methods. It is /// up to the caller to call an appropriate method to fill the transaction and block /// environment before executing any transactions using the provided EVM. - fn evm_with_inspector<'a, DB: Database + 'a, I>(&self, db: DB, inspector: I) -> Evm<'a, I, DB> { - EvmBuilder::default().with_db(db).with_external_context(inspector).build() + fn evm_with_inspector<'a, DB, I>(&self, db: DB, inspector: I) -> Evm<'a, I, DB> + where + DB: Database + 'a, + I: GetInspector, + { + EvmBuilder::default() + .with_db(db) + .with_external_context(inspector) + .append_handler_register(inspector_handle_register) + .build() } } diff --git a/crates/node-optimism/src/evm.rs b/crates/node-optimism/src/evm.rs index 93ea7f330..d2bbaff17 100644 --- a/crates/node-optimism/src/evm.rs +++ b/crates/node-optimism/src/evm.rs @@ -4,7 +4,7 @@ use reth_primitives::{ revm_primitives::{AnalysisKind, CfgEnvWithHandlerCfg, HandlerCfg, SpecId, TxEnv}, Address, Bytes, ChainSpec, Head, Header, Transaction, U256, }; -use revm::{Database, Evm, EvmBuilder}; +use revm::{inspector_handle_register, Database, Evm, EvmBuilder, GetInspector}; /// Optimism-related EVM configuration. #[derive(Debug, Default, Clone, Copy)] @@ -52,12 +52,17 @@ impl ConfigureEvm for OptimismEvmConfig { EvmBuilder::default().with_db(db).with_handler_cfg(handler_cfg).build() } - fn evm_with_inspector<'a, DB: Database + 'a, I>(&self, db: DB, inspector: I) -> Evm<'a, I, DB> { + fn evm_with_inspector<'a, DB, I>(&self, db: DB, inspector: I) -> Evm<'a, I, DB> + where + DB: Database + 'a, + I: GetInspector, + { let handler_cfg = HandlerCfg { spec_id: SpecId::LATEST, is_optimism: true }; EvmBuilder::default() .with_db(db) .with_external_context(inspector) .with_handler_cfg(handler_cfg) + .append_handler_register(inspector_handle_register) .build() } } diff --git a/crates/revm/src/test_utils.rs b/crates/revm/src/test_utils.rs index 0921ee49c..6534fcb78 100644 --- a/crates/revm/src/test_utils.rs +++ b/crates/revm/src/test_utils.rs @@ -11,7 +11,9 @@ use reth_provider::{AccountReader, BlockHashReader, StateProvider, StateRootProv use reth_trie::updates::TrieUpdates; use revm::{ db::BundleState, + inspector_handle_register, primitives::{AnalysisKind, CfgEnvWithHandlerCfg, TxEnv}, + GetInspector, }; use std::collections::HashMap; #[cfg(feature = "optimism")] @@ -162,12 +164,17 @@ impl ConfigureEvm for TestEvmConfig { } #[cfg(feature = "optimism")] - fn evm_with_inspector<'a, DB: Database + 'a, I>(&self, db: DB, inspector: I) -> Evm<'a, I, DB> { + fn evm_with_inspector<'a, DB, I>(&self, db: DB, inspector: I) -> Evm<'a, I, DB> + where + DB: Database + 'a, + I: GetInspector, + { let handler_cfg = HandlerCfg { spec_id: SpecId::LATEST, is_optimism: true }; EvmBuilder::default() .with_db(db) .with_external_context(inspector) .with_handler_cfg(handler_cfg) + .append_handler_register(inspector_handle_register) .build() } } diff --git a/crates/rpc/rpc/Cargo.toml b/crates/rpc/rpc/Cargo.toml index e74cf7fcf..0331238b4 100644 --- a/crates/rpc/rpc/Cargo.toml +++ b/crates/rpc/rpc/Cargo.toml @@ -82,7 +82,7 @@ derive_more.workspace = true dyn-clone.workspace = true [dev-dependencies] -reth-node-ethereum.workspace = true +reth-evm-ethereum.workspace = true jsonrpsee = { workspace = true, features = ["client"] } assert_matches.workspace = true tempfile.workspace = true diff --git a/crates/rpc/rpc/src/eth/api/server.rs b/crates/rpc/rpc/src/eth/api/server.rs index 543ca6cb9..0d31339f5 100644 --- a/crates/rpc/rpc/src/eth/api/server.rs +++ b/crates/rpc/rpc/src/eth/api/server.rs @@ -443,9 +443,9 @@ mod tests { EthApi, }; use jsonrpsee::types::error::INVALID_PARAMS_CODE; + use reth_evm_ethereum::EthEvmConfig; use reth_interfaces::test_utils::{generators, generators::Rng}; use reth_network_api::noop::NoopNetwork; - use reth_node_ethereum::EthEvmConfig; use reth_primitives::{ basefee::calculate_next_block_base_fee, constants::ETHEREUM_BLOCK_GAS_LIMIT, BaseFeeParams, Block, BlockNumberOrTag, Header, TransactionSigned, B256, U256, diff --git a/crates/rpc/rpc/src/eth/api/state.rs b/crates/rpc/rpc/src/eth/api/state.rs index 5eac3db31..d9577f23e 100644 --- a/crates/rpc/rpc/src/eth/api/state.rs +++ b/crates/rpc/rpc/src/eth/api/state.rs @@ -121,7 +121,7 @@ mod tests { use crate::eth::{ cache::EthStateCache, gas_oracle::GasPriceOracle, FeeHistoryCache, FeeHistoryCacheConfig, }; - use reth_node_ethereum::EthEvmConfig; + use reth_evm_ethereum::EthEvmConfig; use reth_primitives::{constants::ETHEREUM_BLOCK_GAS_LIMIT, StorageKey, StorageValue}; use reth_provider::test_utils::{ExtendedAccount, MockEthProvider, NoopProvider}; use reth_tasks::pool::BlockingTaskPool; diff --git a/crates/rpc/rpc/src/eth/api/transactions.rs b/crates/rpc/rpc/src/eth/api/transactions.rs index 9c6161007..82b9dca19 100644 --- a/crates/rpc/rpc/src/eth/api/transactions.rs +++ b/crates/rpc/rpc/src/eth/api/transactions.rs @@ -39,7 +39,6 @@ use reth_rpc_types_compat::transaction::from_recovered_with_block_context; use reth_transaction_pool::{TransactionOrigin, TransactionPool}; use revm::{ db::CacheDB, - inspector_handle_register, primitives::{ db::DatabaseCommit, BlockEnv, CfgEnvWithHandlerCfg, EnvWithHandlerCfg, ExecutionResult, ResultAndState, SpecId, State, @@ -553,7 +552,7 @@ where DB: Database, ::Error: Into, { - let mut evm = revm::Evm::builder().with_db(db).with_env_with_handler_cfg(env).build(); + let mut evm = self.inner.evm_config.evm_with_env(db, env); let res = evm.transact()?; let (_, env) = evm.into_db_and_env_with_handler_cfg(); Ok((res, env)) @@ -570,12 +569,7 @@ where ::Error: Into, I: GetInspector, { - let mut evm = revm::Evm::builder() - .with_db(db) - .with_external_context(inspector) - .with_env_with_handler_cfg(env) - .append_handler_register(inspector_handle_register) - .build(); + let mut evm = self.inner.evm_config.evm_with_env_and_inspector(db, env, inspector); let res = evm.transact()?; let (_, env) = evm.into_db_and_env_with_handler_cfg(); Ok((res, env)) @@ -592,12 +586,7 @@ where ::Error: Into, I: GetInspector, { - let mut evm = revm::Evm::builder() - .with_external_context(inspector) - .with_db(db) - .with_env_with_handler_cfg(env) - .append_handler_register(inspector_handle_register) - .build(); + let mut evm = self.inner.evm_config.evm_with_env_and_inspector(db, env, inspector); let res = evm.transact()?; let (db, env) = evm.into_db_and_env_with_handler_cfg(); Ok((res, env, db)) @@ -617,14 +606,9 @@ where I: IntoIterator, Tx: FillableTransaction, { - let mut evm = revm::Evm::builder() - .with_db(db) - .with_env_with_handler_cfg(EnvWithHandlerCfg::new_with_cfg_env( - cfg, - block_env, - Default::default(), - )) - .build(); + let env = EnvWithHandlerCfg::new_with_cfg_env(cfg, block_env, Default::default()); + + let mut evm = self.inner.evm_config.evm_with_env(db, env); let mut index = 0; for tx in transactions.into_iter() { if tx.hash() == target_tx_hash { @@ -1817,8 +1801,8 @@ mod tests { use crate::eth::{ cache::EthStateCache, gas_oracle::GasPriceOracle, FeeHistoryCache, FeeHistoryCacheConfig, }; + use reth_evm_ethereum::EthEvmConfig; use reth_network_api::noop::NoopNetwork; - use reth_node_ethereum::EthEvmConfig; use reth_primitives::{constants::ETHEREUM_BLOCK_GAS_LIMIT, hex_literal::hex}; use reth_provider::test_utils::NoopProvider; use reth_tasks::pool::BlockingTaskPool; diff --git a/examples/custom-evm/src/main.rs b/examples/custom-evm/src/main.rs index 4a8ad03eb..bd1952f87 100644 --- a/examples/custom-evm/src/main.rs +++ b/examples/custom-evm/src/main.rs @@ -12,8 +12,9 @@ use reth::{ }, revm::{ handler::register::EvmHandler, + inspector_handle_register, precompile::{Precompile, PrecompileSpecId, Precompiles}, - Database, Evm, EvmBuilder, + Database, Evm, EvmBuilder, GetInspector, }, tasks::TaskManager, }; @@ -89,12 +90,17 @@ impl ConfigureEvm for MyEvmConfig { .build() } - fn evm_with_inspector<'a, DB: Database + 'a, I>(&self, db: DB, inspector: I) -> Evm<'a, I, DB> { + fn evm_with_inspector<'a, DB, I>(&self, db: DB, inspector: I) -> Evm<'a, I, DB> + where + DB: Database + 'a, + I: GetInspector, + { EvmBuilder::default() .with_db(db) .with_external_context(inspector) // add additional precompiles .append_handler_register(MyEvmConfig::set_precompiles) + .append_handler_register(inspector_handle_register) .build() } }