Merge pull request #479 from gzliudan/get-account-info

add method `eth_getAccountInfo`
This commit is contained in:
Daniel Liu 2024-03-06 21:00:27 +08:00 committed by GitHub
commit 476bda6515
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 70 additions and 0 deletions

View file

@ -393,6 +393,10 @@ func (self *stateObject) Nonce() uint64 {
return self.data.Nonce
}
func (self *stateObject) Root() common.Hash {
return self.data.Root
}
// Never called, but must be present to allow stateObject to be used
// as a vm.Account interface that also satisfies the vm.ContractRef
// interface. Interfaces are awesome.

View file

@ -83,6 +83,14 @@ type StateDB struct {
lock sync.Mutex
}
type AccountInfo struct {
CodeSize int
Nonce uint64
Balance *big.Int
CodeHash common.Hash
StorageHash common.Hash
}
func (self *StateDB) SubRefund(gas uint64) {
self.journal = append(self.journal, refundChange{
prev: self.refund})
@ -221,6 +229,16 @@ func (self *StateDB) GetNonce(addr common.Address) uint64 {
return 0
}
// GetStorageRoot retrieves the storage root from the given address or empty
// if object not found.
func (self *StateDB) GetStorageRoot(addr common.Address) common.Hash {
stateObject := self.getStateObject(addr)
if stateObject != nil {
return stateObject.Root()
}
return common.Hash{}
}
func (self *StateDB) GetCode(addr common.Address) []byte {
stateObject := self.getStateObject(addr)
if stateObject != nil {
@ -252,6 +270,28 @@ func (self *StateDB) GetCodeHash(addr common.Address) common.Hash {
return common.BytesToHash(stateObject.CodeHash())
}
func (self *StateDB) GetAccountInfo(addr common.Address) *AccountInfo {
result := AccountInfo{}
stateObject := self.getStateObject(addr)
if stateObject == nil {
result.Balance = common.Big0
return &result
}
if stateObject.code != nil {
result.CodeSize = len(stateObject.code)
} else {
result.CodeSize, _ = self.db.ContractCodeSize(stateObject.addrHash, common.BytesToHash(stateObject.CodeHash()))
}
result.Nonce = stateObject.Nonce()
result.Balance = stateObject.Balance()
result.CodeHash = common.BytesToHash(stateObject.CodeHash())
result.StorageHash = stateObject.Root()
return &result
}
func (self *StateDB) GetState(addr common.Address, bhash common.Hash) common.Hash {
stateObject := self.getStateObject(addr)
if stateObject != nil {

View file

@ -623,6 +623,24 @@ func (s *PublicBlockChainAPI) GetCode(ctx context.Context, address common.Addres
return code, state.Error()
}
// GetAccountInfo returns the information at the given address in the state for the given block number.
func (s *PublicBlockChainAPI) GetAccountInfo(ctx context.Context, address common.Address, blockNr rpc.BlockNumber) (map[string]interface{}, error) {
state, _, err := s.b.StateAndHeaderByNumber(ctx, blockNr)
if state == nil || err != nil {
return nil, err
}
info := state.GetAccountInfo(address)
result := map[string]interface{}{
"address": address,
"balance": (*hexutil.Big)(info.Balance),
"codeSize": info.CodeSize,
"codeHash": info.CodeHash,
"nonce": info.Nonce,
"storageHash": info.StorageHash,
}
return result, nil
}
// GetStorageAt returns the storage from the state at the given address, key and
// block number. The rpc.LatestBlockNumber and rpc.PendingBlockNumber meta block
// numbers are also allowed.

View file

@ -5329,6 +5329,13 @@ var methods = function () {
inputFormatter: [formatters.inputAddressFormatter, formatters.inputDefaultBlockNumberFormatter]
});
var getAccountInfo = new Method({
name: 'getAccountInfo',
call: 'eth_getAccountInfo',
params: 2,
inputFormatter: [formatters.inputAddressFormatter, formatters.inputDefaultBlockNumberFormatter]
});
var getBlock = new Method({
name: 'getBlock',
call: blockCall,
@ -5513,6 +5520,7 @@ var methods = function () {
getBalance,
getStorageAt,
getCode,
getAccountInfo,
getBlock,
getBlockSigners,
getStakerROI,