Skip to content

spec: allow EIP-1898 block objects in BlockNumberOrTagOrHash - #859

Open
MysticRyuujin wants to merge 1 commit into
ethereum:mainfrom
MysticRyuujin:eip1898-block-object
Open

spec: allow EIP-1898 block objects in BlockNumberOrTagOrHash#859
MysticRyuujin wants to merge 1 commit into
ethereum:mainfrom
MysticRyuujin:eip1898-block-object

Conversation

@MysticRyuujin

@MysticRyuujin MysticRyuujin commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Closes #713 (mostly)

EIP-1898 defines two object forms for the block parameter: {"blockNumber": ...} and
{"blockHash": ..., "requireCanonical": ...}. Clients accept them, but the schema only
allowed a number, a tag, or a bare hash. So the spec rejected valid requests.

This adds both object forms to the union. additionalProperties: false keeps the two
shapes distinct, and requireCanonical stays optional on the hash form.

The change applies to every method that uses BlockNumberOrTagOrHash: eth_call,
eth_simulateV1, eth_getBlockReceipts, eth_getBlockAccessList, eth_getBalance,
eth_getStorageAt, eth_getStorageValues, eth_getTransactionCount, eth_getCode
and eth_getProof.

On errors, the schema documents what EIP-1898 recommends: -32000: Invalid input when
requireCanonical is true and the block is not canonical, and -32001: Resource not found when the block does not exist. A missing block takes precedence. This is a
description only. The codes are not added to the methods' errors lists, so nothing
enforces them. Say the word if you want them enforced instead.

New tests cover the object forms in three parameter positions:

  • eth_getBalance with blockNumber, with blockHash, and with blockHash plus
    requireCanonical
  • eth_call, which uses the callenv contract so a client that ignores the block
    parameter fails
  • eth_getProof, which targets head rather than a historical block, because clients
    bound how far back they serve proofs

EIP-1898 lets state-access methods take the block parameter as an object,
either {"blockNumber": "0x..."} or {"blockHash": "0x...",
"requireCanonical": bool}. The spec only described the string forms, so
speccheck rejected the object form outright.

Add both shapes as anyOf branches and cover them with tests on
eth_getBalance, eth_call and eth_getProof. The branches set
additionalProperties: false, so an object combining blockNumber and
blockHash is invalid.

The non-canonical case stays untested: the test chain has no sidechain, so
there is no way to reference a non-canonical block.

@bomanaps bomanaps left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

:shipit: looks good

Comment thread src/schemas/block.yaml
$ref: '#/components/schemas/BlockTag'
- title: Block hash
$ref: '#/components/schemas/hash32'
- title: EIP-1898 block number object

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

does this have to be a separate object? ideally it would be an optional value on "Block Number" and "Block hash" object?

@MysticRyuujin MysticRyuujin Aug 10, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Can you elaborate on this question?

The options are basically:

"0x1234" - a Block Number
"0x..." - a Block Hash

or and object {} that object can be one of:

{"blockNumber":"0x1234"...}
{"blockHash":"0x...","requireCanonical":true|false,...}

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.

Fully apply EIP-1898 in specs

3 participants