internal/ethapi: fix codehash lookup in eth_getProof

This commit is contained in:
Martin Holst Swende 2023-10-16 19:52:48 +02:00
parent 1e55e52b26
commit ca99a741c6
No known key found for this signature in database
GPG key ID: 683B438C05A5DDF0

View file

@ -676,8 +676,7 @@ func (s *BlockChainAPI) GetProof(ctx context.Context, address common.Address, st
keyLengths = make([]int, len(storageKeys)) keyLengths = make([]int, len(storageKeys))
storageProof = make([]StorageResult, len(storageKeys)) storageProof = make([]StorageResult, len(storageKeys))
storageTrie state.Trie storageRoot = types.EmptyRootHash
storageHash = types.EmptyRootHash
codeHash = types.EmptyCodeHash codeHash = types.EmptyCodeHash
) )
// Deserialize all keys. This prevents state access on invalid input. // Deserialize all keys. This prevents state access on invalid input.
@ -692,45 +691,40 @@ func (s *BlockChainAPI) GetProof(ctx context.Context, address common.Address, st
if state == nil || err != nil { if state == nil || err != nil {
return nil, err return nil, err
} }
if storageRoot := state.GetStorageRoot(address); storageRoot != types.EmptyRootHash && storageRoot != (common.Hash{}) { codeHash = state.GetCodeHash(address)
storageRoot = state.GetStorageRoot(address)
if len(keys) > 0 && storageRoot != types.EmptyRootHash && storageRoot != (common.Hash{}) { // Create storage proof
id := trie.StorageTrieID(header.Root, crypto.Keccak256Hash(address.Bytes()), storageRoot) id := trie.StorageTrieID(header.Root, crypto.Keccak256Hash(address.Bytes()), storageRoot)
tr, err := trie.NewStateTrie(id, state.Database().TrieDB()) storageTrie, err := trie.NewStateTrie(id, state.Database().TrieDB())
if err != nil { if err != nil {
return nil, err return nil, err
} }
storageTrie = tr // Create the proofs for the storageKeys.
} for i, key := range keys {
// If we have a storageTrie, the account exists and we must update // Output key encoding is a bit special: if the input was a 32-byte hash, it is
// the storage root hash and the code hash. // returned as such. Otherwise, we apply the QUANTITY encoding mandated by the
if storageTrie != nil { // JSON-RPC spec for getProof. This behavior exists to preserve backwards
storageHash = storageTrie.Hash() // compatibility with older client versions.
codeHash = state.GetCodeHash(address) var outputKey string
} if keyLengths[i] != 32 {
// Create the proofs for the storageKeys. outputKey = hexutil.EncodeBig(key.Big())
for i, key := range keys { } else {
// Output key encoding is a bit special: if the input was a 32-byte hash, it is outputKey = hexutil.Encode(key[:])
// returned as such. Otherwise, we apply the QUANTITY encoding mandated by the }
// JSON-RPC spec for getProof. This behavior exists to preserve backwards
// compatibility with older client versions.
var outputKey string
if keyLengths[i] != 32 {
outputKey = hexutil.EncodeBig(key.Big())
} else {
outputKey = hexutil.Encode(key[:])
}
if storageTrie == nil { if storageTrie == nil {
storageProof[i] = StorageResult{outputKey, &hexutil.Big{}, []string{}} storageProof[i] = StorageResult{outputKey, &hexutil.Big{}, []string{}}
continue continue
}
var proof proofList
if err := storageTrie.Prove(crypto.Keccak256(key.Bytes()), &proof); err != nil {
return nil, err
}
value := (*hexutil.Big)(state.GetState(address, key).Big())
storageProof[i] = StorageResult{outputKey, value, proof}
} }
var proof proofList
if err := storageTrie.Prove(crypto.Keccak256(key.Bytes()), &proof); err != nil {
return nil, err
}
value := (*hexutil.Big)(state.GetState(address, key).Big())
storageProof[i] = StorageResult{outputKey, value, proof}
} }
// Create the accountProof. // Create the accountProof.
tr, err := trie.NewStateTrie(trie.StateTrieID(header.Root), state.Database().TrieDB()) tr, err := trie.NewStateTrie(trie.StateTrieID(header.Root), state.Database().TrieDB())
if err != nil { if err != nil {
@ -746,7 +740,7 @@ func (s *BlockChainAPI) GetProof(ctx context.Context, address common.Address, st
Balance: (*hexutil.Big)(state.GetBalance(address)), Balance: (*hexutil.Big)(state.GetBalance(address)),
CodeHash: codeHash, CodeHash: codeHash,
Nonce: hexutil.Uint64(state.GetNonce(address)), Nonce: hexutil.Uint64(state.GetNonce(address)),
StorageHash: storageHash, StorageHash: storageRoot,
StorageProof: storageProof, StorageProof: storageProof,
}, state.Error() }, state.Error()
} }