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

graphql: use a decimal representation for gas limit and gas used #21883

Merged
merged 10 commits into from
Jan 5, 2021

Conversation

atoulme
Copy link
Contributor

@atoulme atoulme commented Nov 21, 2020

No description provided.

@fjl fjl changed the title Use a decimal representation for gas limit and gas used graphql: use a decimal representation for gas limit and gas used Nov 23, 2020
@renaynay
Copy link
Contributor

Here's the diff from Hive of the control (graphql tested on master) vs. on this branch:

diff graphql_control.log graphql_use_longs.log| colordiff
348,349c348,349
<       "gasLimit": "0x2fefd8",
<       "gasUsed": "0x5c21",
---
>       "gasLimit": 3141592,
>       "gasUsed": 23585,
407,484d406
< Test failed.
< HTTP response code: 200 OK
< expected: {
<   "data": {
<     "block": {
<       "account": {
<         "balance": "0x12c"
<       },
<       "difficulty": "0x20740",
<       "extraData": "0x",
<       "gasLimit": 3141592,
<       "gasUsed": 23585,
<       "hash": "0xc8df1f061abb4d0c107b2b1a794ade8780b3120e681f723fe55a7be586d95ba6",
<       "logsBloom": "0x00000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000080000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000400000000000000000200000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000800000000040000000000000000000000000000000000000000010000000000000000000000000",
<       "miner": {
<         "address": "0x8888f1f195afa192cfee860698584c030f4c9db1"
<       },
<       "mixHash": "0x6ce1c4afb4f85fefd1b0ed966b20cd248f08d9a5b0df773f75c6c2f5cc237b7c",
<       "nonce": "0x5c321bd9e9f040f1",
<       "ommerAt": null,
<       "ommerCount": 0,
<       "ommerHash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
<       "ommers": [],
<       "parent": {
<         "hash": "0xf8cfa377bd766cdf22edb388dd08cc149e85d24f2796678c835f3c54ab930803"
<       },
<       "receiptsRoot": "0x88b3b304b058b39791c26fdb94a05cc16ce67cf8f84f7348cb3c60c0ff342d0d",
<       "stateRoot": "0xdb46d6bb168130fe2cb60b4b24346137b5741f11283e0d7edace65c5f5466b2e",
<       "timestamp": "0x561bc336",
<       "totalDifficulty": "0x3e6cc0",
<       "transactionCount": 1,
<       "transactions": [
<         {
<           "hash": "0x9cc6c7e602c56aa30c554bb691377f8703d778cec8845f4b88c0f72516b304f4"
<         }
<       ],
<       "transactionsRoot": "0x5a8d5d966b48e1331ae19eb459eb28882cdc7654e615d37774b79204e875dc01"
<     }
<   }
< }
< got: {
<   "data": {
<     "block": {
<       "account": {
<         "balance": "0x12c"
<       },
<       "difficulty": "0x20740",
<       "extraData": "0x",
<       "gasLimit": "0x2fefd8",
<       "gasUsed": "0x5c21",
<       "hash": "0xc8df1f061abb4d0c107b2b1a794ade8780b3120e681f723fe55a7be586d95ba6",
<       "logsBloom": "0x00000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000080000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000400000000000000000200000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000800000000040000000000000000000000000000000000000000010000000000000000000000000",
<       "miner": {
<         "address": "0x8888f1f195afa192cfee860698584c030f4c9db1"
<       },
<       "mixHash": "0x6ce1c4afb4f85fefd1b0ed966b20cd248f08d9a5b0df773f75c6c2f5cc237b7c",
<       "nonce": "0x5c321bd9e9f040f1",
<       "ommerAt": null,
<       "ommerCount": 0,
<       "ommerHash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
<       "ommers": [],
<       "parent": {
<         "hash": "0xf8cfa377bd766cdf22edb388dd08cc149e85d24f2796678c835f3c54ab930803"
<       },
<       "receiptsRoot": "0x88b3b304b058b39791c26fdb94a05cc16ce67cf8f84f7348cb3c60c0ff342d0d",
<       "stateRoot": "0xdb46d6bb168130fe2cb60b4b24346137b5741f11283e0d7edace65c5f5466b2e",
<       "timestamp": "0x561bc336",
<       "totalDifficulty": "0x3e6cc0",
<       "transactionCount": 1,
<       "transactions": [
<         {
<           "hash": "0x9cc6c7e602c56aa30c554bb691377f8703d778cec8845f4b88c0f72516b304f4"
<         }
<       ],
<       "transactionsRoot": "0x5a8d5d966b48e1331ae19eb459eb28882cdc7654e615d37774b79204e875dc01"
<     }
<   }
< }
550,605d471
<     "block": {
<       "difficulty": "0x20740",
<       "extraData": "0x",
<       "gasLimit": 3141592,
<       "gasUsed": 23585,
<       "hash": "0xc8df1f061abb4d0c107b2b1a794ade8780b3120e681f723fe55a7be586d95ba6",
<       "logsBloom": "0x00000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000080000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000400000000000000000200000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000800000000040000000000000000000000000000000000000000010000000000000000000000000",
<       "mixHash": "0x6ce1c4afb4f85fefd1b0ed966b20cd248f08d9a5b0df773f75c6c2f5cc237b7c",
<       "nonce": "0x5c321bd9e9f040f1",
<       "ommerCount": 0,
<       "ommerHash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
<       "receiptsRoot": "0x88b3b304b058b39791c26fdb94a05cc16ce67cf8f84f7348cb3c60c0ff342d0d",
<       "stateRoot": "0xdb46d6bb168130fe2cb60b4b24346137b5741f11283e0d7edace65c5f5466b2e",
<       "timestamp": "0x561bc336",
<       "totalDifficulty": "0x3e6cc0",
<       "transactionCount": 1,
<       "transactions": [
<         {
<           "hash": "0x9cc6c7e602c56aa30c554bb691377f8703d778cec8845f4b88c0f72516b304f4"
<         }
<       ],
<       "transactionsRoot": "0x5a8d5d966b48e1331ae19eb459eb28882cdc7654e615d37774b79204e875dc01"
<     }
<   }
< }
< got: {
<   "data": {
<     "block": {
<       "difficulty": "0x20740",
<       "extraData": "0x",
<       "gasLimit": "0x2fefd8",
<       "gasUsed": "0x5c21",
<       "hash": "0xc8df1f061abb4d0c107b2b1a794ade8780b3120e681f723fe55a7be586d95ba6",
<       "logsBloom": "0x00000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000080000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000400000000000000000200000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000800000000040000000000000000000000000000000000000000010000000000000000000000000",
<       "mixHash": "0x6ce1c4afb4f85fefd1b0ed966b20cd248f08d9a5b0df773f75c6c2f5cc237b7c",
<       "nonce": "0x5c321bd9e9f040f1",
<       "ommerCount": 0,
<       "ommerHash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
<       "receiptsRoot": "0x88b3b304b058b39791c26fdb94a05cc16ce67cf8f84f7348cb3c60c0ff342d0d",
<       "stateRoot": "0xdb46d6bb168130fe2cb60b4b24346137b5741f11283e0d7edace65c5f5466b2e",
<       "timestamp": "0x561bc336",
<       "totalDifficulty": "0x3e6cc0",
<       "transactionCount": 1,
<       "transactions": [
<         {
<           "hash": "0x9cc6c7e602c56aa30c554bb691377f8703d778cec8845f4b88c0f72516b304f4"
<         }
<       ],
<       "transactionsRoot": "0x5a8d5d966b48e1331ae19eb459eb28882cdc7654e615d37774b79204e875dc01"
<     }
<   }
< }
< Test failed.
< HTTP response code: 200 OK
< expected: {
<   "data": {
1096,1097c962,963
<         "gasLimit": "0x2fefd8",
<         "gasUsed": "0x5c21",
---
>         "gasLimit": 3141592,
>         "gasUsed": 23585,
1106,1107c972,973
<         "gasLimit": "0x2fefd8",
<         "gasUsed": "0x5eef",
---
>         "gasLimit": 3141592,
>         "gasUsed": 24303,
1116,1117c982,983
<         "gasLimit": "0x2fefd8",
<         "gasUsed": "0x5c99",
---
>         "gasLimit": 3141592,
>         "gasUsed": 23705,

@holiman
Copy link
Contributor

holiman commented Nov 25, 2020

This now needs a rebase

Copy link
Contributor

@renaynay renaynay left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM -- this change would increase geth's conformance to the graphql spec

@atoulme
Copy link
Contributor Author

atoulme commented Nov 27, 2020

Rebased.

Copy link
Contributor

@holiman holiman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some comments + questions

Comment on lines 53 to 56
case string:
value, err := strconv.ParseUint(input, 10, 64)
*b = Long(value)
return err
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This feels a bit breaking. Generally, when interacting with geth, you can feed it strings representing integers. In all those cases, the string is 0x-prefixed hex encodings. Now, in this particular instance, you have to feed it "10" instead of "0x0a".

So basically, some options are :

  • Allow 0x-prefixed hex-encoded strings on input, and non-0x-prefixed decimal encoded strings,
  • Only allow non-0x-prefixed decimal encoded strings (the way it is in this PR)
  • Reject string-encoded values

I'm not sure which is best, just wanted to raise the topic.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, actually, I don't quite get this.
If I modify the testcase like so:

	body := strings.NewReader(`{"query": "{block(number:\"0\"){number,gasUsed,gasLimit}}","variables": null}`)

Then I get

        	            	expected: "{\"data\":{\"block\":{\"number\":0,\"gasUsed\":0,\"gasLimit\":11500000}}}"
        	            	actual  : "{\"errors\":[{\"message\":\"hex string without 0x prefix\"}],\"data\":{}}"

So it appears that block number selectors on input are still required to be 0x-prefixed (if strings).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a bug. I'll fix it now.

The schema of the EIP is clear: decimals only. You can probably support strings for hex values but that's beyond what the spec recommends and won't be in line with other clients.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 ambiguity == bad, strictness == good

header, err := b.resolveHeader(ctx)
if err != nil {
return 0, err
return Long(0), err
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

explicit cast not needed, you can leave this as it was

Suggested change
return Long(0), err
return 0, err

@holiman
Copy link
Contributor

holiman commented Nov 27, 2020

I pushed some changes, mainly to make the tests table-driven. I also added a couple of tests, one which shows that a common graphql query to get a specific block now fails, due to some dissonance about whether the number is int32 or int64.

I don't really know why one is to be preferred over another (although geth typically uses a third option normally, uint64). So there are some TODO's still left here.

@atoulme
Copy link
Contributor Author

atoulme commented Nov 28, 2020

OK, I fixed the tests. Take a look?

Copy link
Contributor

@holiman holiman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Almost done :)

graphql/graphql.go Show resolved Hide resolved
code int
}{
{
name: "get_number",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO, making tests table-driven makes it easier to just dump in new test-vectors without having to do a lot of work. Having a name on each vector may look "nice", but also makes "dump in X new test vectors" more laborious.

Not a blocker though, leave them in if you feel like it

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm old - I can't count. I get interrupted by kids when I count to 7.
I'll find a compromise.

},
// uncomment to test hex string support
//{
// name: "string_0x0",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah let's either uncomment or remove these. The tests run blazing fast now that they reuse the same stack, so IMO just uncomment them (and add whatever the response is) for more coverage.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code enabling this behavior is commented out too.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My view on this: We should get the EIP updated before this gets uncommented.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll push a change to show what I mean. If we don't support it, the tests should be there anyway, to 'cement' the behaviour of not supporting it. If we decide to support it, then we change the test. Tests are good to prevent accidental changes.

Copy link
Contributor

@holiman holiman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Notes for other reviewers, or release-notes. This PR contains some backwards-incompatible change, in that

  • hex-strings are no longer allowed in graphql selectors/filters, and
  • the number -1 can no longer be used to select latest.

@fjl fjl removed the status:triage label Dec 8, 2020
@fjl fjl added this to the 1.10.0 milestone Dec 8, 2020
@fjl
Copy link
Contributor

fjl commented Dec 8, 2020

Note to self: need to figure out if this breaks getting the latest block

@holiman
Copy link
Contributor

holiman commented Dec 12, 2020

Note to self: need to figure out if this breaks getting the latest block

Or perhaps @atoulme can answer: What is the 'correct' way to write a query that returns you the gas limit for the latest block?

Historically, the string latest or the number -1 have been used for this purpose, which IIUC is not supported with this PR.

@atoulme
Copy link
Contributor Author

atoulme commented Dec 12, 2020

Spec says:

# Block fetches an Ethereum block by number or by hash. If neither is
    # supplied, the most recent known block is returned.

@atoulme
Copy link
Contributor Author

atoulme commented Dec 12, 2020

And iirc that’s what geth code does. No number or hash passed in? Apply -1 for latest.

@holiman
Copy link
Contributor

holiman commented Dec 13, 2020

We should change the tests so that it actually contains some blocks, and not just a genesis.

@holiman
Copy link
Contributor

holiman commented Dec 14, 2020

I have now modified the test so that it imports 10 blocks, and indeed, unless a block number is given, it does return info about the latest block.
@fjl PTAL

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants