From a122dbe459932868a73fb937376c6badd01d364f Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Fri, 28 Nov 2025 11:28:31 +0100 Subject: [PATCH] internal/ethapi: return error code -32602 for invalid storage key (#33282) This was found because other clients are failing RPC tests generated by Geth. Nethermind and Besu return the correct error code, -32602, in this situation. --- internal/ethapi/api.go | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index d7cf47468c..997ed47926 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -374,9 +374,9 @@ func (api *BlockChainAPI) GetProof(ctx context.Context, address common.Address, // Deserialize all keys. This prevents state access on invalid input. for i, hexKey := range storageKeys { var err error - keys[i], keyLengths[i], err = decodeHash(hexKey) + keys[i], keyLengths[i], err = decodeStorageKey(hexKey) if err != nil { - return nil, err + return nil, &invalidParamsError{fmt.Sprintf("%v: %q", err, hexKey)} } } statedb, header, err := api.b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash) @@ -441,9 +441,10 @@ func (api *BlockChainAPI) GetProof(ctx context.Context, address common.Address, }, statedb.Error() } -// decodeHash parses a hex-encoded 32-byte hash. The input may optionally -// be prefixed by 0x and can have a byte length up to 32. -func decodeHash(s string) (h common.Hash, inputLength int, err error) { +// decodeStorageKey parses a hex-encoded 32-byte hash. +// For legacy compatibility reasons, we parse these keys leniently, +// with the 0x prefix being optional. +func decodeStorageKey(s string) (h common.Hash, inputLength int, err error) { if strings.HasPrefix(s, "0x") || strings.HasPrefix(s, "0X") { s = s[2:] } @@ -451,11 +452,11 @@ func decodeHash(s string) (h common.Hash, inputLength int, err error) { s = "0" + s } if len(s) > 64 { - return common.Hash{}, len(s) / 2, errors.New("hex string too long, want at most 32 bytes") + return common.Hash{}, len(s) / 2, errors.New("storage key too long (want at most 32 bytes)") } b, err := hex.DecodeString(s) if err != nil { - return common.Hash{}, 0, errors.New("hex string invalid") + return common.Hash{}, 0, errors.New("invalid hex in storage key") } return common.BytesToHash(b), len(b), nil } @@ -589,9 +590,9 @@ func (api *BlockChainAPI) GetStorageAt(ctx context.Context, address common.Addre if state == nil || err != nil { return nil, err } - key, _, err := decodeHash(hexKey) + key, _, err := decodeStorageKey(hexKey) if err != nil { - return nil, fmt.Errorf("unable to decode storage key: %s", err) + return nil, &invalidParamsError{fmt.Sprintf("%v: %q", err, hexKey)} } res := state.GetState(address, key) return res[:], state.Error()