Support external trace source #12550
Open
+879
−53
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Motivation
When testing smart contracts against Cosmos-EVM compatible chains (such as Evmos, Injective, SagaEVM, and others), developers encounter a critical limitation: local REVM-based tracing cannot accurately reproduce the chain's execution behavior, especially when dealing with chain-specific precompiles and custom EVM implementations.
The problem manifests in several ways:
Precompile Behavior Mismatch: Cosmos-EVM chains often implement custom precompiles (e.g., ERC20 precompiles at fixed addresses) that behave differently than standard Ethereum precompiles. Local REVM tracing cannot execute these precompiles, leading to incorrect trace outputs and missed execution paths.
Chain-Specific Execution Differences: Different EVM implementations may have subtle differences in gas accounting, opcode behavior, or state transitions that are not captured by local tracing. This makes it difficult to debug issues that only occur on the actual chain.
Inability to Verify Chain Behavior: Developers need a way to verify that their contracts execute correctly on the target chain's actual node implementation, not just a local simulation.
Debugging Challenges: When tests pass locally but fail on-chain, developers lack visibility into the actual execution trace from the chain node, making debugging significantly more difficult.
The existing
--fork-urlfeature allows testing against remote chains, but tracing was still performed locally using REVM, which doesn't capture the chain's actual execution behavior. This PR adds the--trace-source remoteflag to enable remote tracing via the node'sdebug_traceCallRPC method, providing accurate execution traces that reflect the chain's actual behavior.Solution
This PR adds a new CLI flag
--trace-sourcetoforge testthat allows developers to choose between local REVM-based tracing (default) and remote tracing via the chain node'sdebug_traceCallmethod.Implementation Details
CLI Flag Addition: Added
--trace-sourceflag toforge testwith two options:local(default): Uses REVM for local tracing (existing behavior)remote: Delegates tracing to the remote RPC node viadebug_traceCallConfiguration Support: The trace source can be configured via:
--trace-source remotefoundry.toml:trace_source = "remote"Remote Tracing Implementation:
--trace-source remoteis specified, Forge constructs aTransactionRequestfrom the local tracedebug_traceCallmethod withcallTracerconfigurationIntegration with Fork Mode: Remote tracing requires
--fork-urlto be specified, as it needs an RPC endpoint to call. The implementation checks forconfig.eth_rpc_urlbefore attempting remote tracing.Trace Rendering: Remote traces are rendered using a minimal call tree format:
Error Handling: The implementation gracefully falls back to local tracing if remote tracing fails (e.g., if the RPC doesn't support
debug_traceCallor returns an error).Code Changes
crates/forge/src/cmd/test/mod.rs:trace_source: Option<TraceSourceArg>field toTestArgsTraceSourceArgenum withLocalandRemotevariantsrun_tests_inner()that checks forTraceSource::Remoteand fetches traces viadebug_traceCallrender_remote_call_frame()function to format remote trace outputcrates/config/src/lib.rs:TraceSourceenum withLocal(default) andRemotevariantstrace_source: TraceSourcefield toConfigstructcrates/forge/tests/remote_trace.rs:debug_trace_call_parses_calltracer()to verify remote tracing RPC integrationcrates/forge/src/cmd/test/mod.rs(tests):trace_source_arg_remote_parses()test to verify CLI flag parsing and config integrationdocs/dev/forge-tracing.md:Usage Example
Or configure in
foundry.toml:Benefits
Limitations
callTraceronly; other tracers likeprestateTracerare not yet exposeddebug_namespace methodsPR Checklist
Added Tests
trace_source_arg_remote_parses()test incrates/forge/src/cmd/test/mod.rsto verify CLI flag parsingdebug_trace_call_parses_calltracer()test incrates/forge/tests/remote_trace.rsto verify RPC integrationAdded Documentation
docs/dev/forge-tracing.mdcovering:Breaking changes
--trace-source remoteflag, and defaults tolocal(existing behavior).