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
10 changes: 10 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ members = [
"examples/database_components",
"examples/uniswap_get_reserves",
"examples/uniswap_v2_usdc_swap",
"examples/erc20_gas",
"examples/erc20_gas", "examples/inspector_with_lifetime",
#"examples/custom_opcodes",
]
resolver = "2"
Expand Down
1 change: 1 addition & 0 deletions crates/inspector/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ state.workspace = true
interpreter.workspace = true

auto_impl.workspace = true
derive-where.workspace = true

# Optional
serde = { workspace = true, features = ["derive", "rc"], optional = true }
Expand Down
11 changes: 8 additions & 3 deletions crates/inspector/src/eip3155.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::inspectors::GasInspector;
use crate::Inspector;
use context::{Cfg, ContextTr, JournalTr, Transaction};
use core::marker::PhantomData;
use interpreter::{
interpreter_types::{Jumps, LoopControl, MemoryTr, RuntimeFlag, StackTr, SubRoutineStack},
CallInputs, CallOutcome, CreateInputs, CreateOutcome, Interpreter, InterpreterResult,
Expand All @@ -12,7 +13,7 @@ use state::bytecode::opcode::OpCode;
use std::io::Write;

/// [EIP-3155](https://eips.ethereum.org/EIPS/eip-3155) tracer [Inspector].
pub struct TracerEip3155 {
pub struct TracerEip3155<CTX> {
output: Box<dyn Write>,
gas_inspector: GasInspector,
/// Print summary of the execution.
Expand All @@ -28,6 +29,7 @@ pub struct TracerEip3155 {
skip: bool,
include_memory: bool,
memory: Option<String>,
phantom: PhantomData<CTX>,
}

// # Output
Expand Down Expand Up @@ -107,7 +109,7 @@ struct Summary {
fork: Option<String>,
}

impl TracerEip3155 {
impl<CTX> TracerEip3155<CTX> {
/// Creates a new EIP-3155 tracer with the given output writer, by first wrapping it in a
/// [`BufWriter`](std::io::BufWriter).
pub fn buffered(output: impl Write + 'static) -> Self {
Expand All @@ -131,6 +133,7 @@ impl TracerEip3155 {
refunded: 0,
mem_size: 0,
skip: false,
phantom: PhantomData,
}
}

Expand Down Expand Up @@ -208,11 +211,13 @@ impl CloneStack for Stack {
}
}

impl<CTX, INTR> Inspector<CTX, INTR> for TracerEip3155
impl<CTX, INTR> Inspector<INTR> for TracerEip3155<CTX>
where
CTX: ContextTr,
INTR: InterpreterTypes<Stack: StackTr + CloneStack>,
{
type Context<'context> = CTX;

fn initialize_interp(&mut self, interp: &mut Interpreter<INTR>, _: &mut CTX) {
self.gas_inspector.initialize_interp(interp.control.gas());
}
Expand Down
12 changes: 9 additions & 3 deletions crates/inspector/src/gas.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,13 @@ impl GasInspector {

#[cfg(test)]
mod tests {
use core::marker::PhantomData;

use super::*;
use crate::{InspectEvm, Inspector};
use context::Context;
use database::{BenchmarkDB, BENCH_CALLER, BENCH_TARGET};
use derive_where::derive_where;
use handler::{MainBuilder, MainContext};
use interpreter::{
interpreter_types::{Jumps, LoopControl},
Expand All @@ -79,14 +82,17 @@ mod tests {
use primitives::{Bytes, TxKind};
use state::bytecode::{opcode, Bytecode};

#[derive(Default, Debug)]
struct StackInspector {
#[derive_where(Default, Debug)]
struct StackInspector<CTX> {
pc: usize,
gas_inspector: GasInspector,
gas_remaining_steps: Vec<(usize, u64)>,
phantom: PhantomData<CTX>,
}

impl<CTX, INTR: InterpreterTypes> Inspector<CTX, INTR> for StackInspector {
impl<CTX, INTR: InterpreterTypes> Inspector<INTR> for StackInspector<CTX> {
type Context<'context> = CTX;

fn initialize_interp(&mut self, interp: &mut Interpreter<INTR>, _context: &mut CTX) {
self.gas_inspector.initialize_interp(interp.control.gas());
}
Expand Down
67 changes: 45 additions & 22 deletions crates/inspector/src/inspector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,19 @@ use std::{vec, vec::Vec};

/// EVM hooks into execution.
#[auto_impl(&mut, Box)]
pub trait Inspector<CTX, INTR: InterpreterTypes = EthInterpreter> {
pub trait Inspector<INTR: InterpreterTypes = EthInterpreter> {
type Context<'context>;

/// Called before the interpreter is initialized.
///
/// If `interp.instruction_result` is set to anything other than [InstructionResult::Continue] then the execution of the interpreter
/// is skipped.
#[inline]
fn initialize_interp(&mut self, interp: &mut Interpreter<INTR>, context: &mut CTX) {
fn initialize_interp(
&mut self,
interp: &mut Interpreter<INTR>,
context: &mut Self::Context<'_>,
) {
let _ = interp;
let _ = context;
}
Expand All @@ -35,7 +41,7 @@ pub trait Inspector<CTX, INTR: InterpreterTypes = EthInterpreter> {
///
/// To get the current opcode, use `interp.current_opcode()`.
#[inline]
fn step(&mut self, interp: &mut Interpreter<INTR>, context: &mut CTX) {
fn step(&mut self, interp: &mut Interpreter<INTR>, context: &mut Self::Context<'_>) {
let _ = interp;
let _ = context;
}
Expand All @@ -45,14 +51,14 @@ pub trait Inspector<CTX, INTR: InterpreterTypes = EthInterpreter> {
/// Setting `interp.instruction_result` to anything other than [InstructionResult::Continue] alters the execution
/// of the interpreter.
#[inline]
fn step_end(&mut self, interp: &mut Interpreter<INTR>, context: &mut CTX) {
fn step_end(&mut self, interp: &mut Interpreter<INTR>, context: &mut Self::Context<'_>) {
let _ = interp;
let _ = context;
}

/// Called when a log is emitted.
#[inline]
fn log(&mut self, interp: &mut Interpreter<INTR>, context: &mut CTX, log: Log) {
fn log(&mut self, interp: &mut Interpreter<INTR>, context: &mut Self::Context<'_>, log: Log) {
let _ = interp;
let _ = context;
let _ = log;
Expand All @@ -62,7 +68,11 @@ pub trait Inspector<CTX, INTR: InterpreterTypes = EthInterpreter> {
///
/// InstructionResulting anything other than [InstructionResult::Continue] overrides the result of the call.
#[inline]
fn call(&mut self, context: &mut CTX, inputs: &mut CallInputs) -> Option<CallOutcome> {
fn call(
&mut self,
context: &mut Self::Context<'_>,
inputs: &mut CallInputs,
) -> Option<CallOutcome> {
let _ = context;
let _ = inputs;
None
Expand All @@ -74,7 +84,12 @@ pub trait Inspector<CTX, INTR: InterpreterTypes = EthInterpreter> {
///
/// This allows the inspector to modify the given `result` before returning it.
#[inline]
fn call_end(&mut self, context: &mut CTX, inputs: &CallInputs, outcome: &mut CallOutcome) {
fn call_end(
&mut self,
context: &mut Self::Context<'_>,
inputs: &CallInputs,
outcome: &mut CallOutcome,
) {
let _ = context;
let _ = inputs;
let _ = outcome;
Expand All @@ -86,7 +101,11 @@ pub trait Inspector<CTX, INTR: InterpreterTypes = EthInterpreter> {
///
/// If this returns `None` then the creation proceeds as normal.
#[inline]
fn create(&mut self, context: &mut CTX, inputs: &mut CreateInputs) -> Option<CreateOutcome> {
fn create(
&mut self,
context: &mut Self::Context<'_>,
inputs: &mut CreateInputs,
) -> Option<CreateOutcome> {
let _ = context;
let _ = inputs;
None
Expand All @@ -99,7 +118,7 @@ pub trait Inspector<CTX, INTR: InterpreterTypes = EthInterpreter> {
#[inline]
fn create_end(
&mut self,
context: &mut CTX,
context: &mut Self::Context<'_>,
inputs: &CreateInputs,
outcome: &mut CreateOutcome,
) {
Expand All @@ -113,7 +132,7 @@ pub trait Inspector<CTX, INTR: InterpreterTypes = EthInterpreter> {
/// This can happen from create TX or from EOFCREATE opcode.
fn eofcreate(
&mut self,
context: &mut CTX,
context: &mut Self::Context<'_>,
inputs: &mut EOFCreateInputs,
) -> Option<CreateOutcome> {
let _ = context;
Expand All @@ -124,7 +143,7 @@ pub trait Inspector<CTX, INTR: InterpreterTypes = EthInterpreter> {
/// Called when eof creating has ended.
fn eofcreate_end(
&mut self,
context: &mut CTX,
context: &mut Self::Context<'_>,
inputs: &EOFCreateInputs,
outcome: &mut CreateOutcome,
) {
Expand Down Expand Up @@ -177,8 +196,12 @@ impl<DB: Database> JournalExt for Journal<DB> {

pub trait InspectorHandler: Handler
where
Self::Evm:
InspectorEvmTr<Inspector: Inspector<<<Self as Handler>::Evm as EvmTr>::Context, Self::IT>>,
Self::Evm: InspectorEvmTr<
Inspector: for<'context> Inspector<
Self::IT,
Context<'context> = <<Self as Handler>::Evm as EvmTr>::Context,
>,
>,
Self::Frame: InspectorFrame<IT = Self::IT>,
{
type IT: InterpreterTypes;
Expand Down Expand Up @@ -307,9 +330,9 @@ where
}
}

fn frame_start<CTX, INTR: InterpreterTypes>(
context: &mut CTX,
inspector: &mut impl Inspector<CTX, INTR>,
fn frame_start<'context, CTX, INTR: InterpreterTypes>(
context: &'context mut CTX,
inspector: &mut impl Inspector<INTR, Context<'context> = CTX>,
frame_input: &mut FrameInput,
) -> Option<FrameResult> {
match frame_input {
Expand All @@ -332,9 +355,9 @@ fn frame_start<CTX, INTR: InterpreterTypes>(
None
}

fn frame_end<CTX, INTR: InterpreterTypes>(
context: &mut CTX,
inspector: &mut impl Inspector<CTX, INTR>,
fn frame_end<'context, CTX, INTR: InterpreterTypes>(
context: &'context mut CTX,
inspector: &mut impl Inspector<INTR, Context<'context> = CTX>,
frame_input: &FrameInput,
frame_output: &mut FrameResult,
) {
Expand All @@ -360,10 +383,10 @@ fn frame_end<CTX, INTR: InterpreterTypes>(
}
}

pub fn inspect_instructions<CTX, IT>(
context: &mut CTX,
pub fn inspect_instructions<'context, CTX, IT>(
context: &'context mut CTX,
interpreter: &mut Interpreter<IT>,
mut inspector: impl Inspector<CTX, IT>,
mut inspector: impl Inspector<IT, Context<'context> = CTX>,
instructions: &InstructionTable<IT, CTX>,
) -> InterpreterAction
where
Expand Down
9 changes: 6 additions & 3 deletions crates/inspector/src/mainnet_inspect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@ impl<EVM, ERROR, FRAME> InspectorHandler for MainnetHandler<EVM, ERROR, FRAME>
where
EVM: InspectorEvmTr<
Context: ContextTr<Journal: JournalTr<FinalOutput = JournalOutput>>,
Inspector: Inspector<<<Self as Handler>::Evm as EvmTr>::Context, EthInterpreter>,
Inspector: for<'context> Inspector<
EthInterpreter,
Context<'context> = <<Self as Handler>::Evm as EvmTr>::Context,
>,
>,
ERROR: EvmTrError<EVM>,
FRAME: Frame<Evm = EVM, Error = ERROR, FrameResult = FrameResult, FrameInit = FrameInput>
Expand All @@ -28,7 +31,7 @@ impl<CTX, INSP, PRECOMPILES> InspectEvm
for Evm<CTX, INSP, EthInstructions<EthInterpreter, CTX>, PRECOMPILES>
where
CTX: ContextSetters + ContextTr<Journal: JournalTr<FinalOutput = JournalOutput> + JournalExt>,
INSP: Inspector<CTX, EthInterpreter>,
INSP: for<'context> Inspector<EthInterpreter, Context<'context> = CTX>,
PRECOMPILES: PrecompileProvider<CTX, Output = InterpreterResult>,
{
type Inspector = INSP;
Expand All @@ -51,7 +54,7 @@ impl<CTX, INSP, PRECOMPILES> InspectCommitEvm
where
CTX: ContextSetters
+ ContextTr<Journal: JournalTr<FinalOutput = JournalOutput> + JournalExt, Db: DatabaseCommit>,
INSP: Inspector<CTX, EthInterpreter>,
INSP: for<'context> Inspector<EthInterpreter, Context<'context> = CTX>,
PRECOMPILES: PrecompileProvider<CTX, Output = InterpreterResult>,
{
fn inspect_commit_previous(&mut self) -> Self::CommitOutput {
Expand Down
13 changes: 10 additions & 3 deletions crates/inspector/src/noop.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
use core::marker::PhantomData;

use crate::inspector::Inspector;
use derive_where::derive_where;
use interpreter::InterpreterTypes;

/// Dummy [Inspector], helpful as standalone replacement.
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct NoOpInspector {}
#[derive_where(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct NoOpInspector<CTX> {
phantom: PhantomData<CTX>,
}

impl<CTX, INTR: InterpreterTypes> Inspector<CTX, INTR> for NoOpInspector {}
impl<CTX, INTR: InterpreterTypes> Inspector<INTR> for NoOpInspector<CTX> {
type Context<'context> = CTX;
}
2 changes: 1 addition & 1 deletion crates/inspector/src/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ where
Context = CTX,
InterpreterTypes: InterpreterTypes<Output = InterpreterAction>,
>,
INSP: Inspector<CTX, I::InterpreterTypes>,
INSP: for<'context> Inspector<I::InterpreterTypes, Context<'context> = CTX>,
{
type Inspector = INSP;

Expand Down
2 changes: 1 addition & 1 deletion crates/optimism/src/api/default_ctx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ mod test {
fn default_run_op() {
let ctx = Context::op();
// convert to optimism context
let mut evm = ctx.build_op_with_inspector(NoOpInspector {});
let mut evm = ctx.build_op_with_inspector(NoOpInspector::default());
// execute
let _ = evm.replay();
// inspect
Expand Down
4 changes: 2 additions & 2 deletions crates/optimism/src/api/exec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ impl<CTX, INSP, PRECOMPILE> InspectEvm
for OpEvm<CTX, INSP, EthInstructions<EthInterpreter, CTX>, PRECOMPILE>
where
CTX: OpContextTr<Journal: JournalExt> + ContextSetters,
INSP: Inspector<CTX, EthInterpreter>,
INSP: for<'context> Inspector<EthInterpreter, Context<'context> = CTX>,
PRECOMPILE: PrecompileProvider<CTX, Output = InterpreterResult>,
{
type Inspector = INSP;
Expand All @@ -103,7 +103,7 @@ impl<CTX, INSP, PRECOMPILE> InspectCommitEvm
for OpEvm<CTX, INSP, EthInstructions<EthInterpreter, CTX>, PRECOMPILE>
where
CTX: OpContextTr<Journal: JournalExt, Db: DatabaseCommit> + ContextSetters,
INSP: Inspector<CTX, EthInterpreter>,
INSP: for<'context> Inspector<EthInterpreter, Context<'context> = CTX>,
PRECOMPILE: PrecompileProvider<CTX, Output = InterpreterResult>,
{
fn inspect_commit_previous(&mut self) -> Self::CommitOutput {
Expand Down
2 changes: 1 addition & 1 deletion crates/optimism/src/evm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ where
Context = CTX,
InterpreterTypes: InterpreterTypes<Output = InterpreterAction>,
>,
INSP: Inspector<CTX, I::InterpreterTypes>,
INSP: for<'context> Inspector<I::InterpreterTypes, Context<'context> = CTX>,
{
type Inspector = INSP;

Expand Down
Loading
Loading