eth,core: debug_iteratorAccountAt use rpc.BlockNumerOrHash

This commit is contained in:
Delweng Zheng 2019-10-16 21:44:17 +08:00 committed by Martin Holst Swende
parent dd316619e3
commit 649e01f4d3
No known key found for this signature in database
GPG key ID: 683B438C05A5DDF0
2 changed files with 26 additions and 21 deletions

View file

@ -51,7 +51,7 @@ type iterativeDump struct {
*json.Encoder *json.Encoder
} }
// IteratorDump is a // IterationDump is an implementation for iterating over data
type IteratorDump struct { type IteratorDump struct {
Root string `json:"root"` Root string `json:"root"`
Accounts map[common.Address]DumpAccount `json:"accounts"` Accounts map[common.Address]DumpAccount `json:"accounts"`
@ -147,12 +147,8 @@ func (s *StateDB) dump(c collector, excludeCode, excludeStorage, excludeMissingP
} }
c.onAccount(addr, account) c.onAccount(addr, account)
if maxResults <= 0 {
continue
}
count++ count++
if count >= maxResults { if maxResults > 0 && count >= maxResults {
if it.Next() { if it.Next() {
nextKey = it.Key nextKey = it.Key
} }

View file

@ -305,36 +305,45 @@ func (api *PublicDebugAPI) DumpBlock(blockNr rpc.BlockNumber) (state.Dump, error
const IteratorAccountMaxResults = 1000 const IteratorAccountMaxResults = 1000
// IteratorAccountAt enumerates all accounts in the given block and start point in paging request // IteratorAccountAt enumerates all accounts in the given block and start point in paging request
func (api *PublicDebugAPI) IteratorAccountAt(blockNr rpc.BlockNumber, start []byte, maxResults int, nocode, nostorage, incompletes bool) (state.IteratorDump, error) { func (api *PublicDebugAPI) IteratorAccountAt(blockNrOrHash rpc.BlockNumberOrHash, start []byte, maxResults int, nocode, nostorage, incompletes bool) (state.IteratorDump, error) {
var stateDb *state.StateDB var stateDb *state.StateDB
var err error var err error
if blockNr == rpc.PendingBlockNumber { if number, ok := blockNrOrHash.Number(); ok {
// If we're dumping the pending state, we need to request if number == rpc.PendingBlockNumber {
// both the pending block as well as the pending state from // If we're dumping the pending state, we need to request
// the miner and operate on those // both the pending block as well as the pending state from
_, stateDb = api.eth.miner.Pending() // the miner and operate on those
} else { _, stateDb = api.eth.miner.Pending()
var block *types.Block
if blockNr == rpc.LatestBlockNumber {
block = api.eth.blockchain.CurrentBlock()
} else { } else {
block = api.eth.blockchain.GetBlockByNumber(uint64(blockNr)) var block *types.Block
if number == rpc.LatestBlockNumber {
block = api.eth.blockchain.CurrentBlock()
} else {
block = api.eth.blockchain.GetBlockByNumber(uint64(number))
}
if block == nil {
return state.IteratorDump{}, fmt.Errorf("block #%d not found", number)
}
stateDb, err = api.eth.BlockChain().StateAt(block.Root())
if err != nil {
return state.IteratorDump{}, err
}
} }
} else if hash, ok := blockNrOrHash.Hash(); ok {
block := api.eth.blockchain.GetBlockByHash(hash)
if block == nil { if block == nil {
return state.IteratorDump{}, fmt.Errorf("block #%d not found", blockNr) return state.IteratorDump{}, fmt.Errorf("block %s not found", hash.Hex())
} }
stateDb, err = api.eth.BlockChain().StateAt(block.Root()) stateDb, err = api.eth.BlockChain().StateAt(block.Root())
if err != nil { if err != nil {
return state.IteratorDump{}, err return state.IteratorDump{}, err
} }
} }
if maxResults > IteratorAccountMaxResults { if maxResults > IteratorAccountMaxResults || maxResults <= 0 {
maxResults = IteratorAccountMaxResults maxResults = IteratorAccountMaxResults
} }
return stateDb.IteratorDump(nocode, nostorage, incompletes, start, maxResults), nil return stateDb.IteratorDump(nocode, nostorage, incompletes, start, maxResults), nil
} }