Query and bug fixes (#110)

* Fix queries and bugs

* Fix issues from rebasing

* Fix rpc query address
This commit is contained in:
Austin Abell 2019-09-26 11:36:23 -04:00 committed by GitHub
parent 192ce2cc1c
commit 7f1eb4b0cf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 143 additions and 78 deletions

View File

@ -8,6 +8,7 @@ import (
emintcrypto "github.com/cosmos/ethermint/crypto" emintcrypto "github.com/cosmos/ethermint/crypto"
emintkeys "github.com/cosmos/ethermint/keys" emintkeys "github.com/cosmos/ethermint/keys"
"github.com/cosmos/ethermint/rpc/args" "github.com/cosmos/ethermint/rpc/args"
"github.com/cosmos/ethermint/utils"
"github.com/cosmos/ethermint/version" "github.com/cosmos/ethermint/version"
"github.com/cosmos/ethermint/x/evm/types" "github.com/cosmos/ethermint/x/evm/types"
@ -120,50 +121,53 @@ func (e *PublicEthAPI) BlockNumber() (hexutil.Uint64, error) {
return hexutil.Uint64(0), err return hexutil.Uint64(0), err
} }
var qRes uint64 var out types.QueryResBlockNumber
e.cliCtx.Codec.MustUnmarshalJSON(res, &qRes) e.cliCtx.Codec.MustUnmarshalJSON(res, &out)
return hexutil.Uint64(out.Number), nil
return hexutil.Uint64(qRes), nil
} }
// 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 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.Hex()), nil)
if err != nil { if err != nil {
return nil, err return nil, err
} }
var out *big.Int var out types.QueryResBalance
e.cliCtx.Codec.MustUnmarshalJSON(res, &out) e.cliCtx.Codec.MustUnmarshalJSON(res, &out)
val, err := utils.UnmarshalBigInt(out.Balance)
if err != nil {
return nil, err
}
return (*hexutil.Big)(out), nil return (*hexutil.Big)(val), nil
} }
// 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 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.Hex(), key), nil)
if err != nil { if err != nil {
return nil, err return nil, err
} }
var out []byte var out types.QueryResStorage
e.cliCtx.Codec.MustUnmarshalJSON(res, &out) e.cliCtx.Codec.MustUnmarshalJSON(res, &out)
return out, nil return out.Value, nil
} }
// 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 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.Hex()), nil)
if err != nil { if err != nil {
return nil, err return nil, err
} }
var out *hexutil.Uint64 var out types.QueryResNonce
e.cliCtx.Codec.MustUnmarshalJSON(res, out) e.cliCtx.Codec.MustUnmarshalJSON(res, &out)
return out, nil return (*hexutil.Uint64)(&out.Nonce), nil
} }
// GetBlockTransactionCountByHash returns the number of transactions in the block identified by hash. // GetBlockTransactionCountByHash returns the number of transactions in the block identified by hash.
@ -200,14 +204,14 @@ func (e *PublicEthAPI) GetUncleCountByBlockNumber(blockNum BlockNumber) hexutil.
// 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 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.Hex()), nil)
if err != nil { if err != nil {
return nil, err return nil, err
} }
var out []byte var out types.QueryResCode
e.cliCtx.Codec.MustUnmarshalJSON(res, &out) e.cliCtx.Codec.MustUnmarshalJSON(res, &out)
return out, nil return out.Code, nil
} }
// Sign signs the provided data using the private key of address via Geth's signature standard. // Sign signs the provided data using the private key of address via Geth's signature standard.

View File

@ -33,7 +33,7 @@ type Request struct {
Version string `json:"jsonrpc"` Version string `json:"jsonrpc"`
Method string `json:"method"` Method string `json:"method"`
Params []string `json:"params"` Params []string `json:"params"`
Id int `json:"id"` ID int `json:"id"`
} }
type RPCError struct { type RPCError struct {
@ -44,7 +44,7 @@ type RPCError struct {
type Response struct { type Response struct {
Error *RPCError `json:"error"` Error *RPCError `json:"error"`
Id int `json:"id"` ID int `json:"id"`
Result json.RawMessage `json:"result,omitempty"` Result json.RawMessage `json:"result,omitempty"`
} }
@ -53,7 +53,7 @@ func createRequest(method string, params []string) Request {
Version: "2.0", Version: "2.0",
Method: method, Method: method,
Params: params, Params: params,
Id: 1, ID: 1,
} }
} }

19
utils/int.go Normal file
View File

@ -0,0 +1,19 @@
package utils
import "math/big"
// MarshalBigInt marshalls big int into text string for consistent encoding
func MarshalBigInt(i *big.Int) string {
bz, err := i.MarshalText()
if err != nil {
panic(err)
}
return string(bz)
}
// UnmarshalBigInt unmarshalls string from *big.Int
func UnmarshalBigInt(s string) (*big.Int, error) {
ret := new(big.Int)
err := ret.UnmarshalText([]byte(s))
return ret, err
}

View File

@ -15,7 +15,7 @@ const AppName = "Ethermint"
const Version = "0.0.0" const Version = "0.0.0"
// ProtocolVersion is the supported Ethereum protocol version (e.g., Homestead, Olympic, etc.) // ProtocolVersion is the supported Ethereum protocol version (e.g., Homestead, Olympic, etc.)
const ProtocolVersion uint = 63 const ProtocolVersion = 63
// GitCommit contains the git SHA1 short hash set by build flags. // GitCommit contains the git SHA1 short hash set by build flags.
var GitCommit = "" var GitCommit = ""

View File

@ -7,7 +7,6 @@ import (
"github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/client/context"
"github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/ethermint/x/evm/types" "github.com/cosmos/ethermint/x/evm/types"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
@ -43,7 +42,7 @@ func GetCmdGetBlockNumber(queryRoute string, cdc *codec.Codec) *cobra.Command {
return nil return nil
} }
var out *hexutil.Big var out types.QueryResBlockNumber
cdc.MustUnmarshalJSON(res, &out) cdc.MustUnmarshalJSON(res, &out)
return cliCtx.PrintOutput(out) return cliCtx.PrintOutput(out)
}, },
@ -68,7 +67,7 @@ func GetCmdGetStorageAt(queryRoute string, cdc *codec.Codec) *cobra.Command {
fmt.Printf("could not resolve: %s\n", err) fmt.Printf("could not resolve: %s\n", err)
return nil return nil
} }
var out hexutil.Bytes var out types.QueryResStorage
cdc.MustUnmarshalJSON(res, &out) cdc.MustUnmarshalJSON(res, &out)
return cliCtx.PrintOutput(out) return cliCtx.PrintOutput(out)
}, },
@ -92,9 +91,9 @@ func GetCmdGetCode(queryRoute string, cdc *codec.Codec) *cobra.Command {
fmt.Printf("could not resolve: %s\n", err) fmt.Printf("could not resolve: %s\n", err)
return nil return nil
} }
var out []byte var out types.QueryResCode
cdc.MustUnmarshalJSON(res, &out) cdc.MustUnmarshalJSON(res, &out)
return cliCtx.PrintOutput(hexutil.Bytes(out)) return cliCtx.PrintOutput(out)
}, },
} }
} }
@ -116,7 +115,7 @@ func GetCmdGetNonce(queryRoute string, cdc *codec.Codec) *cobra.Command {
fmt.Printf("could not resolve: %s\n", err) fmt.Printf("could not resolve: %s\n", err)
return nil return nil
} }
var out hexutil.Uint64 var out types.QueryResNonce
cdc.MustUnmarshalJSON(res, &out) cdc.MustUnmarshalJSON(res, &out)
return cliCtx.PrintOutput(out) return cliCtx.PrintOutput(out)
}, },

View File

@ -3,7 +3,9 @@ package evm
import ( import (
"github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types" sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/ethermint/utils"
"github.com/cosmos/ethermint/version" "github.com/cosmos/ethermint/version"
"github.com/cosmos/ethermint/x/evm/types"
ethcmn "github.com/ethereum/go-ethereum/common" ethcmn "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/common/hexutil"
abci "github.com/tendermint/tendermint/abci/types" abci "github.com/tendermint/tendermint/abci/types"
@ -44,8 +46,7 @@ func NewQuerier(keeper Keeper) sdk.Querier {
func queryProtocolVersion(keeper Keeper) ([]byte, sdk.Error) { func queryProtocolVersion(keeper Keeper) ([]byte, sdk.Error) {
vers := version.ProtocolVersion vers := version.ProtocolVersion
bigRes := hexutil.Uint(vers) res, err := codec.MarshalJSONIndent(keeper.cdc, hexutil.Uint(vers))
res, err := codec.MarshalJSONIndent(keeper.cdc, bigRes)
if err != nil { if err != nil {
panic("could not marshal result to JSON") panic("could not marshal result to JSON")
} }
@ -54,11 +55,13 @@ func queryProtocolVersion(keeper Keeper) ([]byte, sdk.Error) {
} }
func queryBalance(ctx sdk.Context, path []string, keeper Keeper) ([]byte, sdk.Error) { func queryBalance(ctx sdk.Context, path []string, keeper Keeper) ([]byte, sdk.Error) {
addr := ethcmn.BytesToAddress([]byte(path[1])) addr := ethcmn.HexToAddress(path[1])
balance := keeper.GetBalance(ctx, addr) balance := keeper.GetBalance(ctx, addr)
res, err := codec.MarshalJSONIndent(keeper.cdc, balance)
bRes := types.QueryResBalance{Balance: utils.MarshalBigInt(balance)}
res, err := codec.MarshalJSONIndent(keeper.cdc, bRes)
if err != nil { if err != nil {
panic("could not marshal result to JSON: ") panic("could not marshal result to JSON: " + err.Error())
} }
return res, nil return res, nil
@ -66,10 +69,8 @@ func queryBalance(ctx sdk.Context, path []string, keeper Keeper) ([]byte, sdk.Er
func queryBlockNumber(ctx sdk.Context, keeper Keeper) ([]byte, sdk.Error) { func queryBlockNumber(ctx sdk.Context, keeper Keeper) ([]byte, sdk.Error) {
num := ctx.BlockHeight() num := ctx.BlockHeight()
hexUint := hexutil.Uint64(num) bnRes := types.QueryResBlockNumber{Number: num}
res, err := codec.MarshalJSONIndent(keeper.cdc, bnRes)
res, err := codec.MarshalJSONIndent(keeper.cdc, hexUint)
if err != nil { if err != nil {
panic("could not marshal result to JSON: " + err.Error()) panic("could not marshal result to JSON: " + err.Error())
} }
@ -78,11 +79,11 @@ func queryBlockNumber(ctx sdk.Context, keeper Keeper) ([]byte, sdk.Error) {
} }
func queryStorage(ctx sdk.Context, path []string, keeper Keeper) ([]byte, sdk.Error) { func queryStorage(ctx sdk.Context, path []string, keeper Keeper) ([]byte, sdk.Error) {
addr := ethcmn.BytesToAddress([]byte(path[1])) addr := ethcmn.HexToAddress(path[1])
key := ethcmn.BytesToHash([]byte(path[2])) key := ethcmn.HexToHash(path[2])
val := keeper.GetState(ctx, addr, key) val := keeper.GetState(ctx, addr, key)
bRes := hexutil.Bytes(val.Bytes()) bRes := types.QueryResStorage{Value: val.Bytes()}
res, err := codec.MarshalJSONIndent(keeper.cdc, &bRes) res, err := codec.MarshalJSONIndent(keeper.cdc, bRes)
if err != nil { if err != nil {
panic("could not marshal result to JSON: " + err.Error()) panic("could not marshal result to JSON: " + err.Error())
} }
@ -90,9 +91,10 @@ func queryStorage(ctx sdk.Context, path []string, keeper Keeper) ([]byte, sdk.Er
} }
func queryCode(ctx sdk.Context, path []string, keeper Keeper) ([]byte, sdk.Error) { func queryCode(ctx sdk.Context, path []string, keeper Keeper) ([]byte, sdk.Error) {
addr := ethcmn.BytesToAddress([]byte(path[1])) addr := ethcmn.HexToAddress(path[1])
code := keeper.GetCode(ctx, addr) code := keeper.GetCode(ctx, addr)
res, err := codec.MarshalJSONIndent(keeper.cdc, code) cRes := types.QueryResCode{Code: code}
res, err := codec.MarshalJSONIndent(keeper.cdc, cRes)
if err != nil { if err != nil {
panic("could not marshal result to JSON: " + err.Error()) panic("could not marshal result to JSON: " + err.Error())
} }
@ -101,9 +103,9 @@ func queryCode(ctx sdk.Context, path []string, keeper Keeper) ([]byte, sdk.Error
} }
func queryNonce(ctx sdk.Context, path []string, keeper Keeper) ([]byte, sdk.Error) { func queryNonce(ctx sdk.Context, path []string, keeper Keeper) ([]byte, sdk.Error) {
addr := ethcmn.BytesToAddress([]byte(path[1])) addr := ethcmn.HexToAddress(path[1])
nonce := keeper.GetNonce(ctx, addr) nonce := keeper.GetNonce(ctx, addr)
nRes := hexutil.Uint64(nonce) nRes := types.QueryResNonce{Nonce: nonce}
res, err := codec.MarshalJSONIndent(keeper.cdc, nRes) res, err := codec.MarshalJSONIndent(keeper.cdc, nRes)
if err != nil { if err != nil {
panic("could not marshal result to JSON: " + err.Error()) panic("could not marshal result to JSON: " + err.Error())

View File

@ -1,9 +1,8 @@
package types package types
import ( import (
"math/big"
"github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/ethermint/utils"
ethcmn "github.com/ethereum/go-ethereum/common" ethcmn "github.com/ethereum/go-ethereum/common"
) )
@ -19,7 +18,7 @@ func RegisterAmino(cdc *codec.Codec) {
cdc.RegisterConcrete(EncodableTxData{}, "ethermint/EncodedMessage", nil) cdc.RegisterConcrete(EncodableTxData{}, "ethermint/EncodedMessage", nil)
} }
// TxData implements the Ethereum transaction data structure. It is used // EncodableTxData implements the Ethereum transaction data structure. It is used
// solely as intended in Ethereum abiding by the protocol. // solely as intended in Ethereum abiding by the protocol.
type EncodableTxData struct { type EncodableTxData struct {
AccountNonce uint64 `json:"nonce"` AccountNonce uint64 `json:"nonce"`
@ -47,33 +46,19 @@ func unmarshalAmino(td *EncodableTxData, text string) (err error) {
return cdc.UnmarshalBinaryBare([]byte(text), td) return cdc.UnmarshalBinaryBare([]byte(text), td)
} }
func marshalBigInt(i *big.Int) string {
bz, err := i.MarshalText()
if err != nil {
panic(err)
}
return string(bz)
}
func unmarshalBigInt(s string) (*big.Int, error) {
ret := new(big.Int)
err := ret.UnmarshalText([]byte(s))
return ret, err
}
// MarshalAmino defines custom encoding scheme for TxData // MarshalAmino defines custom encoding scheme for TxData
func (td TxData) MarshalAmino() (string, error) { func (td TxData) MarshalAmino() (string, error) {
e := EncodableTxData{ e := EncodableTxData{
AccountNonce: td.AccountNonce, AccountNonce: td.AccountNonce,
Price: marshalBigInt(td.Price), Price: utils.MarshalBigInt(td.Price),
GasLimit: td.GasLimit, GasLimit: td.GasLimit,
Recipient: td.Recipient, Recipient: td.Recipient,
Amount: marshalBigInt(td.Amount), Amount: utils.MarshalBigInt(td.Amount),
Payload: td.Payload, Payload: td.Payload,
V: marshalBigInt(td.V), V: utils.MarshalBigInt(td.V),
R: marshalBigInt(td.R), R: utils.MarshalBigInt(td.R),
S: marshalBigInt(td.S), S: utils.MarshalBigInt(td.S),
Hash: td.Hash, Hash: td.Hash,
} }
@ -95,7 +80,7 @@ func (td *TxData) UnmarshalAmino(text string) (err error) {
td.Payload = e.Payload td.Payload = e.Payload
td.Hash = e.Hash td.Hash = e.Hash
price, err := unmarshalBigInt(e.Price) price, err := utils.UnmarshalBigInt(e.Price)
if err != nil { if err != nil {
return return
} }
@ -105,7 +90,7 @@ func (td *TxData) UnmarshalAmino(text string) (err error) {
td.Price = price td.Price = price
} }
amt, err := unmarshalBigInt(e.Amount) amt, err := utils.UnmarshalBigInt(e.Amount)
if err != nil { if err != nil {
return return
} }
@ -115,7 +100,7 @@ func (td *TxData) UnmarshalAmino(text string) (err error) {
td.Amount = amt td.Amount = amt
} }
v, err := unmarshalBigInt(e.V) v, err := utils.UnmarshalBigInt(e.V)
if err != nil { if err != nil {
return return
} }
@ -125,7 +110,7 @@ func (td *TxData) UnmarshalAmino(text string) (err error) {
td.V = v td.V = v
} }
r, err := unmarshalBigInt(e.R) r, err := utils.UnmarshalBigInt(e.R)
if err != nil { if err != nil {
return return
} }
@ -135,7 +120,7 @@ func (td *TxData) UnmarshalAmino(text string) (err error) {
td.R = r td.R = r
} }
s, err := unmarshalBigInt(e.S) s, err := utils.UnmarshalBigInt(e.S)
if err != nil { if err != nil {
return return
} }

View File

@ -7,6 +7,7 @@ import (
"testing" "testing"
"github.com/cosmos/ethermint/crypto" "github.com/cosmos/ethermint/crypto"
"github.com/cosmos/ethermint/utils"
ethcmn "github.com/ethereum/go-ethereum/common" ethcmn "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/rlp"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
@ -140,8 +141,8 @@ func TestMsgEthereumTxAmino(t *testing.T) {
func TestMarshalAndUnmarshalInt(t *testing.T) { func TestMarshalAndUnmarshalInt(t *testing.T) {
i := big.NewInt(3) i := big.NewInt(3)
m := marshalBigInt(i) m := utils.MarshalBigInt(i)
i2, err := unmarshalBigInt(m) i2, err := utils.UnmarshalBigInt(m)
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, i, i2) require.Equal(t, i, i2)
@ -152,15 +153,15 @@ func TestMarshalAndUnmarshalData(t *testing.T) {
hash := ethcmn.BigToHash(big.NewInt(2)) hash := ethcmn.BigToHash(big.NewInt(2))
e := EncodableTxData{ e := EncodableTxData{
AccountNonce: 2, AccountNonce: 2,
Price: marshalBigInt(big.NewInt(3)), Price: utils.MarshalBigInt(big.NewInt(3)),
GasLimit: 1, GasLimit: 1,
Recipient: &addr, Recipient: &addr,
Amount: marshalBigInt(big.NewInt(4)), Amount: utils.MarshalBigInt(big.NewInt(4)),
Payload: []byte("test"), Payload: []byte("test"),
V: marshalBigInt(big.NewInt(5)), V: utils.MarshalBigInt(big.NewInt(5)),
R: marshalBigInt(big.NewInt(6)), R: utils.MarshalBigInt(big.NewInt(6)),
S: marshalBigInt(big.NewInt(7)), S: utils.MarshalBigInt(big.NewInt(7)),
Hash: &hash, Hash: &hash,
} }

55
x/evm/types/querier.go Normal file
View File

@ -0,0 +1,55 @@
package types
// QueryResProtocolVersion is response type for protocol version query
type QueryResProtocolVersion struct {
Version string `json:"version"`
}
func (q QueryResProtocolVersion) String() string {
return q.Version
}
// QueryResBalance is response type for balance query
type QueryResBalance struct {
Balance string `json:"balance"`
}
func (q QueryResBalance) String() string {
return q.Balance
}
// QueryResBlockNumber is response type for block number query
type QueryResBlockNumber struct {
Number int64 `json:"blockNumber"`
}
func (q QueryResBlockNumber) String() string {
return string(q.Number)
}
// QueryResStorage is response type for storage query
type QueryResStorage struct {
Value []byte `json:"value"`
}
func (q QueryResStorage) String() string {
return string(q.Value)
}
// QueryResCode is response type for code query
type QueryResCode struct {
Code []byte
}
func (q QueryResCode) String() string {
return string(q.Code)
}
// QueryResNonce is response type for Nonce query
type QueryResNonce struct {
Nonce uint64 `json:"nonce"`
}
func (q QueryResNonce) String() string {
return string(q.Nonce)
}