Skip to content
This repository has been archived by the owner on Nov 30, 2021. It is now read-only.

Commit

Permalink
x/evm: unit tests and fixes (#223)
Browse files Browse the repository at this point in the history
* evm: move Keeper and Querier to /keeper package

* keeper: update keeper_test.go

* fix format

* evm: use aliased types

* bump SDK version to v0.38.1

* app: updates from new version

* errors: switch sdk.Error -> error

* errors: switch sdk.Error -> error. Continuation

* more fixes

* update app/

* update keys and client pkgs

* build

* fix tests

* lint

* minor changes

* changelog

* address @AustinBell comments

* Fix keyring usage in rpc API and CLI

* fix keyring

* break line

* Misc cleanup (#188)

* evm: move Begin and EndBlock to abci.go

* evm: use expected keeper interfaces

* app: use EthermintApp for integration and unit test setup

* evm: remove count type; update codec

* go mod verify

* evm: rename msgs for consistency

* evm: events

* minor cleanup

* lint

* ante: update tests

* changelog

* nolint

* evm: update statedb to create ethermint Account instead of BaseAccount

* fix importer test

* address @austinabell comments

* update README

* changelog

* evm: update codec

* rename GasLimit->Gas and Price ->GasPrice

* msg cleanup and tests

* cleanup TxData

* fix marshaling

* revert rename

* move types

* evm/keeper: querier tests

* switch MarshalLengthPrefixed -> BinaryBare; remove panics

* fix event sender

* fix panic

* try fix txDecoder error

* evm: handler tests

* evm: handler MsgEthermint test

* fix tests

* store logs in keeper after transition (#210)

* add some comments

* begin log handler test

* update TransitionCSDB to return ReturnData

* use rlp for result data encode/decode

* update tests

* implement SetBlockLogs

* implement GetBlockLogs

* test log set/get

* update keeper get/set logs to use hash as key

* fix test

* move logsKey to csdb

* attempt to fix test

* attempt to fix test

* attempt to fix test

* lint

* lint

* lint

* save logs after handling msg

* update k.Logs

* cleanup

* remove unused

* fix issues

* comment out handler test

* address comments

* lint

* fix handler test

* address comments

* use amino

* lint

* address comments

* merge

* fix encoding bug

* minor fix

* rpc: error handling

* rpc: simulate only returns gasConsumed

* rpc: error ineffassign

* evm: handler test

* go: bump version to 1.14 and SDK version to latest master

* rpc: fix simulation return value

* breaking changes from SDK

* sdk: breaking changes; build

* tests: fixes

* minor fix

* proto: ethermint types attempt

* proto: define EthAccount proto type and extend sdk std.Codec

* evm: fix panic on handler test

* evm: minor state object changes

* cleanup

* tests: update test-importer

* fix evm test

* fix pubkey registration

* lint

* cleanup

* more test checks for importer

* minor change

* codec fixes

* rm init func

* fix importer test build

* fixes

* test fixes

* fix bloom key

* rm unnecesary func

* remove comment

Co-authored-by: austinabell <austinabell8@gmail.com>
Co-authored-by: noot <36753753+noot@users.noreply.github.com>
  • Loading branch information
3 people authored Apr 23, 2020
1 parent 4d609b2 commit 8ec7edf
Show file tree
Hide file tree
Showing 24 changed files with 770 additions and 510 deletions.
23 changes: 16 additions & 7 deletions app/ante/ante_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@ func (suite *AnteTestSuite) TestValidEthTx() {
gas := big.NewInt(20)
ethMsg := evmtypes.NewMsgEthereumTx(0, &to, amt, 34910, gas, []byte("test"))

tx := newTestEthTx(suite.ctx, ethMsg, priv1)
tx, err := newTestEthTx(suite.ctx, ethMsg, priv1)
suite.Require().NoError(err)
requireValidTx(suite.T(), suite.anteHandler, suite.ctx, tx, false)
}

Expand Down Expand Up @@ -183,7 +184,9 @@ func (suite *AnteTestSuite) TestEthInvalidSig() {
gas := big.NewInt(20)
ethMsg := evmtypes.NewMsgEthereumTx(0, &to, amt, 22000, gas, []byte("test"))

tx := newTestEthTx(suite.ctx, ethMsg, priv1)
tx, err := newTestEthTx(suite.ctx, ethMsg, priv1)
suite.Require().NoError(err)

ctx := suite.ctx.WithChainID("4")
requireInvalidTx(suite.T(), suite.anteHandler, ctx, tx, false)
}
Expand All @@ -208,7 +211,8 @@ func (suite *AnteTestSuite) TestEthInvalidNonce() {
gas := big.NewInt(20)
ethMsg := evmtypes.NewMsgEthereumTx(0, &to, amt, 22000, gas, []byte("test"))

tx := newTestEthTx(suite.ctx, ethMsg, priv1)
tx, err := newTestEthTx(suite.ctx, ethMsg, priv1)
suite.Require().NoError(err)
requireInvalidTx(suite.T(), suite.anteHandler, suite.ctx, tx, false)
}

Expand All @@ -227,7 +231,8 @@ func (suite *AnteTestSuite) TestEthInsufficientBalance() {
gas := big.NewInt(20)
ethMsg := evmtypes.NewMsgEthereumTx(0, &to, amt, 22000, gas, []byte("test"))

tx := newTestEthTx(suite.ctx, ethMsg, priv1)
tx, err := newTestEthTx(suite.ctx, ethMsg, priv1)
suite.Require().NoError(err)
requireInvalidTx(suite.T(), suite.anteHandler, suite.ctx, tx, false)
}

Expand All @@ -249,7 +254,8 @@ func (suite *AnteTestSuite) TestEthInvalidIntrinsicGas() {
gasLimit := uint64(1000)
ethMsg := evmtypes.NewMsgEthereumTx(0, &to, amt, gasLimit, gas, []byte("test"))

tx := newTestEthTx(suite.ctx, ethMsg, priv1)
tx, err := newTestEthTx(suite.ctx, ethMsg, priv1)
suite.Require().NoError(err)
requireInvalidTx(suite.T(), suite.anteHandler, suite.ctx, tx, false)
}

Expand All @@ -274,7 +280,8 @@ func (suite *AnteTestSuite) TestEthInvalidMempoolFees() {
gas := big.NewInt(20)
ethMsg := evmtypes.NewMsgEthereumTx(0, &to, amt, 22000, gas, []byte("payload"))

tx := newTestEthTx(suite.ctx, ethMsg, priv1)
tx, err := newTestEthTx(suite.ctx, ethMsg, priv1)
suite.Require().NoError(err)
requireInvalidTx(suite.T(), suite.anteHandler, suite.ctx, tx, false)
}

Expand All @@ -295,7 +302,9 @@ func (suite *AnteTestSuite) TestEthInvalidChainID() {
gas := big.NewInt(20)
ethMsg := evmtypes.NewMsgEthereumTx(0, &to, amt, 22000, gas, []byte("test"))

tx := newTestEthTx(suite.ctx, ethMsg, priv1)
tx, err := newTestEthTx(suite.ctx, ethMsg, priv1)
suite.Require().NoError(err)

ctx := suite.ctx.WithChainID("bad-chain-id")
requireInvalidTx(suite.T(), suite.anteHandler, ctx, tx, false)
}
14 changes: 9 additions & 5 deletions app/ante/utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,17 +88,21 @@ func newTestSDKTx(
return auth.NewStdTx(msgs, fee, sigs, "")
}

func newTestEthTx(ctx sdk.Context, msg evmtypes.MsgEthereumTx, priv tmcrypto.PrivKey) sdk.Tx {
func newTestEthTx(ctx sdk.Context, msg evmtypes.MsgEthereumTx, priv tmcrypto.PrivKey) (sdk.Tx, error) {
chainID, ok := new(big.Int).SetString(ctx.ChainID(), 10)
if !ok {
panic(fmt.Sprintf("invalid chainID: %s", ctx.ChainID()))
return nil, fmt.Errorf("invalid chainID: %s", ctx.ChainID())
}

privkey, ok := priv.(crypto.PrivKeySecp256k1)
if !ok {
panic(fmt.Sprintf("invalid private key type: %T", priv))
return nil, fmt.Errorf("invalid private key type: %T", priv)
}

msg.Sign(chainID, privkey.ToECDSA())
return msg
err := msg.Sign(chainID, privkey.ToECDSA())
if err != nil {
return nil, err
}

return msg, nil
}
2 changes: 1 addition & 1 deletion codec/codec.proto
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,4 @@ message Account {
cosmos_sdk.x.supply.v1.ModuleAccount module_account = 5;
ethermint.v1.EthAccount eth_account = 6;
}
}
}
56 changes: 0 additions & 56 deletions go.sum

Large diffs are not rendered by default.

4 changes: 3 additions & 1 deletion rpc/eth_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,9 @@ func (e *PublicEthAPI) SendTransaction(args params.SendTxArgs) (common.Hash, err
}

// Sign transaction
tx.Sign(intChainID, e.key.ToECDSA())
if err := tx.Sign(intChainID, e.key.ToECDSA()); err != nil {
return common.Hash{}, err
}

// Encode transaction by default Tx encoder
txEncoder := authclient.GetTxEncoder(e.cliCtx.Codec)
Expand Down
12 changes: 6 additions & 6 deletions third_party/proto/tendermint/abci/types/types.proto
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,8 @@ message RequestSetOption {
}

message RequestInitChain {
google.protobuf.Timestamp time = 1 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true];
string chain_id = 2;
google.protobuf.Timestamp time = 1 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true];
string chain_id = 2;
ConsensusParams consensus_params = 3;
repeated ValidatorUpdate validators = 4 [(gogoproto.nullable) = false];
bytes app_state_bytes = 5;
Expand Down Expand Up @@ -321,10 +321,10 @@ message PubKey {
}

message Evidence {
string type = 1;
Validator validator = 2 [(gogoproto.nullable) = false];
int64 height = 3;
google.protobuf.Timestamp time = 4 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true];
string type = 1;
Validator validator = 2 [(gogoproto.nullable) = false];
int64 height = 3;
google.protobuf.Timestamp time = 4 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true];
int64 total_voting_power = 5;
}

Expand Down
25 changes: 19 additions & 6 deletions utils/int.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,38 @@ package utils
import "math/big"

// MarshalBigInt marshalls big int into text string for consistent encoding
func MarshalBigInt(i *big.Int) string {
func MarshalBigInt(i *big.Int) (string, error) {
bz, err := i.MarshalText()
if err != nil {
return "", err
}
return string(bz), nil
}

// MustMarshalBigInt marshalls big int into text string for consistent encoding.
// It panics if an error is encountered.
func MustMarshalBigInt(i *big.Int) string {
str, err := MarshalBigInt(i)
if err != nil {
panic(err)
}
return string(bz)
return str
}

// 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
if err != nil {
return nil, err
}
return ret, nil
}

// MustUnmarshalBigInt unmarshalls string from *big.Int
// MustUnmarshalBigInt unmarshalls string from *big.Int.
// It panics if an error is encountered.
func MustUnmarshalBigInt(s string) *big.Int {
ret := new(big.Int)
err := ret.UnmarshalText([]byte(s))
ret, err := UnmarshalBigInt(s)
if err != nil {
panic(err)
}
Expand Down
18 changes: 18 additions & 0 deletions utils/int_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package utils

import (
"math/big"
"testing"

"github.com/stretchr/testify/require"
)

func TestMarshalAndUnmarshalInt(t *testing.T) {
i := big.NewInt(3)
m, err := MarshalBigInt(i)
require.NoError(t, err)

i2, err := UnmarshalBigInt(m)
require.NoError(t, err)
require.Equal(t, i, i2)
}
9 changes: 5 additions & 4 deletions x/evm/abci.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,13 @@ import (
// BeginBlock sets the Bloom and Hash mappings and resets the Bloom filter and
// the transaction count to 0.
func BeginBlock(k Keeper, ctx sdk.Context, req abci.RequestBeginBlock) {
if req.Header.LastBlockId.GetHash() == nil || req.Header.GetHeight() < 1 {
return
}

// Consider removing this when using evm as module without web3 API
bloom := ethtypes.BytesToBloom(k.Bloom.Bytes())
err := k.SetBlockBloomMapping(ctx, bloom, req.Header.GetHeight()-1)
if err != nil {
panic(err)
}
k.SetBlockBloomMapping(ctx, bloom, req.Header.GetHeight()-1)
k.SetBlockHashMapping(ctx, req.Header.LastBlockId.GetHash(), req.Header.GetHeight()-1)
k.Bloom = big.NewInt(0)
k.TxCount = 0
Expand Down
11 changes: 6 additions & 5 deletions x/evm/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,17 @@ func NewHandler(k Keeper) sdk.Handler {
ctx = ctx.WithEventManager(sdk.NewEventManager())
switch msg := msg.(type) {
case types.MsgEthereumTx:
return HandleMsgEthereumTx(ctx, k, msg)
return handleMsgEthereumTx(ctx, k, msg)
case types.MsgEthermint:
return HandleMsgEthermint(ctx, k, msg)
return handleMsgEthermint(ctx, k, msg)
default:
return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized %s message type: %T", ModuleName, msg)
}
}
}

// HandleMsgEthereumTx handles an Ethereum specific tx
func HandleMsgEthereumTx(ctx sdk.Context, k Keeper, msg types.MsgEthereumTx) (*sdk.Result, error) {
// handleMsgEthereumTx handles an Ethereum specific tx
func handleMsgEthereumTx(ctx sdk.Context, k Keeper, msg types.MsgEthereumTx) (*sdk.Result, error) {
// parse the chainID from a string to a base-10 integer
intChainID, ok := new(big.Int).SetString(ctx.ChainID(), 10)
if !ok {
Expand Down Expand Up @@ -105,7 +105,8 @@ func HandleMsgEthereumTx(ctx sdk.Context, k Keeper, msg types.MsgEthereumTx) (*s
return returnData.Result, nil
}

func HandleMsgEthermint(ctx sdk.Context, k Keeper, msg types.MsgEthermint) (*sdk.Result, error) {
// handleMsgEthermint handles an sdk.StdTx for an Ethereum state transition
func handleMsgEthermint(ctx sdk.Context, k Keeper, msg types.MsgEthermint) (*sdk.Result, error) {
// parse the chainID from a string to a base-10 integer
intChainID, ok := new(big.Int).SetString(ctx.ChainID(), 10)
if !ok {
Expand Down
Loading

0 comments on commit 8ec7edf

Please sign in to comment.