Skip to content

Commit

Permalink
refactor: decouple EVMData from Inspector trait
Browse files Browse the repository at this point in the history
  • Loading branch information
Wodann committed Apr 12, 2023
1 parent dc90ac2 commit c67e9d4
Show file tree
Hide file tree
Showing 8 changed files with 105 additions and 64 deletions.
27 changes: 23 additions & 4 deletions crates/revm/src/evm.rs
Original file line number Diff line number Diff line change
@@ -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},
Expand Down Expand Up @@ -49,7 +50,7 @@ impl<DB: Database + DatabaseCommit> EVM<DB> {
Ok(result)
}
/// Inspect transaction and commit changes to database.
pub fn inspect_commit<INSP: Inspector<DB>>(
pub fn inspect_commit<INSP: Inspector<DB::Error>>(
&mut self,
inspector: INSP,
) -> Result<ExecutionResult, EVMError<DB::Error>> {
Expand All @@ -72,7 +73,10 @@ impl<DB: Database> EVM<DB> {
}

/// Execute transaction with given inspector, without wring to DB. Return change state.
pub fn inspect<INSP: Inspector<DB>>(&mut self, mut inspector: INSP) -> EVMResult<DB::Error> {
pub fn inspect<INSP: Inspector<DB::Error>>(
&mut self,
mut inspector: INSP,
) -> EVMResult<DB::Error> {
if let Some(db) = self.db.as_mut() {
evm_inner::<DB, true>(&mut self.env, db, &mut inspector).transact()
} else {
Expand All @@ -98,7 +102,7 @@ impl<'a, DB: DatabaseRef> EVM<DB> {
}

/// Execute transaction with given inspector, without wring to DB. Return change state.
pub fn inspect_ref<INSP: Inspector<RefDBWrapper<'a, DB::Error>>>(
pub fn inspect_ref<INSP: Inspector<DB::Error>>(
&'a self,
mut inspector: INSP,
) -> EVMResult<DB::Error> {
Expand Down Expand Up @@ -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<DB>,
insp: &'a mut dyn Inspector<DB::Error>,
) -> Box<dyn Transact<DB::Error> + 'a> {
use specification::*;
match env.cfg.spec_id {
Expand All @@ -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<E> {
/// 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<Error = E>;

/// Returns a mutable reference to the last error, if one occured.
fn error(&mut self) -> &mut Option<E>;
}
29 changes: 24 additions & 5 deletions crates/revm/src/evm_impl.rs
Original file line number Diff line number Diff line change
@@ -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,
Expand All @@ -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<DB::Error>,
}

impl<'a, DB: Database> EVMData<DB::Error> 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<Error = DB::Error> {
self.db
}

fn error(&mut self) -> &mut Option<DB::Error> {
&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<DB>,
inspector: &'a mut dyn Inspector<DB::Error>,
_phantomdata: PhantomData<GSPEC>,
}

Expand Down Expand Up @@ -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<DB>,
inspector: &'a mut dyn Inspector<DB::Error>,
precompiles: Precompiles,
) -> Self {
let journaled_state = if GSPEC::enabled(SpecId::SPURIOUS_DRAGON) {
Expand All @@ -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,
Expand Down
22 changes: 11 additions & 11 deletions crates/revm/src/inspector.rs
Original file line number Diff line number Diff line change
@@ -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;

Expand All @@ -22,15 +22,15 @@ pub mod inspectors {
}

#[auto_impl(&mut, Box)]
pub trait Inspector<DB: Database> {
pub trait Inspector<E> {
/// Called Before the interpreter is initialized.
///
/// If anything other than [InstructionResult::Continue] is returned then execution of the interpreter is
/// skipped.
fn initialize_interp(
&mut self,
_interp: &mut Interpreter,
_data: &mut EVMData<'_, DB>,
_data: &mut dyn EVMData<E>,
_is_static: bool,
) -> InstructionResult {
InstructionResult::Continue
Expand All @@ -47,7 +47,7 @@ pub trait Inspector<DB: Database> {
fn step(
&mut self,
_interp: &mut Interpreter,
_data: &mut EVMData<'_, DB>,
_data: &mut dyn EVMData<E>,
_is_static: bool,
) -> InstructionResult {
InstructionResult::Continue
Expand All @@ -56,7 +56,7 @@ pub trait Inspector<DB: Database> {
/// Called when a log is emitted.
fn log(
&mut self,
_evm_data: &mut EVMData<'_, DB>,
_evm_data: &mut dyn EVMData<E>,
_address: &B160,
_topics: &[B256],
_data: &Bytes,
Expand All @@ -69,7 +69,7 @@ pub trait Inspector<DB: Database> {
fn step_end(
&mut self,
_interp: &mut Interpreter,
_data: &mut EVMData<'_, DB>,
_data: &mut dyn EVMData<E>,
_is_static: bool,
_eval: InstructionResult,
) -> InstructionResult {
Expand All @@ -81,7 +81,7 @@ pub trait Inspector<DB: Database> {
/// InstructionResulting anything other than [InstructionResult::Continue] overrides the result of the call.
fn call(
&mut self,
_data: &mut EVMData<'_, DB>,
_data: &mut dyn EVMData<E>,
_inputs: &mut CallInputs,
_is_static: bool,
) -> (InstructionResult, Gas, Bytes) {
Expand All @@ -94,7 +94,7 @@ pub trait Inspector<DB: Database> {
/// out)`) will alter the result of the call.
fn call_end(
&mut self,
_data: &mut EVMData<'_, DB>,
_data: &mut dyn EVMData<E>,
_inputs: &CallInputs,
remaining_gas: Gas,
ret: InstructionResult,
Expand All @@ -109,7 +109,7 @@ pub trait Inspector<DB: Database> {
/// InstructionResulting anything other than [InstructionResult::Continue] overrides the result of the creation.
fn create(
&mut self,
_data: &mut EVMData<'_, DB>,
_data: &mut dyn EVMData<E>,
_inputs: &mut CreateInputs,
) -> (InstructionResult, Option<B160>, Gas, Bytes) {
(
Expand All @@ -126,7 +126,7 @@ pub trait Inspector<DB: Database> {
/// address, out)`) will alter the result of the create.
fn create_end(
&mut self,
_data: &mut EVMData<'_, DB>,
_data: &mut dyn EVMData<E>,
_inputs: &CreateInputs,
ret: InstructionResult,
address: Option<B160>,
Expand Down
21 changes: 11 additions & 10 deletions crates/revm/src/inspector/customprinter.rs
Original file line number Diff line number Diff line change
@@ -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<DB: Database> Inspector<DB> for CustomPrintTracer {
impl<E> Inspector<E> for CustomPrintTracer {
fn initialize_interp(
&mut self,
interp: &mut Interpreter,
data: &mut EVMData<'_, DB>,
data: &mut dyn EVMData<E>,
is_static: bool,
) -> InstructionResult {
self.gas_inspector
Expand All @@ -26,7 +27,7 @@ impl<DB: Database> Inspector<DB> for CustomPrintTracer {
fn step(
&mut self,
interp: &mut Interpreter,
data: &mut EVMData<'_, DB>,
data: &mut dyn EVMData<E>,
is_static: bool,
) -> InstructionResult {
let opcode = interp.current_opcode();
Expand All @@ -36,7 +37,7 @@ impl<DB: Database> Inspector<DB> 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,
Expand All @@ -56,7 +57,7 @@ impl<DB: Database> Inspector<DB> for CustomPrintTracer {
fn step_end(
&mut self,
interp: &mut Interpreter,
data: &mut EVMData<'_, DB>,
data: &mut dyn EVMData<E>,
is_static: bool,
eval: InstructionResult,
) -> InstructionResult {
Expand All @@ -66,7 +67,7 @@ impl<DB: Database> Inspector<DB> for CustomPrintTracer {

fn call_end(
&mut self,
data: &mut EVMData<'_, DB>,
data: &mut dyn EVMData<E>,
inputs: &CallInputs,
remaining_gas: Gas,
ret: InstructionResult,
Expand All @@ -80,7 +81,7 @@ impl<DB: Database> Inspector<DB> for CustomPrintTracer {

fn create_end(
&mut self,
data: &mut EVMData<'_, DB>,
data: &mut dyn EVMData<E>,
inputs: &CreateInputs,
ret: InstructionResult,
address: Option<B160>,
Expand All @@ -94,7 +95,7 @@ impl<DB: Database> Inspector<DB> for CustomPrintTracer {

fn call(
&mut self,
_data: &mut EVMData<'_, DB>,
_data: &mut dyn EVMData<E>,
inputs: &mut CallInputs,
is_static: bool,
) -> (InstructionResult, Gas, Bytes) {
Expand All @@ -111,7 +112,7 @@ impl<DB: Database> Inspector<DB> for CustomPrintTracer {

fn create(
&mut self,
_data: &mut EVMData<'_, DB>,
_data: &mut dyn EVMData<E>,
inputs: &mut CreateInputs,
) -> (InstructionResult, Option<B160>, Gas, Bytes) {
println!(
Expand Down
Loading

0 comments on commit c67e9d4

Please sign in to comment.