Rpc getBalance (#775)

* rpc addBalance

* handle isCanonical case

* fmt
This commit is contained in:
Evgeny Danilenko 2020-07-21 17:31:02 +03:00 committed by GitHub
parent 8971624ec6
commit f11f960814
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 45 additions and 0 deletions

View File

@ -37,6 +37,7 @@ func splitAndTrim(input string) []string {
type EthAPI interface {
BlockNumber(ctx context.Context) (hexutil.Uint64, error)
GetBlockByNumber(ctx context.Context, number rpc.BlockNumber, fullTx bool) (map[string]interface{}, error)
GetBalance(_ context.Context, address common.Address, blockNrOrHash rpc.BlockNumberOrHash) (*hexutil.Big, error)
}
// APIImpl is implementation of the EthAPI interface based on remote Db access

View File

@ -0,0 +1,44 @@
package commands
import (
"context"
"fmt"
"github.com/ledgerwatch/turbo-geth/common"
"github.com/ledgerwatch/turbo-geth/common/hexutil"
"github.com/ledgerwatch/turbo-geth/core/rawdb"
"github.com/ledgerwatch/turbo-geth/core/types/accounts"
"github.com/ledgerwatch/turbo-geth/ethdb"
"github.com/ledgerwatch/turbo-geth/rpc"
)
func (api *APIImpl) GetBalance(_ context.Context, address common.Address, blockNrOrHash rpc.BlockNumberOrHash) (*hexutil.Big, error) {
var blockNumber uint64
hash, ok := blockNrOrHash.Hash()
if !ok {
blockNumber = uint64(blockNrOrHash.BlockNumber.Int64())
} else {
block := rawdb.ReadBlockByHash(api.dbReader, hash)
if block == nil {
return nil, fmt.Errorf("block %x not found", hash)
}
blockNumber = block.NumberU64()
if blockNrOrHash.RequireCanonical && rawdb.ReadCanonicalHash(api.dbReader, blockNumber) != hash {
return nil, fmt.Errorf("hash %q is not currently canonical", hash.String())
}
}
acc, err := GetAccount(api.db, blockNumber, address)
if err != nil {
return nil, fmt.Errorf("cant get a balance for account %q for block %v", address.String(), blockNumber)
}
return (*hexutil.Big)(acc.Balance.ToBig()), nil
}
func GetAccount(chainKV ethdb.KV, blockNumber uint64, address common.Address) (*accounts.Account, error) {
reader := NewStateReader(chainKV, blockNumber)
return reader.ReadAccountData(address)
}