Implement block tags (#106)
* Implemented tm/ethermint specific block tags * Fix edge case for block query
This commit is contained in:
parent
d1900826a0
commit
9383c743dd
@ -17,7 +17,6 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
"github.com/ethereum/go-ethereum/rpc"
|
|
||||||
|
|
||||||
"github.com/cosmos/cosmos-sdk/client/context"
|
"github.com/cosmos/cosmos-sdk/client/context"
|
||||||
"github.com/cosmos/cosmos-sdk/client/flags"
|
"github.com/cosmos/cosmos-sdk/client/flags"
|
||||||
@ -113,7 +112,7 @@ func (e *PublicEthAPI) BlockNumber() (hexutil.Uint64, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetBalance returns the provided account's balance up to the provided block number.
|
// GetBalance returns the provided account's balance up to the provided block number.
|
||||||
func (e *PublicEthAPI) GetBalance(address common.Address, blockNum rpc.BlockNumber) (*hexutil.Big, error) {
|
func (e *PublicEthAPI) GetBalance(address common.Address, blockNum BlockNumber) (*hexutil.Big, error) {
|
||||||
ctx := e.cliCtx.WithHeight(blockNum.Int64())
|
ctx := e.cliCtx.WithHeight(blockNum.Int64())
|
||||||
res, _, err := ctx.QueryWithData(fmt.Sprintf("custom/%s/balance/%s", types.ModuleName, address), nil)
|
res, _, err := ctx.QueryWithData(fmt.Sprintf("custom/%s/balance/%s", types.ModuleName, address), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -127,7 +126,7 @@ func (e *PublicEthAPI) GetBalance(address common.Address, blockNum rpc.BlockNumb
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetStorageAt returns the contract storage at the given address, block number, and key.
|
// GetStorageAt returns the contract storage at the given address, block number, and key.
|
||||||
func (e *PublicEthAPI) GetStorageAt(address common.Address, key string, blockNum rpc.BlockNumber) (hexutil.Bytes, error) {
|
func (e *PublicEthAPI) GetStorageAt(address common.Address, key string, blockNum BlockNumber) (hexutil.Bytes, error) {
|
||||||
ctx := e.cliCtx.WithHeight(blockNum.Int64())
|
ctx := e.cliCtx.WithHeight(blockNum.Int64())
|
||||||
res, _, err := ctx.QueryWithData(fmt.Sprintf("custom/%s/storage/%s/%s", types.ModuleName, address, key), nil)
|
res, _, err := ctx.QueryWithData(fmt.Sprintf("custom/%s/storage/%s/%s", types.ModuleName, address, key), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -140,7 +139,7 @@ func (e *PublicEthAPI) GetStorageAt(address common.Address, key string, blockNum
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetTransactionCount returns the number of transactions at the given address up to the given block number.
|
// GetTransactionCount returns the number of transactions at the given address up to the given block number.
|
||||||
func (e *PublicEthAPI) GetTransactionCount(address common.Address, blockNum rpc.BlockNumber) (*hexutil.Uint64, error) {
|
func (e *PublicEthAPI) GetTransactionCount(address common.Address, blockNum BlockNumber) (*hexutil.Uint64, error) {
|
||||||
ctx := e.cliCtx.WithHeight(blockNum.Int64())
|
ctx := e.cliCtx.WithHeight(blockNum.Int64())
|
||||||
res, _, err := ctx.QueryWithData(fmt.Sprintf("custom/%s/nonce/%s", types.ModuleName, address), nil)
|
res, _, err := ctx.QueryWithData(fmt.Sprintf("custom/%s/nonce/%s", types.ModuleName, address), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -158,7 +157,7 @@ func (e *PublicEthAPI) GetBlockTransactionCountByHash(hash common.Hash) hexutil.
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetBlockTransactionCountByNumber returns the number of transactions in the block identified by number.
|
// GetBlockTransactionCountByNumber returns the number of transactions in the block identified by number.
|
||||||
func (e *PublicEthAPI) GetBlockTransactionCountByNumber(blockNum rpc.BlockNumber) (hexutil.Uint, error) {
|
func (e *PublicEthAPI) GetBlockTransactionCountByNumber(blockNum BlockNumber) (hexutil.Uint, error) {
|
||||||
node, err := e.cliCtx.GetNode()
|
node, err := e.cliCtx.GetNode()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
@ -179,12 +178,12 @@ func (e *PublicEthAPI) GetUncleCountByBlockHash(hash common.Hash) hexutil.Uint {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetUncleCountByBlockNumber returns the number of uncles in the block idenfied by number. Always zero.
|
// GetUncleCountByBlockNumber returns the number of uncles in the block idenfied by number. Always zero.
|
||||||
func (e *PublicEthAPI) GetUncleCountByBlockNumber(blockNum rpc.BlockNumber) hexutil.Uint {
|
func (e *PublicEthAPI) GetUncleCountByBlockNumber(blockNum BlockNumber) hexutil.Uint {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetCode returns the contract code at the given address and block number.
|
// GetCode returns the contract code at the given address and block number.
|
||||||
func (e *PublicEthAPI) GetCode(address common.Address, blockNumber rpc.BlockNumber) (hexutil.Bytes, error) {
|
func (e *PublicEthAPI) GetCode(address common.Address, blockNumber BlockNumber) (hexutil.Bytes, error) {
|
||||||
ctx := e.cliCtx.WithHeight(blockNumber.Int64())
|
ctx := e.cliCtx.WithHeight(blockNumber.Int64())
|
||||||
res, _, err := ctx.QueryWithData(fmt.Sprintf("custom/%s/code/%s", types.ModuleName, address), nil)
|
res, _, err := ctx.QueryWithData(fmt.Sprintf("custom/%s/code/%s", types.ModuleName, address), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -304,12 +303,12 @@ type CallArgs struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Call performs a raw contract call.
|
// Call performs a raw contract call.
|
||||||
func (e *PublicEthAPI) Call(args CallArgs, blockNum rpc.BlockNumber) hexutil.Bytes {
|
func (e *PublicEthAPI) Call(args CallArgs, blockNum BlockNumber) hexutil.Bytes {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// EstimateGas estimates gas usage for the given smart contract call.
|
// EstimateGas estimates gas usage for the given smart contract call.
|
||||||
func (e *PublicEthAPI) EstimateGas(args CallArgs, blockNum rpc.BlockNumber) hexutil.Uint64 {
|
func (e *PublicEthAPI) EstimateGas(args CallArgs, blockNum BlockNumber) hexutil.Uint64 {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -319,9 +318,16 @@ func (e *PublicEthAPI) GetBlockByHash(hash common.Hash, fullTx bool) map[string]
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetBlockByNumber returns the block identified by number.
|
// GetBlockByNumber returns the block identified by number.
|
||||||
func (e *PublicEthAPI) GetBlockByNumber(blockNum rpc.BlockNumber, fullTx bool) (map[string]interface{}, error) {
|
func (e *PublicEthAPI) GetBlockByNumber(blockNum BlockNumber, fullTx bool) (map[string]interface{}, error) {
|
||||||
value := blockNum.Int64()
|
value := blockNum.Int64()
|
||||||
block, err := e.cliCtx.Client.Block(&value)
|
|
||||||
|
// Remove this check when 0 query is fixed ref: (https://github.com/tendermint/tendermint/issues/4014)
|
||||||
|
var blkNumPtr *int64
|
||||||
|
if value != 0 {
|
||||||
|
blkNumPtr = &value
|
||||||
|
}
|
||||||
|
|
||||||
|
block, err := e.cliCtx.Client.Block(blkNumPtr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -450,7 +456,7 @@ func (e *PublicEthAPI) GetTransactionByBlockHashAndIndex(hash common.Hash, idx h
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetTransactionByBlockNumberAndIndex returns the transaction identified by number and index.
|
// GetTransactionByBlockNumberAndIndex returns the transaction identified by number and index.
|
||||||
func (e *PublicEthAPI) GetTransactionByBlockNumberAndIndex(blockNumber rpc.BlockNumber, idx hexutil.Uint) *Transaction {
|
func (e *PublicEthAPI) GetTransactionByBlockNumberAndIndex(blockNumber BlockNumber, idx hexutil.Uint) *Transaction {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
62
rpc/types.go
Normal file
62
rpc/types.go
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
package rpc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"math"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
// BlockNumber represents decoding hex string to block values
|
||||||
|
type BlockNumber int64
|
||||||
|
|
||||||
|
const (
|
||||||
|
// LatestBlockNumber mapping from "latest" to 0 for tm query
|
||||||
|
LatestBlockNumber = BlockNumber(0)
|
||||||
|
|
||||||
|
// EarliestBlockNumber mapping from "earliest" to 1 for tm query (earliest query not supported)
|
||||||
|
EarliestBlockNumber = BlockNumber(1)
|
||||||
|
)
|
||||||
|
|
||||||
|
// UnmarshalJSON parses the given JSON fragment into a BlockNumber. It supports:
|
||||||
|
// - "latest", "earliest" or "pending" as string arguments
|
||||||
|
// - the block number
|
||||||
|
// Returned errors:
|
||||||
|
// - an invalid block number error when the given argument isn't a known strings
|
||||||
|
// - an out of range error when the given block number is either too little or too large
|
||||||
|
func (bn *BlockNumber) UnmarshalJSON(data []byte) error {
|
||||||
|
input := strings.TrimSpace(string(data))
|
||||||
|
if len(input) >= 2 && input[0] == '"' && input[len(input)-1] == '"' {
|
||||||
|
input = input[1 : len(input)-1]
|
||||||
|
}
|
||||||
|
|
||||||
|
switch input {
|
||||||
|
case "earliest":
|
||||||
|
*bn = EarliestBlockNumber
|
||||||
|
return nil
|
||||||
|
case "latest":
|
||||||
|
*bn = LatestBlockNumber
|
||||||
|
return nil
|
||||||
|
case "pending":
|
||||||
|
return fmt.Errorf("pending queries not implemented")
|
||||||
|
// *bn = PendingBlockNumber
|
||||||
|
// return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
blckNum, err := hexutil.DecodeUint64(input)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if blckNum > math.MaxInt64 {
|
||||||
|
return fmt.Errorf("Blocknumber too high")
|
||||||
|
}
|
||||||
|
|
||||||
|
*bn = BlockNumber(blckNum)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Int64 converts block number to primitive type
|
||||||
|
func (bn BlockNumber) Int64() int64 {
|
||||||
|
return (int64)(bn)
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user