eth_chainId is called every time the provider is used
See original GitHub issueHi, I am seeing a lot of unexpected eth_chainId calls:
My application is a node server calling provider.getBlockNumber()
and contract.constantMethod()
repeatedly. Based on the response it decides to build a transaction by calling provider.send('eth_getBlockByNumber')
for a range of blocks (since I need transaction and receipt roots of these blocks hence justifies 5725 calls) send a transaction (justifies 46 calls to eth_gasPrice
). The application has to perform this routine 24x7.
If number of eth_blockNumber
requests and eth_call
requests is added, it approximately gives number of requests to eth_chainId
. Looks like every eth_blockNumber
and eth_call
requests eth_chainId
before the actual call while custom methods using .send
don’t do that.
At first, it comes to my mind that this can be some sort of safety check to prevent errors due to changing backend. Most of the developers might not be concerned about these calls with a new dapp, but if users increase then it would double the costs, this would then be an issue for them. Can something be done to reduce requests?
Issue Analytics
- State:
- Created 3 years ago
- Reactions:12
- Comments:12 (7 by maintainers)
Top GitHub Comments
This should be fixed in 5.0.4.
Try it out and let me know. 😃
You are correct, this is a safety feature for v5. In v4, if a backend changed, results were simply undefined (which could result in hanging the UI, returning wrong or inconsistent data), so v5 added the ability (to match EIP-1193) to support a changing backend which requires verifying each call that the backend hasn’t changed. An upcoming multi-call provider will mitigate much of this, since the multi call contract will execute these operations in a single call.
For most uses it is not a huge overhead, since the default provider uses sources that intrinsically know their chain ID (and hence do not make external calls) and the next largest group of users are MetaMask (or similar clients), for which the chainId is free and does not hit the network.
But you are absolutely correct that there are cases that you would like to discard safety (since you know the network won’t change) and this just adds overhead. The InfuraProvider and ilk do not need to do this (since the network is intrinsic and dictates the URL to hit), so I will probably add a provider similar to:
The
getNetwork()
method is where the network is verified, so overriding this to skip verification is what you need. All other calls call this to do verification. I’ll think another day about this and if nothing better comes to mind add this.However, for your case, I think there is a better solution:
Since the
"block"
event uses the internal blockNumber and fast blockNumber, it will likely make far fewer calls to the chain ID.Also, if you are using INFURA, Make sure you are using the
ethers.providers.InfuraProvider
and not theethers.providers.JsonRpcProvider
, as it has these sorts of optimizations built-in.Make sense? Other suggestions?