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

Write storage change in trace #213

Merged
merged 9 commits into from
Oct 16, 2024
49 changes: 48 additions & 1 deletion src/tracing/writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@ use super::{
use alloy_primitives::{address, hex, Address};
use anstyle::{AnsiColor, Color, Style};
use colorchoice::ColorChoice;
use std::io::{self, Write};
use std::{
collections::HashMap,
io::{self, Write},
};

const CHEATCODE_ADDRESS: Address = address!("7109709ECfa91a80626fF3989D68f67F5b1DD12D");

Expand Down Expand Up @@ -161,6 +164,8 @@ impl<W: Write> TraceWriter<W> {
self.indentation_level += 1;
self.write_items(nodes, idx)?;

self.write_storage_changes(node)?;

// Write return data.
self.write_edge()?;
self.write_trace_footer(&node.trace)?;
Expand Down Expand Up @@ -291,6 +296,7 @@ impl<W: Write> TraceWriter<W> {
match decoded {
DecodedTraceStep::InternalCall(call, end_idx) => {
let gas_used = node.trace.steps[*end_idx].gas_used.saturating_sub(step.gas_used);

self.write_branch()?;
self.indentation_level += 1;

Expand Down Expand Up @@ -409,6 +415,47 @@ impl<W: Write> TraceWriter<W> {
}
LOG_STYLE
}

fn write_storage_changes(&mut self, node: &CallTraceNode) -> io::Result<()> {
let mut changes_map = HashMap::new();

// For each call trace, compact the results so we do not write the intermediate storage
// writes
for step in &node.trace.steps {
if let Some(ref change) = step.storage_change {
let entry =
changes_map.entry((&step.contract, &change.key)).or_insert((None, None));
cassc marked this conversation as resolved.
Show resolved Hide resolved
if entry.0.is_none() {
entry.0 = Some(change);
}
entry.1 = Some(change);
}
}

for ((contract, key), (first_change, last_change)) in changes_map {
if let (Some(first), Some(last)) = (first_change, last_change) {
let had_value = first.had_value;
let value = last.value;

self.write_branch()?;
writeln!(
self.writer,
" storage write {} [0x{}]:",
contract.to_checksum_buffer(None).as_str(),
cassc marked this conversation as resolved.
Show resolved Hide resolved
hex::encode(key.to_be_bytes_vec())
)?;
self.write_pipes()?;
writeln!(
self.writer,
" 0x{:>64} → 0x{:>64}",
had_value.map_or("".into(), |v| hex::encode(v.to_be_bytes_vec())),
hex::encode(value.to_be_bytes_vec())
)?;
}
}

Ok(())
}
}

fn use_colors(choice: ColorChoice) -> bool {
Expand Down
Loading