internal/ethapi: return error when requesting invalid trie key (#25762)
This change makes eth_getProof and eth_getStorageAt return an error when the argument contains invalid hex in storage keys. Co-authored-by: Felix Lange <fjl@twurst.com>
This commit is contained in:
parent
d213cb0924
commit
8ade5e6c14
@ -18,6 +18,7 @@ package ethapi
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"encoding/hex"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
@ -674,15 +675,19 @@ func (s *BlockChainAPI) GetProof(ctx context.Context, address common.Address, st
|
|||||||
}
|
}
|
||||||
|
|
||||||
// create the proof for the storageKeys
|
// create the proof for the storageKeys
|
||||||
for i, key := range storageKeys {
|
for i, hexKey := range storageKeys {
|
||||||
|
key, err := decodeHash(hexKey)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
if storageTrie != nil {
|
if storageTrie != nil {
|
||||||
proof, storageError := state.GetStorageProof(address, common.HexToHash(key))
|
proof, storageError := state.GetStorageProof(address, key)
|
||||||
if storageError != nil {
|
if storageError != nil {
|
||||||
return nil, storageError
|
return nil, storageError
|
||||||
}
|
}
|
||||||
storageProof[i] = StorageResult{key, (*hexutil.Big)(state.GetState(address, common.HexToHash(key)).Big()), toHexSlice(proof)}
|
storageProof[i] = StorageResult{hexKey, (*hexutil.Big)(state.GetState(address, key).Big()), toHexSlice(proof)}
|
||||||
} else {
|
} else {
|
||||||
storageProof[i] = StorageResult{key, &hexutil.Big{}, []string{}}
|
storageProof[i] = StorageResult{hexKey, &hexutil.Big{}, []string{}}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -703,6 +708,22 @@ func (s *BlockChainAPI) GetProof(ctx context.Context, address common.Address, st
|
|||||||
}, state.Error()
|
}, state.Error()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// decodeHash parses a hex-encoded 32-byte hash. The input may optionally
|
||||||
|
// be prefixed by 0x and can have an byte length up to 32.
|
||||||
|
func decodeHash(s string) (common.Hash, error) {
|
||||||
|
if strings.HasPrefix(s, "0x") || strings.HasPrefix(s, "0X") {
|
||||||
|
s = s[2:]
|
||||||
|
}
|
||||||
|
b, err := hex.DecodeString(s)
|
||||||
|
if err != nil {
|
||||||
|
return common.Hash{}, fmt.Errorf("hex string invalid")
|
||||||
|
}
|
||||||
|
if len(b) > 32 {
|
||||||
|
return common.Hash{}, fmt.Errorf("hex string too long, want at most 32 bytes")
|
||||||
|
}
|
||||||
|
return common.BytesToHash(b), nil
|
||||||
|
}
|
||||||
|
|
||||||
// GetHeaderByNumber returns the requested canonical block header.
|
// GetHeaderByNumber returns the requested canonical block header.
|
||||||
// * When blockNr is -1 the chain head is returned.
|
// * When blockNr is -1 the chain head is returned.
|
||||||
// * When blockNr is -2 the pending chain head is returned.
|
// * When blockNr is -2 the pending chain head is returned.
|
||||||
@ -821,12 +842,16 @@ func (s *BlockChainAPI) GetCode(ctx context.Context, address common.Address, blo
|
|||||||
// GetStorageAt returns the storage from the state at the given address, key and
|
// GetStorageAt returns the storage from the state at the given address, key and
|
||||||
// block number. The rpc.LatestBlockNumber and rpc.PendingBlockNumber meta block
|
// block number. The rpc.LatestBlockNumber and rpc.PendingBlockNumber meta block
|
||||||
// numbers are also allowed.
|
// numbers are also allowed.
|
||||||
func (s *BlockChainAPI) GetStorageAt(ctx context.Context, address common.Address, key string, blockNrOrHash rpc.BlockNumberOrHash) (hexutil.Bytes, error) {
|
func (s *BlockChainAPI) GetStorageAt(ctx context.Context, address common.Address, hexKey string, blockNrOrHash rpc.BlockNumberOrHash) (hexutil.Bytes, error) {
|
||||||
state, _, err := s.b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash)
|
state, _, err := s.b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash)
|
||||||
if state == nil || err != nil {
|
if state == nil || err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
res := state.GetState(address, common.HexToHash(key))
|
key, err := decodeHash(hexKey)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("unable to decode storage key: %s", err)
|
||||||
|
}
|
||||||
|
res := state.GetState(address, key)
|
||||||
return res[:], state.Error()
|
return res[:], state.Error()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user