Skip to content

Commit

Permalink
feat: upstream trace formatting from Foundry (#38)
Browse files Browse the repository at this point in the history
Will need a follow-up to add the "decoded" fields.

Ref #14
  • Loading branch information
DaniPopes authored Feb 15, 2024
1 parent e564191 commit 552f47c
Show file tree
Hide file tree
Showing 11 changed files with 564 additions and 52 deletions.
9 changes: 6 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,11 @@ alloy-sol-types = "0.6"
alloy-primitives = "0.6"
alloy-rpc-types = { git = "https://github.com/alloy-rs/alloy", rev = "b9dd518" }
alloy-rpc-trace-types = { git = "https://github.com/alloy-rs/alloy", rev = "b9dd518" }

# revm
revm = { version = "5.0", default-features = false, features = ["std"] }

anstyle = "1.0"
colorchoice = "1.0"

# js-tracing-inspector
boa_engine = { version = "0.17", optional = true }
boa_gc = { version = "0.17", optional = true }
Expand All @@ -37,6 +38,8 @@ serde = { version = "1", features = ["derive"] }
thiserror = { version = "1", optional = true }
serde_json = { version = "1", optional = true }

[dev-dependencies]
expect-test = "1.4"

[features]
default = []
js-tracer = ["boa_engine", "boa_gc", "thiserror", "serde_json"]
12 changes: 4 additions & 8 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,6 @@
html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256",
issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/"
)]
#![warn(
missing_copy_implementations,
missing_debug_implementations,
missing_docs,
unreachable_pub,
clippy::missing_const_for_fn,
rustdoc::all
)]
#![cfg_attr(not(test), warn(unused_crate_dependencies))]
#![deny(unused_must_use, rust_2018_idioms)]
#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
Expand All @@ -28,9 +20,13 @@ pub mod access_list;

/// implementation of an opcode counter for the EVM.
pub mod opcode;

/// An inspector stack abstracting the implementation details of
/// each inspector and allowing to hook on block/transaction execution,
/// used in the main RETH executor.
pub mod stack;

/// An inspector for recording traces
pub mod tracing;

pub use colorchoice::ColorChoice;
25 changes: 9 additions & 16 deletions src/tracing/builder/walker.rs
Original file line number Diff line number Diff line change
@@ -1,22 +1,20 @@
use crate::tracing::types::CallTraceNode;
use std::collections::VecDeque;

/// Traverses Reths internal tracing structure breadth-first
/// Traverses the internal tracing structure breadth-first.
///
/// This is a lazy iterator
/// This is a lazy iterator.
pub(crate) struct CallTraceNodeWalkerBF<'trace> {
/// the entire arena
/// The entire arena.
nodes: &'trace Vec<CallTraceNode>,

/// holds indexes of nodes to visit as we traverse
/// Indexes of nodes to visit as we traverse.
queue: VecDeque<usize>,
}

impl<'trace> CallTraceNodeWalkerBF<'trace> {
pub(crate) fn new(nodes: &'trace Vec<CallTraceNode>) -> Self {
let mut queue = VecDeque::with_capacity(nodes.len());
queue.push_back(0);

Self { nodes, queue }
}
}
Expand All @@ -25,15 +23,10 @@ impl<'trace> Iterator for CallTraceNodeWalkerBF<'trace> {
type Item = &'trace CallTraceNode;

fn next(&mut self) -> Option<Self::Item> {
match self.queue.pop_front() {
Some(idx) => {
let curr = self.nodes.get(idx).expect("there should be a node");

self.queue.extend(curr.children.iter());

Some(curr)
}
None => None,
}
self.queue.pop_front().map(|idx| {
let curr = &self.nodes[idx];
self.queue.extend(curr.children.iter().copied());
curr
})
}
}
28 changes: 18 additions & 10 deletions src/tracing/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
use std::ops::Range;

use self::parity::stack_push_count;
use crate::tracing::{
arena::PushTraceKind,
Expand All @@ -18,25 +16,34 @@ use revm::{
primitives::SpecId,
Database, EvmContext, Inspector, JournalEntry,
};
use types::{CallTrace, CallTraceStep};
use std::ops::Range;

mod arena;
pub use arena::CallTraceArena;

mod builder;
mod config;
mod fourbyte;
mod opcount;
pub mod types;
mod utils;
pub use arena::CallTraceArena;
pub use builder::{
geth::{self, GethTraceBuilder},
parity::{self, ParityTraceBuilder},
};

mod config;
pub use config::{StackSnapshotType, TracingInspectorConfig};

mod fourbyte;
pub use fourbyte::FourByteInspector;

mod opcount;
pub use opcount::OpcodeCountInspector;

pub mod types;
use types::{CallTrace, CallTraceStep};

mod utils;

mod writer;
pub use writer::TraceWriter;

#[cfg(feature = "js-tracer")]
pub mod js;

Expand Down Expand Up @@ -391,7 +398,8 @@ impl TracingInspector {

// The gas cost is the difference between the recorded gas remaining at the start of the
// step the remaining gas here, at the end of the step.
step.gas_cost = step.gas_remaining - self.gas_inspector.gas_remaining();
// TODO: Figure out why this can overflow. https://github.com/paradigmxyz/evm-inspectors/pull/38
step.gas_cost = step.gas_remaining.saturating_sub(self.gas_inspector.gas_remaining());

// set the status
step.status = interp.instruction_result;
Expand Down
12 changes: 2 additions & 10 deletions src/tracing/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,8 @@ pub(crate) fn maybe_revert_reason(output: &[u8]) -> Option<String> {
let reason = match GenericRevertReason::decode(output)? {
GenericRevertReason::ContractError(err) => {
match err {
ContractError::Revert(revert) => {
// return the raw revert reason and don't use the revert's display message
revert.reason
}
// return the raw revert reason and don't use the revert's display message
ContractError::Revert(revert) => revert.reason,
err => err.to_string(),
}
}
Expand All @@ -75,12 +73,6 @@ mod tests {
use super::*;
use alloy_sol_types::{GenericContractError, SolInterface};

#[test]
fn decode_empty_revert() {
let reason = GenericRevertReason::decode("".as_bytes()).map(|x| x.to_string());
assert_eq!(reason, Some("".to_string()));
}

#[test]
fn decode_revert_reason() {
let err = GenericContractError::Revert("my revert".into());
Expand Down
Loading

0 comments on commit 552f47c

Please sign in to comment.