eth/api: add eth_listAccounts API (compatible with the parity_listAccounts)

Please see https://wiki.parity.io/JSONRPC-parity-module#parity_listaccounts
This commit is contained in:
hackyminer 2019-01-28 15:58:22 +09:00
parent 277a8c975b
commit d2c268b516
No known key found for this signature in database
GPG key ID: 46D453DDCA4B766F
3 changed files with 56 additions and 0 deletions

View file

@ -568,6 +568,11 @@ func (self *StateDB) GetRefund() uint64 {
return self.refund
}
// GetTrie returns the current value of the trie.
func (self *StateDB) GetTrie() Trie {
return self.trie
}
// Finalise finalises the state by removing the self destructed objects
// and clears the journal as well as the refunds.
func (s *StateDB) Finalise(deleteEmptyObjects bool) {

View file

@ -34,6 +34,7 @@ import (
"github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/internal/ethapi"
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/rlp"
@ -76,6 +77,50 @@ func (api *PublicEthereumAPI) ChainId() hexutil.Uint64 {
return (hexutil.Uint64)(chainID.Uint64())
}
// ListAccounts retrieves accounts of the database at a given block.
func (api *PublicEthereumAPI) ListAccounts(count uint64, offset *common.Address, blockNr *rpc.BlockNumber) ([]common.Address, error) {
var block *types.Block = nil
var tr state.Trie
if blockNr == nil || *blockNr == rpc.LatestBlockNumber {
block = api.e.blockchain.CurrentBlock()
} else if *blockNr != rpc.PendingBlockNumber {
block = api.e.blockchain.GetBlockByNumber(uint64(*blockNr))
}
if block != nil {
stateDb, err := api.e.BlockChain().StateAt(block.Root())
if err != nil {
return nil, err
}
tr, err = stateDb.Database().OpenTrie(block.Root())
if err != nil {
return nil, err
}
} else if *blockNr != rpc.PendingBlockNumber {
return nil, fmt.Errorf("block #%d not found", *blockNr)
} else {
// Get the pending state
_, stateDb := api.e.miner.Pending()
tr = stateDb.GetTrie()
}
var accounts []common.Address
var it *trie.Iterator
if offset != nil && *offset != (common.Address{}) {
it = trie.NewIterator(tr.NodeIterator(crypto.Keccak256(offset[:])))
it.Next()
} else {
it = trie.NewIterator(tr.NodeIterator(nil))
}
for ; count > 0 && it.Next(); count-- {
addr := tr.GetKey(it.Key)
accounts = append(accounts, common.BytesToAddress(addr))
}
return accounts, nil
}
// PublicMinerAPI provides an API to control the miner.
// It offers only methods that operate on data that pose no security risk when it is publicly accessible.
type PublicMinerAPI struct {

View file

@ -500,6 +500,12 @@ web3._extend({
params: 3,
inputFormatter: [web3._extend.formatters.inputAddressFormatter, null, web3._extend.formatters.inputBlockNumberFormatter]
}),
new web3._extend.Method({
name: 'listAccounts',
call: 'eth_listAccounts',
params: 3,
inputFormatter: [null, null, web3._extend.formatters.inputDefaultBlockNumberFormatter],
}),
],
properties: [
new web3._extend.Property({