Skip to content
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

Performance regression between 2bcb4a1 and 293fad7 #7131

Closed
1 of 2 tasks
vlad-blana opened this issue Feb 14, 2024 · 5 comments · Fixed by #7156
Closed
1 of 2 tasks

Performance regression between 2bcb4a1 and 293fad7 #7131

vlad-blana opened this issue Feb 14, 2024 · 5 comments · Fixed by #7156
Assignees
Labels
T-bug Type: bug

Comments

@vlad-blana
Copy link

vlad-blana commented Feb 14, 2024

Component

Anvil

Have you ensured that all of these are up to date?

  • Foundry
  • Foundryup

What version of Foundry are you on?

forge 0.2.0 (293fad7 2024-01-14T00:29:03.206718800Z)

What command(s) is the bug in?

.\anvil.exe --fork-url "ws://127.0.0.1:8546" --auto-impersonate --no-storage-caching --no-mining

Operating System

Windows

Describe the bug

I encounter 2 performance issues between nightly builds 2bcb4a1 (2 Jan 2024) and 293fad7 (14 Jan 2024)

I also verified prior and post versions (Nov 2023-Feb 2024) to be certain the issues showed up sometime between the 2 builds and it's still present in the latest nightly (14 Feb 2024)

  1. Establishing rpc websocket connections fail when opening 32 instances of anvil.exe and requires a wait time of about 6-7 seconds compared to 3 seconds on 2bcb4a1 and around 4-5 in some of the older ones. The behavior is consistent - I mean it's slower in the newer versions for some reason. Opening one instance for the human eye seems to be the same, but it's obviously not quite the same

  2. Opening one instance in fork mode of geth node in the same network (I mean it's low latency) and trying to interact with some contracts takes up to 10x more time more. The environment, code, inputs and calls are the same, only the anvil.exe is different

In one instance eth_call execution time jumped from 19-21 seconds on the older versions to 193-200 seconds on the newer ones.

  • the contract allows batch reading balances of an input array of tuples like [account address, erc20 token address]

  • I'm sending 100 calls of 1000 tuples each

  • the inner code does a simple for and calls balanceOf 1000 times and writes the balance in an output array

  • the contract was compiled with solidity version 0.8.22 and I used both the non optimized and yul/inline assembly versions and they exhibit the same slow down in newer anvil versions

  • to get the mentioned execution times (19 seconds/193 seconds) the accounts count is 50K and 11k erc20 tokens mixed to achieve 100k tuples

  • each anvil version execution time stays roughly the same if I rerun the code - I mean it's consistent within the same version. The 10x it's not a one time thing, it's there all the time for the newer versions

  • keep in mind the --no-storage-caching option so everything is in memory, but anvil starts from scratch in these tests so nothing is cached anyway

  • anvil is forked on the latest live block - not using historical data

On the other hand erc20 transfer transactions seem to perform about the same, the performance seems slower on the newer versions but very slightly and I also perform evm_mine and anvil_reset after each transfer transaction so it's hard to reproduce reliably.

The eth_call is blatantly slower

@vlad-blana vlad-blana added the T-bug Type: bug label Feb 14, 2024
@mattsse
Copy link
Member

mattsse commented Feb 14, 2024

what regressed?
any additional info would be helpful

@vlad-blana
Copy link
Author

Enrique the admin in the telegram group mentioned that it might be related to the switch from ethers to alloy

#6219

I'm going to build a project and share it here to pinpoint the issue better so you may reproduce it much easier

@Evalir
Copy link
Member

Evalir commented Feb 15, 2024

@vlad-blana getting a repro would be amazing 🙏

@vlad-blana
Copy link
Author

Here is the repo that reproduces both issues. I only managed to add the demo for the startup issue. The demo for the eth_call issue will come later in 1-2 days.

https://github.com/vlad-blana/repro-foundry-rs-7131

@vlad-blana
Copy link
Author

I added the 2nd demo and I understood how to trigger the issue.

The performance regression happens when calling concurrent eth_call at the same time.

A single eth_call seems faster on the newer versions, but when calling 100 it suffers a huge performance penalty that grows even larger on public nodes, 30-40 times slower on the best rpcs and the newer anvil nightly builds.

I built the demos on pulsechain as the fork because I only have a pulsechain private node, but you could easily use your ethereum mainnet rpc and it would still work because the contracts I used exist on both networks and if you also change the contract addresses (uniswap v2 factory and multicall 3) it could easily run on any evm network.

I did not try, but maybe it would be enough to make any 100 concurrent eth_calls and experience the performance regression between the anvil pre 2 Jan versions and post 14 Jan ones.

Also public nodes should be avoided because of the network latency that ruins the experience. But you could change a few settings to minimize the number of network interactions. I mentioned them in the readme, but ask anyway if it's not clear.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
T-bug Type: bug
Projects
No open projects
Status: Done
Development

Successfully merging a pull request may close this issue.

5 participants