-
Notifications
You must be signed in to change notification settings - Fork 1.9k
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(forge): readCallers cheatcode #4884
Conversation
readPrank
cheatcodeThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This lgtm. Looks like it needs linting.
Would appreciate some followup PRs for the book and forge-std! Deferring to Matt for final approval & merge.
On it 😉 |
Do we need the |
Given that use case, we'd probably want to rename this to something more generic like Another consideration: how does this cheatcode behave in scripts, where instead of pranks you have broadcasts, but which have similar semantics of changing the |
Following what @PaulRBerg described in #4875, I preferred using a bool instead of returning the current caller and origin because in case the user wants to call any of the prank cheat codes he would only need to check the boolean instead of having to manually compare the pranked address and the original caller. contract CounterTest is Test {
Counter public counter;
function setUp() public {
counter = new Counter();
counter.setNumber(0);
}
function testIncrement() public {
vm.prank(address(this));
(bool isActive, address newSender, ) = vm.readPrank();
counter.increment();
assertEq(counter.number(), 1);
}
} |
I honestly hadn't thought about it, thank you for pointing it out. Maybe we should implement a new cheat code for that scenario considering that with broadcast you alter only the |
Hmm, based on his description of this cheat:
It's not clear what the details of the use case are, so it's hard to say which UX makes more sense. Note that you can also change the sender used in tests from the CLI with the For the script scenario, I think this cheat would have to (1) detect that we're in a script environment and revert, or (2) return the address that would be used for the next |
Hmm, maybe we should wait for him to provide a practical scenario where this cheat code would be used to narrow down the implementation and not diverge from his expected behavior. |
Consider this function: // src/Foo.sol
contract Foo {
function doSomethingUseful() external onlyOwner {
// --- snip --- //
}
} And imagine that your code base has hundreds of test files (as our code base does). Now, the use case is to be able to write a subroutine that calls the function above, like this: // test/MyTest.sol
contract Utils {
function usefulSubroutine() internal {
address initialPrank = vm.readPrank();
changePrank(users.admin);
foo.doSomethingUseful();
changePrank(initialPrank);
}
} The goal is to perform a call only an admin can perform, then switch back to whatever prank was before. |
So for your use case, either approach would work. With the
With the no
One downside of the second is that now you technically are in a prank state even though you weren't before, but functionality wise everything should be the same. This could be mitigated by forge detecting when a I think I've convinced myself that |
Cool thanks for shedding some light on this. Please @mds1 tell me what should I do next. Do we keep the current implementation or change something? |
Nice I'll do that. thank you! |
Done! Sorry for the delayed changes |
@xeno097 what approach did you go with for how this cheat behaves in scripts? I don't see any tests using this cheat in a script env so I'm not sure it's currently handled. Quoting from above I think the options are:
|
Sorry, my bad. Of the 2 options, I prefer the revert one because I think it is cleaner. Maybe later we can add an equivalent cheat code for the broadcasting scenario called |
…new cheatcode logic
…s form read_callers
I haven't followed the recent discussion here closely, but it looks like this is ready for review? |
This is not ready for review yet, it needs to be updated to one of the too versions described in #4884 (comment) @wighawag @PaulRBerg just want to sanity check we're all on board with that approach, and see if either of you have a preference on which of those two we use? |
I'd go with the first option described in #4884 (comment), i.e. the one which uses this enum: enum CallerMode {
None
Broadcast
StartBroadcast
Prank
StartPrank
} It's more explicit and specific; whereas |
Nice! I had already updated the implementation with this option last week. Let's see if @wighawag has any comment about this if not I think this is ready for review @mds1 @mattsse |
This is good for me, I also prefer the enum version. thanks! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
testdata/cheats/ReadCallers.t.sol
Outdated
Cheats constant cheats = Cheats(HEVM_ADDRESS); | ||
|
||
function testReadCallersWithNoActivePrankOrBroadcast() public { | ||
// Arrange |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we remove these? :D
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yup np 😅
I won't be able to look at this until sometime monday, but cc'ing @wighawag @PaulRBerg in case you have the bandwidth the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
test+code lgtm!
any objections @mds1 ?
enum CallerMode { | ||
None, | ||
Broadcast, | ||
RecurrentBroadcast, | ||
Prank, | ||
RecurrentPrank | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this we'd need to move to forge-std?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep no problem! I think I also need to add a new page to the fpundry book with documentation for the cheatcode right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes please that would be great! 🙏
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yup ci failure is unrelated. merging! |
Motivation
#4875
Solution
Implements a
readPCallers
cheat code that allows to read the currentmsg.sender
andtx.origin
addresses that will be used to send transactions in later calls