Skip to content

Commit

Permalink
[wip] feat: identify internal function invocations in traces
Browse files Browse the repository at this point in the history
  • Loading branch information
klkvr committed Jun 21, 2024
1 parent 806e1c9 commit 3b2b1fe
Show file tree
Hide file tree
Showing 19 changed files with 505 additions and 208 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ foundry-compilers = { version = "0.8.0", default-features = false }
# no default features to avoid c-kzg
revm = { version = "9.0.0", default-features = false }
revm-primitives = { version = "4.0.0", default-features = false }
revm-inspectors = { git = "https://github.com/paradigmxyz/revm-inspectors", rev = "4fe17f0", features = [
revm-inspectors = { git = "https://github.com/klkvr/evm-inspectors", rev = "f9f953e", features = [
"serde",
] }

Expand Down
8 changes: 6 additions & 2 deletions crates/cast/bin/cmd/call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ pub struct CallArgs {
#[arg(long, requires = "trace")]
debug: bool,

#[arg(long, requires = "trace")]
decode_internal: bool,

/// Labels to apply to the traces; format: `address:label`.
/// Can only be used with `--trace`.
#[arg(long, requires = "trace")]
Expand Down Expand Up @@ -106,6 +109,7 @@ impl CallArgs {
trace,
evm_version,
debug,
decode_internal,
labels,
data,
} = self;
Expand Down Expand Up @@ -159,7 +163,7 @@ impl CallArgs {
}

let (env, fork, chain) = TracingExecutor::get_fork_material(&config, evm_opts).await?;
let mut executor = TracingExecutor::new(env, fork, evm_version, debug);
let mut executor = TracingExecutor::new(env, fork, evm_version, debug, decode_internal);

let value = tx.value.unwrap_or_default();
let input = tx.inner.input.into_input().unwrap_or_default();
Expand All @@ -175,7 +179,7 @@ impl CallArgs {
),
};

handle_traces(trace, &config, chain, labels, debug).await?;
handle_traces(trace, &config, chain, labels, debug, decode_internal).await?;

return Ok(());
}
Expand Down
8 changes: 6 additions & 2 deletions crates/cast/bin/cmd/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ pub struct RunArgs {
#[arg(long, short)]
debug: bool,

/// Whether to identify internal functions in traces.
#[arg(long)]
decode_internal: bool,

/// Print out opcode traces.
#[arg(long, short)]
trace_printer: bool,
Expand Down Expand Up @@ -142,7 +146,7 @@ impl RunArgs {
}
}

let mut executor = TracingExecutor::new(env.clone(), fork, evm_version, self.debug);
let mut executor = TracingExecutor::new(env.clone(), fork, evm_version, self.debug, self.decode_internal);
let mut env =
EnvWithHandlerCfg::new_with_spec_id(Box::new(env.clone()), executor.spec_id());

Expand Down Expand Up @@ -220,7 +224,7 @@ impl RunArgs {
}
};

handle_traces(result, &config, chain, self.label, self.debug).await?;
handle_traces(result, &config, chain, self.label, self.debug, self.decode_internal).await?;

Ok(())
}
Expand Down
30 changes: 22 additions & 8 deletions crates/cli/src/utils/cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,13 @@ use foundry_compilers::{
Artifact, ProjectCompileOutput,
};
use foundry_config::{error::ExtractConfigError, figment::Figment, Chain, Config, NamedChain};
use foundry_debugger::Debugger;
use foundry_debugger::{DebugTraceIdentifier, Debugger};
use foundry_evm::{
debug::DebugArena,
executors::{DeployResult, EvmError, RawCallResult},
opts::EvmOpts,
traces::{
identifier::{EtherscanIdentifier, SignaturesIdentifier},
render_trace_arena, CallTraceDecoder, CallTraceDecoderBuilder, TraceKind, Traces,
identifier::{EtherscanIdentifier, SignaturesIdentifier}, render_trace_arena, render_trace_arena_with_internals, CallTraceDecoder, CallTraceDecoderBuilder, TraceKind, Traces
},
};
use std::{
Expand Down Expand Up @@ -357,6 +356,7 @@ pub async fn handle_traces(
chain: Option<Chain>,
labels: Vec<String>,
debug: bool,
decode_internal: bool,
) -> Result<()> {
let labels = labels.iter().filter_map(|label_str| {
let mut iter = label_str.split(':');
Expand Down Expand Up @@ -392,23 +392,37 @@ pub async fn handle_traces(
};
let mut debugger = Debugger::builder()
.debug_arena(result.debug.as_ref().expect("missing debug arena"))
.decoder(&decoder)
.sources(sources)
.identifier(|b| b.decoder(&decoder).sources(sources))
.build();
debugger.try_run()?;
} else {
print_traces(&mut result, &decoder).await?;
let identifier = if decode_internal {
let sources = if let Some(etherscan_identifier) = etherscan_identifier {
etherscan_identifier.get_compiled_contracts().await?
} else {
Default::default()
};
Some(DebugTraceIdentifier::builder().sources(sources).decoder(&decoder).build())
} else {
None
};
print_traces(&mut result, &decoder, identifier.as_ref()).await?;
}

Ok(())
}

pub async fn print_traces(result: &mut TraceResult, decoder: &CallTraceDecoder) -> Result<()> {
pub async fn print_traces(result: &mut TraceResult, decoder: &CallTraceDecoder, identifier: Option<&DebugTraceIdentifier>) -> Result<()> {
let traces = result.traces.as_ref().expect("No traces found");

println!("Traces:");
for (_, arena) in traces {
println!("{}", render_trace_arena(arena, decoder).await?);
let arena = if let Some(identifier) = identifier {
render_trace_arena_with_internals(arena, decoder, &identifier.identify_arena(arena)).await?
} else {
render_trace_arena(arena, decoder).await?
};
println!("{}", arena);
}
println!();

Expand Down
Loading

0 comments on commit 3b2b1fe

Please sign in to comment.