ethers.js icon indicating copy to clipboard operation
ethers.js copied to clipboard

FallbackProvider not catch detectNetwork error

Open cliff0412 opened this issue 3 years ago • 6 comments

Ethers Version

5.6.0

Search Terms

No response

Describe the Problem

the issue is regarding the fallback-provider. i have 3 providers configured and the quorum is set to 1. However, the query request (such as getBalance) will fail with only 1 JsonRpcProvider malfunction. As the quorum is set to 1, that's not expected to happen.

After digging into the source code, i find the detectNetwork function is not catching the no network error. i have made changes to the original source code, and then my test passed.

below is the new code

  async detectNetwork(): Promise<Network> {
    const networks = await Promise.all(
      this.providerConfigs.map(async (c) => {
        try {
          return c.provider.getNetwork();
        } catch (error) {
          return null;
        }
      }),
    );
    return checkNetworks(networks as Array<Network>);
  }

also in checkNetworks, the check should continue in the for loop when no network is provided

   if (network == null) {
      continue;
    }

Code Snippet

the way i initiated a FallbackProvider


new FallbackProvider(
      [
        {
          provider: new ethers.providers.JsonRpcProvider(url1), 
          priority: 3,
          stallTimeout: 200,
          weight: 1,
        },
        {
          provider: new ethers.providers.JsonRpcProvider(url2), 
          priority: 1,
          stallTimeout: 200,
          weight: 1,
        },
        {
          provider: new ethers.providers.JsonRpcProvider(url3), 
          priority: 2,
          stallTimeout: 200,
          weight: 1,
        },
      ],
      1,
    );

Contract ABI

No response

Errors

No response

Environment

node.js (v12 or newer)

Environment (Other)

No response

cliff0412 avatar Mar 23 '22 12:03 cliff0412

Could you share the line changes that have fixed this issue for your test? I could really use this patch.

samholmes avatar Apr 05 '22 23:04 samholmes

as of current master branch fallback-provider.ts

  • line 471 i changed to
async detectNetwork(): Promise<Network> {
    const networks = await Promise.all(
      this.providerConfigs.map(async (c) => {
        try {
          return c.provider.getNetwork();
        } catch (error) {
          return null;
        }
      }),
    );
    return checkNetworks(networks as Array<Network>);
  }
  • line 29 changed to
if (network == null) {
      continue;
    }
  • line 631 changed to
// e.message contains more useful message than e.reason
logger.throwError(e.message || e.reason, <any>errorCode, props);

the third change is not relevant to the issue. however it could be better to return message because it contains the evm revert message

BTW, is it possible for me to make a PR if it is a valid patch? It will be a small achievement for me even if i only make a small contribution :)

At last, i find the fall back provider is not handling timeout during detectNetwork. i am still checking on this. will open another issue if that's indeed an issue

cliff0412 avatar Apr 06 '22 04:04 cliff0412

Sorry for the delay, I’m trying to get the v6 beta out this week. I’ll look at this soon though.

ricmoo avatar Apr 06 '22 04:04 ricmoo

@cliff0412 A PR would be super helpful IMO. I wouldn't ask permission, but rather just contribute the PR and let the maintainers decide whether it's worth including.

Do you have a link to your fork so I may evaluate your code-changes and fork from your fixed state until the change moves upstream?

samholmes avatar Apr 11 '22 21:04 samholmes

The same issue

agmitron avatar Jun 30 '22 14:06 agmitron

@ricmoo i have forked and made a pr. pls refer to https://github.com/ethers-io/ethers.js/pull/3247

cliff0412 avatar Aug 08 '22 03:08 cliff0412

any update or WA for this issue?

tkeidar avatar Dec 29 '22 07:12 tkeidar

Leaving this here incase it helps someone else out.

I used StaticJsonRpcProvider within FallbackProvider and was getting the detectNetwork errors when my primary node was still in sync mode or booting up (and not servicing requests yet).

I was able to get around the detectNetwork error by specifying the network in the provider (which then skips the network check).

What tipped me off was this comment in the source code: https://github.com/ethers-io/ethers.js/blob/ce8f1e4015c0f27bf178238770b1325136e3351a/packages/providers/src.ts/url-json-rpc-provider.ts#L25-L27

Example:

   new FallbackProvider(
      [
        {
          provider: new ethers.providers.StaticJsonRpcProvider(url1, "mainnet"), 
          priority: 3,
          stallTimeout: 200,
          weight: 1,
        },
        {
          provider: new ethers.providers.StaticJsonRpcProvider(url2, "mainnet"), 
          priority: 1,
          stallTimeout: 200,
          weight: 1,
        },
        {
          provider: new ethers.providers.StaticJsonRpcProvider(url3, "mainnet"), 
          priority: 2,
          stallTimeout: 200,
          weight: 1,
        },
      ],
      1,
    );

TheBoroer avatar Jan 04 '23 17:01 TheBoroer