2019-07-25 20:38:55 +00:00
|
|
|
// This is a test utility for Ethermint's Web3 JSON-RPC services.
|
|
|
|
//
|
|
|
|
// To run these tests please first ensure you have the emintd running
|
|
|
|
// and have started the RPC service with `emintcl rest-server`.
|
|
|
|
//
|
|
|
|
// You can configure the desired port (or host) below.
|
|
|
|
|
|
|
|
package tester
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
|
|
|
"encoding/json"
|
2019-09-24 14:49:40 +00:00
|
|
|
"errors"
|
2019-07-25 20:38:55 +00:00
|
|
|
"fmt"
|
|
|
|
"math/big"
|
|
|
|
"net/http"
|
|
|
|
"testing"
|
2019-09-24 14:49:40 +00:00
|
|
|
|
|
|
|
"github.com/cosmos/ethermint/version"
|
|
|
|
"github.com/ethereum/go-ethereum/common/hexutil"
|
2019-07-25 20:38:55 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
2019-09-24 14:49:40 +00:00
|
|
|
host = "localhost"
|
|
|
|
port = 8545
|
2019-07-25 20:38:55 +00:00
|
|
|
addrA = "0xc94770007dda54cF92009BFF0dE90c06F603a09f"
|
|
|
|
addrAStoreKey = 0
|
|
|
|
)
|
|
|
|
|
|
|
|
var addr = fmt.Sprintf("http://%s:%d/rpc", host, port)
|
|
|
|
|
|
|
|
type Request struct {
|
|
|
|
Version string `json:"jsonrpc"`
|
|
|
|
Method string `json:"method"`
|
|
|
|
Params []string `json:"params"`
|
|
|
|
Id int `json:"id"`
|
|
|
|
}
|
|
|
|
|
2019-09-24 14:49:40 +00:00
|
|
|
type RPCError struct {
|
|
|
|
Code int `json:"code"`
|
|
|
|
Message string `json:"message"`
|
|
|
|
Data interface{} `json:"data,omitempty"`
|
|
|
|
}
|
|
|
|
|
|
|
|
type Response struct {
|
|
|
|
Error *RPCError `json:"error"`
|
|
|
|
Id int `json:"id"`
|
|
|
|
Result json.RawMessage `json:"result,omitempty"`
|
|
|
|
}
|
|
|
|
|
2019-07-25 20:38:55 +00:00
|
|
|
func createRequest(method string, params []string) Request {
|
|
|
|
return Request{
|
|
|
|
Version: "2.0",
|
|
|
|
Method: method,
|
|
|
|
Params: params,
|
|
|
|
Id: 1,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-09-24 14:49:40 +00:00
|
|
|
func call(method string, params []string) (*Response, error) {
|
2019-07-25 20:38:55 +00:00
|
|
|
req, err := json.Marshal(createRequest(method, params))
|
|
|
|
if err != nil {
|
2019-09-24 14:49:40 +00:00
|
|
|
return nil, err
|
2019-07-25 20:38:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
res, err := http.Post(addr, "application/json", bytes.NewBuffer(req))
|
|
|
|
if err != nil {
|
2019-09-24 14:49:40 +00:00
|
|
|
return nil, err
|
2019-07-25 20:38:55 +00:00
|
|
|
}
|
|
|
|
|
2019-09-24 14:49:40 +00:00
|
|
|
decoder := json.NewDecoder(res.Body)
|
|
|
|
var rpcRes *Response
|
|
|
|
err = decoder.Decode(&rpcRes)
|
2019-07-25 20:38:55 +00:00
|
|
|
if err != nil {
|
2019-09-24 14:49:40 +00:00
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
if rpcRes.Error != nil {
|
|
|
|
return nil, errors.New(rpcRes.Error.Message)
|
2019-07-25 20:38:55 +00:00
|
|
|
}
|
|
|
|
|
2019-09-24 14:49:40 +00:00
|
|
|
err = res.Body.Close()
|
2019-07-25 20:38:55 +00:00
|
|
|
if err != nil {
|
2019-09-24 14:49:40 +00:00
|
|
|
return nil, err
|
2019-07-25 20:38:55 +00:00
|
|
|
}
|
2019-09-24 14:49:40 +00:00
|
|
|
|
|
|
|
return rpcRes, nil
|
2019-07-25 20:38:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestEth_protocolVersion(t *testing.T) {
|
2019-09-24 14:49:40 +00:00
|
|
|
expectedRes := hexutil.Uint(version.ProtocolVersion)
|
2019-07-25 20:38:55 +00:00
|
|
|
|
2019-09-24 14:49:40 +00:00
|
|
|
rpcRes, err := call("eth_protocolVersion", []string{})
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
2019-07-25 20:38:55 +00:00
|
|
|
|
2019-09-24 14:49:40 +00:00
|
|
|
var res hexutil.Uint
|
|
|
|
err = res.UnmarshalJSON(rpcRes.Result)
|
2019-07-25 20:38:55 +00:00
|
|
|
|
2019-09-24 14:49:40 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
t.Logf("Got protocol version: %s\n", res.String())
|
|
|
|
|
|
|
|
if res != expectedRes {
|
|
|
|
t.Fatalf("expected: %s got: %s\n", expectedRes.String(), rpcRes.Result)
|
2019-07-25 20:38:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestEth_blockNumber(t *testing.T) {
|
2019-09-24 14:49:40 +00:00
|
|
|
rpcRes, err := call("eth_blockNumber", []string{})
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
var res hexutil.Uint64
|
|
|
|
err = res.UnmarshalJSON(rpcRes.Result)
|
2019-07-25 20:38:55 +00:00
|
|
|
|
2019-09-24 14:49:40 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
2019-07-25 20:38:55 +00:00
|
|
|
}
|
2019-09-24 14:49:40 +00:00
|
|
|
|
|
|
|
t.Logf("Got block number: %s\n", res.String())
|
|
|
|
|
2019-07-25 20:38:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestEth_GetBalance(t *testing.T) {
|
2019-09-24 14:49:40 +00:00
|
|
|
rpcRes, err := call("eth_getBalance", []string{addrA, "0x0"})
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
return
|
|
|
|
}
|
2019-07-25 20:38:55 +00:00
|
|
|
|
2019-09-24 14:49:40 +00:00
|
|
|
var res hexutil.Big
|
|
|
|
err = res.UnmarshalJSON(rpcRes.Result)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
t.Logf("Got balance %s for %s\n", res.String(), addrA)
|
2019-07-25 20:38:55 +00:00
|
|
|
|
|
|
|
// 0 if x == y; where x is res, y is 0
|
2019-09-24 14:49:40 +00:00
|
|
|
if res.ToInt().Cmp(big.NewInt(0)) != 0 {
|
|
|
|
t.Errorf("expected balance: %d, got: %s", 0, res.String())
|
2019-07-25 20:38:55 +00:00
|
|
|
}
|
2019-09-24 14:49:40 +00:00
|
|
|
|
2019-07-25 20:38:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestEth_GetStorageAt(t *testing.T) {
|
2019-09-24 14:49:40 +00:00
|
|
|
expectedRes := hexutil.Bytes{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
|
|
|
rpcRes, err := call("eth_getStorageAt", []string{addrA, string(addrAStoreKey), "0x0"})
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
2019-07-25 20:38:55 +00:00
|
|
|
|
2019-09-24 14:49:40 +00:00
|
|
|
var storage hexutil.Bytes
|
|
|
|
err = storage.UnmarshalJSON(rpcRes.Result)
|
2019-07-25 20:38:55 +00:00
|
|
|
|
2019-09-24 14:49:40 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
t.Logf("Got value [%X] for %s with key %X\n", storage, addrA, addrAStoreKey)
|
|
|
|
|
|
|
|
if !bytes.Equal(storage, expectedRes) {
|
|
|
|
t.Errorf("expected: %d (%d bytes) got: %d (%d bytes)", expectedRes, len(expectedRes), storage, len(storage))
|
2019-07-25 20:38:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestEth_GetCode(t *testing.T) {
|
2019-09-24 14:49:40 +00:00
|
|
|
expectedRes := hexutil.Bytes{}
|
|
|
|
rpcRes, err := call("eth_getCode", []string{addrA, "0x0"})
|
|
|
|
if err != nil {
|
|
|
|
t.Error(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
var code hexutil.Bytes
|
|
|
|
err = code.UnmarshalJSON(rpcRes.Result)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
2019-07-25 20:38:55 +00:00
|
|
|
|
2019-09-24 14:49:40 +00:00
|
|
|
t.Logf("Got code [%X] for %s\n", code, addrA)
|
|
|
|
if !bytes.Equal(expectedRes, code) {
|
|
|
|
t.Errorf("expected: %X got: %X", expectedRes, code)
|
2019-07-25 20:38:55 +00:00
|
|
|
}
|
|
|
|
}
|