diff --git a/crates/revm/src/evm.rs b/crates/revm/src/evm.rs index 3333c1ba31b..987fa07c235 100644 --- a/crates/revm/src/evm.rs +++ b/crates/revm/src/evm.rs @@ -1,4 +1,5 @@ use crate::primitives::{specification, EVMError, EVMResult, Env, ExecutionResult, SpecId}; +use crate::JournaledState; use crate::{ db::{Database, DatabaseCommit, DatabaseRef, RefDBWrapper}, evm_impl::{EVMImpl, Transact}, @@ -49,7 +50,7 @@ impl EVM { Ok(result) } /// Inspect transaction and commit changes to database. - pub fn inspect_commit>( + pub fn inspect_commit>( &mut self, inspector: INSP, ) -> Result> { @@ -72,7 +73,10 @@ impl EVM { } /// Execute transaction with given inspector, without wring to DB. Return change state. - pub fn inspect>(&mut self, mut inspector: INSP) -> EVMResult { + pub fn inspect>( + &mut self, + mut inspector: INSP, + ) -> EVMResult { if let Some(db) = self.db.as_mut() { evm_inner::(&mut self.env, db, &mut inspector).transact() } else { @@ -98,7 +102,7 @@ impl<'a, DB: DatabaseRef> EVM { } /// Execute transaction with given inspector, without wring to DB. Return change state. - pub fn inspect_ref>>( + pub fn inspect_ref>( &'a self, mut inspector: INSP, ) -> EVMResult { @@ -179,7 +183,7 @@ pub fn to_precompile_id(spec_id: SpecId) -> revm_precompile::SpecId { pub fn evm_inner<'a, DB: Database, const INSPECT: bool>( env: &'a mut Env, db: &'a mut DB, - insp: &'a mut dyn Inspector, + insp: &'a mut dyn Inspector, ) -> Box + 'a> { use specification::*; match env.cfg.spec_id { @@ -200,3 +204,18 @@ pub fn evm_inner<'a, DB: Database, const INSPECT: bool>( SpecId::LATEST => create_evm!(LatestSpec, db, env, insp), } } + +/// Trait that exposes internal EVM data. +pub trait EVMData { + /// Returns a mutable reference to the EVM's environment. + fn env(&mut self) -> &mut Env; + + /// Returns a mutable reference to the [`JournaledState`] of the evm. + fn journaled_state(&mut self) -> &mut JournaledState; + + /// Returns a mutable reference to the [`Database`] of the evm. + fn database(&mut self) -> &mut dyn Database; + + /// Returns a mutable reference to the last error, if one occured. + fn error(&mut self) -> &mut Option; +} diff --git a/crates/revm/src/evm_impl.rs b/crates/revm/src/evm_impl.rs index a1417ef2253..1ad1e0f1e75 100644 --- a/crates/revm/src/evm_impl.rs +++ b/crates/revm/src/evm_impl.rs @@ -1,3 +1,4 @@ +use crate::evm::EVMData; use crate::interpreter::{ analysis::to_analysed, gas, instruction_result::SuccessOrHalt, return_ok, return_revert, CallContext, CallInputs, CallScheme, Contract, CreateInputs, CreateScheme, Gas, Host, @@ -17,17 +18,35 @@ use core::{cmp::min, marker::PhantomData}; use revm_interpreter::{MAX_CODE_SIZE, MAX_INITCODE_SIZE}; use revm_precompile::{Precompile, Precompiles}; -pub struct EVMData<'a, DB: Database> { +pub struct EVMDataImpl<'a, DB: Database> { pub env: &'a mut Env, pub journaled_state: JournaledState, pub db: &'a mut DB, pub error: Option, } +impl<'a, DB: Database> EVMData for EVMDataImpl<'a, DB> { + fn env(&mut self) -> &mut Env { + &mut self.env + } + + fn journaled_state(&mut self) -> &mut JournaledState { + &mut self.journaled_state + } + + fn database(&mut self) -> &mut dyn Database { + self.db + } + + fn error(&mut self) -> &mut Option { + &mut self.error + } +} + pub struct EVMImpl<'a, GSPEC: Spec, DB: Database, const INSPECT: bool> { - data: EVMData<'a, DB>, + data: EVMDataImpl<'a, DB>, precompiles: Precompiles, - inspector: &'a mut dyn Inspector, + inspector: &'a mut dyn Inspector, _phantomdata: PhantomData, } @@ -293,7 +312,7 @@ impl<'a, GSPEC: Spec, DB: Database, const INSPECT: bool> EVMImpl<'a, GSPEC, DB, pub fn new( db: &'a mut DB, env: &'a mut Env, - inspector: &'a mut dyn Inspector, + inspector: &'a mut dyn Inspector, precompiles: Precompiles, ) -> Self { let journaled_state = if GSPEC::enabled(SpecId::SPURIOUS_DRAGON) { @@ -302,7 +321,7 @@ impl<'a, GSPEC: Spec, DB: Database, const INSPECT: bool> EVMImpl<'a, GSPEC, DB, JournaledState::new_legacy(precompiles.len()) }; Self { - data: EVMData { + data: EVMDataImpl { env, journaled_state, db, diff --git a/crates/revm/src/inspector.rs b/crates/revm/src/inspector.rs index 1058e8d680d..5ebc2121eef 100644 --- a/crates/revm/src/inspector.rs +++ b/crates/revm/src/inspector.rs @@ -1,6 +1,6 @@ -use crate::evm_impl::EVMData; +use crate::evm::EVMData; use crate::interpreter::{CallInputs, CreateInputs, Gas, InstructionResult, Interpreter}; -use crate::primitives::{db::Database, Bytes, B160, B256}; +use crate::primitives::{Bytes, B160, B256}; use auto_impl::auto_impl; @@ -22,7 +22,7 @@ pub mod inspectors { } #[auto_impl(&mut, Box)] -pub trait Inspector { +pub trait Inspector { /// Called Before the interpreter is initialized. /// /// If anything other than [InstructionResult::Continue] is returned then execution of the interpreter is @@ -30,7 +30,7 @@ pub trait Inspector { fn initialize_interp( &mut self, _interp: &mut Interpreter, - _data: &mut EVMData<'_, DB>, + _data: &mut dyn EVMData, _is_static: bool, ) -> InstructionResult { InstructionResult::Continue @@ -47,7 +47,7 @@ pub trait Inspector { fn step( &mut self, _interp: &mut Interpreter, - _data: &mut EVMData<'_, DB>, + _data: &mut dyn EVMData, _is_static: bool, ) -> InstructionResult { InstructionResult::Continue @@ -56,7 +56,7 @@ pub trait Inspector { /// Called when a log is emitted. fn log( &mut self, - _evm_data: &mut EVMData<'_, DB>, + _evm_data: &mut dyn EVMData, _address: &B160, _topics: &[B256], _data: &Bytes, @@ -69,7 +69,7 @@ pub trait Inspector { fn step_end( &mut self, _interp: &mut Interpreter, - _data: &mut EVMData<'_, DB>, + _data: &mut dyn EVMData, _is_static: bool, _eval: InstructionResult, ) -> InstructionResult { @@ -81,7 +81,7 @@ pub trait Inspector { /// InstructionResulting anything other than [InstructionResult::Continue] overrides the result of the call. fn call( &mut self, - _data: &mut EVMData<'_, DB>, + _data: &mut dyn EVMData, _inputs: &mut CallInputs, _is_static: bool, ) -> (InstructionResult, Gas, Bytes) { @@ -94,7 +94,7 @@ pub trait Inspector { /// out)`) will alter the result of the call. fn call_end( &mut self, - _data: &mut EVMData<'_, DB>, + _data: &mut dyn EVMData, _inputs: &CallInputs, remaining_gas: Gas, ret: InstructionResult, @@ -109,7 +109,7 @@ pub trait Inspector { /// InstructionResulting anything other than [InstructionResult::Continue] overrides the result of the creation. fn create( &mut self, - _data: &mut EVMData<'_, DB>, + _data: &mut dyn EVMData, _inputs: &mut CreateInputs, ) -> (InstructionResult, Option, Gas, Bytes) { ( @@ -126,7 +126,7 @@ pub trait Inspector { /// address, out)`) will alter the result of the create. fn create_end( &mut self, - _data: &mut EVMData<'_, DB>, + _data: &mut dyn EVMData, _inputs: &CreateInputs, ret: InstructionResult, address: Option, diff --git a/crates/revm/src/inspector/customprinter.rs b/crates/revm/src/inspector/customprinter.rs index c16cf298261..c7f0a21bb45 100644 --- a/crates/revm/src/inspector/customprinter.rs +++ b/crates/revm/src/inspector/customprinter.rs @@ -1,19 +1,20 @@ //! Custom print inspector, it has step level information of execution. //! It is a great tool if some debugging is needed. //! +use crate::evm::EVMData; use crate::interpreter::{opcode, CallInputs, CreateInputs, Gas, InstructionResult, Interpreter}; use crate::primitives::{hex, Bytes, B160}; -use crate::{inspectors::GasInspector, Database, EVMData, Inspector}; +use crate::{inspectors::GasInspector, Inspector}; #[derive(Clone, Default)] pub struct CustomPrintTracer { gas_inspector: GasInspector, } -impl Inspector for CustomPrintTracer { +impl Inspector for CustomPrintTracer { fn initialize_interp( &mut self, interp: &mut Interpreter, - data: &mut EVMData<'_, DB>, + data: &mut dyn EVMData, is_static: bool, ) -> InstructionResult { self.gas_inspector @@ -26,7 +27,7 @@ impl Inspector for CustomPrintTracer { fn step( &mut self, interp: &mut Interpreter, - data: &mut EVMData<'_, DB>, + data: &mut dyn EVMData, is_static: bool, ) -> InstructionResult { let opcode = interp.current_opcode(); @@ -36,7 +37,7 @@ impl Inspector for CustomPrintTracer { println!( "depth:{}, PC:{}, gas:{:#x}({}), OPCODE: {:?}({:?}) refund:{:#x}({}) Stack:{:?}, Data size:{}", - data.journaled_state.depth(), + data.journaled_state().depth(), interp.program_counter(), gas_remaining, gas_remaining, @@ -56,7 +57,7 @@ impl Inspector for CustomPrintTracer { fn step_end( &mut self, interp: &mut Interpreter, - data: &mut EVMData<'_, DB>, + data: &mut dyn EVMData, is_static: bool, eval: InstructionResult, ) -> InstructionResult { @@ -66,7 +67,7 @@ impl Inspector for CustomPrintTracer { fn call_end( &mut self, - data: &mut EVMData<'_, DB>, + data: &mut dyn EVMData, inputs: &CallInputs, remaining_gas: Gas, ret: InstructionResult, @@ -80,7 +81,7 @@ impl Inspector for CustomPrintTracer { fn create_end( &mut self, - data: &mut EVMData<'_, DB>, + data: &mut dyn EVMData, inputs: &CreateInputs, ret: InstructionResult, address: Option, @@ -94,7 +95,7 @@ impl Inspector for CustomPrintTracer { fn call( &mut self, - _data: &mut EVMData<'_, DB>, + _data: &mut dyn EVMData, inputs: &mut CallInputs, is_static: bool, ) -> (InstructionResult, Gas, Bytes) { @@ -111,7 +112,7 @@ impl Inspector for CustomPrintTracer { fn create( &mut self, - _data: &mut EVMData<'_, DB>, + _data: &mut dyn EVMData, inputs: &mut CreateInputs, ) -> (InstructionResult, Option, Gas, Bytes) { println!( diff --git a/crates/revm/src/inspector/gas.rs b/crates/revm/src/inspector/gas.rs index 85325742068..af67aac0a6b 100644 --- a/crates/revm/src/inspector/gas.rs +++ b/crates/revm/src/inspector/gas.rs @@ -1,8 +1,9 @@ //! GasIspector. Helper Inspector to calculate gas for others. //! +use crate::evm::EVMData; use crate::interpreter::{CallInputs, CreateInputs, Gas, InstructionResult}; -use crate::primitives::{db::Database, Bytes, B160}; -use crate::{evm_impl::EVMData, Inspector}; +use crate::primitives::{Bytes, B160}; +use crate::Inspector; #[allow(dead_code)] #[derive(Clone, Copy, Debug, Default)] @@ -21,12 +22,12 @@ impl GasInspector { } } -impl Inspector for GasInspector { +impl Inspector for GasInspector { #[cfg(not(feature = "no_gas_measuring"))] fn initialize_interp( &mut self, interp: &mut crate::interpreter::Interpreter, - _data: &mut EVMData<'_, DB>, + _data: &mut dyn EVMData, _is_static: bool, ) -> InstructionResult { self.gas_remaining = interp.gas.limit(); @@ -40,7 +41,7 @@ impl Inspector for GasInspector { fn step( &mut self, _interp: &mut crate::interpreter::Interpreter, - _data: &mut EVMData<'_, DB>, + _data: &mut dyn EVMData, _is_static: bool, ) -> InstructionResult { InstructionResult::Continue @@ -50,7 +51,7 @@ impl Inspector for GasInspector { fn step_end( &mut self, interp: &mut crate::interpreter::Interpreter, - _data: &mut EVMData<'_, DB>, + _data: &mut dyn EVMData, _is_static: bool, _eval: InstructionResult, ) -> InstructionResult { @@ -66,7 +67,7 @@ impl Inspector for GasInspector { fn call_end( &mut self, - _data: &mut EVMData<'_, DB>, + _data: &mut dyn EVMData, _inputs: &CallInputs, remaining_gas: Gas, ret: InstructionResult, @@ -78,7 +79,7 @@ impl Inspector for GasInspector { fn create_end( &mut self, - _data: &mut EVMData<'_, DB>, + _data: &mut dyn EVMData, _inputs: &CreateInputs, ret: InstructionResult, address: Option, @@ -92,13 +93,14 @@ impl Inspector for GasInspector { #[cfg(test)] mod tests { use crate::db::BenchmarkDB; + use crate::evm::EVMData; use crate::interpreter::{ opcode, CallInputs, CreateInputs, Gas, InstructionResult, Interpreter, OpCode, }; use crate::primitives::{ hex_literal::hex, Bytecode, Bytes, ResultAndState, TransactTo, B160, B256, }; - use crate::{inspectors::GasInspector, Database, EVMData, Inspector}; + use crate::{inspectors::GasInspector, Inspector}; #[derive(Default, Debug)] struct StackInspector { @@ -107,11 +109,11 @@ mod tests { gas_remaining_steps: Vec<(usize, u64)>, } - impl Inspector for StackInspector { + impl Inspector for StackInspector { fn initialize_interp( &mut self, interp: &mut Interpreter, - data: &mut EVMData<'_, DB>, + data: &mut dyn EVMData, is_static: bool, ) -> InstructionResult { self.gas_inspector @@ -122,7 +124,7 @@ mod tests { fn step( &mut self, interp: &mut Interpreter, - data: &mut EVMData<'_, DB>, + data: &mut dyn EVMData, is_static: bool, ) -> InstructionResult { self.pc = interp.program_counter(); @@ -132,7 +134,7 @@ mod tests { fn log( &mut self, - evm_data: &mut EVMData<'_, DB>, + evm_data: &mut dyn EVMData, address: &B160, topics: &[B256], data: &Bytes, @@ -143,7 +145,7 @@ mod tests { fn step_end( &mut self, interp: &mut Interpreter, - data: &mut EVMData<'_, DB>, + data: &mut dyn EVMData, is_static: bool, eval: InstructionResult, ) -> InstructionResult { @@ -155,7 +157,7 @@ mod tests { fn call( &mut self, - data: &mut EVMData<'_, DB>, + data: &mut dyn EVMData, call: &mut CallInputs, is_static: bool, ) -> (InstructionResult, Gas, Bytes) { @@ -170,7 +172,7 @@ mod tests { fn call_end( &mut self, - data: &mut EVMData<'_, DB>, + data: &mut dyn EVMData, inputs: &CallInputs, remaining_gas: Gas, ret: InstructionResult, @@ -184,7 +186,7 @@ mod tests { fn create( &mut self, - data: &mut EVMData<'_, DB>, + data: &mut dyn EVMData, call: &mut CreateInputs, ) -> (InstructionResult, Option, Gas, Bytes) { self.gas_inspector.create(data, call); @@ -199,7 +201,7 @@ mod tests { fn create_end( &mut self, - data: &mut EVMData<'_, DB>, + data: &mut dyn EVMData, inputs: &CreateInputs, status: InstructionResult, address: Option, diff --git a/crates/revm/src/inspector/noop.rs b/crates/revm/src/inspector/noop.rs index 41b3062b01a..981a9edd6aa 100644 --- a/crates/revm/src/inspector/noop.rs +++ b/crates/revm/src/inspector/noop.rs @@ -1,8 +1,8 @@ //! Dummy NoOp Inspector, helpful as standalone replacemnt. -use crate::{Database, Inspector}; +use crate::Inspector; #[derive(Clone, Copy)] pub struct NoOpInspector(); -impl Inspector for NoOpInspector {} +impl Inspector for NoOpInspector {} diff --git a/crates/revm/src/inspector/tracer_eip3155.rs b/crates/revm/src/inspector/tracer_eip3155.rs index a9b80c9a53c..dda6d2a737e 100644 --- a/crates/revm/src/inspector/tracer_eip3155.rs +++ b/crates/revm/src/inspector/tracer_eip3155.rs @@ -1,9 +1,10 @@ //! Inspector that support tracing of EIP-3155 https://eips.ethereum.org/EIPS/eip-3155 +use crate::evm::EVMData; use crate::inspectors::GasInspector; use crate::interpreter::{CallInputs, CreateInputs, Gas, InstructionResult}; -use crate::primitives::{db::Database, hex, Bytes, B160}; -use crate::{evm_impl::EVMData, Inspector}; +use crate::primitives::{hex, Bytes, B160}; +use crate::Inspector; use revm_interpreter::primitives::U256; use revm_interpreter::{opcode, Interpreter, Memory, Stack}; use serde_json::json; @@ -46,11 +47,11 @@ impl TracerEip3155 { } } -impl Inspector for TracerEip3155 { +impl Inspector for TracerEip3155 { fn initialize_interp( &mut self, interp: &mut Interpreter, - data: &mut EVMData<'_, DB>, + data: &mut dyn EVMData, is_static: bool, ) -> InstructionResult { self.gas_inspector @@ -63,7 +64,7 @@ impl Inspector for TracerEip3155 { fn step( &mut self, interp: &mut Interpreter, - data: &mut EVMData<'_, DB>, + data: &mut dyn EVMData, is_static: bool, ) -> InstructionResult { self.gas_inspector.step(interp, data, is_static); @@ -79,7 +80,7 @@ impl Inspector for TracerEip3155 { fn step_end( &mut self, interp: &mut Interpreter, - data: &mut EVMData<'_, DB>, + data: &mut dyn EVMData, is_static: bool, eval: InstructionResult, ) -> InstructionResult { @@ -89,23 +90,23 @@ impl Inspector for TracerEip3155 { return InstructionResult::Continue; }; - self.print_log_line(data.journaled_state.depth()); + self.print_log_line(data.journaled_state().depth()); InstructionResult::Continue } fn call( &mut self, - data: &mut EVMData<'_, DB>, + data: &mut dyn EVMData, _inputs: &mut CallInputs, _is_static: bool, ) -> (InstructionResult, Gas, Bytes) { - self.print_log_line(data.journaled_state.depth()); + self.print_log_line(data.journaled_state().depth()); (InstructionResult::Continue, Gas::new(0), Bytes::new()) } fn call_end( &mut self, - data: &mut EVMData<'_, DB>, + data: &mut dyn EVMData, inputs: &CallInputs, remaining_gas: Gas, ret: InstructionResult, @@ -116,7 +117,7 @@ impl Inspector for TracerEip3155 { .call_end(data, inputs, remaining_gas, ret, out.clone(), is_static); // self.log_step(interp, data, is_static, eval); self.skip = true; - if data.journaled_state.depth() == 0 { + if data.journaled_state().depth() == 0 { let log_line = json!({ //stateroot "output": format!("{out:?}"), @@ -137,7 +138,7 @@ impl Inspector for TracerEip3155 { fn create_end( &mut self, - data: &mut EVMData<'_, DB>, + data: &mut dyn EVMData, inputs: &CreateInputs, ret: InstructionResult, address: Option, diff --git a/crates/revm/src/lib.rs b/crates/revm/src/lib.rs index 308c778f38d..4396fb8b810 100644 --- a/crates/revm/src/lib.rs +++ b/crates/revm/src/lib.rs @@ -13,8 +13,7 @@ pub(crate) const USE_GAS: bool = !cfg!(feature = "no_gas_measuring"); pub type DummyStateDB = InMemoryDB; pub use db::{Database, DatabaseCommit, InMemoryDB}; -pub use evm::{evm_inner, new, EVM}; -pub use evm_impl::EVMData; +pub use evm::{evm_inner, new, EVMData, EVM}; pub use journaled_state::{JournalEntry, JournaledState}; extern crate alloc;