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: "block" query ignores hash if both hash and number are present #25899

Closed
DragonDev1906 opened this issue Sep 30, 2022 · 2 comments · Fixed by #27876
Closed

GraphQL: "block" query ignores hash if both hash and number are present #25899

DragonDev1906 opened this issue Sep 30, 2022 · 2 comments · Fixed by #27876
Assignees
Labels

Comments

@DragonDev1906
Copy link
Contributor

DragonDev1906 commented Sep 30, 2022

System information

Geth version: 1.10.25-stable (and current master)

Expected behaviour

Requesting a block by hash AND number using graphql should only return the block if both are valid.

Actual behaviour

If both arguments are set Go-Ethereum only cares about the number and ignores the hash argument. This could cause an unsuspecting user to assume he got the block he wants.

The query description does not inform the user about this (non-intuitive in my opinion) behavior either:

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

Steps to reproduce the behaviour

  1. Submit the following GraphQL request to Go-Ethereum (with hash beeing different from the real hash at that number, this is on Goerli):
query testBlockWithConflictingHashAndNumber {
  conflicting:block(number:7670343, hash:"0x37bea088a214c679358d6af9d54442151ec34cb5dcc58f0f5b6e572e01e6ed1f") {
    number
    hash
    parent{hash}
  }
  number:block(number:7670343) {
    number
    hash
    parent{hash}
  }
  hash:block(hash:"0x37bea088a214c679358d6af9d54442151ec34cb5dcc58f0f5b6e572e01e6ed1f") {
    number
    hash
    parent{hash}
  }
}
  1. Look at the response. The first entry returns a block with the expected number but a different hash, completely ignoring the hash argument instead of detecting this and returning there is no block with this hash and number.
{
  "data": {
    "conflicting": {
      "number": 7670343,
      "hash": "0x3ae1a25a8c75226ca7fc2904a833d1fdb252dd69268b1bcc2139388bd190b8bb",
      "parent": {
        "hash": "0x37bea088a214c679358d6af9d54442151ec34cb5dcc58f0f5b6e572e01e6ed1f"
      }
    },
    "number": {
      "number": 7670343,
      "hash": "0x3ae1a25a8c75226ca7fc2904a833d1fdb252dd69268b1bcc2139388bd190b8bb",
      "parent": {
        "hash": "0x37bea088a214c679358d6af9d54442151ec34cb5dcc58f0f5b6e572e01e6ed1f"
      }
    },
    "hash": {
      "number": 7670342,
      "hash": "0x37bea088a214c679358d6af9d54442151ec34cb5dcc58f0f5b6e572e01e6ed1f",
      "parent": {
        "hash": "0x3bf17cb2276be603000a7a45678ecb1ed0b432c0309de9a5611f17381a367204"
      }
    }
  }
}

Edit:
This becomes even clearer when setting hash to 0x0000..0000:


query testBlockWithConflictingHashAndNumber {
  conflicting:block(number:7670343, hash:"0x0000000000000000000000000000000000000000000000000000000000000000") {
    number
    hash
    parent{hash}
  }
  number:block(number:7670343) {
    number
    hash
    parent{hash}
  }
  hash:block(hash:"0x0000000000000000000000000000000000000000000000000000000000000000") {
    number
    hash
    parent{hash}
  }

Results in:

{
  "errors": [
    {
      "message": "header for hash not found",
      "path": [
        "hash"
      ]
    }
  ],
  "data": {
    "conflicting": {
      "number": 7670343,
      "hash": "0x3ae1a25a8c75226ca7fc2904a833d1fdb252dd69268b1bcc2139388bd190b8bb",
      "parent": {
        "hash": "0x37bea088a214c679358d6af9d54442151ec34cb5dcc58f0f5b6e572e01e6ed1f"
      }
    },
    "number": {
      "number": 7670343,
      "hash": "0x3ae1a25a8c75226ca7fc2904a833d1fdb252dd69268b1bcc2139388bd190b8bb",
      "parent": {
        "hash": "0x37bea088a214c679358d6af9d54442151ec34cb5dcc58f0f5b6e572e01e6ed1f"
      }
    },
    "hash": null
  }
}

And happily returns the "conflicting" block.

@holiman
Copy link
Contributor

holiman commented Sep 30, 2022

If this is the specification:

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

Then I'd say the behaviour when both are supplied is undefined. But I don't know if there exist any official spec for this.. ?

@DragonDev1906
Copy link
Contributor Author

Only the stagnant EIP-1767 as far as I know, which does not define a behavior for this case either.

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

Successfully merging a pull request may close this issue.

3 participants