Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: refactor interpreter run and remove inspector static flag #481

Merged
merged 1 commit into from May 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 1 addition & 2 deletions crates/interpreter/src/host.rs
Expand Up @@ -10,11 +10,10 @@ pub use dummy_host::DummyHost;

/// EVM context host.
pub trait Host {
fn step(&mut self, interpreter: &mut Interpreter, is_static: bool) -> InstructionResult;
fn step(&mut self, interpreter: &mut Interpreter) -> InstructionResult;
fn step_end(
&mut self,
interpreter: &mut Interpreter,
is_static: bool,
ret: InstructionResult,
) -> InstructionResult;

Expand Down
3 changes: 1 addition & 2 deletions crates/interpreter/src/host/dummy_host.rs
Expand Up @@ -26,14 +26,13 @@ impl DummyHost {
}

impl Host for DummyHost {
fn step(&mut self, _interp: &mut Interpreter, _is_static: bool) -> InstructionResult {
fn step(&mut self, _interp: &mut Interpreter) -> InstructionResult {
InstructionResult::Continue
}

fn step_end(
&mut self,
_interp: &mut Interpreter,
_is_static: bool,
_ret: InstructionResult,
) -> InstructionResult {
InstructionResult::Continue
Expand Down
4 changes: 2 additions & 2 deletions crates/interpreter/src/interpreter.rs
Expand Up @@ -149,14 +149,14 @@ impl Interpreter {
pub fn run_inspect<H: Host, SPEC: Spec>(&mut self, host: &mut H) -> InstructionResult {
while self.instruction_result == InstructionResult::Continue {
// step
let ret = host.step(self, self.is_static);
let ret = host.step(self);
if ret != InstructionResult::Continue {
return ret;
}
self.step::<H, SPEC>(host);

// step ends
let ret = host.step_end(self, self.is_static, self.instruction_result);
let ret = host.step_end(self, self.instruction_result);
if ret != InstructionResult::Continue {
return ret;
}
Expand Down
104 changes: 48 additions & 56 deletions crates/revm/src/evm_impl.rs
Expand Up @@ -553,35 +553,19 @@ impl<'a, GSPEC: Spec, DB: Database, const INSPECT: bool> EVMImpl<'a, GSPEC, DB,
}

// Create new interpreter and execute initcode
let contract = Contract::new(
Bytes::new(),
Bytecode::new_raw(inputs.init_code.clone()),
created_address,
inputs.caller,
inputs.value,
);

#[cfg(feature = "memory_limit")]
let mut interpreter = Interpreter::new_with_memory_limit(
contract,
let (exit_reason, mut interpreter) = self.run_interpreter(
Contract::new(
Bytes::new(),
Bytecode::new_raw(inputs.init_code.clone()),
created_address,
inputs.caller,
inputs.value,
),
gas.limit(),
false,
self.data.env.cfg.memory_limit,
);

#[cfg(not(feature = "memory_limit"))]
let mut interpreter = Interpreter::new(contract, gas.limit(), false);

if INSPECT {
self.inspector
.initialize_interp(&mut interpreter, &mut self.data, false);
}
let exit_reason = if INSPECT {
interpreter.run_inspect::<Self, GSPEC>(self)
} else {
interpreter.run::<Self, GSPEC>(self)
};
// Host error if present on execution\
// Host error if present on execution
match exit_reason {
return_ok!() => {
// if ok, check contract creation limit and calculate gas deduction on output len.
Expand Down Expand Up @@ -657,6 +641,39 @@ impl<'a, GSPEC: Spec, DB: Database, const INSPECT: bool> EVMImpl<'a, GSPEC, DB,
}
}

/// Create a Interpreter and run it.
/// Returns the exit reason and created interpreter as it contains return values and gas spend.
pub fn run_interpreter(
&mut self,
contract: Contract,
gas_limit: u64,
is_static: bool,
) -> (InstructionResult, Interpreter) {
// Create inspector
#[cfg(feature = "memory_limit")]
let mut interpreter = Interpreter::new_with_memory_limit(
contract,
gas_limit,
is_static,
self.data.env.cfg.memory_limit,
);

#[cfg(not(feature = "memory_limit"))]
let mut interpreter = Interpreter::new(contract, gas_limit, is_static);

if INSPECT {
self.inspector
.initialize_interp(&mut interpreter, &mut self.data);
}
let exit_reason = if INSPECT {
interpreter.run_inspect::<Self, GSPEC>(self)
} else {
interpreter.run::<Self, GSPEC>(self)
};

(exit_reason, interpreter)
}

fn call_inner(&mut self, inputs: &mut CallInputs) -> (InstructionResult, Gas, Bytes) {
let mut gas = Gas::new(inputs.gas_limit);
// Load account and get code. Account is now hot.
Expand Down Expand Up @@ -719,31 +736,12 @@ impl<'a, GSPEC: Spec, DB: Database, const INSPECT: bool> EVMImpl<'a, GSPEC, DB,
}
} else {
// Create interpreter and execute subcall
let contract =
Contract::new_with_context(inputs.input.clone(), bytecode, &inputs.context);

#[cfg(feature = "memory_limit")]
let mut interpreter = Interpreter::new_with_memory_limit(
contract,
let (exit_reason, interpreter) = self.run_interpreter(
Contract::new_with_context(inputs.input.clone(), bytecode, &inputs.context),
gas.limit(),
inputs.is_static,
self.data.env.cfg.memory_limit,
);

#[cfg(not(feature = "memory_limit"))]
let mut interpreter = Interpreter::new(contract, gas.limit(), inputs.is_static);

if INSPECT {
// create is always no static call.
self.inspector
.initialize_interp(&mut interpreter, &mut self.data, false);
}
let exit_reason = if INSPECT {
interpreter.run_inspect::<Self, GSPEC>(self)
} else {
interpreter.run::<Self, GSPEC>(self)
};

if matches!(exit_reason, return_ok!()) {
self.data.journaled_state.checkpoint_commit();
} else {
Expand All @@ -758,18 +756,12 @@ impl<'a, GSPEC: Spec, DB: Database, const INSPECT: bool> EVMImpl<'a, GSPEC, DB,
impl<'a, GSPEC: Spec, DB: Database + 'a, const INSPECT: bool> Host
for EVMImpl<'a, GSPEC, DB, INSPECT>
{
fn step(&mut self, interp: &mut Interpreter, is_static: bool) -> InstructionResult {
self.inspector.step(interp, &mut self.data, is_static)
fn step(&mut self, interp: &mut Interpreter) -> InstructionResult {
self.inspector.step(interp, &mut self.data)
}

fn step_end(
&mut self,
interp: &mut Interpreter,
is_static: bool,
ret: InstructionResult,
) -> InstructionResult {
self.inspector
.step_end(interp, &mut self.data, is_static, ret)
fn step_end(&mut self, interp: &mut Interpreter, ret: InstructionResult) -> InstructionResult {
self.inspector.step_end(interp, &mut self.data, ret)
}

fn env(&mut self) -> &mut Env {
Expand Down
3 changes: 0 additions & 3 deletions crates/revm/src/inspector.rs
Expand Up @@ -31,7 +31,6 @@ pub trait Inspector<DB: Database> {
&mut self,
_interp: &mut Interpreter,
_data: &mut EVMData<'_, DB>,
_is_static: bool,
) -> InstructionResult {
InstructionResult::Continue
}
Expand All @@ -48,7 +47,6 @@ pub trait Inspector<DB: Database> {
&mut self,
_interp: &mut Interpreter,
_data: &mut EVMData<'_, DB>,
_is_static: bool,
) -> InstructionResult {
InstructionResult::Continue
}
Expand All @@ -70,7 +68,6 @@ pub trait Inspector<DB: Database> {
&mut self,
_interp: &mut Interpreter,
_data: &mut EVMData<'_, DB>,
_is_static: bool,
_eval: InstructionResult,
) -> InstructionResult {
InstructionResult::Continue
Expand Down
16 changes: 4 additions & 12 deletions crates/revm/src/inspector/customprinter.rs
Expand Up @@ -14,21 +14,14 @@ impl<DB: Database> Inspector<DB> for CustomPrintTracer {
&mut self,
interp: &mut Interpreter,
data: &mut EVMData<'_, DB>,
is_static: bool,
) -> InstructionResult {
self.gas_inspector
.initialize_interp(interp, data, is_static);
self.gas_inspector.initialize_interp(interp, data);
InstructionResult::Continue
}

// get opcode by calling `interp.contract.opcode(interp.program_counter())`.
// all other information can be obtained from interp.
fn step(
&mut self,
interp: &mut Interpreter,
data: &mut EVMData<'_, DB>,
is_static: bool,
) -> InstructionResult {
fn step(&mut self, interp: &mut Interpreter, data: &mut EVMData<'_, DB>) -> InstructionResult {
let opcode = interp.current_opcode();
let opcode_str = opcode::OPCODE_JUMPMAP[opcode as usize];

Expand All @@ -48,7 +41,7 @@ impl<DB: Database> Inspector<DB> for CustomPrintTracer {
interp.memory.data().len(),
);

self.gas_inspector.step(interp, data, is_static);
self.gas_inspector.step(interp, data);

InstructionResult::Continue
}
Expand All @@ -57,10 +50,9 @@ impl<DB: Database> Inspector<DB> for CustomPrintTracer {
&mut self,
interp: &mut Interpreter,
data: &mut EVMData<'_, DB>,
is_static: bool,
eval: InstructionResult,
) -> InstructionResult {
self.gas_inspector.step_end(interp, data, is_static, eval);
self.gas_inspector.step_end(interp, data, eval);
InstructionResult::Continue
}

Expand Down
13 changes: 3 additions & 10 deletions crates/revm/src/inspector/gas.rs
Expand Up @@ -27,7 +27,6 @@ impl<DB: Database> Inspector<DB> for GasInspector {
&mut self,
interp: &mut crate::interpreter::Interpreter,
_data: &mut EVMData<'_, DB>,
_is_static: bool,
) -> InstructionResult {
self.gas_remaining = interp.gas.limit();
InstructionResult::Continue
Expand All @@ -41,7 +40,6 @@ impl<DB: Database> Inspector<DB> for GasInspector {
&mut self,
_interp: &mut crate::interpreter::Interpreter,
_data: &mut EVMData<'_, DB>,
_is_static: bool,
) -> InstructionResult {
InstructionResult::Continue
}
Expand All @@ -51,7 +49,6 @@ impl<DB: Database> Inspector<DB> for GasInspector {
&mut self,
interp: &mut crate::interpreter::Interpreter,
_data: &mut EVMData<'_, DB>,
_is_static: bool,
_eval: InstructionResult,
) -> InstructionResult {
let last_gas = self.gas_remaining;
Expand Down Expand Up @@ -111,21 +108,18 @@ mod tests {
&mut self,
interp: &mut Interpreter,
data: &mut EVMData<'_, DB>,
is_static: bool,
) -> InstructionResult {
self.gas_inspector
.initialize_interp(interp, data, is_static);
self.gas_inspector.initialize_interp(interp, data);
InstructionResult::Continue
}

fn step(
&mut self,
interp: &mut Interpreter,
data: &mut EVMData<'_, DB>,
is_static: bool,
) -> InstructionResult {
self.pc = interp.program_counter();
self.gas_inspector.step(interp, data, is_static);
self.gas_inspector.step(interp, data);
InstructionResult::Continue
}

Expand All @@ -143,10 +137,9 @@ mod tests {
&mut self,
interp: &mut Interpreter,
data: &mut EVMData<'_, DB>,
is_static: bool,
eval: InstructionResult,
) -> InstructionResult {
self.gas_inspector.step_end(interp, data, is_static, eval);
self.gas_inspector.step_end(interp, data, eval);
self.gas_remaining_steps
.push((self.pc, self.gas_inspector.gas_remaining()));
eval
Expand Down
16 changes: 4 additions & 12 deletions crates/revm/src/inspector/tracer_eip3155.rs
Expand Up @@ -51,22 +51,15 @@ impl<DB: Database> Inspector<DB> for TracerEip3155 {
&mut self,
interp: &mut Interpreter,
data: &mut EVMData<'_, DB>,
is_static: bool,
) -> InstructionResult {
self.gas_inspector
.initialize_interp(interp, data, is_static);
self.gas_inspector.initialize_interp(interp, data);
InstructionResult::Continue
}

// get opcode by calling `interp.contract.opcode(interp.program_counter())`.
// all other information can be obtained from interp.
fn step(
&mut self,
interp: &mut Interpreter,
data: &mut EVMData<'_, DB>,
is_static: bool,
) -> InstructionResult {
self.gas_inspector.step(interp, data, is_static);
fn step(&mut self, interp: &mut Interpreter, data: &mut EVMData<'_, DB>) -> InstructionResult {
self.gas_inspector.step(interp, data);
self.stack = interp.stack.clone();
self.pc = interp.program_counter();
self.opcode = interp.current_opcode();
Expand All @@ -80,10 +73,9 @@ impl<DB: Database> Inspector<DB> for TracerEip3155 {
&mut self,
interp: &mut Interpreter,
data: &mut EVMData<'_, DB>,
is_static: bool,
eval: InstructionResult,
) -> InstructionResult {
self.gas_inspector.step_end(interp, data, is_static, eval);
self.gas_inspector.step_end(interp, data, eval);
if self.skip {
self.skip = false;
return InstructionResult::Continue;
Expand Down