-
Notifications
You must be signed in to change notification settings - Fork 21.4k
Closed
Labels
Description
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
- 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}
}
}
- 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.