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.25k stars 1.73k forks source link

perf: `anvil_mine` is much slower than `hardhat_mine` #5499

Open fp-crypto opened 1 year ago

fp-crypto commented 1 year ago

I attempted to move my testing from hardhat node to anvil. Some of my testing requires mining a large number of blocks. anvil_mine execution time seems to scale linearly relative to block count, whereas hardhat_mine with hardhat node is nearly constant. See the following benchmarks:

Anvil

In [1]: import timeit

In [2]: [timeit.timeit(stmt=(f'chain.mine({i})'), globals=globals(), number=50) for i in [1, 1
   ...: 0, 100, 1000]]
Out[2]:
[0.07101033299113624,
 0.39050891700026114,
 6.034164124997915,
 276.3122650830046]

Hardhat

In [1]: import timeit

In [2]: [timeit.timeit(stmt=(f'chain.mine({i})'), globals=globals(), number=50) for i in [1, 1
   ...: 0, 100, 1000]]
Out[2]:
[0.10906625000643544,
 0.09370395800215192,
 0.0902477499912493,
 0.08129970800655428]

I'm using:

https://github.com/foundry-rs/foundry/blob/41bae8e6265e905f73c3f4eac14a5ba9275417a4/anvil/src/eth/api.rs#L1421-L1440

fvictorio commented 1 year ago

The reason Hardhat's time is constant is that when more than N blocks are mined (I don't remember the value of N) they are not actually mined. Instead, a fake range of blocks is created and then the last ones are actually mined. This means that the hash of the latest block is kind of fake, but that's an acceptable trade-off.

There are some non-obvious things to keep in mind to implement this approach though. Happy to share them here if someone is interested in implementing this in Anvil.

janjakubnanista commented 7 months ago

What would be the way to go about implementing this @fvictorio?

orph3usLyre commented 5 days ago

Hi @fvictorio,

Following up on this issue since there hasn't been any activity for a while. Would it be possible to discuss implementing this functionality, either here or via email? We're currently using anvil extensively for testing and this functionality would save us a lot of CI time. I'm more than willing to tackle this issue if pointed in the right direction.

Cheers :tada: