web3 / web3.js

Collection of comprehensive TypeScript libraries for Interaction with the Ethereum JSON RPC API and utility functions.
https://web3js.org/
Other
19.21k stars 4.92k forks source link

Connection with provider is suddenly lost. #2916

Closed edzillion closed 5 years ago

edzillion commented 5 years ago

Description

Connection with provider is suddenly lost. Calls to web3.eth start returning

Error: Invalid JSON RPC response: ""

This is a react-native project. This issue happens the same on both Windows 8.1 using Android Studio emulator & MacOS High Sierra using XCode emulator

Expected behavior

Calling web3.eth.net.getId() should return the network id.

Actual behavior

Calling web3.eth.net.getId() returns Error: Invalid JSON RPC response: "".

Steps to reproduce the behavior

I am betting this wont be possible to repro as there are too many elements involved. The bug is in this package metatx-server

It crashes on the getGasPrice() call in the signRelayerTx func:

  async signRelayerTx (txHex) {

    let id = await this.web3.eth.net.getId()
    console.log('signRelayerTx: rpc network connected, id:' + id)

    if (!txHex) throw new Error('no txHex')
    const tx = new Transaction(Buffer.from(txHex, 'hex'))
    const signer = this.initSimpleSigner()
    const price = await this.web3.eth.getGasPrice()
    tx.gasPrice = new this.BN(price).toNumber()
    tx.nonce = await this.web3.eth.getTransactionCount(signer.getAddress())
    const estimatedGas = await this.estimateGas(tx, signer.getAddress())
    // add some buffer to the limit
    tx.gasLimit = estimatedGas.add(new this.BN(1000000))
    const rawTx = tx.serialize().toString('hex')
    return new Promise((resolve, reject) => {
      signer.signRawTx(rawTx, (error, signedRawTx) => {
        if (error) reject(error)
        resolve(signedRawTx)
      })
    })
  }

The console log at the top of the function block works fine:

> signRelayerTx: rpc network connected, id:5777

But by the time it hits the getGasPrice call the network is lost and any call to web3.eth returns the same error:

Error: Invalid JSON RPC response: "".

The ganache-cli output seems to show that the blockchain continues on fine without an error (?):

net_version
eth_gasPrice
eth_getTransactionCount
eth_estimateGas

Versions

edzillion commented 5 years ago

trapped the error

Error: Connection refused or URL couldn't be resolved: http://192.168.99.100:8545
    at XMLHttpRequest.request.onreadystatechange (d:\dev\circles\circles-api\node_modules\web3-providers\dist\web3-providers.cjs.js:759:22)
    at XMLHttpRequestEventTarget.dispatchEvent (d:\dev\circles\circles-api\node_modules\xhr2-cookies\dist\xml-http-request-event-target.js:34:22)
    at XMLHttpRequest._setReadyState (d:\dev\circles\circles-api\node_modules\xhr2-cookies\dist\xml-http-request.js:208:14)
    at XMLHttpRequest._onHttpRequestError (d:\dev\circles\circles-api\node_modules\xhr2-cookies\dist\xml-http-request.js:349:14)
    at ClientRequest.<anonymous> (d:\dev\circles\circles-api\node_modules\xhr2-cookies\dist\xml-http-request.js:252:61)
    at ClientRequest.emit (events.js:198:13)
    at ClientRequest.EventEmitter.emit (domain.js:448:20)
    at Socket.socketErrorListener (_http_client.js:392:9)
    at Socket.emit (events.js:198:13)
    at Socket.EventEmitter.emit (domain.js:448:20)
    at emitErrorNT (internal/streams/destroy.js:91:8)
    at emitErrorAndCloseNT (internal/streams/destroy.js:59:3)
    at process._tickCallback (internal/process/next_tick.js:63:19)
edzillion commented 5 years ago

hmmm. If I let it run without stopping at breakpoints I instead get this error:

Node error: {"message":"VM Exception while processing transaction: revert","code":-32000,"data":{"stack":"o: VM Exception while processing transaction: revert\n    at Function.o.fromResults (/app/ganache-core.docker.cli.js:10:82299)\n    at /app/ganache-core.docker.cli.js:47:150985\n    at /app/ganache-core.docker.cli.js:61:1684702\n    at /app/ganache-core.docker.cli.js:2:69007\n    at i (/app/ganache-core.docker.cli.js:2:84062)\n    at /app/ganache-core.docker.cli.js:61:1041954\n    at /app/ganache-core.docker.cli.js:2:148305\n    at /app/ganache-core.docker.cli.js:32:392\n    at c (/app/ganache-core.docker.cli.js:32:5407)\n    at /app/ganache-core.docker.cli.js:32:317\n    at /app/ganache-core.docker.cli.js:61:1703080\n    at /app/ganache-core.docker.cli.js:2:66120\n    at o (/app/ganache-core.docker.cli.js:2:69529)\n    at /app/ganache-core.docker.cli.js:2:69007\n    at /app/ganache-core.docker.cli.js:61:1696165\n    at /app/ganache-core.docker.cli.js:61:1694028\n    at /app/ganache-core.docker.cli.js:61:1721192\n    at /app/ganache-core.docker.cli.js:2:66120\n    at o (/app/ganache-core.docker.cli.js:2:69529)\n    at /app/ganache-core.docker.cli.js:2:69007\n    at /app/ganache-core.docker.cli.js:2:5342\n    at FSReqWrap.oncomplete (fs.js:141:20)","name":"o"}} Error: Node error: {"message":"VM Exception while processing transaction: revert","code":-32000,"data":{"stack":"o: VM Exception while processing transaction: revert\n    at Function.o.fromResults (/app/ganache-core.docker.cli.js:10:82299)\n    at /app/ganache-core.docker.cli.js:47:150985\n    at /app/ganache-core.docker.cli.js:61:1684702\n    at /app/ganache-core.docker.cli.js:2:69007\n    at i (/app/ganache-core.docker.cli.js:2:84062)\n    at /app/ganache-core.docker.cli.js:61:1041954\n    at /app/ganache-core.docker.cli.js:2:148305\n    at /app/ganache-core.docker.cli.js:32:392\n    at c (/app/ganache-core.docker.cli.js:32:5407)\n    at /app/ganache-core.docker.cli.js:32:317\n    at /app/ganache-core.docker.cli.js:61:1703080\n    at /app/ganache-core.docker.cli.js:2:66120\n    at o (/app/ganache-core.docker.cli.js:2:69529)\n    at /app/ganache-core.docker.cli.js:2:69007\n    at /app/ganache-core.docker.cli.js:61:1696165\n    at /app/ganache-core.docker.cli.js:61:1694028\n    at /app/ganache-core.docker.cli.js:61:1721192\n    at /app/ganache-core.docker.cli.js:2:66120\n    at o (/app/ganache-core.docker.cli.js:2:69529)\n    at /app/ganache-core.docker.cli.js:2:69007\n    at /app/ganache-core.docker.cli.js:2:5342\n    at FSReqWrap.oncomplete (fs.js:141:20)","name":"o"}}
    at Function.validate (d:\dev\circles\circles-api\node_modules\web3-providers\dist\web3-providers.cjs.js:114:18)
    at HttpProvider._callee$ (d:\dev\circles\circles-api\node_modules\web3-providers\dist\web3-providers.cjs.js:710:61)
    at tryCatch (d:\dev\circles\circles-api\node_modules\@babel\runtime\node_modules\regenerator-runtime\runtime.js:45:40)
    at Generator.invoke [as _invoke] (d:\dev\circles\circles-api\node_modules\@babel\runtime\node_modules\regenerator-runtime\runtime.js:271:22)
    at Generator.prototype.(anonymous function) [as next] (d:\dev\circles\circles-api\node_modules\@babel\runtime\node_modules\regenerator-runtime\runtime.js:97:21)
    at asyncGeneratorStep (d:\dev\circles\circles-api\node_modules\@babel\runtime\helpers\asyncToGenerator.js:3:24)
    at _next (d:\dev\circles\circles-api\node_modules\@babel\runtime\helpers\asyncToGenerator.js:25:9)
    at process._tickCallback (internal/process/next_tick.js:68:7)
edzillion commented 5 years ago

I think what is happening is that the connection is being lost at a later point. I have been following through and simplifying things and I can get it to a later point where it fails:

this.web3.eth.sendSignedTransaction(signedRawTx, (error, txHash) => {
        if (error) reject(error)
        resolve(txHash)
      })
ehanoc commented 5 years ago

@edzillion i've experienced the same just recently, but with version beta37.

Is it clear if web3js is meant to re-establish connection to the provider on it's own by design? Do you know?

edzillion commented 5 years ago

Is it clear if web3js is meant to re-establish connection to the provider on it's own by design? Do you know?

Not sure what you mean by this? I didn't think it would need to re-establish a connection at all.

In my case the provider is instantiated like so: const provider = new Web3.providers.HttpProvider(rpcUrl)

and then in the component itself I just pass in the provider: this.web3 = new Web3(provider)

ehanoc commented 5 years ago

I mean that web3.js is suppose to attempt to re-establish connection on it's own

https://github.com/ethereum/web3.js/search?q=reconnect%28%29&unscoped_q=reconnect%28%29 https://github.com/ethereum/web3.js/search?q=reconnect%28%29&type=Commits

You should only need to instantiate provider once

edzillion commented 5 years ago

Interesting. Is there a way to listen for those events (like event.code === 'ECONNREFUSED' etc)?

edzillion commented 5 years ago

I noticed that HttpProvider is deprecated and thought to try WebsocketProvider instead, which does not have the connection issue.

edzillion commented 5 years ago

Not entirely clear what was going on with this but changing to WebsocketProvider resolved it for me