Skip to content

rpc: eth_getProof rejects genesis ("0x0"/"earliest") with "block not found" #22531

Description

@yperbasis

Surfaced by a Copilot review comment on #21293 (since split — the eth_getProof changes live in #22533); the behavior predates both, and #22533 only renames the variable on the guilty line.

Behavior

eth_getProof(addr, keys, "0x0") and eth_getProof(addr, keys, "earliest") return block not found even though block 0 exists and resolves successfully:

blockNumber, _, isLatest, err := rpchelper.GetCanonicalBlockNumber(ctx, blockNrOrHash, roTx, api._blockReader, nil)
if err != nil {
	return nil, err
} else if blockNumber == 0 {
	return nil, errors.New("block not found")
}

The sentinel is redundant for its apparent purpose: GetCanonicalBlockNumber already returns rpc.BlockNotFoundErr for unknown blocks (the !found path), so the only requests the blockNumber == 0 check actually affects are valid genesis/earliest ones. Geth serves genesis proofs.

Fix shape

Remove the sentinel — but as its own red→green cycle, not a drive-by: the historical-proof path needs validating at the block-0 edge first (txNumReader.Min(ctx, roTx, 1) for the rewind bound, commitment-history start, no-transactions block). Red-first test: eth_getProof at "earliest" on an unpruned test chain returns a proof that verifies against the genesis state root; on a node with pruned commitment history it returns the existing PrunedError, not block not found.

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions