foundry-rs / foundry

Foundry is a blazing fast, portable and modular toolkit for Ethereum application development written in Rust.
https://getfoundry.sh
Apache License 2.0
8.29k stars 1.75k forks source link

feat: support offline forks in `vm.createFork` #7728

Open Lohann opened 6 months ago

Lohann commented 6 months ago

Component

Forge

Describe the feature you would like

I'm building a cross-chain bridge, and forge's vm.createFork is being super useful! However in the unit tests my intent is not fork a real network, instead I just want to create many isolated networks locally, so I can simulate sending cross-chain messages between them.

I need isolated networks because: 1 - Support two contracts deployed at the same address, but with different states. 2 - Isolation: A contract on Chain A doesn't see the contract on Chain B.

If you just want two isolated networks, vm.createFork() has the limitation that it must request a real RPC node, this has several disadvantages:

  1. it slowdown the tests
  2. can't alter the chain_id, block gas limit, etc...
  3. Lot of tests does a lot calls, so you can easily get rate limited by the RPC node, for now I'm running a local node and forking it.. but still not optimal.

Here an example of what I'm doing: https://github.com/Analog-Labs/analog-gmp-examples/simple/Counter.t.sol

I wish some way to use the createFork to create a clean state context, ex:

uint256 forkId = vm.createFork("default");
// or a specialized method
uint256 forkId = vm.createLocalFork();
// or reading some genesis state file
uint256 forkId = vm.createFork("file:../genesis.json");

The other solution is using vm.snapshot().. but this one is harder because it doesn't persist the state, so I need to create a new snapshot and delete the previous one everytime I switch between networks, it also doesn't create a clean context as it will contains everything you deployed in the constructor and in the setUp().

Additional context

No response

pikonha commented 5 months ago

This would be incredibly helpful for my project. I am developing an Offchain Resolver for ENS and need to fork a local network to test various scenarios using both Ethereum and Arbitrum nodes.

For example:

I want to set up a local Ethereum node with the Registry, UniversalResolver, and ReverseRegistrar deployed at fixed addresses. This setup will allow me to run integration tests using Viem, implementing offchain reading and writing by redirecting requests to a local API.

mattsse commented 5 months ago

Ah I see, rn, forking involves fetching the latest head from the an rpc provider, but I believe you only want in memory forking?

I believe this could work, fyi @klkvr

0xMySt1c commented 5 months ago

@mattsse i believe this is similar in anvil forking. where even when an anvil fork at a given block has already been created. it still reaches out to the RPC instead of reaching for cache first.