chisel injection into test function
Component
Chisel
Describe the feature you would like
This feature would introduce the possibility to add a call such as vm.chisel() or vm.chiselBreakpoint() anywhere in a test function.
The desired behavior is that calling chisel on that function will result in the session being loaded with the entire state of the test at the time the call was made, including the storage state as well as the memory.
Running forge test should not result in a different behavior than usual.
Example
pragma solidity ^0.8.15;
import "forge-std/Test.sol";
import "forge-std/console.sol";
import "src/Kevin.sol";
contract KevinTest is Test {
Kevin public kevin;
function setUp() public {
kevin = new Kevin();
}
function testKevin() public {
uint256 bob = 15;
vm.chisel();
uint256 stewart = 1;
}
}
Followed by chisel --match testKevin, which opens up a chisel session.
➜ address(kevin)
Type: address
└ Data: 0xf4d9599afd90b5038b18e3b551bc21a97ed21c37
➜ bob
Type: uint
├ Hex: 0xf
└ Decimal: 15
➜ stewart
Compiler errors:
error[7576]: DeclarationError: Undeclared identifier.
--> ReplContract.sol:18:1:
|
18 | stewart;
| ^^^^^^^
➜
Additional context
No response
@clabby this seems like a great idea. do u have the capacity to implement this?
@clabby this seems like a great idea. do u have the capacity to implement this?
Bandwidth constrained at work over the next couple of weeks, but can soon! Spoke w/ @exp-table about this a while back while I was initially making Chisel, imagine it wouldn't be a huge lift. I know @gakonst also had some ideas about pulling out Chisel's eval module in order to integrate it into a revamped debugger- this might be something to add during that process, but can be done by itself as well.
This would be a pretty sweet feature. Huge bonus points if you can evaluate state variables by name from the source code too, like you can with tenderly debugger (both from local source or source downloaded from etherscan in fork tests).
A few comments:
- This should be behind the
forge testcommand instead of the suggestedchisel --match. Because this is something to help debug tests, soforge test --chisel <testName>, analogous toforge test --debug <testName>, seems more logical. - I'd suggest either (1) naming the cheat just
vm.breakpoint(), or (2) replacing the cheat with some magic bytes that forge recognizes, and when executed, activates the debugger. The rationale for this is:- Breakpoints are also useful in the regular debugger with
forge test --debug, and they would just behave differently if you're runningforge test --debugorforge test --chisel - The rationale for magic bytes is: If you want a breakpoint in your source code, now you need to setup a
vmstate var which is a bit more work than just executing some meaningless bytes that do nothing. However, can we guarantee that solc won't optimize away useless bytes? Cheatcode is probably the way to go, just thinking out loud a bit here
- Breakpoints are also useful in the regular debugger with
- Let's also have a
vm.breakpoint(bool)overload so you can conditionally trigger breakpoints
And I agree merging this with the debugger so that the debugger has this evaluator built in and accessible at every step would be an awesome end state. Defer to everyone else if it makes sense to do that upfront or keep the two features separate for now
Let's zoom out here and start by refactoring the debugger IMO, and this will come naturally. ref https://github.com/foundry-rs/foundry/pull/2692
So refactoring the debugger got stale, meaning this aswell?
Yep :) Open to contribs..
I can help refactoring the debugger, this sounds like a very nice feature
I can help refactoring the debugger, this sounds like a very nice feature
This is a neat future, any help on the debugger is welcome :)
I can help refactoring the debugger, this sounds like a very nice feature
This is a neat future, any help on the debugger is welcome :)
Refactored a decent amount of tech debt in https://github.com/foundry-rs/foundry/pull/5753 maybe that the code is ready to get this feature in now