foundry icon indicating copy to clipboard operation
foundry copied to clipboard

feat: move cheatcodes from forge-std to forge

Open mds1 opened this issue 2 years ago • 2 comments

Component

Forge

Describe the feature you would like

Right now the forge vm defines many cheat codes, and forge-std builds on these with many additional helpers. The distinction between the two is fairly arbitrary (though that hasn't been much of a problem, just occasional discussions about where a feature should live, e.g. https://github.com/foundry-rs/foundry/issues/3732#issuecomment-1328401986)

The suggestion in this issue is to move as many of the forge-std cheats out of solidity and directly into forge in rust. The main rationale is that the src/ dir of forge-std takes ~3-4s to compile on my machine, so the more we can remove from it the faster it will be for users to compile/run their test suites (since native cheats add no compilation overhead, but solidity ones do), and compilation speed is a common bottleneck.

Of course, this doesn't mean you'd save the full 4s in testing, since if you're not using all of forge-std you aren't compiling/optimizing all of it. So true benefit may be smaller—a rough benchmark here is take a few repos, replace all forge-std functions with empty implementations, and compare build times before and after those changes. This should underestimate the savings (since there are still more functions to compile, even though they have empty implementations)

Smaller benefits are:

  1. All cheats would now be namespaced behind vm.*(), instead of the current split between some vm.*() methods for native cheats and *() for forge-std cheats (related to discussion in https://github.com/foundry-rs/foundry/issues/3322#issuecomment-1327383210)
  2. Can also add assertion helpers like vm.assertEq() and vm.failed() to remove the need for ds-test as a dependency which is nice

There would still be some things we want to keep in forge-std, such as:

  • Defining and instantiating the vm variable/interface in all tests by simply inheriting from Test/Script, and keeping the safe vs. unsafe cheats distinction for scripts
  • The stdJson lib for better UX (edit: now I can't recall why I thought these shouldn't be native cheats)
  • The console lib for Hardhat compatibility
  • Standard interfaces for simpler imports

Additional context

No response

mds1 avatar Nov 28 '22 20:11 mds1

This migration could also be an opportunity to introduce a few breaking changes to cheats, such as:

  • https://github.com/foundry-rs/forge-std/issues/349#issuecomment-1510888015

mds1 avatar Apr 18 '23 11:04 mds1

main rationale is that the src/ dir of forge-std takes ~3-4s to compile on my machine

I've done some testing and just want to share the results:

  • Removing safeconsole.sol and its usage from all files decreased compilation time to 2.2-2.4s.
  • Removing also console.sol and console2.sol decreased compilation time to 1.1-1.2s
  • Removing MockERC20, MockERC721 and their deployment functions in StdUtils decreased compilation time to 0.7-0.8s

I don't really know much about how solc deals with dependecies and which of those are getting compiled more often for external projects, I think it makes sense to try removing console libs or mocks for some big codebases to see how it would affect compilation time.

klkvr avatar Feb 08 '24 18:02 klkvr