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/hexutil"
|
||||
"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/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.
|
||||
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())
|
||||
res, _, err := ctx.QueryWithData(fmt.Sprintf("custom/%s/balance/%s", types.ModuleName, address), 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.
|
||||
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())
|
||||
res, _, err := ctx.QueryWithData(fmt.Sprintf("custom/%s/storage/%s/%s", types.ModuleName, address, key), 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.
|
||||
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())
|
||||
res, _, err := ctx.QueryWithData(fmt.Sprintf("custom/%s/nonce/%s", types.ModuleName, address), 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.
|
||||
func (e *PublicEthAPI) GetBlockTransactionCountByNumber(blockNum rpc.BlockNumber) (hexutil.Uint, error) {
|
||||
func (e *PublicEthAPI) GetBlockTransactionCountByNumber(blockNum BlockNumber) (hexutil.Uint, error) {
|
||||
node, err := e.cliCtx.GetNode()
|
||||
if err != nil {
|
||||
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.
|
||||
func (e *PublicEthAPI) GetUncleCountByBlockNumber(blockNum rpc.BlockNumber) hexutil.Uint {
|
||||
func (e *PublicEthAPI) GetUncleCountByBlockNumber(blockNum BlockNumber) hexutil.Uint {
|
||||
return 0
|
||||
}
|
||||
|
||||
// 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())
|
||||
res, _, err := ctx.QueryWithData(fmt.Sprintf("custom/%s/code/%s", types.ModuleName, address), nil)
|
||||
if err != nil {
|
||||
@ -304,12 +303,12 @@ type CallArgs struct {
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
@ -319,9 +318,16 @@ func (e *PublicEthAPI) GetBlockByHash(hash common.Hash, fullTx bool) map[string]
|
||||
}
|
||||
|
||||
// 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()
|
||||
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 {
|
||||
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.
|
||||
func (e *PublicEthAPI) GetTransactionByBlockNumberAndIndex(blockNumber rpc.BlockNumber, idx hexutil.Uint) *Transaction {
|
||||
func (e *PublicEthAPI) GetTransactionByBlockNumberAndIndex(blockNumber BlockNumber, idx hexutil.Uint) *Transaction {
|
||||
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