From 8584fbe846133c89763fe622cb5c1c0bb161ec73 Mon Sep 17 00:00:00 2001 From: devopsbo3 <69951731+devopsbo3@users.noreply.github.com> Date: Fri, 10 Nov 2023 12:31:54 -0600 Subject: [PATCH] Revert "internal/ethapi: prevent unnecessary resource usage in eth_getProof implementation (#27310)" This reverts commit 4fb431188766005e72ed3fc4039d1df0d90aeb41. --- internal/ethapi/api.go | 65 +++++++++++++++--------------------------- 1 file changed, 23 insertions(+), 42 deletions(-) diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index 40cf6e131f543..080d809d38944 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -655,62 +655,43 @@ type StorageResult struct { Proof []string `json:"proof"` } -// proofList implements ethdb.KeyValueWriter and collects the proofs as -// hex-strings for delivery to rpc-caller. -type proofList []string - -func (n *proofList) Put(key []byte, value []byte) error { - *n = append(*n, hexutil.Encode(value)) - return nil -} - -func (n *proofList) Delete(key []byte) error { - panic("not supported") -} - // GetProof returns the Merkle-proof for a given account and optionally some storage keys. func (s *BlockChainAPI) GetProof(ctx context.Context, address common.Address, storageKeys []string, blockNrOrHash rpc.BlockNumberOrHash) (*AccountResult, error) { - var ( - keys = make([]common.Hash, len(storageKeys)) - storageProof = make([]StorageResult, len(storageKeys)) - storageTrie state.Trie - storageHash = types.EmptyRootHash - codeHash = types.EmptyCodeHash - ) - // Greedily deserialize all keys. This prevents state access on invalid input - for i, hexKey := range storageKeys { - if key, err := decodeHash(hexKey); err != nil { - return nil, err - } else { - keys[i] = key - } - } state, _, err := s.b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash) if state == nil || err != nil { return nil, err } - if storageTrie, err = state.StorageTrie(address); err != nil { + storageTrie, err := state.StorageTrie(address) + if err != nil { return nil, err } - // if we have a storageTrie, the account exists and we must update - // the storage root hash and the code hash. + storageHash := types.EmptyRootHash + codeHash := state.GetCodeHash(address) + storageProof := make([]StorageResult, len(storageKeys)) + + // if we have a storageTrie, (which means the account exists), we can update the storagehash if storageTrie != nil { storageHash = storageTrie.Hash() - codeHash = state.GetCodeHash(address) + } else { + // no storageTrie means the account does not exist, so the codeHash is the hash of an empty bytearray. + codeHash = crypto.Keccak256Hash(nil) } + // create the proof for the storageKeys - for i, key := range keys { - if storageTrie == nil { - storageProof[i] = StorageResult{storageKeys[i], &hexutil.Big{}, []string{}} - continue - } - var proof proofList - if err := storageTrie.Prove(crypto.Keccak256(key.Bytes()), 0, &proof); err != nil { + for i, hexKey := range storageKeys { + key, err := decodeHash(hexKey) + if err != nil { return nil, err } - storageProof[i] = StorageResult{storageKeys[i], - (*hexutil.Big)(state.GetState(address, key).Big()), - proof} + if storageTrie != nil { + proof, storageError := state.GetStorageProof(address, key) + if storageError != nil { + return nil, storageError + } + storageProof[i] = StorageResult{hexKey, (*hexutil.Big)(state.GetState(address, key).Big()), toHexSlice(proof)} + } else { + storageProof[i] = StorageResult{hexKey, &hexutil.Big{}, []string{}} + } } // create the accountProof