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

fix(TracerEip3155): clear Inspector data after transaction. #1230

Merged
merged 6 commits into from
Mar 31, 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
85 changes: 73 additions & 12 deletions crates/revm/src/inspector/eip3155.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
use crate::{
inspectors::GasInspector,
interpreter::{opcode, CallInputs, CallOutcome, Interpreter},
interpreter::{
opcode, CallInputs, CallOutcome, CreateInputs, CreateOutcome, Interpreter,
InterpreterResult,
},
primitives::{db::Database, hex, HashMap, B256, U256},
EvmContext, Inspector,
};
Expand Down Expand Up @@ -95,6 +98,30 @@ impl TracerEip3155 {
pub fn set_writer(&mut self, writer: Box<dyn Write>) {
self.output = writer;
}

/// Resets the Tracer to its initial state of [Self::new].
/// This makes the inspector ready to be used again.
pub fn clear(&mut self) {
let Self {
gas_inspector,
stack,
pc,
opcode,
gas,
refunded,
mem_size,
skip,
..
} = self;
*gas_inspector = GasInspector::default();
stack.clear();
*pc = 0;
*opcode = 0;
*gas = 0;
*refunded = 0;
*mem_size = 0;
*skip = false;
}
}

impl TracerEip3155 {
Expand All @@ -118,6 +145,28 @@ impl TracerEip3155 {
self.output.write_all(b"\n")?;
self.output.flush()
}

fn print_summary<DB: Database>(
&mut self,
result: &InterpreterResult,
context: &mut EvmContext<DB>,
) {
if self.print_summary {
let spec_name: &str = context.spec_id().into();
let value = Summary {
state_root: B256::ZERO.to_string(),
output: result.output.to_string(),
gas_used: hex_number(
context.inner.env().tx.gas_limit - self.gas_inspector.gas_remaining(),
),
pass: result.is_ok(),

time: None,
fork: Some(spec_name.to_string()),
};
let _ = self.write_value(&value);
}
}
}

impl<DB: Database> Inspector<DB> for TracerEip3155 {
Expand Down Expand Up @@ -173,19 +222,31 @@ impl<DB: Database> Inspector<DB> for TracerEip3155 {
outcome: CallOutcome,
) -> CallOutcome {
let outcome = self.gas_inspector.call_end(context, inputs, outcome);
if self.print_summary && context.journaled_state.depth() == 0 {
let spec_name: &str = context.spec_id().into();
let value = Summary {
state_root: B256::ZERO.to_string(),
output: outcome.result.output.to_string(),
gas_used: hex_number(inputs.gas_limit - self.gas_inspector.gas_remaining()),
pass: outcome.result.is_ok(),

time: None,
fork: Some(spec_name.to_string()),
};
let _ = self.write_value(&value);
if context.journaled_state.depth() == 0 {
self.print_summary(&outcome.result, context);
// clear the state if we are at the top level
self.clear();
}

outcome
}

fn create_end(
&mut self,
context: &mut EvmContext<DB>,
inputs: &CreateInputs,
outcome: CreateOutcome,
) -> CreateOutcome {
let outcome = self.gas_inspector.create_end(context, inputs, outcome);

if context.journaled_state.depth() == 0 {
self.print_summary(&outcome.result, context);

// clear the state if we are at the top level
self.clear();
}

outcome
}
}
Expand Down
2 changes: 1 addition & 1 deletion crates/revm/src/inspector/handler_register.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ pub fn inspector_handle_register<'a, DB: Database, EXT: GetInspector<DB>>(
let call_input_stack = Rc::<RefCell<Vec<_>>>::new(RefCell::new(Vec::new()));
let create_input_stack = Rc::<RefCell<Vec<_>>>::new(RefCell::new(Vec::new()));

// Create handle
// Create handler
let create_input_stack_inner = create_input_stack.clone();
let old_handle = handler.execution.create.clone();
handler.execution.create = Arc::new(
Expand Down
4 changes: 2 additions & 2 deletions documentation/src/crates/interpreter/instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@ The `Opcode` enum represents the opcodes that are available in the Ethereum Virt

The `Instruction` struct represents a single instruction in the EVM. It contains the opcode, which is the operation to be performed, and a list of bytes representing the operands for the instruction.

## `execute` Function
## `step` Function

The `execute` function interprets an instruction. It uses the opcode to determine what operation to perform and then performs the operation using the operands in the instruction.
The `step` function interprets an instruction. It uses the opcode to determine what operation to perform and then performs the operation using the operands in the instruction.
4 changes: 2 additions & 2 deletions documentation/src/crates/revm.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ The `evm` crate is focused on the implementation of Ethereum Virtual Machine (EV
This crate pulls Primitives, Interpreter and Precompiles together to deliver the rust evm.

The starting point for reading the documentation is [`Evm`](./revm/evm.md), that is main structure of EVM.
Then, I read about the [`EvmBuilder`](./revm/builder.md) that is used to create the `Evm` and modify it.
Then, you can read about the [`EvmBuilder`](./revm/builder.md) that is used to create the `Evm` and modify it.
After, you can read about the [`Handler`](./revm/handler.md) that is used to modify the logic of the Evm, and it will tie with how Evm introspection can be done.
Finally, you can read about the [`Inspector`](./revm/inspector.md), a legacy interface for inspecting execution that is now repurposed as a handler register example.

Expand Down Expand Up @@ -34,6 +34,6 @@ Finally, you can read about the [`Inspector`](./revm/inspector.md), a legacy int

- `Database`, `DatabaseCommit`, `InMemoryDB`: These types from the `db` module are re-exported for handling the database operations.
- `EVM`: The `EVM` struct from the `evm` module is re-exported, serving as the main interface to the EVM implementation.
- `EvmContext`: The `EvmContext` struct from the `evm_impl` module is re-exported, providing data structures to encapsulate EVM execution data.
- `EvmContext`: The `EvmContext` struct from the `context` module is re-exported, providing data structures to encapsulate EVM execution data.
- `JournalEntry`, `JournaledState`: These types from the `journaled_state` module are re-exported, providing the journaling system for the EVM state.
- `inspectors`, `Inspector`: The `Inspector` trait and its implementations from the `inspector` module are re-exported for observing the EVM execution.
5 changes: 4 additions & 1 deletion examples/generate_block_traces.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use std::io::BufWriter;
use std::io::Write;
use std::sync::Arc;
use std::sync::Mutex;
use std::time::Instant;

macro_rules! local_fill {
($left:expr, $right:expr, $fun:expr) => {
Expand Down Expand Up @@ -100,7 +101,7 @@ async fn main() -> anyhow::Result<()> {
println!("Found {txs} transactions.");

let console_bar = Arc::new(ProgressBar::new(txs as u64));
let elapsed = std::time::Duration::ZERO;
let start = Instant::now();

// Create the traces directory if it doesn't exist
std::fs::create_dir_all("traces").expect("Failed to create traces directory");
Expand Down Expand Up @@ -176,6 +177,8 @@ async fn main() -> anyhow::Result<()> {
}

console_bar.finish_with_message("Finished all transactions.");

let elapsed = start.elapsed();
println!(
"Finished execution. Total CPU time: {:.6}s",
elapsed.as_secs_f64()
Expand Down
Loading