Skip to content

Commit

Permalink
feat: Add creation code printing in traces (paradigmxyz#202)
Browse files Browse the repository at this point in the history
  • Loading branch information
CodeSandwich authored and lwedge99 committed Oct 8, 2024
1 parent e6eab82 commit b6f6b64
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 8 deletions.
15 changes: 15 additions & 0 deletions src/tracing/writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ pub struct TraceWriter<W> {
use_colors: bool,
color_cheatcodes: bool,
indentation_level: u16,
write_bytecodes: bool,
}

impl<W: Write> TraceWriter<W> {
Expand All @@ -41,6 +42,7 @@ impl<W: Write> TraceWriter<W> {
use_colors: use_colors(ColorChoice::global()),
color_cheatcodes: false,
indentation_level: 0,
write_bytecodes: false,
}
}

Expand All @@ -65,6 +67,13 @@ impl<W: Write> TraceWriter<W> {
self
}

/// Sets whether contract creation codes and deployed codes should be written.
#[inline]
pub fn write_bytecodes(mut self, yes: bool) -> Self {
self.write_bytecodes = yes;
self
}

/// Returns a reference to the inner writer.
#[inline]
pub const fn writer(&self) -> &W {
Expand Down Expand Up @@ -175,6 +184,9 @@ impl<W: Write> TraceWriter<W> {
"{trace_kind_style}{CALL}new{trace_kind_style:#} {label}@{address}",
label = trace.decoded.label.as_deref().unwrap_or("<unknown>")
)?;
if self.write_bytecodes {
write!(self.writer, "({})", hex::encode(&trace.data))?;
}
} else {
let (func_name, inputs) = match &trace.decoded.call_data {
Some(DecodedCallData { signature, args }) => {
Expand Down Expand Up @@ -332,6 +344,9 @@ impl<W: Write> TraceWriter<W> {

if trace.kind.is_any_create() && trace.status.is_ok() {
write!(self.writer, "{} bytes of code", trace.output.len())?;
if self.write_bytecodes {
write!(self.writer, " ({})", hex::encode(&trace.output))?;
}
} else if !trace.output.is_empty() {
write!(self.writer, "{}", trace.output)?;
}
Expand Down
18 changes: 14 additions & 4 deletions tests/it/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,16 +113,26 @@ where
}

pub fn write_traces(tracer: &TracingInspector) -> String {
write_traces_with(tracer, ColorChoice::Never)
write_traces_with(tracer, ColorChoice::Never, false)
}

pub fn write_traces_with(tracer: &TracingInspector, color: ColorChoice) -> String {
let mut w = revm_inspectors::tracing::TraceWriter::new(Vec::<u8>::new()).use_colors(color);
pub fn write_traces_with_bytecodes(tracer: &TracingInspector) -> String {
write_traces_with(tracer, ColorChoice::Never, true)
}

pub fn write_traces_with(
tracer: &TracingInspector,
color: ColorChoice,
write_bytecodes: bool,
) -> String {
let mut w = revm_inspectors::tracing::TraceWriter::new(Vec::<u8>::new())
.use_colors(color)
.write_bytecodes(write_bytecodes);
w.write_arena(tracer.traces()).expect("failed to write traces to Vec<u8>");
String::from_utf8(w.into_writer()).expect("trace writer wrote invalid UTF-8")
}

pub fn print_traces(tracer: &TracingInspector) {
// Use `println!` so that the output is captured by the test runner.
println!("{}", write_traces_with(tracer, ColorChoice::Auto));
println!("{}", write_traces_with(tracer, ColorChoice::Auto, false));
}
20 changes: 16 additions & 4 deletions tests/it/writer.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::utils::{write_traces, TestEvm};
use alloy_primitives::{address, b256, bytes, hex, Address, Bytes, B256, U256};
use crate::utils::{write_traces, write_traces_with_bytecodes, TestEvm};
use alloy_primitives::{address, b256, bytes, hex, Address, B256, U256};
use alloy_sol_types::{sol, SolCall};
use revm_inspectors::tracing::{
types::{DecodedCallData, DecodedInternalCall, DecodedTraceStep},
Expand All @@ -11,12 +11,13 @@ use snapbox::{assert_data_eq, data::Inline, str};
fn test_trace_printing() {
// solc +0.8.26 testdata/Counter.sol --via-ir --optimize --bin
sol!("testdata/Counter.sol");
static BYTECODE: Bytes = bytes!("60808060405234601557610415908161001a8239f35b5f80fdfe6080806040526004361015610012575f80fd5b5f905f3560e01c9081630aa7318514610347575080633fb5c1cb14610326578063526f6fc5146102cb57806377fa5d9e1461026e5780638381f58a14610252578063943ee48c146101a85780639db265eb1461014e578063d09de08a146101325763f267ce9e14610081575f80fd5b346101245780600319360112610124576100996103ba565b303b1561012457604051639db265eb60e01b81528190818160048183305af180156101275761010f575b50607b90547f5ae719eb0250b8686767e291df04bec55e7f45a5997e120be020424da1896d766060604051602081526009602082015268343490333937b6901960b91b6040820152a380f35b8161011991610384565b61012457805f6100c3565b80fd5b6040513d84823e3d90fd5b503461012457806003193601126101245761014b6103ba565b80f35b503461012457806003193601126101245780547f9d39c21a43a4dfcd7857f27f3399f31a24694b6cb361496355ab537d16f745ca606060405160208152600960208201526868692066726f6d203360b81b6040820152a280f35b503461024e575f36600319011261024e575f547f9d39c21a43a4dfcd7857f27f3399f31a24694b6cb361496355ab537d16f745ca606060405160208152600960208201526868692066726f6d203160b81b6040820152a2303b1561024e57604051637933e74f60e11b81525f8160048183305af1801561024357610230575b5061014b6103ba565b61023c91505f90610384565b5f80610227565b6040513d5f823e3d90fd5b5f80fd5b3461024e575f36600319011261024e5760205f54604051908152f35b3461024e575f36600319011261024e57607b5f547f5ae719eb0250b8686767e291df04bec55e7f45a5997e120be020424da1896d76606060405160208152600c60208201526b343490333937b6903637b39960a11b6040820152a3005b3461024e575f36600319011261024e575f547f9d39c21a43a4dfcd7857f27f3399f31a24694b6cb361496355ab537d16f745ca606060405160208152600c60208201526b68692066726f6d206c6f673160a01b6040820152a2005b3461024e57602036600319011261024e576004355f55602060405160018152f35b3461024e575f36600319011261024e576080905f54815260406020820152600c60408201526b068692066726f6d206c6f67360a41b6060820152a0005b90601f8019910116810190811067ffffffffffffffff8211176103a657604052565b634e487b7160e01b5f52604160045260245ffd5b5f545f1981146103cb576001015f55565b634e487b7160e01b5f52601160045260245ffdfea2646970667358221220d26cb46e1b195f4ef2e419f8dc457a622eb5066ea0a97b4ab2619d684fe597f764736f6c634300081a0033");
static CREATION_CODE: &str = "60808060405234601557610415908161001a8239f35b5f80fdfe6080806040526004361015610012575f80fd5b5f905f3560e01c9081630aa7318514610347575080633fb5c1cb14610326578063526f6fc5146102cb57806377fa5d9e1461026e5780638381f58a14610252578063943ee48c146101a85780639db265eb1461014e578063d09de08a146101325763f267ce9e14610081575f80fd5b346101245780600319360112610124576100996103ba565b303b1561012457604051639db265eb60e01b81528190818160048183305af180156101275761010f575b50607b90547f5ae719eb0250b8686767e291df04bec55e7f45a5997e120be020424da1896d766060604051602081526009602082015268343490333937b6901960b91b6040820152a380f35b8161011991610384565b61012457805f6100c3565b80fd5b6040513d84823e3d90fd5b503461012457806003193601126101245761014b6103ba565b80f35b503461012457806003193601126101245780547f9d39c21a43a4dfcd7857f27f3399f31a24694b6cb361496355ab537d16f745ca606060405160208152600960208201526868692066726f6d203360b81b6040820152a280f35b503461024e575f36600319011261024e575f547f9d39c21a43a4dfcd7857f27f3399f31a24694b6cb361496355ab537d16f745ca606060405160208152600960208201526868692066726f6d203160b81b6040820152a2303b1561024e57604051637933e74f60e11b81525f8160048183305af1801561024357610230575b5061014b6103ba565b61023c91505f90610384565b5f80610227565b6040513d5f823e3d90fd5b5f80fd5b3461024e575f36600319011261024e5760205f54604051908152f35b3461024e575f36600319011261024e57607b5f547f5ae719eb0250b8686767e291df04bec55e7f45a5997e120be020424da1896d76606060405160208152600c60208201526b343490333937b6903637b39960a11b6040820152a3005b3461024e575f36600319011261024e575f547f9d39c21a43a4dfcd7857f27f3399f31a24694b6cb361496355ab537d16f745ca606060405160208152600c60208201526b68692066726f6d206c6f673160a01b6040820152a2005b3461024e57602036600319011261024e576004355f55602060405160018152f35b3461024e575f36600319011261024e576080905f54815260406020820152600c60408201526b068692066726f6d206c6f67360a41b6060820152a0005b90601f8019910116810190811067ffffffffffffffff8211176103a657604052565b634e487b7160e01b5f52604160045260245ffd5b5f545f1981146103cb576001015f55565b634e487b7160e01b5f52601160045260245ffdfea2646970667358221220d26cb46e1b195f4ef2e419f8dc457a622eb5066ea0a97b4ab2619d684fe597f764736f6c634300081a0033";
static DEPLOYED_CODE: &str = "6080806040526004361015610012575f80fd5b5f905f3560e01c9081630aa7318514610347575080633fb5c1cb14610326578063526f6fc5146102cb57806377fa5d9e1461026e5780638381f58a14610252578063943ee48c146101a85780639db265eb1461014e578063d09de08a146101325763f267ce9e14610081575f80fd5b346101245780600319360112610124576100996103ba565b303b1561012457604051639db265eb60e01b81528190818160048183305af180156101275761010f575b50607b90547f5ae719eb0250b8686767e291df04bec55e7f45a5997e120be020424da1896d766060604051602081526009602082015268343490333937b6901960b91b6040820152a380f35b8161011991610384565b61012457805f6100c3565b80fd5b6040513d84823e3d90fd5b503461012457806003193601126101245761014b6103ba565b80f35b503461012457806003193601126101245780547f9d39c21a43a4dfcd7857f27f3399f31a24694b6cb361496355ab537d16f745ca606060405160208152600960208201526868692066726f6d203360b81b6040820152a280f35b503461024e575f36600319011261024e575f547f9d39c21a43a4dfcd7857f27f3399f31a24694b6cb361496355ab537d16f745ca606060405160208152600960208201526868692066726f6d203160b81b6040820152a2303b1561024e57604051637933e74f60e11b81525f8160048183305af1801561024357610230575b5061014b6103ba565b61023c91505f90610384565b5f80610227565b6040513d5f823e3d90fd5b5f80fd5b3461024e575f36600319011261024e5760205f54604051908152f35b3461024e575f36600319011261024e57607b5f547f5ae719eb0250b8686767e291df04bec55e7f45a5997e120be020424da1896d76606060405160208152600c60208201526b343490333937b6903637b39960a11b6040820152a3005b3461024e575f36600319011261024e575f547f9d39c21a43a4dfcd7857f27f3399f31a24694b6cb361496355ab537d16f745ca606060405160208152600c60208201526b68692066726f6d206c6f673160a01b6040820152a2005b3461024e57602036600319011261024e576004355f55602060405160018152f35b3461024e575f36600319011261024e576080905f54815260406020820152600c60408201526b068692066726f6d206c6f67360a41b6060820152a0005b90601f8019910116810190811067ffffffffffffffff8211176103a657604052565b634e487b7160e01b5f52604160045260245ffd5b5f545f1981146103cb576001015f55565b634e487b7160e01b5f52601160045260245ffdfea2646970667358221220d26cb46e1b195f4ef2e419f8dc457a622eb5066ea0a97b4ab2619d684fe597f764736f6c634300081a0033";

let mut evm = TestEvm::new();

let mut tracer = TracingInspector::new(TracingInspectorConfig::all().disable_steps());
let address = evm.deploy(BYTECODE.clone(), &mut tracer).unwrap();
let address = evm.deploy(CREATION_CODE.parse().unwrap(), &mut tracer).unwrap();

let s = write_traces(&tracer);
assert_data_eq!(
Expand All @@ -28,6 +29,17 @@ fn test_trace_printing() {
"#]]
);

let s = write_traces_with_bytecodes(&tracer);
let raw = r#"
[209257] → new <unknown>@0xBd770416a3345F91E4B34576cb804a576fa48EB1(<CREATION_CODE>)
└─ ← [Return] 1045 bytes of code (<DEPLOYED_CODE>)
"#
.strip_prefix("\n")
.unwrap()
.replace("<CREATION_CODE>", CREATION_CODE)
.replace("<DEPLOYED_CODE>", DEPLOYED_CODE);
assert_data_eq!(s, raw);

let mut index = 0;

let mut call = |data: Vec<u8>, raw: Inline, decoded: Inline| {
Expand Down

0 comments on commit b6f6b64

Please sign in to comment.