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

feat(inspector): Share call/create inputs in Inspector call_end/create_end #1003

Merged
merged 2 commits into from
Jan 23, 2024
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions crates/revm/src/inspector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,11 @@ pub trait Inspector<DB: Database> {
fn call_end(
&mut self,
context: &mut EvmContext<DB>,
inputs: &CallInputs,
result: InterpreterResult,
) -> InterpreterResult {
let _ = context;
let _ = inputs;
result
}

Expand All @@ -122,10 +124,12 @@ pub trait Inspector<DB: Database> {
fn create_end(
&mut self,
context: &mut EvmContext<DB>,
inputs: &CreateInputs,
result: InterpreterResult,
address: Option<Address>,
) -> CreateOutcome {
let _ = context;
let _ = inputs;
CreateOutcome::new(result, address)
}

Expand Down
7 changes: 5 additions & 2 deletions crates/revm/src/inspector/customprinter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,18 +64,21 @@ impl<DB: Database> Inspector<DB> for CustomPrintTracer {
fn call_end(
&mut self,
context: &mut EvmContext<DB>,
inputs: &CallInputs,
result: InterpreterResult,
) -> InterpreterResult {
self.gas_inspector.call_end(context, result)
self.gas_inspector.call_end(context, inputs, result)
}

fn create_end(
&mut self,
context: &mut EvmContext<DB>,
inputs: &CreateInputs,
result: InterpreterResult,
address: Option<Address>,
) -> CreateOutcome {
self.gas_inspector.create_end(context, result, address)
self.gas_inspector
.create_end(context, inputs, result, address)
}

fn call(
Expand Down
7 changes: 5 additions & 2 deletions crates/revm/src/inspector/eip3155.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,9 +98,10 @@ impl<DB: Database> Inspector<DB> for TracerEip3155 {
fn call_end(
&mut self,
context: &mut EvmContext<DB>,
inputs: &CallInputs,
result: InterpreterResult,
) -> InterpreterResult {
let result = self.gas_inspector.call_end(context, result);
let result = self.gas_inspector.call_end(context, inputs, result);
if context.journaled_state.depth() == 0 {
let log_line = json!({
//stateroot
Expand All @@ -127,10 +128,12 @@ impl<DB: Database> Inspector<DB> for TracerEip3155 {
fn create_end(
&mut self,
context: &mut EvmContext<DB>,
inputs: &CreateInputs,
result: InterpreterResult,
address: Option<Address>,
) -> CreateOutcome {
self.gas_inspector.create_end(context, result, address)
self.gas_inspector
.create_end(context, inputs, result, address)
}
}

Expand Down
19 changes: 15 additions & 4 deletions crates/revm/src/inspector/gas.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
//! GasIspector. Helper Inspector to calculate gas for others.

use revm_interpreter::CreateOutcome;
use revm_interpreter::{CallInputs, CreateInputs, CreateOutcome};

use crate::{
interpreter::InterpreterResult,
primitives::{db::Database, Address},
EvmContext, Inspector,
EvmContext, GetInspector, Inspector,
};

/// Helper [Inspector] that keeps track of gas.
Expand All @@ -26,6 +26,12 @@ impl GasInspector {
}
}

impl<DB: Database> GetInspector<'_, DB> for GasInspector {
fn get_inspector(&mut self) -> &mut dyn Inspector<DB> {
self
}
}

impl<DB: Database> Inspector<DB> for GasInspector {
fn initialize_interp(
&mut self,
Expand All @@ -47,6 +53,7 @@ impl<DB: Database> Inspector<DB> for GasInspector {
fn call_end(
&mut self,
_context: &mut EvmContext<DB>,
_inputs: &CallInputs,
mut result: InterpreterResult,
) -> InterpreterResult {
if result.result.is_error() {
Expand All @@ -59,6 +66,7 @@ impl<DB: Database> Inspector<DB> for GasInspector {
fn create_end(
&mut self,
_context: &mut EvmContext<DB>,
_inputs: &CreateInputs,
result: InterpreterResult,
address: Option<Address>,
) -> CreateOutcome {
Expand Down Expand Up @@ -123,9 +131,10 @@ mod tests {
fn call_end(
&mut self,
context: &mut EvmContext<DB>,
inputs: &CallInputs,
result: InterpreterResult,
) -> InterpreterResult {
self.gas_inspector.call_end(context, result)
self.gas_inspector.call_end(context, inputs, result)
}

fn create(
Expand All @@ -140,10 +149,12 @@ mod tests {
fn create_end(
&mut self,
context: &mut EvmContext<DB>,
inputs: &CreateInputs,
result: InterpreterResult,
address: Option<Address>,
) -> CreateOutcome {
self.gas_inspector.create_end(context, result, address)
self.gas_inspector
.create_end(context, inputs, result, address)
}
}

Expand Down
47 changes: 40 additions & 7 deletions crates/revm/src/inspector/handler_register.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use core::cell::RefCell;

use crate::{
db::Database,
handler::register::{EvmHandler, EvmInstructionTables},
Expand All @@ -8,7 +10,7 @@ use crate::{
primitives::TransactTo,
CallStackFrame, Evm, FrameData, FrameOrResult, Inspector, JournalEntry,
};
use alloc::{boxed::Box, sync::Arc, vec::Vec};
use alloc::{boxed::Box, rc::Rc, sync::Arc, vec::Vec};
use revm_interpreter::{CallOutcome, CreateInputs};

pub trait GetInspector<'a, DB: Database> {
Expand Down Expand Up @@ -93,6 +95,14 @@ pub fn inspector_handle_register<'a, DB: Database, EXT: GetInspector<'a, DB>>(
inspect_log(opcode::LOG3);
inspect_log(opcode::LOG4);

// call and create input stack shared between handlers. They are used to share
// inputs in *_end Inspector calls.
let call_input_stack = Rc::<RefCell<Vec<_>>>::new(RefCell::new(Vec::new()));
let create_input_stack = Rc::<RefCell<Vec<_>>>::new(RefCell::new(Vec::new()));

let create_input_stack_inner = create_input_stack.clone();
let call_input_stack_inner = call_input_stack.clone();

// wrap first frame create and main frame return.
handler.execution_loop.create_first_frame =
Arc::new(move |context, gas_limit| -> FrameOrResult {
Expand All @@ -109,7 +119,11 @@ pub fn inspector_handle_register<'a, DB: Database, EXT: GetInspector<'a, DB>>(
return FrameOrResult::Result(output.interpreter_result);
}
// first call frame does not have return range.
context.evm.make_call_frame(&call_inputs, 0..0)
let out = context.evm.make_call_frame(&call_inputs, 0..0);
call_input_stack_inner
.borrow_mut()
.push(Box::new(call_inputs));
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does this need to be boxed?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It doesn't need to be, but in other places, it is a Box

out
}
TransactTo::Create(_) => {
let mut create_inputs =
Expand All @@ -121,7 +135,11 @@ pub fn inspector_handle_register<'a, DB: Database, EXT: GetInspector<'a, DB>>(
{
return FrameOrResult::Result(output.result);
};
context.evm.make_create_frame(spec_id, &create_inputs)
let out = context.evm.make_create_frame(spec_id, &create_inputs);
create_input_stack_inner
.borrow_mut()
.push(Box::new(create_inputs));
out
}
};

Expand Down Expand Up @@ -174,6 +192,7 @@ pub fn inspector_handle_register<'a, DB: Database, EXT: GetInspector<'a, DB>>(
));

// handle sub create
let create_input_stack_inner = create_input_stack.clone();
handler.execution_loop.sub_create = Arc::new(
move |context, frame, mut inputs| -> Option<Box<CallStackFrame>> {
let inspector = context.external.get_inspector();
Expand All @@ -185,11 +204,16 @@ pub fn inspector_handle_register<'a, DB: Database, EXT: GetInspector<'a, DB>>(
match context.evm.make_create_frame(spec_id, &inputs) {
FrameOrResult::Frame(mut new_frame) => {
inspector.initialize_interp(&mut new_frame.interpreter, &mut context.evm);
create_input_stack_inner.borrow_mut().push(inputs);
Some(new_frame)
}
FrameOrResult::Result(result) => {
let create_outcome =
inspector.create_end(&mut context.evm, result, frame.created_address());
let create_outcome = inspector.create_end(
&mut context.evm,
&inputs,
result,
frame.created_address(),
);
// insert result of the failed creation of create CallStackFrame.
frame.interpreter.insert_create_outcome(create_outcome);
None
Expand All @@ -199,6 +223,7 @@ pub fn inspector_handle_register<'a, DB: Database, EXT: GetInspector<'a, DB>>(
);

// handle sub call
let call_input_stack_inner = call_input_stack.clone();
handler.execution_loop.sub_call = Arc::new(
move |context, mut inputs, frame, memory, return_memory_offset| -> Option<Box<_>> {
// inspector handle
Expand All @@ -213,11 +238,12 @@ pub fn inspector_handle_register<'a, DB: Database, EXT: GetInspector<'a, DB>>(
{
FrameOrResult::Frame(mut new_frame) => {
inspector.initialize_interp(&mut new_frame.interpreter, &mut context.evm);
call_input_stack_inner.borrow_mut().push(inputs);
Some(new_frame)
}
FrameOrResult::Result(result) => {
// inspector handle
let result = inspector.call_end(&mut context.evm, result);
let result = inspector.call_end(&mut context.evm, &inputs, result);
let call_outcome = CallOutcome::new(result, return_memory_offset);
frame.interpreter.insert_call_outcome(memory, call_outcome);
None
Expand All @@ -233,8 +259,10 @@ pub fn inspector_handle_register<'a, DB: Database, EXT: GetInspector<'a, DB>>(
let inspector = &mut context.external.get_inspector();
result = match &mut child.frame_data {
FrameData::Create { created_address } => {
let create_input = create_input_stack.borrow_mut().pop().unwrap();
let create_outcome = inspector.create_end(
&mut context.evm,
&create_input,
result.clone(),
Some(*created_address),
);
Expand All @@ -243,7 +271,10 @@ pub fn inspector_handle_register<'a, DB: Database, EXT: GetInspector<'a, DB>>(
}
result
}
FrameData::Call { .. } => inspector.call_end(&mut context.evm, result),
FrameData::Call { .. } => {
let call_input = call_input_stack.borrow_mut().pop().unwrap();
inspector.call_end(&mut context.evm, &call_input, result)
}
};
old_handle(context, child, parent, memory, result)
},
Expand Down Expand Up @@ -359,6 +390,7 @@ mod tests {
fn call_end(
&mut self,
_context: &mut EvmContext<DB>,
_inputs: &CallInputs,
result: InterpreterResult,
) -> InterpreterResult {
if self.call_end {
Expand All @@ -379,6 +411,7 @@ mod tests {
fn create_end(
&mut self,
_context: &mut EvmContext<DB>,
_inputs: &CreateInputs,
result: InterpreterResult,
address: Option<Address>,
) -> CreateOutcome {
Expand Down
Loading