Skip to content

eth_getBlockReceipts contract drift: block-hash ReceiptSelector form is not supported #37

Description

@roninjin10

Summary

eth_getBlockReceipts does not honor the contract's ReceiptSelector union. Block-hash selectors are rejected because the handler always routes through numeric block-number resolution.

Why this matters

Clients using the documented hash selector form for receipts cannot query by canonical block hash.

Normative contract

  • docs/specs/json-rpc-contract.md:28 defines ReceiptSelector as one BlockTag or one Hash32 block hash.
  • docs/specs/json-rpc-contract.md:598 specifies eth_getBlockReceipts uses ReceiptSelector.

Evidence

Handler always resolves to block number:

  • src/rpc/handlers/block_query_handlers.zig:90-95
const block_number = block_spec.resolveBlockNumber(ctx.rt, params.block) ...
const block = try ctx.rt.getBlockByNumberWithFork(allocator, block_number);

Resolver treats any 0x... string as integer quantity parsing (not hash dispatch):

  • src/rpc/handlers/block_spec.zig:27-31
if (s.len >= 2 and s[0] == '0' and (s[1] == 'x' or s[1] == 'X')) {
    const num = std.fmt.parseInt(u64, s[2..], 16) ...

A 32-byte hash string therefore fails numeric parsing and cannot be used as selector.

Suggested scope

  • Extend eth_getBlockReceipts selector resolution to branch on Hash32 vs block tag/number.
  • Resolve hash selectors via getBlockByHashWithFork path.
  • Keep null semantics for canonical miss.
  • Add server-level tests for both selector forms (latest and explicit block hash).

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions