question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

eth_chainId is called every time the provider is used

See original GitHub issue

Hi, I am seeing a lot of unexpected eth_chainId calls:

Screenshot 2020-06-23 00 48 09

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:closed
  • Created 3 years ago
  • Reactions:12
  • Comments:12 (7 by maintainers)

github_iconTop GitHub Comments

6reactions
ricmoocommented, Jul 5, 2020

This should be fixed in 5.0.4.

Try it out and let me know. 😃

5reactions
ricmoocommented, Jun 23, 2020

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:

class StaticJsonRpcProvider extends JsonRpcProvider {
    async getNetwork(): Promise<Network> {
        if (this._network) { return Promise.resolve(this._network); }
        return super.getNetwork();
    }
}

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:

provider.on("block", (blockNumber) => {
    contract.constantMethod()
    // ...
});

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 the ethers.providers.JsonRpcProvider, as it has these sorts of optimizations built-in.

Make sense? Other suggestions?

Read more comments on GitHub >

github_iconTop Results From Across the Web

eth_chainId - Alchemy Docs
Returns the currently configured chain ID, a value used in replay-protected transaction signing as introduced by EIP-155.
Read more >
What is a chainID in Ethereum, how is it different than ...
Basically, chain identifier is an integer number being used in the processes of signing transactions and verifying transaction signatures. If ...
Read more >
svelte-ethers-store - npm
You can import them directly in any Svelte or JavaScript files : import { connected, provider, chainId, chainData, signer, signerAddress, ...
Read more >
Release Notes — Web3.py 5.31.3 documentation
Address the use of multiple providers in the docs (#1701) ... __getattr__ overloader method (since __getattr__ HAS to be called in every __hasattr__...
Read more >
How To Connect Ethers.Js To Metamask Await Is Only Valid In ...
ethchainId is called every time the provider is used #901. Ethereum networks have two identifiers a network ID and a chain ID.Although they...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found