diff options
author | jwasinger <j-wasinger@hotmail.com> | 2019-07-13 21:48:55 +0800 |
---|---|---|
committer | Felix Lange <fjl@twurst.com> | 2019-07-13 21:48:55 +0800 |
commit | 6bd896a97f0c86fdb6d0538f5f839d7ea104e888 (patch) | |
tree | d17ca465e4c3ea73e187d7b469508c94d94d27e8 /eth/api.go | |
parent | 49a7ee460e839499ef41f5110b219ec8c8edc5e8 (diff) | |
download | go-tangerine-6bd896a97f0c86fdb6d0538f5f839d7ea104e888.tar go-tangerine-6bd896a97f0c86fdb6d0538f5f839d7ea104e888.tar.gz go-tangerine-6bd896a97f0c86fdb6d0538f5f839d7ea104e888.tar.bz2 go-tangerine-6bd896a97f0c86fdb6d0538f5f839d7ea104e888.tar.lz go-tangerine-6bd896a97f0c86fdb6d0538f5f839d7ea104e888.tar.xz go-tangerine-6bd896a97f0c86fdb6d0538f5f839d7ea104e888.tar.zst go-tangerine-6bd896a97f0c86fdb6d0538f5f839d7ea104e888.zip |
eth: add debug_accountRange (#17438)
This adds the debug_accountRange method which returns all accounts in
the state for a given block and transaction index.
Diffstat (limited to 'eth/api.go')
-rw-r--r-- | eth/api.go | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/eth/api.go b/eth/api.go index 8afa21a38..98c2f5874 100644 --- a/eth/api.go +++ b/eth/api.go @@ -334,6 +334,72 @@ func (api *PrivateDebugAPI) GetBadBlocks(ctx context.Context) ([]*BadBlockArgs, return results, nil } +// AccountRangeResult returns a mapping from the hash of an account addresses +// to its preimage. It will return the JSON null if no preimage is found. +// Since a query can return a limited amount of results, a "next" field is +// also present for paging. +type AccountRangeResult struct { + Accounts map[common.Hash]*common.Address `json:"accounts"` + Next common.Hash `json:"next"` +} + +func accountRange(st state.Trie, start *common.Hash, maxResults int) (AccountRangeResult, error) { + if start == nil { + start = &common.Hash{0} + } + it := trie.NewIterator(st.NodeIterator(start.Bytes())) + result := AccountRangeResult{Accounts: make(map[common.Hash]*common.Address), Next: common.Hash{}} + + if maxResults > AccountRangeMaxResults { + maxResults = AccountRangeMaxResults + } + + for i := 0; i < maxResults && it.Next(); i++ { + if preimage := st.GetKey(it.Key); preimage != nil { + addr := &common.Address{} + addr.SetBytes(preimage) + result.Accounts[common.BytesToHash(it.Key)] = addr + } else { + result.Accounts[common.BytesToHash(it.Key)] = nil + } + } + + if it.Next() { + result.Next = common.BytesToHash(it.Key) + } + + return result, nil +} + +// AccountRangeMaxResults is the maximum number of results to be returned per call +const AccountRangeMaxResults = 256 + +// AccountRange enumerates all accounts in the latest state +func (api *PrivateDebugAPI) AccountRange(ctx context.Context, start *common.Hash, maxResults int) (AccountRangeResult, error) { + var statedb *state.StateDB + var err error + block := api.eth.blockchain.CurrentBlock() + + if len(block.Transactions()) == 0 { + statedb, err = api.computeStateDB(block, defaultTraceReexec) + if err != nil { + return AccountRangeResult{}, err + } + } else { + _, _, statedb, err = api.computeTxEnv(block.Hash(), len(block.Transactions())-1, 0) + if err != nil { + return AccountRangeResult{}, err + } + } + + trie, err := statedb.Database().OpenTrie(block.Header().Root) + if err != nil { + return AccountRangeResult{}, err + } + + return accountRange(trie, start, maxResults) +} + // StorageRangeResult is the result of a debug_storageRangeAt API call. type StorageRangeResult struct { Storage storageMap `json:"storage"` |