Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 44 additions & 8 deletions crates/handler/src/evm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,49 @@ pub trait EvmTr {
&mut self,
result: <Self::Frame as FrameTr>::FrameResult,
) -> Result<Option<<Self::Frame as FrameTr>::FrameResult>, ContextDbError<Self::Context>>;

/// Run the execution loop.
#[inline]
fn run_exec_loop(
&mut self,
frame_init: <Self::Frame as FrameTr>::FrameInit,
) -> Result<<Self::Frame as FrameTr>::FrameResult, ContextDbError<Self::Context>> {
let res = self.frame_init(frame_init)?;

if let ItemOrResult::Result(frame_result) = res {
return Ok(frame_result);
}
// local depth of the call stack
let mut depth = 1;
loop {
let call_or_result = self.frame_run()?;

match call_or_result {
ItemOrResult::Item(init) => {
match self.frame_init(init)? {
ItemOrResult::Item(_) => {
depth += 1;
}
// Do not pop the frame since no new frame was created
ItemOrResult::Result(result) => {
if let Some(result) = self.frame_return_result(result)? {
return Ok(result);
}
}
}
}
ItemOrResult::Result(result) => {
self.frame_stack().pop();
depth -= 1;
// if depth is 0, return the result
if depth == 0 {
return Ok(result);
}
self.frame_return_result(result)?;
}
};
}
}
}

impl<CTX, INSP, I, P> EvmTr for Evm<CTX, INSP, I, P, EthFrame<EthInterpreter>>
Expand Down Expand Up @@ -206,11 +249,7 @@ where
.interpreter
.run_plain(instructions.instruction_table(), context);

frame.process_next_action(context, action).inspect(|i| {
if i.is_result() {
frame.set_finished(true);
}
})
frame.process_next_action(context, action)
}

/// Returns the result of the frame to the caller. Frame is popped from the frame stack.
Expand All @@ -219,9 +258,6 @@ where
&mut self,
result: <Self::Frame as FrameTr>::FrameResult,
) -> Result<Option<<Self::Frame as FrameTr>::FrameResult>, ContextDbError<Self::Context>> {
if self.frame_stack.get().is_finished() {
self.frame_stack.pop();
}
if self.frame_stack.index().is_none() {
return Ok(Some(result));
}
Expand Down
16 changes: 0 additions & 16 deletions crates/handler/src/frame.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,6 @@ pub struct EthFrame<IW: InterpreterTypes = EthInterpreter> {
pub checkpoint: JournalCheckpoint,
/// Interpreter instance for executing bytecode.
pub interpreter: Interpreter<IW>,
/// Whether the frame has been finished its execution.
/// Frame is considered finished if it has been called and returned a result.
pub is_finished: bool,
}

impl<IT: InterpreterTypes> FrameTr for EthFrame<IT> {
Expand Down Expand Up @@ -80,19 +77,8 @@ impl EthFrame<EthInterpreter> {
depth: 0,
checkpoint: JournalCheckpoint::default(),
interpreter,
is_finished: false,
}
}

/// Returns true if the frame has finished execution.
pub fn is_finished(&self) -> bool {
self.is_finished
}

/// Sets the finished state of the frame.
pub fn set_finished(&mut self, finished: bool) {
self.is_finished = finished;
}
}

/// Type alias for database errors from a context.
Expand Down Expand Up @@ -120,12 +106,10 @@ impl EthFrame<EthInterpreter> {
depth: depth_ref,
interpreter,
checkpoint: checkpoint_ref,
is_finished: is_finished_ref,
} = self;
*data_ref = data;
*input_ref = input;
*depth_ref = depth;
*is_finished_ref = false;
interpreter.clear(memory, bytecode, inputs, is_static, spec_id, gas_limit);
*checkpoint_ref = checkpoint;
}
Expand Down
46 changes: 1 addition & 45 deletions crates/handler/src/handler.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use crate::{
evm::FrameTr, execution, post_execution, pre_execution, validation, EvmTr, FrameResult,
ItemOrResult,
};
use context::{
result::{ExecutionResult, FromStringError},
Expand Down Expand Up @@ -196,7 +195,7 @@ pub trait Handler {
let first_frame_input = self.first_frame_input(evm, gas_limit)?;

// Run execution loop
let mut frame_result = self.run_exec_loop(evm, first_frame_input)?;
let mut frame_result = evm.run_exec_loop(first_frame_input)?;

// Handle last frame result
self.last_frame_result(evm, &mut frame_result)?;
Expand Down Expand Up @@ -354,49 +353,6 @@ pub trait Handler {
Ok(())
}

/* FRAMES */

/// Executes the main frame processing loop.
///
/// This loop manages the frame stack, processing each frame until execution completes.
/// For each iteration:
/// 1. Calls the current frame
/// 2. Handles the returned frame input or result
/// 3. Creates new frames or propagates results as needed
#[inline]
fn run_exec_loop(
&mut self,
evm: &mut Self::Evm,
first_frame_input: <<Self::Evm as EvmTr>::Frame as FrameTr>::FrameInit,
) -> Result<FrameResult, Self::Error> {
let res = evm.frame_init(first_frame_input)?;

if let ItemOrResult::Result(frame_result) = res {
return Ok(frame_result);
}

loop {
let call_or_result = evm.frame_run()?;

let result = match call_or_result {
ItemOrResult::Item(init) => {
match evm.frame_init(init)? {
ItemOrResult::Item(_) => {
continue;
}
// Do not pop the frame since no new frame was created
ItemOrResult::Result(result) => result,
}
}
ItemOrResult::Result(result) => result,
};

if let Some(result) = evm.frame_return_result(result)? {
return Ok(result);
}
}
}

/* POST EXECUTION */

/// Validates that the minimum gas floor requirements are satisfied.
Expand Down
49 changes: 3 additions & 46 deletions crates/inspector/src/handler.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::{Inspector, InspectorEvmTr, JournalExt};
use context::{result::ExecutionResult, ContextTr, JournalEntry, JournalTr, Transaction};
use handler::{evm::FrameTr, EvmTr, FrameResult, Handler, ItemOrResult};
use handler::{EvmTr, FrameResult, Handler};
use interpreter::{
instructions::InstructionTable,
interpreter_types::{Jumps, LoopControl},
Expand All @@ -24,7 +24,7 @@ use state::bytecode::opcode;
/// * [`Handler::run`] replaced with [`InspectorHandler::inspect_run`]
/// * [`Handler::run_without_catch_error`] replaced with [`InspectorHandler::inspect_run_without_catch_error`]
/// * [`Handler::execution`] replaced with [`InspectorHandler::inspect_execution`]
/// * [`Handler::run_exec_loop`] replaced with [`InspectorHandler::inspect_run_exec_loop`]
/// * [`EvmTr::run_exec_loop`] replaced with [`InspectorEvmTr::inspect_run_exec_loop`]
/// * `run_exec_loop` calls `inspect_frame_init` and `inspect_frame_run` that call inspector inside.
/// * [`Handler::run_system_call`] replaced with [`InspectorHandler::inspect_run_system_call`]
pub trait InspectorHandler: Handler
Expand Down Expand Up @@ -75,56 +75,13 @@ where
let first_frame_input = self.first_frame_input(evm, gas_limit)?;

// Run execution loop
let mut frame_result = self.inspect_run_exec_loop(evm, first_frame_input)?;
let mut frame_result = evm.inspect_run_exec_loop(first_frame_input)?;

// Handle last frame result
self.last_frame_result(evm, &mut frame_result)?;
Ok(frame_result)
}

/* FRAMES */

/// Run inspection on execution loop.
///
/// This method acts as [`Handler::run_exec_loop`] method for inspection.
///
/// It will call:
/// * [`Inspector::call`],[`Inspector::create`] to inspect call, create and eofcreate.
/// * [`Inspector::call_end`],[`Inspector::create_end`] to inspect call, create and eofcreate end.
/// * [`Inspector::initialize_interp`] to inspect initialized interpreter.
fn inspect_run_exec_loop(
&mut self,
evm: &mut Self::Evm,
first_frame_input: <<Self::Evm as EvmTr>::Frame as FrameTr>::FrameInit,
) -> Result<FrameResult, Self::Error> {
let res = evm.inspect_frame_init(first_frame_input)?;

if let ItemOrResult::Result(frame_result) = res {
return Ok(frame_result);
}

loop {
let call_or_result = evm.inspect_frame_run()?;

let result = match call_or_result {
ItemOrResult::Item(init) => {
match evm.inspect_frame_init(init)? {
ItemOrResult::Item(_) => {
continue;
}
// Do not pop the frame since no new frame was created
ItemOrResult::Result(result) => result,
}
}
ItemOrResult::Result(result) => result,
};

if let Some(result) = evm.frame_return_result(result)? {
return Ok(result);
}
}
}

/// Run system call with inspection support.
///
/// This method acts as [`Handler::run_system_call`] method for inspection.
Expand Down
52 changes: 51 additions & 1 deletion crates/inspector/src/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,11 +162,61 @@ pub trait InspectorEvmTr:
// TODO When all_mut fn is added we can fetch inspector at the top of the function.s
if let Some(frame) = frame.eth_frame() {
frame_end(ctx, inspector, &frame.input, frame_result);
frame.set_finished(true);
}
};
result
}

/// Run inspection on execution loop.
///
/// This method acts as [`EvmTr::run_exec_loop`] method for inspection.
///
/// It will call:
/// * [`Inspector::call`],[`Inspector::create`] to inspect call, create and eofcreate.
/// * [`Inspector::call_end`],[`Inspector::create_end`] to inspect call, create and eofcreate end.
/// * [`Inspector::initialize_interp`] to inspect initialized interpreter.
fn inspect_run_exec_loop(
&mut self,
frame_init: <Self::Frame as FrameTr>::FrameInit,
) -> Result<<Self::Frame as FrameTr>::FrameResult, ContextDbError<Self::Context>> {
let res = self.inspect_frame_init(frame_init)?;

if let ItemOrResult::Result(frame_result) = res {
return Ok(frame_result);
}

let mut depth = 1;
loop {
let call_or_result: ItemOrResult<FrameInit, FrameResult> = self.inspect_frame_run()?;

match call_or_result {
ItemOrResult::Item(init) => {
match self.inspect_frame_init(init)? {
ItemOrResult::Item(_) => {
depth += 1;
}
// Do not pop the frame since no new frame was created
ItemOrResult::Result(result) => {
self.frame_return_result(result)?;
}
}
continue;
}
ItemOrResult::Result(result) => {
self.frame_stack().pop();
// local depth of the call stack
depth -= 1;
// if depth is 0, return the result
if depth == 0 {
// pop first frame
self.frame_stack().pop();
return Ok(result);
}
self.frame_return_result(result)?;
}
};
}
}
}

/// Trait that extends the [`FrameTr`] trait with additional functionality that is needed for inspection.
Expand Down
8 changes: 4 additions & 4 deletions examples/my_evm/src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,11 @@ where
type Block = <CTX as ContextTr>::Block;

fn set_block(&mut self, block: Self::Block) {
self.0.ctx.set_block(block);
self.evm.ctx.set_block(block);
}

fn transact_one(&mut self, tx: Self::Tx) -> Result<Self::ExecutionResult, Self::Error> {
self.0.ctx.set_tx(tx);
self.evm.ctx.set_tx(tx);
let mut handler = MyHandler::default();
handler.run(self)
}
Expand Down Expand Up @@ -75,11 +75,11 @@ where
type Inspector = INSP;

fn set_inspector(&mut self, inspector: Self::Inspector) {
self.0.inspector = inspector;
self.evm.inspector = inspector;
}

fn inspect_one_tx(&mut self, tx: Self::Tx) -> Result<Self::ExecutionResult, Self::Error> {
self.0.ctx.set_tx(tx);
self.evm.ctx.set_tx(tx);
let mut handler = MyHandler::default();
handler.inspect_run(self)
}
Expand Down
Loading
Loading