Skip to content

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

@DragonDev1906

Description

@DragonDev1906

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.

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions