You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When the FallbackProvider is sent call requests concurrently, the jsonrpc id sent to different rpc providers for the same request will differ, and if the response for the request is an error (e.g. execution reverted), it will cause the FallbackProvider to throw a SERVER_ERROR: quorum not met error.
The checkQuorum function in the FallbackProvider is comparing the entire error object which includes the sent payload which contains the differing id. I'm thinking errors should be compared by the actual error object (runner.result.error.info.error) returned by the rpc rather than the entire ethers error object.
Inside the normalizeResult function of the FallbackProvider, it compares the entire error object which includes the differing id rather than just the error response from the rpc.
// let's create 5 providers for bsc mainnet const providers = [ "https://rpc.ankr.com/bsc", "https://bsc.blockpi.network/v1/rpc/public", "https://bsc-rpc.publicnode.com", "https://1rpc.io/bnb", "https://bsc.drpc.org", ]; const provider1 = new JsonRpcProvider(providers[0]); const provider2 = new JsonRpcProvider(providers[1]); const provider3 = new JsonRpcProvider(providers[2]); const provider4 = new JsonRpcProvider(providers[3]); const provider5 = new JsonRpcProvider(providers[4]); // let's call different providers different number of times to throw the id off
await provider1.getBlockNumber();
await provider2.getBlockNumber();
await provider2.getBlockNumber();
await provider3.getBlockNumber();
await provider3.getBlockNumber();
await provider3.getBlockNumber();
await provider4.getBlockNumber();
await provider4.getBlockNumber();
await provider4.getBlockNumber();
await provider4.getBlockNumber();
await provider5.getBlockNumber();
await provider5.getBlockNumber();
await provider5.getBlockNumber();
await provider5.getBlockNumber();
await provider5.getBlockNumber();
// now we create a fallback provider with all the providers
const fallbackProvider = new FallbackProvider([
provider1,
provider2,
provider3,
provider4,
provider5,
]);
// abi of a ERC20 contract
// totalSupply is valid so it will return a value
// hello doesn't exist so it will throw a call exception const abi = [ "function totalSupply() view returns (uint256)", "function hello() view returns (uint256)", ]; // BUSD contract on bsc mainnet const contract = new Contract( "0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56", abi, fallbackProvider ); // totalSupply will return us the value correctly const firstResult = await contract .getFunction("totalSupply") .staticCallResult(); console.log(firstResult); // hello will throw a quorum not met error const secondResult = await contract.getFunction("hello").staticCallResult(); console.log(secondResult);
Ethers Version
6.13.4
Search Terms
fallbackprovider, quorum
Describe the Problem
When the FallbackProvider is sent call requests concurrently, the jsonrpc id sent to different rpc providers for the same request will differ, and if the response for the request is an error (e.g. execution reverted), it will cause the FallbackProvider to throw a SERVER_ERROR: quorum not met error.
The checkQuorum function in the FallbackProvider is comparing the entire error object which includes the sent payload which contains the differing id. I'm thinking errors should be compared by the actual error object (runner.result.error.info.error) returned by the rpc rather than the entire ethers error object.
Inside the normalizeResult function of the FallbackProvider, it compares the entire error object which includes the differing id rather than just the error response from the rpc.
Reproducible example: https://github.com/longbigbronzeelephantfish1/ethers-fallback-provider-bug
Code Snippet
Contract ABI
Errors
Environment
Ethereum (mainnet/ropsten/rinkeby/goerli), Altcoin - Please specify (e.g. Polygon), Browser (Chrome, Safari, etc)
Environment (Other)
No response
The text was updated successfully, but these errors were encountered: