Skip to content

New interface feedback for cheatcode inspector #1924

@agostbiro

Description

@agostbiro

Hey,

following #1865 I did a spike to implement a Foundry-style cheatcode inspector using the new interfaces. I really like the new design, but I ran into difficulties when trying to implement the transact and rollFork(uint256 forkId, bytes32 transaction) cheatcodes. Both of these cheatcodes initiate transactions from a call step in the cheatcode inspector.

I'll detail the issues below. I created a minimal repro with comments explaining the setup, but it's still ~500 LOC, so I will link to the relevant sections.

JournaledState<DB>

Moving the database inside the journal state in the EVM context prevents mutably borrowing both at the same from a &mut Context. This causes problems detailed here. There is also a failing test case related to this here.

I think this could be solved by lifting the DB to the Context and introducing a temporary struct that has mutable journaled state and database fields and implementing the JournaledState trait for this temporary struct.

Precompiles

When using an inspector, the PrecompileProvider needs an InspectorContext as its context. The InspectorContext needs to know the inspector type and the database type. This prevents declaring a method that takes the precompile provider as a generic parameter and constructs an inspector in the body to execute a transaction. There is an example here.

I think this could be solved by just passing the block, transaction and config environments to the PrecompileProvider instead of the entire context.

I also noticed that precompiles are no longer accessible in Inspector::call. Previously this was available via EvmContext::precompiles, but as far as I can tell, removing this doesn't block any cheatcode functionality.

Missing implementations

The following seems to be only implemented for mainnet types:

  • Evm::transact() implementation hard-codes mainnet HaltReason in the EVMResult return type.
  • InspectorCtx for InspectorContext implementation hard-codes mainnet EthInterpreter. It should be possible to pass a generic interpreter type here.

I also noticed that NoOpInspector::default() doesn't work with mainnet types due to unsatisfied trait bounds.


It's possible that I overlooked something and there is a solution for the mentioned issues. I'm also happy to submit PRs to resolve them. Let me know please!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions