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

feat: vm.pauseTracing + vm.resumeTracing #8696

Merged
merged 8 commits into from
Aug 26, 2024
Merged

Conversation

klkvr
Copy link
Member

@klkvr klkvr commented Aug 19, 2024

Motivation

ref foundry-rs/forge-std#505 (comment), and I've also seen a request for this in one of the telegram chats recently (can't find now)

Adds pauseTracing and resumeTracing cheats which allow hiding parts of the call trace.

Solution

  • Extend CheatcodeExecutor with fn tracing_inspector(&mut self) -> Option<&mut TracingInspector> allowing to manipulate traces and tracing configuration from cheatcodes. This should also be useful for feat(cheatcode): startDebugTraceRecording and stopDebugTraceRecording for ERC4337 testing #8571 and feat(cheatcodes): mark unmatched expectedEmits as unemitted #8686
  • Record ranges of ignored traces into the following struct:
    /// Contains locations of traces ignored via cheatcodes.
    ///
    /// The way we identify location in traces is by (node_idx, item_idx) tuple where node_idx is an
    /// index of a call trace node, and item_idx is a value between 0 and `node.ordering.len()` where i
    /// represents point after ith item, and 0 represents the beginning of the node trace.
    #[derive(Debug, Default, Clone)]
    pub struct IgnoredTraces {
    /// Mapping from (start_node_idx, start_item_idx) to (end_node_idx, end_item_idx) representing
    /// ranges of trace nodes to ignore.
    pub ignored: HashMap<(usize, usize), (usize, usize)>,
    /// Keeps track of (start_node_idx, start_item_idx) of the last `vm.pauseTracing` call.
    pub last_pause_call: Option<(usize, usize)>,
    }

    Another approach could be to remove trace nodes and items through a mutable reference, though we're using traces for debugger and gas reports, so keeping an instance of complete trace is useful even if it was partially ignored
  • Changed type Traces = Vec<(TraceKind, CallTraceArena)> to Vec<(TraceKind, SparsedTraceArena)> where SparsedTraceArena keeps data about ignored traces and when being printed, constructs a copy of call trace arena without ignored items.
  • Also included drive-by fix for CheatcodeExecutor::exec_create to support EOF bytecode

This already works pretty much reliably, though it messes with TracingInspector internals and thus there's at least one edge case I can think of related to --decode-internal:

function _someInternalFn() internal {
    vm.pauseTracing();
}

function test() public {
    _someInternalFn();
}

Such test will result in a panic during printing if run with --decode-internal as pauseTracing would result in end of decoded trace step being removed, causing issues in TraceWriter

We might want to introduce support for this feature on revm-inspectors level to address this and to also support more verbose output for ignored traces, e.g.:

├─ [0] VM::pauseTracing()
├─ [...30 collapsed traces...]
├─ [0] VM::unpauseTracing()

Copy link
Member

@mattsse mattsse left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is reasonable, this feature isn't too invasive and still easy to follow

pedantic doc nits

crates/cheatcodes/src/utils.rs Outdated Show resolved Hide resolved
crates/evm/traces/src/lib.rs Outdated Show resolved Hide resolved
@klkvr klkvr merged commit bdf48aa into master Aug 26, 2024
21 checks passed
@klkvr klkvr deleted the klkvr/pause-resume-trace branch August 26, 2024 11:57
benwjhack pushed a commit to CompassLabs/foundry-test that referenced this pull request Sep 11, 2024
* feat: vm.pauseTracing + vm.resumeTracing

* clippy

* fixes

* fix --decode-internal edge case

* fmt

* clippy + change tracing_inspector return type

* update fixture

* fix fixture
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants