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).
Summary
eth_getBlockReceiptsdoes not honor the contract'sReceiptSelectorunion. 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:28definesReceiptSelectoras oneBlockTagor oneHash32block hash.docs/specs/json-rpc-contract.md:598specifieseth_getBlockReceiptsusesReceiptSelector.Evidence
Handler always resolves to block number:
src/rpc/handlers/block_query_handlers.zig:90-95Resolver treats any
0x...string as integer quantity parsing (not hash dispatch):src/rpc/handlers/block_spec.zig:27-31A 32-byte hash string therefore fails numeric parsing and cannot be used as selector.
Suggested scope
eth_getBlockReceiptsselector resolution to branch onHash32vs block tag/number.getBlockByHashWithForkpath.nullsemantics for canonical miss.latestand explicit block hash).