-
Notifications
You must be signed in to change notification settings - Fork 2k
feat(perf): batch eth_call
requests in tests/scripts
#5363
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
Comments
Another approach to this could be to use the standard JSON RPC batching—not all providers support this, and it also doesn’t result in reduced RPC usage, but it can still be useful for users using their own node or a provider that supports it. This would probably have to be opt-in as a result, whereas the approach described above can be abstracted from the user as the default |
Perhaps this is a suggestion that can be implemented
|
Another approach: assuming the RPC URL supports state overrides (like geth does), use Dedaub's storage extractor code to batch |
This comment was marked as abuse.
This comment was marked as abuse.
This will be trivial to add after Alloy multicall support has been added: alloy-rs/alloy#328 |
Just stumbled over this when looking for why some of our scripts are so slow. Looking forward to an improvement on that front. Happy to test once there is a pr. |
@zerosnacks @grandizzy any chance we can get this in for v1? A lot of folks have scripts or fork tests that fetch a lot of data and this would significantly improve performance |
Related upstream PR in Alloy: alloy-rs/alloy#2010 The 1.0 pre-release has been cut but our release cycle should be short enough to get this in soon cc @yash-atreya |
that would be amazing, thank you! |
On a further note the upstream PR (alloy-rs/alloy#2010) I linked is, while tangentially related, not directly related and would not automatically resolve this issue. From conversation / discussion it appears my note here #5363 (comment) that it would be trivial to add is incorrect and it was based on some incorrect assumptions I had at the time about the proposed implementation |
Got it, so what would be your estimate for when this can be implemented? |
@grandizzy @mattsse This would really help speed up our CI pipelines and improve productivity by a lot. Can we get this prioritized? |
@grandizzy, following up with details on our use case: In the superchain-ops repo at OP Labs, which handles upgrades across the Superchain, we perform a network-heavy operation per chain. You can see the relevant code here: https://github.com/ethereum-optimism/superchain-ops/blob/main/src/improvements/SuperchainAddressRegistry.sol#L214-L257 We’d like to parallelize these network calls to improve performance (it's pretty slow right now). They’re all read-only operations, no writes involved. |
@grandizzy any updates on this issue? |
@mattsse and I discussed about this and something we're looking for improving such is adding new |
@grandizzy What do you think about this idea from above? This is similar to how viem works by default when making calls. Note this is a separate type of RPC call from the kind where we need to collect all account info before simulating state changing operations, and is specifically a performance increase when users have multiple consecutive view calls, but it's nice because it doesn't rely on reth
|
@mds1 Ah, I see, so you mean if we need to fetch 2 accounts, instead doing 6 calls (3 for each account to get their balance, nonce, code) we could batch 2 |
Yep that's exactly correct! Multicall3 has a method to get balance, but not code or nonce. Do you always need to fetch code and nonce even if the user is just making an eth_call? |
They're the fields of an Ethereum account ( Here's where the requests happen: https://github.com/foundry-rs/foundry-fork-db/blob/5b03d6e9320d502daa3a6687298e59a51967de3e/src/backend.rs#L281
This is not as straight forward as you think. Requests are issued inside/by the EVM, which is sequential. This essentially means that every single statement in your Solidity code must execute fully before the next one can even begin to be evaluated; there is no "async" in the EVM. Even if we had the perfect viem-like multicall backend, every The only actionable improvement I can see here is the aforementioned |
Relevant fork-db PR foundry-rs/foundry-fork-db#48 that add supports for |
Component
Forge
Describe the feature you would like
See gakonst/ethers-rs#2508 for details/rationale on the request here
forge batching is not necessarily dependent on that ethers-rs feature, as even without it forge could presumably convert batches calls into multicalls. This could result in significant performance improvements for RPC-heavy scripts and fork tests
Currently instead of
eth_call
we simulate the call and useeth_getStorageAt
as needed. This is suboptimal than just usingeth_call
directly because:eth_getStorageAt
at 17 CUPS buteth_call
is 26, so any tx reading 2+ slots is currently paying more (and running slower due to multiple requests) than necessary, especially when you consider that we can batcheth_call
s but can't batcheth_getStorageAt
So I think the best path forward is:
eth_call
insteadeth_call
s. The approach here would be:eth_call
state overrides to place it there as part of the call, or just send normal requests without Multicall3Additional context
No response
The text was updated successfully, but these errors were encountered: