From 9322145a9cf388a7b8afee962fcbe7b103cadd42 Mon Sep 17 00:00:00 2001 From: Wodann Date: Fri, 13 Sep 2024 21:00:43 +0000 Subject: [PATCH] refactor: make ChainSpec associated type on EvmWiring --- crates/inspector/src/gas.rs | 7 +- crates/inspector/src/handler_register.rs | 6 +- crates/interpreter/src/host/dummy.rs | 11 +-- .../interpreter_action/eof_create_inputs.rs | 7 +- crates/optimism/src/lib.rs | 18 +++- crates/optimism/src/spec.rs | 23 +++-- crates/revm/src/builder.rs | 93 ++++++++++++------- crates/revm/src/context.rs | 20 ++-- crates/revm/src/context/evm_context.rs | 13 ++- crates/revm/src/context/inner_evm_context.rs | 15 ++- crates/revm/src/evm.rs | 32 ++++--- crates/revm/src/evm_wiring.rs | 6 +- crates/revm/src/handler.rs | 18 ++-- .../handler/handle_types/post_execution.rs | 10 +- .../src/handler/handle_types/validation.rs | 4 +- .../src/handler/mainnet/post_execution.rs | 6 +- crates/revm/src/handler/mainnet/validation.rs | 10 +- crates/wiring/src/default.rs | 7 +- crates/wiring/src/evm_wiring.rs | 36 ++++--- crates/wiring/src/lib.rs | 4 +- crates/wiring/src/result.rs | 22 +++-- 21 files changed, 240 insertions(+), 128 deletions(-) diff --git a/crates/inspector/src/gas.rs b/crates/inspector/src/gas.rs index f9e505993d..3be1fb6bb3 100644 --- a/crates/inspector/src/gas.rs +++ b/crates/inspector/src/gas.rs @@ -79,8 +79,9 @@ mod tests { bytecode::Bytecode, interpreter::{opcode, Interpreter}, primitives::{address, Bytes, Log, TxKind}, - wiring::EvmWiring as PrimitiveEvmWiring, - wiring::{DefaultEthereumWiring, EthereumWiring}, + wiring::{ + ChainSpec, DefaultEthereumWiring, EthereumWiring, EvmWiring as PrimitiveEvmWiring, + }, Evm, EvmWiring, }; @@ -181,7 +182,7 @@ mod tests { .with_db(BenchmarkDB::new_bytecode(bytecode.clone())) .with_default_ext_ctx() .modify_tx_env(|tx| { - *tx = ::Transaction::default(); + *tx = <::ChainSpec as ChainSpec>::Transaction::default(); tx.caller = address!("1000000000000000000000000000000000000000"); tx.transact_to = TxKind::Call(address!("0000000000000000000000000000000000000000")); diff --git a/crates/inspector/src/handler_register.rs b/crates/inspector/src/handler_register.rs index 5bfbe510dc..75ebe90a57 100644 --- a/crates/inspector/src/handler_register.rs +++ b/crates/inspector/src/handler_register.rs @@ -269,7 +269,9 @@ mod tests { database_interface::EmptyDB, interpreter::{opcode, CallInputs, CallOutcome, CreateInputs, CreateOutcome}, primitives::{address, Bytes, TxKind}, - wiring::{DefaultEthereumWiring, EthereumWiring, EvmWiring as PrimitiveEvmWiring}, + wiring::{ + ChainSpec, DefaultEthereumWiring, EthereumWiring, EvmWiring as PrimitiveEvmWiring, + }, Evm, EvmContext, EvmWiring, }; @@ -374,7 +376,7 @@ mod tests { .with_db(BenchmarkDB::new_bytecode(bytecode.clone())) .with_external_context(StackInspector::default()) .modify_tx_env(|tx| { - *tx = ::Transaction::default(); + *tx = <::ChainSpec as ChainSpec>::Transaction::default(); tx.caller = address!("1000000000000000000000000000000000000000"); tx.transact_to = TxKind::Call(address!("0000000000000000000000000000000000000000")); diff --git a/crates/interpreter/src/host/dummy.rs b/crates/interpreter/src/host/dummy.rs index 724519777d..b3973c229c 100644 --- a/crates/interpreter/src/host/dummy.rs +++ b/crates/interpreter/src/host/dummy.rs @@ -2,20 +2,17 @@ use crate::{Host, SStoreResult, SelfDestructResult}; use derive_where::derive_where; use primitives::{hash_map::Entry, Address, Bytes, HashMap, Log, B256, KECCAK_EMPTY, U256}; use std::vec::Vec; -use wiring::{ - default::{Env, EnvWiring}, - EvmWiring, -}; +use wiring::{default::EnvWiring, ChainSpec, EvmWiring}; use super::{AccountLoad, Eip7702CodeLoad, StateLoad}; /// A dummy [Host] implementation. -#[derive_where(Clone, Debug, Default; EvmWiringT::Block, EvmWiringT::Transaction)] +#[derive_where(Clone, Debug, Default; ::Block, ::Transaction)] pub struct DummyHost where EvmWiringT: EvmWiring, { - pub env: Env, + pub env: EnvWiring, pub storage: HashMap, pub transient_storage: HashMap, pub log: Vec, @@ -25,7 +22,7 @@ impl DummyHost where EvmWiringT: EvmWiring, { - /// Create a new dummy host with the given [`Env`]. + /// Create a new dummy host with the given [`EnvWiring`]. #[inline] pub fn new(env: EnvWiring) -> Self { Self { diff --git a/crates/interpreter/src/interpreter_action/eof_create_inputs.rs b/crates/interpreter/src/interpreter_action/eof_create_inputs.rs index e0bfe51243..1371751d5e 100644 --- a/crates/interpreter/src/interpreter_action/eof_create_inputs.rs +++ b/crates/interpreter/src/interpreter_action/eof_create_inputs.rs @@ -1,6 +1,6 @@ use bytecode::Eof; use primitives::{Address, Bytes, U256}; -use wiring::{EvmWiring, Transaction}; +use wiring::{ChainSpec, EvmWiring, Transaction}; /// EOF create can be called from two places: /// * EOFCREATE opcode @@ -75,7 +75,10 @@ impl EOFCreateInputs { } /// Creates new EOFCreateInputs from transaction. - pub fn new_tx(tx: &EvmWiringT::Transaction, gas_limit: u64) -> Self { + pub fn new_tx( + tx: &::Transaction, + gas_limit: u64, + ) -> Self { EOFCreateInputs::new( *tx.caller(), *tx.value(), diff --git a/crates/optimism/src/lib.rs b/crates/optimism/src/lib.rs index 3b602b6297..af5e6ef1e2 100644 --- a/crates/optimism/src/lib.rs +++ b/crates/optimism/src/lib.rs @@ -22,7 +22,7 @@ pub use l1block::{L1BlockInfo, BASE_FEE_RECIPIENT, L1_BLOCK_CONTRACT, L1_FEE_REC pub use result::{OptimismHaltReason, OptimismInvalidTransaction}; use revm::{ primitives::{Bytes, B256}, - wiring::TransactionValidation, + wiring::{ChainSpec, TransactionValidation}, }; pub use spec::*; @@ -63,8 +63,8 @@ pub trait OptimismTransaction { } /// Trait for an Optimism chain spec. -pub trait OptimismWiring: - revm::EvmWiring< +pub trait OptimismChainSpec: + ChainSpec< ChainContext: OptimismContext, Hardfork = OptimismSpecId, HaltReason = OptimismHaltReason, @@ -74,8 +74,8 @@ pub trait OptimismWiring: { } -impl OptimismWiring for EvmWiringT where - EvmWiringT: revm::EvmWiring< +impl OptimismChainSpec for ChainSpecT where + ChainSpecT: ChainSpec< ChainContext: OptimismContext, Hardfork = OptimismSpecId, HaltReason = OptimismHaltReason, @@ -84,3 +84,11 @@ impl OptimismWiring for EvmWiringT where > { } + +/// Trait for Optimism `EvmWiring`. +pub trait OptimismWiring: revm::EvmWiring {} + +impl OptimismWiring for EvmWiringT where + EvmWiringT: revm::EvmWiring +{ +} diff --git a/crates/optimism/src/spec.rs b/crates/optimism/src/spec.rs index a8be1a6690..6147782652 100644 --- a/crates/optimism/src/spec.rs +++ b/crates/optimism/src/spec.rs @@ -8,27 +8,34 @@ use revm::{ precompile::PrecompileSpecId, specification::hardfork::{Spec, SpecId}, wiring::default::block::BlockEnv, - wiring::EvmWiring, + wiring::{ChainSpec, EvmWiring}, EvmHandler, }; +#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash, PartialOrd, Ord)] +pub struct OptimismChainSpec; + +impl ChainSpec for OptimismChainSpec { + type Block = BlockEnv; + type ChainContext = Context; + type Transaction = TxEnv; + type Hardfork = OptimismSpecId; + type HaltReason = OptimismHaltReason; +} + #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash, PartialOrd, Ord)] pub struct OptimismEvmWiring { - _phantom: PhantomData<(DB, EXT)>, + phantom: PhantomData<(DB, EXT)>, } impl EvmWiring for OptimismEvmWiring { - type Block = BlockEnv; + type ChainSpec = OptimismChainSpec; type Database = DB; - type ChainContext = Context; type ExternalContext = EXT; - type Hardfork = OptimismSpecId; - type HaltReason = OptimismHaltReason; - type Transaction = TxEnv; } impl revm::EvmWiring for OptimismEvmWiring { - fn handler<'evm>(hardfork: Self::Hardfork) -> EvmHandler<'evm, Self> + fn handler<'evm>(hardfork: ::Hardfork) -> EvmHandler<'evm, Self> where DB: Database, { diff --git a/crates/revm/src/builder.rs b/crates/revm/src/builder.rs index 9630ae345e..68de1afe9a 100644 --- a/crates/revm/src/builder.rs +++ b/crates/revm/src/builder.rs @@ -6,7 +6,7 @@ use wiring::{ default::{CfgEnv, EnvWiring}, result::InvalidTransaction, transaction::TransactionValidation, - EthereumWiring, + ChainSpec, EthereumWiring, }; /// Evm Builder allows building or modifying EVM. @@ -38,8 +38,8 @@ impl<'a> Default for EvmBuilder<'a, SetGenericStage, EthereumWiring impl<'a, EvmWiringT: EvmWiring> EvmBuilder<'a, SetGenericStage, EvmWiringT> where - EvmWiringT::Transaction: Default, - EvmWiringT::Block: Default, + ::Transaction: Default, + ::Block: Default, { /// Sets the [`EvmWiring`] that will be used by [`Evm`]. pub fn new() -> EvmBuilder<'a, SetGenericStage, EvmWiringT> { @@ -47,7 +47,9 @@ where database: None, external_context: None, env: Some(Box::new(EnvWiring::::default())), - handler: EvmWiringT::handler::<'a>(EvmWiringT::Hardfork::default()), + handler: EvmWiringT::handler::<'a>( + ::Hardfork::default(), + ), phantom: PhantomData, } } @@ -73,14 +75,16 @@ impl<'a, EvmWiringT: EvmWiring> EvmBuilder<'a, SetGenericStage, EvmWiringT> { self, ) -> EvmBuilder<'a, SetGenericStage, NewEvmWiringT> where - NewEvmWiringT::Transaction: Default, - NewEvmWiringT::Block: Default, + ::Transaction: Default, + ::Block: Default, { EvmBuilder { database: None, external_context: None, env: Some(Box::new(EnvWiring::::default())), - handler: NewEvmWiringT::handler::<'a>(NewEvmWiringT::Hardfork::default()), + handler: NewEvmWiringT::handler::<'a>( + ::Hardfork::default(), + ), phantom: PhantomData, } } @@ -88,10 +92,12 @@ impl<'a, EvmWiringT: EvmWiring> EvmBuilder<'a, SetGenericStage, EvmWiringT> { pub fn reset_handler_with_external_context< NewEvmWiringT: EvmWiring< Database = EvmWiringT::Database, - Block = EvmWiringT::Block, - Transaction = EvmWiringT::Transaction, - Hardfork = EvmWiringT::Hardfork, - HaltReason = EvmWiringT::HaltReason, + ChainSpec: ChainSpec< + Block = ::Block, + Transaction = ::Transaction, + Hardfork = ::Hardfork, + HaltReason = ::HaltReason, + >, >, >( self, @@ -101,7 +107,9 @@ impl<'a, EvmWiringT: EvmWiring> EvmBuilder<'a, SetGenericStage, EvmWiringT> { external_context: None, env: self.env, // Handler that will be used by EVM. It contains handle registers - handler: NewEvmWiringT::handler::<'a>(NewEvmWiringT::Hardfork::default()), + handler: NewEvmWiringT::handler::<'a>( + ::Hardfork::default(), + ), phantom: PhantomData, } } @@ -109,10 +117,12 @@ impl<'a, EvmWiringT: EvmWiring> EvmBuilder<'a, SetGenericStage, EvmWiringT> { pub fn reset_new_database< NewEvmWiringT: EvmWiring< ExternalContext = EvmWiringT::ExternalContext, - Block = EvmWiringT::Block, - Transaction = EvmWiringT::Transaction, - Hardfork = EvmWiringT::Hardfork, - HaltReason = EvmWiringT::HaltReason, + ChainSpec: ChainSpec< + Block = ::Block, + Transaction = ::Transaction, + Hardfork = ::Hardfork, + HaltReason = ::HaltReason, + >, >, >( self, @@ -122,7 +132,9 @@ impl<'a, EvmWiringT: EvmWiring> EvmBuilder<'a, SetGenericStage, EvmWiringT> { external_context: self.external_context, env: self.env, // Handler that will be used by EVM. It contains handle registers - handler: NewEvmWiringT::handler::<'a>(NewEvmWiringT::Hardfork::default()), + handler: NewEvmWiringT::handler::<'a>( + ::Hardfork::default(), + ), phantom: PhantomData, } } @@ -130,8 +142,11 @@ impl<'a, EvmWiringT: EvmWiring> EvmBuilder<'a, SetGenericStage, EvmWiringT> { impl<'a, EvmWiringT> EvmBuilder<'a, SetGenericStage, EvmWiringT> where - EvmWiringT: - EvmWiring>>, + EvmWiringT: EvmWiring< + ChainSpec: ChainSpec< + Transaction: TransactionValidation>, + >, + >, { /// Creates the default [EvmWiring]::[crate::Database] that will be used by [`Evm`]. pub fn with_default_db(mut self) -> EvmBuilder<'a, SetGenericStage, EvmWiringT> @@ -376,25 +391,37 @@ impl<'a, BuilderStage, EvmWiringT: EvmWiring> EvmBuilder<'a, BuilderStage, EvmWi } /// Allows modification of Evm's Transaction Environment. - pub fn modify_tx_env(mut self, f: impl FnOnce(&mut EvmWiringT::Transaction)) -> Self { + pub fn modify_tx_env( + mut self, + f: impl FnOnce(&mut ::Transaction), + ) -> Self { f(&mut self.env.as_mut().unwrap().tx); self } /// Sets Evm's Transaction Environment. - pub fn with_tx_env(mut self, tx_env: EvmWiringT::Transaction) -> Self { + pub fn with_tx_env( + mut self, + tx_env: ::Transaction, + ) -> Self { self.env.as_mut().unwrap().tx = tx_env; self } /// Allows modification of Evm's Block Environment. - pub fn modify_block_env(mut self, f: impl FnOnce(&mut EvmWiringT::Block)) -> Self { + pub fn modify_block_env( + mut self, + f: impl FnOnce(&mut ::Block), + ) -> Self { f(&mut self.env.as_mut().unwrap().block); self } /// Sets Evm's Block Environment. - pub fn with_block_env(mut self, block_env: EvmWiringT::Block) -> Self { + pub fn with_block_env( + mut self, + block_env: ::Block, + ) -> Self { self.env.as_mut().unwrap().block = block_env; self } @@ -408,29 +435,30 @@ impl<'a, BuilderStage, EvmWiringT: EvmWiring> EvmBuilder<'a, BuilderStage, EvmWi impl<'a, BuilderStage, EvmWiringT> EvmBuilder<'a, BuilderStage, EvmWiringT> where - EvmWiringT: EvmWiring, + EvmWiringT: EvmWiring>, { /// Clears Block environment of EVM. pub fn with_clear_block_env(mut self) -> Self { - self.env.as_mut().unwrap().block = EvmWiringT::Block::default(); + self.env.as_mut().unwrap().block = ::Block::default(); self } } impl<'a, BuilderStage, EvmWiringT> EvmBuilder<'a, BuilderStage, EvmWiringT> where - EvmWiringT: EvmWiring, + EvmWiringT: EvmWiring>, { /// Clears Transaction environment of EVM. pub fn with_clear_tx_env(mut self) -> Self { - self.env.as_mut().unwrap().tx = EvmWiringT::Transaction::default(); + self.env.as_mut().unwrap().tx = + ::Transaction::default(); self } } impl<'a, BuilderStage, EvmWiringT> EvmBuilder<'a, BuilderStage, EvmWiringT> where - EvmWiringT: EvmWiring, + EvmWiringT: EvmWiring>, { /// Clears Environment of EVM. pub fn with_clear_env(mut self) -> Self { @@ -441,8 +469,11 @@ where impl<'a, BuilderStage, EvmWiringT: EvmWiring> EvmBuilder<'a, BuilderStage, EvmWiringT> where - EvmWiringT: - EvmWiring>>, + EvmWiringT: EvmWiring< + ChainSpec: ChainSpec< + Transaction: TransactionValidation>, + >, + >, { /// Sets specification Id , that will mark the version of EVM. /// It represent the hard fork of ethereum. @@ -451,7 +482,7 @@ where /// /// When changed it will reapply all handle registers, this can be /// expensive operation depending on registers. - pub fn with_spec_id(mut self, spec_id: EvmWiringT::Hardfork) -> Self { + pub fn with_spec_id(mut self, spec_id: ::Hardfork) -> Self { self.handler.modify_spec_id(spec_id); self } diff --git a/crates/revm/src/context.rs b/crates/revm/src/context.rs index ea6da4bc1a..6ed69fe6d8 100644 --- a/crates/revm/src/context.rs +++ b/crates/revm/src/context.rs @@ -18,10 +18,10 @@ use interpreter::{ }; use primitives::{Address, Bytes, Log, B256, BLOCK_HASH_HISTORY, U256}; use std::boxed::Box; -use wiring::{default::EnvWiring, Block, EthereumWiring}; +use wiring::{default::EnvWiring, Block, ChainSpec, EthereumWiring}; /// Main Context structure that contains both EvmContext and External context. -#[derive_where(Clone; EvmWiringT::Block, EvmWiringT::ChainContext, EvmWiringT::Transaction, EvmWiringT::Database, ::Error, EvmWiringT::ExternalContext)] +#[derive_where(Clone; ::Block, ::ChainContext, ::Transaction, EvmWiringT::Database, ::Error, EvmWiringT::ExternalContext)] pub struct Context { /// Evm Context (internal context). pub evm: EvmContext, @@ -40,8 +40,11 @@ impl Default for Context> { impl Context where - EvmWiringT: - EvmWiring, + EvmWiringT: EvmWiring< + ChainSpec: ChainSpec, + ExternalContext = (), + Database = DB, + >, { /// Creates new context with database. pub fn new_with_db(db: DB) -> Context { @@ -63,17 +66,20 @@ impl Context { } /// Context with handler configuration. -#[derive_where(Clone; EvmWiringT::Block, EvmWiringT::ChainContext, EvmWiringT::Transaction,EvmWiringT::Database, ::Error, EvmWiringT::ExternalContext)] +#[derive_where(Clone; ::Block, ::ChainContext, ::Transaction, EvmWiringT::Database, ::Error, EvmWiringT::ExternalContext)] pub struct ContextWithEvmWiring { /// Context of execution. pub context: Context, /// Handler configuration. - pub spec_id: EvmWiringT::Hardfork, + pub spec_id: ::Hardfork, } impl ContextWithEvmWiring { /// Creates new context with handler configuration. - pub fn new(context: Context, spec_id: EvmWiringT::Hardfork) -> Self { + pub fn new( + context: Context, + spec_id: ::Hardfork, + ) -> Self { Self { spec_id, context } } } diff --git a/crates/revm/src/context/evm_context.rs b/crates/revm/src/context/evm_context.rs index 22279a7dd8..8e6fca21d6 100644 --- a/crates/revm/src/context/evm_context.rs +++ b/crates/revm/src/context/evm_context.rs @@ -16,11 +16,11 @@ use std::{boxed::Box, sync::Arc}; use wiring::{ default::{CreateScheme, EnvWiring}, result::{EVMError, EVMResultGeneric}, - Transaction, + ChainSpec, Transaction, }; /// EVM context that contains the inner EVM context and precompiles. -#[derive_where(Clone, Debug; EvmWiringT::Block, EvmWiringT::ChainContext, EvmWiringT::Transaction, EvmWiringT::Database, ::Error)] +#[derive_where(Clone, Debug; ::Block, ::ChainContext, ::Transaction, EvmWiringT::Database, ::Error)] pub struct EvmContext { /// Inner EVM context. pub inner: InnerEvmContext, @@ -44,7 +44,7 @@ impl DerefMut for EvmContext { impl EvmContext where - EvmWiringT: EvmWiring, + EvmWiringT: EvmWiring>, { /// Create new context with database. pub fn new(db: EvmWiringT::Database) -> Self { @@ -73,7 +73,12 @@ where /// Note that this will ignore the previous `error` if set. #[inline] pub fn with_db< - OEvmWiring: EvmWiring, + OEvmWiring: EvmWiring< + ChainSpec: ChainSpec< + Block = ::Block, + Transaction = ::Transaction, + >, + >, >( self, db: OEvmWiring::Database, diff --git a/crates/revm/src/context/inner_evm_context.rs b/crates/revm/src/context/inner_evm_context.rs index 85770a110b..051d131510 100644 --- a/crates/revm/src/context/inner_evm_context.rs +++ b/crates/revm/src/context/inner_evm_context.rs @@ -19,11 +19,11 @@ use state::Account; use std::{boxed::Box, sync::Arc}; use wiring::{ default::{AnalysisKind, CfgEnv, EnvWiring}, - EvmWiring, Transaction, + ChainSpec, EvmWiring, Transaction, }; /// EVM contexts contains data that EVM needs for execution. -#[derive_where(Clone, Debug; EvmWiringT::Block, EvmWiringT::ChainContext, EvmWiringT::Transaction, EvmWiringT::Database, ::Error)] +#[derive_where(Clone, Debug; ::Block, ::ChainContext, ::Transaction, EvmWiringT::Database, ::Error)] pub struct InnerEvmContext { /// EVM Environment contains all the information about config, block and transaction that /// evm needs. @@ -33,14 +33,14 @@ pub struct InnerEvmContext { /// Database to load data from. pub db: EvmWiringT::Database, /// Inner context. - pub chain: EvmWiringT::ChainContext, + pub chain: ::ChainContext, /// Error that happened during execution. pub error: Result<(), ::Error>, } impl InnerEvmContext where - EvmWiringT: EvmWiring, + EvmWiringT: EvmWiring>, { pub fn new(db: EvmWiringT::Database) -> Self { Self { @@ -71,7 +71,12 @@ impl InnerEvmContext { /// Note that this will ignore the previous `error` if set. #[inline] pub fn with_db< - OWiring: EvmWiring, + OWiring: EvmWiring< + ChainSpec: ChainSpec< + Block = ::Block, + Transaction = ::Transaction, + >, + >, >( self, db: OWiring::Database, diff --git a/crates/revm/src/evm.rs b/crates/revm/src/evm.rs index 6922d08cf8..1f748f704f 100644 --- a/crates/revm/src/evm.rs +++ b/crates/revm/src/evm.rs @@ -16,7 +16,7 @@ use std::{boxed::Box, vec::Vec}; use wiring::{ default::{CfgEnv, EnvWiring}, result::{EVMError, EVMResult, EVMResultGeneric, ExecutionResult, ResultAndState}, - Transaction, + ChainSpec, Transaction, }; /// EVM call stack limit. @@ -34,8 +34,11 @@ pub struct Evm<'a, EvmWiringT: EvmWiring> { impl Debug for Evm<'_, EvmWiringT> where - EvmWiringT: - EvmWiring, + EvmWiringT: EvmWiring< + ChainSpec: ChainSpec, + Database: Debug, + ExternalContext: Debug, + >, ::Error: Debug, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { @@ -49,7 +52,10 @@ impl> Evm<'_, EvmWiringT> { /// Commit the changes to the database. pub fn transact_commit( &mut self, - ) -> EVMResultGeneric, EvmWiringT> { + ) -> EVMResultGeneric< + ExecutionResult<::HaltReason>, + EvmWiringT, + > { let ResultAndState { result, state } = self.transact()?; self.context.evm.db.commit(state); Ok(result) @@ -58,8 +64,8 @@ impl> Evm<'_, EvmWiringT> { impl<'a, EvmWiringT: EvmWiring> Evm<'a, EvmWiringT> where - EvmWiringT::Transaction: Default, - EvmWiringT::Block: Default, + ::Transaction: Default, + ::Block: Default, { /// Returns evm builder with the mainnet chain spec, empty database, and empty external context. pub fn builder() -> EvmBuilder<'a, SetGenericStage, EvmWiringT> { @@ -201,7 +207,7 @@ impl Evm<'_, EvmWiringT> { /// Returns specification (hardfork) that the EVM is instanced with. /// /// SpecId depends on the handler. - pub fn spec_id(&self) -> EvmWiringT::Hardfork { + pub fn spec_id(&self) -> ::Hardfork { self.handler.spec_id } @@ -280,13 +286,13 @@ impl Evm<'_, EvmWiringT> { /// Returns the reference of transaction #[inline] - pub fn tx(&self) -> &EvmWiringT::Transaction { + pub fn tx(&self) -> &::Transaction { &self.context.evm.env.tx } /// Returns the mutable reference of transaction #[inline] - pub fn tx_mut(&mut self) -> &mut EvmWiringT::Transaction { + pub fn tx_mut(&mut self) -> &mut ::Transaction { &mut self.context.evm.env.tx } @@ -304,18 +310,18 @@ impl Evm<'_, EvmWiringT> { /// Returns the reference of block #[inline] - pub fn block(&self) -> &EvmWiringT::Block { + pub fn block(&self) -> &::Block { &self.context.evm.env.block } /// Returns the mutable reference of block #[inline] - pub fn block_mut(&mut self) -> &mut EvmWiringT::Block { + pub fn block_mut(&mut self) -> &mut ::Block { &mut self.context.evm.env.block } /// Modify spec id, this will create new EVM that matches this spec id. - pub fn modify_spec_id(&mut self, spec_id: EvmWiringT::Hardfork) { + pub fn modify_spec_id(&mut self, spec_id: ::Hardfork) { self.context.evm.journaled_state.set_spec_id(spec_id.into()); self.handler.modify_spec_id(spec_id); } @@ -333,7 +339,7 @@ impl Evm<'_, EvmWiringT> { ) -> ( EvmWiringT::Database, Box>, - EvmWiringT::Hardfork, + ::Hardfork, ) { ( self.context.evm.inner.db, diff --git a/crates/revm/src/evm_wiring.rs b/crates/revm/src/evm_wiring.rs index 72f6a9ce23..9e42f65c95 100644 --- a/crates/revm/src/evm_wiring.rs +++ b/crates/revm/src/evm_wiring.rs @@ -7,15 +7,15 @@ use interpreter::opcode::InstructionTables; use specification::spec_to_generic; use std::fmt::Debug; use std::vec::Vec; -use wiring::{EthereumWiring, EvmWiring as PrimitiveEvmWiring}; +use wiring::{ChainSpec, EthereumWiring, EvmWiring as PrimitiveEvmWiring}; pub trait EvmWiring: PrimitiveEvmWiring { /// Creates a new handler with the given hardfork. - fn handler<'evm>(hardfork: Self::Hardfork) -> EvmHandler<'evm, Self>; + fn handler<'evm>(hardfork: ::Hardfork) -> EvmHandler<'evm, Self>; } impl EvmWiring for EthereumWiring { - fn handler<'evm>(hardfork: Self::Hardfork) -> EvmHandler<'evm, Self> + fn handler<'evm>(hardfork: ::Hardfork) -> EvmHandler<'evm, Self> where DB: Database, { diff --git a/crates/revm/src/handler.rs b/crates/revm/src/handler.rs index 60f5009184..ab5c3b4ef5 100644 --- a/crates/revm/src/handler.rs +++ b/crates/revm/src/handler.rs @@ -17,6 +17,7 @@ use std::vec::Vec; use wiring::{ result::{EVMResultGeneric, InvalidTransaction}, transaction::TransactionValidation, + ChainSpec, }; use self::register::{HandleRegister, HandleRegisterBox}; @@ -26,7 +27,7 @@ use self::register::{HandleRegister, HandleRegisterBox}; /// to disable some mainnet behavior. pub struct Handler<'a, EvmWiringT: EvmWiring, H: Host + 'a> { /// Handler hardfork - pub spec_id: EvmWiringT::Hardfork, + pub spec_id: ::Hardfork, /// Instruction table type. pub instruction_table: InstructionTables<'a, H>, /// Registers that will be called on initialization. @@ -43,11 +44,14 @@ pub struct Handler<'a, EvmWiringT: EvmWiring, H: Host + 'a> { impl<'a, EvmWiringT> EvmHandler<'a, EvmWiringT> where - EvmWiringT: - EvmWiring>>, + EvmWiringT: EvmWiring< + ChainSpec: ChainSpec< + Transaction: TransactionValidation>, + >, + >, { /// Creates a base/vanilla Ethereum handler with the provided spec id. - pub fn mainnet_with_spec(spec_id: EvmWiringT::Hardfork) -> Self { + pub fn mainnet_with_spec(spec_id: ::Hardfork) -> Self { spec_to_generic!( spec_id.into(), Self { @@ -65,7 +69,7 @@ where impl<'a, EvmWiringT: EvmWiring> EvmHandler<'a, EvmWiringT> { /// Returns the specification ID. - pub fn spec_id(&self) -> EvmWiringT::Hardfork { + pub fn spec_id(&self) -> ::Hardfork { self.spec_id } @@ -150,7 +154,7 @@ impl<'a, EvmWiringT: EvmWiring> EvmHandler<'a, EvmWiringT> { } /// Creates the Handler with variable SpecId, inside it will call function with Generic Spec. - pub fn modify_spec_id(&mut self, spec_id: EvmWiringT::Hardfork) { + pub fn modify_spec_id(&mut self, spec_id: ::Hardfork) { if self.spec_id == spec_id { return; } @@ -189,7 +193,7 @@ mod test { }; let mut handler = EvmHandler::<'_, TestEvmWiring>::mainnet_with_spec( - ::Hardfork::default(), + <::ChainSpec as ChainSpec>::Hardfork::default(), ); let test = Rc::new(RefCell::new(0)); diff --git a/crates/revm/src/handler/handle_types/post_execution.rs b/crates/revm/src/handler/handle_types/post_execution.rs index 66ca67675c..c702eb7f19 100644 --- a/crates/revm/src/handler/handle_types/post_execution.rs +++ b/crates/revm/src/handler/handle_types/post_execution.rs @@ -3,7 +3,10 @@ use crate::{handler::mainnet, Context, EvmWiring, FrameResult}; use interpreter::Gas; use specification::hardfork::Spec; use std::sync::Arc; -use wiring::result::{EVMResult, EVMResultGeneric, ResultAndState}; +use wiring::{ + result::{EVMResult, EVMResultGeneric, ResultAndState}, + ChainSpec, +}; /// Reimburse the caller with ethereum it didn't spent. pub type ReimburseCallerHandle<'a, EvmWiringT> = @@ -98,7 +101,10 @@ impl<'a, EvmWiringT: EvmWiring> PostExecutionHandler<'a, EvmWiringT> { pub fn end( &self, context: &mut Context, - end_output: EVMResultGeneric, EvmWiringT>, + end_output: EVMResultGeneric< + ResultAndState<::HaltReason>, + EvmWiringT, + >, ) -> EVMResult { (self.end)(context, end_output) } diff --git a/crates/revm/src/handler/handle_types/validation.rs b/crates/revm/src/handler/handle_types/validation.rs index 90239cede0..2858be111b 100644 --- a/crates/revm/src/handler/handle_types/validation.rs +++ b/crates/revm/src/handler/handle_types/validation.rs @@ -5,6 +5,7 @@ use wiring::{ default::EnvWiring, result::{EVMResultGeneric, InvalidTransaction}, transaction::TransactionValidation, + ChainSpec, }; /// Handle that validates env. @@ -32,7 +33,8 @@ pub struct ValidationHandler<'a, EvmWiringT: EvmWiring> { impl<'a, EvmWiringT: EvmWiring + 'a> ValidationHandler<'a, EvmWiringT> where - ::ValidationError: From, + <::Transaction as TransactionValidation>::ValidationError: + From, { /// Create new ValidationHandles pub fn new() -> Self { diff --git a/crates/revm/src/handler/mainnet/post_execution.rs b/crates/revm/src/handler/mainnet/post_execution.rs index 5cfd7d5d32..620a1eec4f 100644 --- a/crates/revm/src/handler/mainnet/post_execution.rs +++ b/crates/revm/src/handler/mainnet/post_execution.rs @@ -4,7 +4,7 @@ use primitives::U256; use specification::hardfork::{Spec, SpecId}; use wiring::{ result::{EVMError, EVMResult, EVMResultGeneric, ExecutionResult, ResultAndState}, - Block, Transaction, + Block, ChainSpec, Transaction, }; /// Mainnet end handle does not change the output. @@ -112,7 +112,9 @@ pub fn output( // reset journal and return present state. let (state, logs) = context.evm.journaled_state.finalize(); - let result = match SuccessOrHalt::::from(instruction_result.result) { + let result = match SuccessOrHalt::<::HaltReason>::from( + instruction_result.result, + ) { SuccessOrHalt::Success(reason) => ExecutionResult::Success { reason, gas_used: final_gas_used, diff --git a/crates/revm/src/handler/mainnet/validation.rs b/crates/revm/src/handler/mainnet/validation.rs index e50cdb29bb..3d954bffba 100644 --- a/crates/revm/src/handler/mainnet/validation.rs +++ b/crates/revm/src/handler/mainnet/validation.rs @@ -5,6 +5,7 @@ use wiring::{ default::EnvWiring, result::{EVMError, EVMResultGeneric, InvalidTransaction}, transaction::{Transaction, TransactionValidation}, + ChainSpec, }; /// Validate environment for the mainnet. @@ -12,7 +13,8 @@ pub fn validate_env( env: &EnvWiring, ) -> EVMResultGeneric<(), EvmWiringT> where - ::ValidationError: From, + <::Transaction as TransactionValidation>::ValidationError: + From, { // Important: validate block before tx. env.validate_block_env::()?; @@ -26,7 +28,8 @@ pub fn validate_tx_against_state( context: &mut Context, ) -> EVMResultGeneric<(), EvmWiringT> where - ::ValidationError: From, + <::Transaction as TransactionValidation>::ValidationError: + From, { // load acc let tx_caller = *context.evm.env.tx.caller(); @@ -52,7 +55,8 @@ pub fn validate_initial_tx_gas( env: &EnvWiring, ) -> EVMResultGeneric where - ::ValidationError: From, + <::Transaction as TransactionValidation>::ValidationError: + From, { let input = &env.tx.data(); let is_create = env.tx.kind().is_create(); diff --git a/crates/wiring/src/default.rs b/crates/wiring/src/default.rs index 028b801bc9..f6b9c4eaa2 100644 --- a/crates/wiring/src/default.rs +++ b/crates/wiring/src/default.rs @@ -4,6 +4,7 @@ pub mod transaction; use crate::block::blob::calc_blob_gasprice; use crate::result::InvalidHeader; use crate::transaction::TransactionValidation; +use crate::ChainSpec; use crate::{result::InvalidTransaction, Block, EvmWiring, Transaction}; use core::cmp::{min, Ordering}; use core::fmt::Debug; @@ -22,8 +23,10 @@ use std::boxed::Box; use std::vec::Vec; /// Subtype -pub type EnvWiring = - Env<::Block, ::Transaction>; +pub type EnvWiring = Env< + <::ChainSpec as ChainSpec>::Block, + <::ChainSpec as ChainSpec>::Transaction, +>; #[derive(Clone, Debug, Default)] /// EVM environment configuration. diff --git a/crates/wiring/src/evm_wiring.rs b/crates/wiring/src/evm_wiring.rs index 78b78259dc..a0005d3c0b 100644 --- a/crates/wiring/src/evm_wiring.rs +++ b/crates/wiring/src/evm_wiring.rs @@ -22,16 +22,10 @@ impl HaltReasonTrait for HaltReasonT where { } -pub trait EvmWiring: Sized { - /// External context type - type ExternalContext: Sized; - +pub trait ChainSpec: Sized { /// Chain context type. type ChainContext: Sized + Default + Debug; - /// Database type. - type Database: Database; - /// The type that contains all block information. type Block: Block; @@ -45,19 +39,37 @@ pub trait EvmWiring: Sized { type HaltReason: HaltReasonTrait; } +pub trait EvmWiring: Sized { + /// Chain specification type. + type ChainSpec: ChainSpec; + + /// External context type + type ExternalContext: Sized; + + /// Database type. + type Database: Database; +} + +#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash, PartialOrd, Ord)] +pub struct EthereumChainSpec; + +impl ChainSpec for EthereumChainSpec { + type ChainContext = (); + type Block = crate::default::block::BlockEnv; + type Transaction = crate::default::TxEnv; + type Hardfork = SpecId; + type HaltReason = crate::result::HaltReason; +} + #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash, PartialOrd, Ord)] pub struct EthereumWiring { phantom: core::marker::PhantomData<(DB, EXT)>, } impl EvmWiring for EthereumWiring { + type ChainSpec = EthereumChainSpec; type Database = DB; type ExternalContext = EXT; - type ChainContext = (); - type Block = crate::default::block::BlockEnv; - type Transaction = crate::default::TxEnv; - type Hardfork = SpecId; - type HaltReason = crate::result::HaltReason; } pub type DefaultEthereumWiring = EthereumWiring; diff --git a/crates/wiring/src/lib.rs b/crates/wiring/src/lib.rs index 1808d524c6..35b53dd510 100644 --- a/crates/wiring/src/lib.rs +++ b/crates/wiring/src/lib.rs @@ -13,7 +13,9 @@ pub mod result; pub mod transaction; pub use block::Block; -pub use evm_wiring::{DefaultEthereumWiring, EthereumWiring, EvmWiring, HaltReasonTrait}; +pub use evm_wiring::{ + ChainSpec, DefaultEthereumWiring, EthereumWiring, EvmWiring, HaltReasonTrait, +}; pub use transaction::{Transaction, TransactionValidation}; // KZG diff --git a/crates/wiring/src/result.rs b/crates/wiring/src/result.rs index 7e8dc3e7ea..8799e087db 100644 --- a/crates/wiring/src/result.rs +++ b/crates/wiring/src/result.rs @@ -1,4 +1,8 @@ -use crate::{evm_wiring::HaltReasonTrait, transaction::TransactionValidation, EvmWiring}; +use crate::{ + evm_wiring::{ChainSpec, HaltReasonTrait}, + transaction::TransactionValidation, + EvmWiring, +}; use core::fmt::{self, Debug}; use database_interface::Database; use primitives::{Address, Bytes, Log, U256}; @@ -7,16 +11,18 @@ use state::EvmState; use std::{boxed::Box, string::String, vec::Vec}; /// Result of EVM execution. -pub type EVMResult = - EVMResultGeneric::HaltReason>, EvmWiringT>; +pub type EVMResult = EVMResultGeneric< + ResultAndState<<::ChainSpec as ChainSpec>::HaltReason>, + EvmWiringT, +>; /// Generic result of EVM execution. Used to represent error and generic output. -pub type EVMResultGeneric = core::result::Result>; +pub type EVMResultGeneric = core::result::Result>; /// EVM error type for a specific chain. -pub type EVMErrorForChain = EVMError< - <::Database as Database>::Error, - <::Transaction as TransactionValidation>::ValidationError, +pub type EVMErrorForChain = EVMError< + DatabaseErrorT, + <::Transaction as TransactionValidation>::ValidationError, >; #[derive(Debug, Clone, PartialEq, Eq)] @@ -147,7 +153,7 @@ impl Output { pub type EVMErrorWiring = EVMError< <::Database as Database>::Error, - <::Transaction as TransactionValidation>::ValidationError, + <<::ChainSpec as ChainSpec>::Transaction as TransactionValidation>::ValidationError, >; /// Main EVM error.