Replies: 1 comment 3 replies
-
PS: I understand that forge is not solc; and that solc does not have pre/post processing features yet ... and that therefore there may not be enough information to know whether cheatcodes are being executed in a modifier or in a body, nor enough hooks to be able to embed execution hints anywhere by as encodings in function names or the like; but maybe you guys are parsing intermediate representations or the like? |
Beta Was this translation helpful? Give feedback.
3 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
Regarding #402:
Some thoughts: Foundry's "solidity first" design principle is awesome for reducing context switching and in this context it has the benefit of promoting parity with other projects which, because they are not solidity based, are by definition both physically and conceptually external to the EVM and have more freedoms to interact with external state.
The features implemented in response to #402 go further towards breaking "the 4th wall" (to borrow a term from film), where the Forge testing code is now orchestrating mainnet transactions with irreversible consequences. It made me extremely nervous to read about the possibility of pointing such code at a mainnet, when its activity may be based on cached values or "copied" state about that mainnet, where those caches may be out of sync with reality. I recently reported (and the team awesomely fixed) various such caching bugs in the build system. For simple (related) reasons, I'd probably only ever use such features if the deployment code in question contained my own explicit checks of chain state in order to decide for itself which deployment steps to continue, retry, omit, etc. And even then, I would carefully --dry-run them first.
Given Foundry's solidity-first approach: When writing tests and likely when using the features discussed in 402, one's mindset is an EVM mindset. You're in some external function that is executing on the basis of some virtual transaction -- albeit one generated by the testing framework and not on-chain (at least insofar as "this" contract). The context is nevertheless transactional.
However, such a transactional context and these features stop short of something which @wighawag touched on: Namely, that without sacrificing the beauty of Foundry's solidity-first approach, we could consider testing of contracts to be part of an "orchestrated" environment where multiple actors, both on and off chain, are participating in tests.
In such an orchestrated context, @wighawag's suggestion to be able to call "pre" and "post" scripts to tests can be cast as a special case of off-chain orchestration. Do X. Then run testA. Then do Y. etc. We could think of "test" functions more like snippets of solidity that can be orchestrated together.
A crude version of this would be a bash script that called
forge test -m testA
did something and then calledforge test -m testB
.The motivations for doing something like that relate to my prior inquiries about gaining access to "external" artifacts (such as logs/events) inside Foundry's solidity-first tests. Ultimately, I acquiesced to the response that vm.warp(); etc should be enough. After all, those are the limits of what a contract can see of the external world.
However, consider contracts that interact with off-chain oracles, and which (for counter-MEV reasons) break up certain behaviors across unrelated transactions; and where such inputs may even come from unrelated chains, or from components that you'd like to nudge to take some next step in the testing process before you continue with another testing step; perhaps even only in order to observe a UX update, based on log emissions.
I mean, obviously, supporting such complex tests can get extremely complex and may be beyond the scope of any near term goals for Foundry; but directionally speaking, cheatcodes that allow some form of synchronous message passing and/or conditional test executions and/or access to external state could be used to compose such things. There could be matching forge commands, RPC endpoints, and or other IPC mechanisms to interact with those cheatcodes. Yes, such message passing could be modeled as normal EVM transactions (e.g., to a Test contract at a well known address). However, not only may that be too heavy, but those interactions may precisely not be appropriate to be recorded on-chain when interacting with mainnet and orchestrating actual transactions (vs tests).
Of course, synchronous pauses or access to externalities within a solidity function breaks the evm/solidity external function execution context paradigm--but then again, so do cheatcodes in general! I.e. it wouldn't necessarily make the most sense to a solidity programmer to see
vm.waitFor("step1");doSomething();vm.waitFor("step2");doSomethingElse();
. Therefore, what I've talked about so far (assuming you're not rolling your eyes) maybe only makes sense between such calls, which could therefore be modeled (in order to remain syntax-compatible with solidity) as modifiers to test functions, and as cheatcodes that are only sensical (if not limited to only being valid) within those modifiers.Thanks for building Foundry.
Beta Was this translation helpful? Give feedback.
All reactions