Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add id to all JSON RPC calls like in advanceBlock #56

Closed
cnasikas opened this issue Jun 9, 2019 · 13 comments
Closed

Add id to all JSON RPC calls like in advanceBlock #56

cnasikas opened this issue Jun 9, 2019 · 13 comments
Labels
bug Something isn't working

Comments

@cnasikas
Copy link

cnasikas commented Jun 9, 2019

Hi

The advanceBlock function does not provide an id as a property. The web3-provider-ws package uses the id as follows:

WebsocketProvider.prototype._addResponseCallback = function(payload, callback) {
    var id = payload.id || payload[0].id;
    var method = payload.method || payload[0].method;

    this.responseCallbacks[id] = callback;
    this.responseCallbacks[id].method = method;

    // more code....
};

The line var id = payload.id || payload[0].id; will produce an error when an id is undefined

The same checks is presented in the new version of web3.

Thanks a lot!

@nventuro
Copy link
Contributor

Hello @cnasikas, thanks for reporting this! It that behavior present in v1.0-beta.37 of web3-provider-ws, or was it introduced recently? We may want to add tests using different providers to make sure the test helpers can be used with all of them.

I'm curious, why are you running tests using a websocket provider?

@cnasikas
Copy link
Author

cnasikas commented Jun 10, 2019

Hi @nventuro

You are welcome! If you remember from #35 we use your helpers for different purpose than running tests.

The behavior is presented in v1.0-beta.37. I do not know if it presented in previous versions. In v1.0-beta.55 is presented also.

@frangio
Copy link
Contributor

frangio commented Jun 10, 2019

@cnasikas Do you know if this id is documented anywhere?

@cnasikas
Copy link
Author

From https://www.jsonrpc.org/specification#request_object and https://github.com/ethereum/wiki/wiki/JSON-RPC

id
An identifier established by the Client that MUST contain a String, Number, or NULL value if included. If it is not included it is assumed to be a notification. The value SHOULD normally not be Null [1] and Numbers SHOULD NOT contain fractional parts [2]

@cnasikas
Copy link
Author

cnasikas commented Jun 10, 2019

As far I understand the id is used as an identifier for a listener. For example in web3js beta.55:

if (isArray(payload)) {
    id = payload[0].id;
} else {
    id = payload.id;
}

this.once(id, (response) => {
    if (timeout) {
        clearTimeout(timeout);
    }

    this.removeListener('error', reject);

    return resolve(response);
});

@frangio
Copy link
Contributor

frangio commented Jun 10, 2019

Makes sense.

You're not guaranteed to get your answers back in the order you asked for them; the id is to help you sort that out.

From Stack Overflow.

@frangio frangio changed the title advanceBlock - Websocket Provider Add id to all JSON RPC calls like in advanceBlock Jun 10, 2019
@frangio frangio added the bug Something isn't working label Jun 10, 2019
@frangio
Copy link
Contributor

frangio commented Jun 10, 2019

Does the id need to be unique every time? I can't find any info on this.

@cnasikas
Copy link
Author

That's a good question. I was thinking myself the same. What will happen if you have two requests with the same id ? If the ID is only used as an event name when you register to a listener then if you register multiple callbacks (one for each requests) to the same event normally all will be fired, right ?

@cnasikas
Copy link
Author

cnasikas commented Jun 10, 2019

I think it should be unique just in case but I am not sure if it is the correct approach.

@cnasikas
Copy link
Author

Metamask's id generator function:

https://github.com/MetaMask/metamask-extension/blob/develop/app/scripts/lib/random-id.js

@nventuro
Copy link
Contributor

nventuro commented Jun 11, 2019

We can probably address this in a 0.4.1 bugfix release.

@cnasikas have you by chance tried this fix locally, to check that it does solve your issue? Also, if you could provide a short snippet that triggers the bug, for us to add as a new test, that'd be great :)

@cnasikas
Copy link
Author

cnasikas commented Jun 25, 2019

@nventuro Sorry for the late response. I tried to fix it locally as follows and it resolves my issue (the id should be change to something unique).

const _ = require('lodash')
const { promisify } = require('util')

const advanceBlock = async (num = 1) => {
  for (const n in _.range(num)) {
    await promisify(web3.currentProvider.send.bind(web3.currentProvider))({
      jsonrpc: '2.0',
      method: 'evm_mine',
      id: n
    })
  }
}

await advanceBlock()

Snippet that triggers the bug:

const Web3 = require('web3')

const web3 = new Web3(new Web3.providers.WebsocketProvider('ws://localhost:7545'))

require('openzeppelin-test-helpers/configure')({ web3 })

const { time } = require('openzeppelin-test-helpers')

const main = async () => {
  await time.advanceBlock()
}

main()
  .catch(err => console.log(err))

@nventuro
Copy link
Contributor

Closed via #92

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants