diff --git a/CHANGELOG.md b/CHANGELOG.md index 966aabc24..7f2b0763d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -41,4 +41,10 @@ Ref: https://keepachangelog.com/en/1.0.0/ * (sdk) [\#171](https://github.com/ChainSafe/ethermint/issues/177) Bump Cosmos SDK version to [v0.38.1](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.38.1) * Add `x/evidence` module to ethermint app -* (x/evm) [\#181](https://github.com/ChainSafe/ethermint/issues/181) Updated EVM module to the recommended module structure. [@fedekunze](https://github.com/fedekunze) +* (`x/evm`) [\#181](https://github.com/ChainSafe/ethermint/issues/181) Updated EVM module to the recommended module structure. [@fedekunze](https://github.com/fedekunze) +* (app) [\#188](https://github.com/ChainSafe/ethermint/issues/186) Misc cleanup [@fedekunze](https://github.com/fedekunze): + * (`x/evm`) Rename `EthereumTxMsg` --> `MsgEthereumTx` and `EmintMsg` --> `MsgEthermint` for consistency with SDK standards + * Updated integration and unit tests to use `EthermintApp` as testing suite + * Use expected keeper interface for `AccountKeeper` + * Replaced `count` type in keeper with `int` + * Add SDK events for transactions diff --git a/app/ante/ante.go b/app/ante/ante.go index 281125a3f..deff97543 100644 --- a/app/ante/ante.go +++ b/app/ante/ante.go @@ -54,7 +54,7 @@ func NewAnteHandler(ak auth.AccountKeeper, sk types.SupplyKeeper) sdk.AnteHandle return stdAnte(ctx, tx, sim) - case *evmtypes.EthereumTxMsg: + case *evmtypes.MsgEthereumTx: return ethAnteHandler(ctx, ak, sk, castTx, sim) default: @@ -92,7 +92,7 @@ func sigGasConsumer( // prevent spam and DoS attacks. func ethAnteHandler( ctx sdk.Context, ak auth.AccountKeeper, sk types.SupplyKeeper, - ethTxMsg *evmtypes.EthereumTxMsg, sim bool, + ethTxMsg *evmtypes.MsgEthereumTx, sim bool, ) (newCtx sdk.Context, err error) { var senderAddr sdk.AccAddress @@ -175,7 +175,7 @@ func ethAnteHandler( } func validateEthTxCheckTx( - ctx sdk.Context, ak auth.AccountKeeper, ethTxMsg *evmtypes.EthereumTxMsg, + ctx sdk.Context, ak auth.AccountKeeper, ethTxMsg *evmtypes.MsgEthereumTx, ) (sdk.AccAddress, error) { // Validate sufficient fees have been provided that meet a minimum threshold // defined by the proposer (for mempool purposes during CheckTx). @@ -202,7 +202,7 @@ func validateEthTxCheckTx( } // Validates signature and returns sender address -func validateSignature(ctx sdk.Context, ethTxMsg *evmtypes.EthereumTxMsg) (sdk.AccAddress, error) { +func validateSignature(ctx sdk.Context, ethTxMsg *evmtypes.MsgEthereumTx) (sdk.AccAddress, error) { // parse the chainID from a string to a base-10 integer chainID, ok := new(big.Int).SetString(ctx.ChainID(), 10) if !ok { @@ -223,7 +223,7 @@ func validateSignature(ctx sdk.Context, ethTxMsg *evmtypes.EthereumTxMsg) (sdk.A // that the transaction uses before the transaction is executed. The gas is a // constant value of 21000 plus any cost inccured by additional bytes of data // supplied with the transaction. -func validateIntrinsicGas(ethTxMsg *evmtypes.EthereumTxMsg) error { +func validateIntrinsicGas(ethTxMsg *evmtypes.MsgEthereumTx) error { gas, err := ethcore.IntrinsicGas(ethTxMsg.Data.Payload, ethTxMsg.To() == nil, true) if err != nil { return sdkerrors.Wrap(err, "failed to compute intrinsic gas cost") @@ -241,7 +241,7 @@ func validateIntrinsicGas(ethTxMsg *evmtypes.EthereumTxMsg) error { // validateAccount validates the account nonce and that the account has enough // funds to cover the tx cost. func validateAccount( - ctx sdk.Context, ak auth.AccountKeeper, ethTxMsg *evmtypes.EthereumTxMsg, signer sdk.AccAddress, + ctx sdk.Context, ak auth.AccountKeeper, ethTxMsg *evmtypes.MsgEthereumTx, signer sdk.AccAddress, ) error { acc := ak.GetAccount(ctx, signer) @@ -272,7 +272,7 @@ func validateAccount( } func checkNonce( - ctx sdk.Context, ak auth.AccountKeeper, ethTxMsg *evmtypes.EthereumTxMsg, signer sdk.AccAddress, + ctx sdk.Context, ak auth.AccountKeeper, ethTxMsg *evmtypes.MsgEthereumTx, signer sdk.AccAddress, ) error { acc := ak.GetAccount(ctx, signer) // Validate the transaction nonce is valid (equivalent to the sender account’s @@ -293,7 +293,7 @@ func checkNonce( // proposer. // // NOTE: This should only be ran during a CheckTx mode. -func ensureSufficientMempoolFees(ctx sdk.Context, ethTxMsg *evmtypes.EthereumTxMsg) error { +func ensureSufficientMempoolFees(ctx sdk.Context, ethTxMsg *evmtypes.MsgEthereumTx) error { // fee = GP * GL fee := sdk.NewDecCoinFromCoin(sdk.NewInt64Coin(emint.DenomDefault, ethTxMsg.Fee().Int64())) diff --git a/app/ante/ante_test.go b/app/ante/ante_test.go index 7fed5beae..4de5b666e 100644 --- a/app/ante/ante_test.go +++ b/app/ante/ante_test.go @@ -3,15 +3,19 @@ package ante_test import ( "math/big" "testing" + "time" "github.com/stretchr/testify/require" ethcmn "github.com/ethereum/go-ethereum/common" + abci "github.com/tendermint/tendermint/abci/types" tmcrypto "github.com/tendermint/tendermint/crypto" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/ethermint/app" + "github.com/cosmos/ethermint/app/ante" "github.com/cosmos/ethermint/types" evmtypes "github.com/cosmos/ethermint/x/evm/types" ) @@ -20,61 +24,58 @@ func requireValidTx( t *testing.T, anteHandler sdk.AnteHandler, ctx sdk.Context, tx sdk.Tx, sim bool, ) { _, err := anteHandler(ctx, tx, sim) - require.True(t, err == nil) + require.NoError(t, err) } func requireInvalidTx( t *testing.T, anteHandler sdk.AnteHandler, ctx sdk.Context, tx sdk.Tx, sim bool, ) { - _, err := anteHandler(ctx, tx, sim) require.Error(t, err) } -func TestValidEthTx(t *testing.T) { - input := newTestSetup() - input.ctx = input.ctx.WithBlockHeight(1) +func (suite *AnteTestSuite) TestValidEthTx() { + suite.ctx = suite.ctx.WithBlockHeight(1) addr1, priv1 := newTestAddrKey() addr2, _ := newTestAddrKey() - acc1 := input.accKeeper.NewAccountWithAddress(input.ctx, addr1) + acc1 := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, addr1) // nolint:errcheck acc1.SetCoins(newTestCoins()) - input.accKeeper.SetAccount(input.ctx, acc1) + suite.app.AccountKeeper.SetAccount(suite.ctx, acc1) - acc2 := input.accKeeper.NewAccountWithAddress(input.ctx, addr2) + acc2 := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, addr2) // nolint:errcheck acc2.SetCoins(newTestCoins()) - input.accKeeper.SetAccount(input.ctx, acc2) + suite.app.AccountKeeper.SetAccount(suite.ctx, acc2) // require a valid Ethereum tx to pass to := ethcmn.BytesToAddress(addr2.Bytes()) amt := big.NewInt(32) gas := big.NewInt(20) - ethMsg := evmtypes.NewEthereumTxMsg(0, &to, amt, 22000, gas, []byte("test")) + ethMsg := evmtypes.NewMsgEthereumTx(0, &to, amt, 22000, gas, []byte("test")) - tx := newTestEthTx(input.ctx, ethMsg, priv1) - requireValidTx(t, input.anteHandler, input.ctx, tx, false) + tx := newTestEthTx(suite.ctx, ethMsg, priv1) + requireValidTx(suite.T(), suite.anteHandler, suite.ctx, tx, false) } -func TestValidTx(t *testing.T) { - input := newTestSetup() - input.ctx = input.ctx.WithBlockHeight(1) +func (suite *AnteTestSuite) TestValidTx() { + suite.ctx = suite.ctx.WithBlockHeight(1) addr1, priv1 := newTestAddrKey() addr2, priv2 := newTestAddrKey() - acc1 := input.accKeeper.NewAccountWithAddress(input.ctx, addr1) + acc1 := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, addr1) // nolint:errcheck acc1.SetCoins(newTestCoins()) - input.accKeeper.SetAccount(input.ctx, acc1) + suite.app.AccountKeeper.SetAccount(suite.ctx, acc1) - acc2 := input.accKeeper.NewAccountWithAddress(input.ctx, addr2) + acc2 := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, addr2) // nolint:errcheck acc2.SetCoins(newTestCoins()) - input.accKeeper.SetAccount(input.ctx, acc2) + suite.app.AccountKeeper.SetAccount(suite.ctx, acc2) // require a valid SDK tx to pass fee := newTestStdFee() @@ -85,28 +86,27 @@ func TestValidTx(t *testing.T) { accNums := []uint64{acc1.GetAccountNumber(), acc2.GetAccountNumber()} accSeqs := []uint64{acc1.GetSequence(), acc2.GetSequence()} - tx := newTestSDKTx(input.ctx, msgs, privKeys, accNums, accSeqs, fee) + tx := newTestSDKTx(suite.ctx, msgs, privKeys, accNums, accSeqs, fee) - requireValidTx(t, input.anteHandler, input.ctx, tx, false) + requireValidTx(suite.T(), suite.anteHandler, suite.ctx, tx, false) } -func TestSDKInvalidSigs(t *testing.T) { - input := newTestSetup() - input.ctx = input.ctx.WithBlockHeight(1) +func (suite *AnteTestSuite) TestSDKInvalidSigs() { + suite.ctx = suite.ctx.WithBlockHeight(1) addr1, priv1 := newTestAddrKey() addr2, priv2 := newTestAddrKey() addr3, priv3 := newTestAddrKey() - acc1 := input.accKeeper.NewAccountWithAddress(input.ctx, addr1) + acc1 := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, addr1) // nolint:errcheck acc1.SetCoins(newTestCoins()) - input.accKeeper.SetAccount(input.ctx, acc1) + suite.app.AccountKeeper.SetAccount(suite.ctx, acc1) - acc2 := input.accKeeper.NewAccountWithAddress(input.ctx, addr2) + acc2 := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, addr2) // nolint:errcheck acc2.SetCoins(newTestCoins()) - input.accKeeper.SetAccount(input.ctx, acc2) + suite.app.AccountKeeper.SetAccount(suite.ctx, acc2) fee := newTestStdFee() msg1 := newTestMsg(addr1, addr2) @@ -118,8 +118,8 @@ func TestSDKInvalidSigs(t *testing.T) { accNums := []uint64{acc1.GetAccountNumber(), acc2.GetAccountNumber()} accSeqs := []uint64{acc1.GetSequence(), acc2.GetSequence()} - tx := newTestSDKTx(input.ctx, msgs, privKeys, accNums, accSeqs, fee) - requireInvalidTx(t, input.anteHandler, input.ctx, tx, false) + tx := newTestSDKTx(suite.ctx, msgs, privKeys, accNums, accSeqs, fee) + requireInvalidTx(suite.T(), suite.anteHandler, suite.ctx, tx, false) // require validation failure with invalid number of signers msgs = []sdk.Msg{msg1} @@ -128,8 +128,8 @@ func TestSDKInvalidSigs(t *testing.T) { accNums = []uint64{acc1.GetAccountNumber(), acc2.GetAccountNumber()} accSeqs = []uint64{acc1.GetSequence(), acc2.GetSequence()} - tx = newTestSDKTx(input.ctx, msgs, privKeys, accNums, accSeqs, fee) - requireInvalidTx(t, input.anteHandler, input.ctx, tx, false) + tx = newTestSDKTx(suite.ctx, msgs, privKeys, accNums, accSeqs, fee) + requireInvalidTx(suite.T(), suite.anteHandler, suite.ctx, tx, false) // require validation failure with an invalid signer msg2 := newTestMsg(addr1, addr3) @@ -139,20 +139,19 @@ func TestSDKInvalidSigs(t *testing.T) { accNums = []uint64{acc1.GetAccountNumber(), acc2.GetAccountNumber(), 0} accSeqs = []uint64{acc1.GetSequence(), acc2.GetSequence(), 0} - tx = newTestSDKTx(input.ctx, msgs, privKeys, accNums, accSeqs, fee) - requireInvalidTx(t, input.anteHandler, input.ctx, tx, false) + tx = newTestSDKTx(suite.ctx, msgs, privKeys, accNums, accSeqs, fee) + requireInvalidTx(suite.T(), suite.anteHandler, suite.ctx, tx, false) } -func TestSDKInvalidAcc(t *testing.T) { - input := newTestSetup() - input.ctx = input.ctx.WithBlockHeight(1) +func (suite *AnteTestSuite) TestSDKInvalidAcc() { + suite.ctx = suite.ctx.WithBlockHeight(1) addr1, priv1 := newTestAddrKey() - acc1 := input.accKeeper.NewAccountWithAddress(input.ctx, addr1) + acc1 := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, addr1) // nolint:errcheck acc1.SetCoins(newTestCoins()) - input.accKeeper.SetAccount(input.ctx, acc1) + suite.app.AccountKeeper.SetAccount(suite.ctx, acc1) fee := newTestStdFee() msg1 := newTestMsg(addr1) @@ -163,142 +162,141 @@ func TestSDKInvalidAcc(t *testing.T) { accNums := []uint64{1} accSeqs := []uint64{acc1.GetSequence()} - tx := newTestSDKTx(input.ctx, msgs, privKeys, accNums, accSeqs, fee) - requireInvalidTx(t, input.anteHandler, input.ctx, tx, false) + tx := newTestSDKTx(suite.ctx, msgs, privKeys, accNums, accSeqs, fee) + requireInvalidTx(suite.T(), suite.anteHandler, suite.ctx, tx, false) // require validation failure with invalid sequence (nonce) accNums = []uint64{acc1.GetAccountNumber()} accSeqs = []uint64{1} - tx = newTestSDKTx(input.ctx, msgs, privKeys, accNums, accSeqs, fee) - requireInvalidTx(t, input.anteHandler, input.ctx, tx, false) + tx = newTestSDKTx(suite.ctx, msgs, privKeys, accNums, accSeqs, fee) + requireInvalidTx(suite.T(), suite.anteHandler, suite.ctx, tx, false) } -func TestEthInvalidSig(t *testing.T) { - input := newTestSetup() - input.ctx = input.ctx.WithBlockHeight(1) +func (suite *AnteTestSuite) TestEthInvalidSig() { + suite.ctx = suite.ctx.WithBlockHeight(1) _, priv1 := newTestAddrKey() addr2, _ := newTestAddrKey() to := ethcmn.BytesToAddress(addr2.Bytes()) amt := big.NewInt(32) gas := big.NewInt(20) - ethMsg := evmtypes.NewEthereumTxMsg(0, &to, amt, 22000, gas, []byte("test")) + ethMsg := evmtypes.NewMsgEthereumTx(0, &to, amt, 22000, gas, []byte("test")) - tx := newTestEthTx(input.ctx, ethMsg, priv1) - ctx := input.ctx.WithChainID("4") - requireInvalidTx(t, input.anteHandler, ctx, tx, false) + tx := newTestEthTx(suite.ctx, ethMsg, priv1) + ctx := suite.ctx.WithChainID("4") + requireInvalidTx(suite.T(), suite.anteHandler, ctx, tx, false) } -func TestEthInvalidNonce(t *testing.T) { - input := newTestSetup() - input.ctx = input.ctx.WithBlockHeight(1) +func (suite *AnteTestSuite) TestEthInvalidNonce() { + + suite.ctx = suite.ctx.WithBlockHeight(1) addr1, priv1 := newTestAddrKey() addr2, _ := newTestAddrKey() - acc := input.accKeeper.NewAccountWithAddress(input.ctx, addr1) + acc := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, addr1) // nolint:errcheck acc.SetCoins(newTestCoins()) // nolint:errcheck acc.SetSequence(10) - input.accKeeper.SetAccount(input.ctx, acc) + suite.app.AccountKeeper.SetAccount(suite.ctx, acc) // require a valid Ethereum tx to pass to := ethcmn.BytesToAddress(addr2.Bytes()) amt := big.NewInt(32) gas := big.NewInt(20) - ethMsg := evmtypes.NewEthereumTxMsg(0, &to, amt, 22000, gas, []byte("test")) + ethMsg := evmtypes.NewMsgEthereumTx(0, &to, amt, 22000, gas, []byte("test")) - tx := newTestEthTx(input.ctx, ethMsg, priv1) - requireInvalidTx(t, input.anteHandler, input.ctx, tx, false) + tx := newTestEthTx(suite.ctx, ethMsg, priv1) + requireInvalidTx(suite.T(), suite.anteHandler, suite.ctx, tx, false) } -func TestEthInsufficientBalance(t *testing.T) { - input := newTestSetup() - input.ctx = input.ctx.WithBlockHeight(1) +func (suite *AnteTestSuite) TestEthInsufficientBalance() { + suite.ctx = suite.ctx.WithBlockHeight(1) addr1, priv1 := newTestAddrKey() addr2, _ := newTestAddrKey() - acc := input.accKeeper.NewAccountWithAddress(input.ctx, addr1) - input.accKeeper.SetAccount(input.ctx, acc) + acc := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, addr1) + suite.app.AccountKeeper.SetAccount(suite.ctx, acc) // require a valid Ethereum tx to pass to := ethcmn.BytesToAddress(addr2.Bytes()) amt := big.NewInt(32) gas := big.NewInt(20) - ethMsg := evmtypes.NewEthereumTxMsg(0, &to, amt, 22000, gas, []byte("test")) + ethMsg := evmtypes.NewMsgEthereumTx(0, &to, amt, 22000, gas, []byte("test")) - tx := newTestEthTx(input.ctx, ethMsg, priv1) - requireInvalidTx(t, input.anteHandler, input.ctx, tx, false) + tx := newTestEthTx(suite.ctx, ethMsg, priv1) + requireInvalidTx(suite.T(), suite.anteHandler, suite.ctx, tx, false) } -func TestEthInvalidIntrinsicGas(t *testing.T) { - input := newTestSetup() - input.ctx = input.ctx.WithBlockHeight(1) +func (suite *AnteTestSuite) TestEthInvalidIntrinsicGas() { + suite.ctx = suite.ctx.WithBlockHeight(1) addr1, priv1 := newTestAddrKey() addr2, _ := newTestAddrKey() - acc := input.accKeeper.NewAccountWithAddress(input.ctx, addr1) + acc := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, addr1) // nolint:errcheck acc.SetCoins(newTestCoins()) - input.accKeeper.SetAccount(input.ctx, acc) + suite.app.AccountKeeper.SetAccount(suite.ctx, acc) // require a valid Ethereum tx to pass to := ethcmn.BytesToAddress(addr2.Bytes()) amt := big.NewInt(32) gas := big.NewInt(20) gasLimit := uint64(1000) - ethMsg := evmtypes.NewEthereumTxMsg(0, &to, amt, gasLimit, gas, []byte("test")) + ethMsg := evmtypes.NewMsgEthereumTx(0, &to, amt, gasLimit, gas, []byte("test")) - tx := newTestEthTx(input.ctx, ethMsg, priv1) - requireInvalidTx(t, input.anteHandler, input.ctx, tx, false) + tx := newTestEthTx(suite.ctx, ethMsg, priv1) + requireInvalidTx(suite.T(), suite.anteHandler, suite.ctx, tx, false) } -func TestEthInvalidMempoolFees(t *testing.T) { - input := newTestSetup() - input.ctx = input.ctx.WithBlockHeight(1) - input.ctx = input.ctx.WithMinGasPrices(sdk.DecCoins{sdk.NewDecCoin(types.DenomDefault, sdk.NewInt(500000))}) +func (suite *AnteTestSuite) TestEthInvalidMempoolFees() { + // setup app with checkTx = true + suite.app = app.Setup(true) + suite.ctx = suite.app.BaseApp.NewContext(true, abci.Header{Height: 1, ChainID: "3", Time: time.Now().UTC()}) + suite.anteHandler = ante.NewAnteHandler(suite.app.AccountKeeper, suite.app.SupplyKeeper) + suite.ctx = suite.ctx.WithMinGasPrices(sdk.NewDecCoins(sdk.NewDecCoin(types.DenomDefault, sdk.NewInt(500000)))) addr1, priv1 := newTestAddrKey() addr2, _ := newTestAddrKey() - acc := input.accKeeper.NewAccountWithAddress(input.ctx, addr1) - // nolint:errcheck - acc.SetCoins(newTestCoins()) - input.accKeeper.SetAccount(input.ctx, acc) + acc := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, addr1) + + err := acc.SetCoins(newTestCoins()) + suite.Require().NoError(err) + suite.app.AccountKeeper.SetAccount(suite.ctx, acc) // require a valid Ethereum tx to pass to := ethcmn.BytesToAddress(addr2.Bytes()) amt := big.NewInt(32) gas := big.NewInt(20) - ethMsg := evmtypes.NewEthereumTxMsg(0, &to, amt, 22000, gas, []byte("test")) + ethMsg := evmtypes.NewMsgEthereumTx(0, &to, amt, 22000, gas, []byte("payload")) - tx := newTestEthTx(input.ctx, ethMsg, priv1) - requireInvalidTx(t, input.anteHandler, input.ctx, tx, false) + tx := newTestEthTx(suite.ctx, ethMsg, priv1) + requireInvalidTx(suite.T(), suite.anteHandler, suite.ctx, tx, false) } -func TestEthInvalidChainID(t *testing.T) { - input := newTestSetup() - input.ctx = input.ctx.WithBlockHeight(1) +func (suite *AnteTestSuite) TestEthInvalidChainID() { + suite.ctx = suite.ctx.WithBlockHeight(1) addr1, priv1 := newTestAddrKey() addr2, _ := newTestAddrKey() - acc := input.accKeeper.NewAccountWithAddress(input.ctx, addr1) + acc := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, addr1) // nolint:errcheck acc.SetCoins(newTestCoins()) - input.accKeeper.SetAccount(input.ctx, acc) + suite.app.AccountKeeper.SetAccount(suite.ctx, acc) // require a valid Ethereum tx to pass to := ethcmn.BytesToAddress(addr2.Bytes()) amt := big.NewInt(32) gas := big.NewInt(20) - ethMsg := evmtypes.NewEthereumTxMsg(0, &to, amt, 22000, gas, []byte("test")) + ethMsg := evmtypes.NewMsgEthereumTx(0, &to, amt, 22000, gas, []byte("test")) - tx := newTestEthTx(input.ctx, ethMsg, priv1) - ctx := input.ctx.WithChainID("bad-chain-id") - requireInvalidTx(t, input.anteHandler, ctx, tx, false) + tx := newTestEthTx(suite.ctx, ethMsg, priv1) + ctx := suite.ctx.WithChainID("bad-chain-id") + requireInvalidTx(suite.T(), suite.anteHandler, ctx, tx, false) } diff --git a/app/ante/utils_test.go b/app/ante/utils_test.go index eaaa07df8..c8dce2c7d 100644 --- a/app/ante/utils_test.go +++ b/app/ante/utils_test.go @@ -3,18 +3,16 @@ package ante_test import ( "fmt" "math/big" + "testing" "time" - "github.com/cosmos/cosmos-sdk/codec" - "github.com/cosmos/cosmos-sdk/store" + "github.com/stretchr/testify/suite" + sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/auth" - "github.com/cosmos/cosmos-sdk/x/auth/types" - "github.com/cosmos/cosmos-sdk/x/mock" - "github.com/cosmos/cosmos-sdk/x/params" "github.com/cosmos/ethermint/app" - . "github.com/cosmos/ethermint/app/ante" + ante "github.com/cosmos/ethermint/app/ante" "github.com/cosmos/ethermint/crypto" emint "github.com/cosmos/ethermint/types" evmtypes "github.com/cosmos/ethermint/x/evm/types" @@ -23,63 +21,28 @@ import ( abci "github.com/tendermint/tendermint/abci/types" tmcrypto "github.com/tendermint/tendermint/crypto" - "github.com/tendermint/tendermint/libs/log" - tmos "github.com/tendermint/tendermint/libs/os" - dbm "github.com/tendermint/tm-db" ) -type testSetup struct { - ctx sdk.Context - cdc *codec.Codec - accKeeper auth.AccountKeeper - supplyKeeper types.SupplyKeeper - anteHandler sdk.AnteHandler +type AnteTestSuite struct { + suite.Suite + + ctx sdk.Context + app *app.EthermintApp + anteHandler sdk.AnteHandler } -func newTestSetup() testSetup { - db := dbm.NewMemDB() - authCapKey := sdk.NewKVStoreKey("authCapKey") - keySupply := sdk.NewKVStoreKey("keySupply") - keyParams := sdk.NewKVStoreKey("params") - tkeyParams := sdk.NewTransientStoreKey("transient_params") - - ms := store.NewCommitMultiStore(db) - ms.MountStoreWithDB(authCapKey, sdk.StoreTypeIAVL, db) - ms.MountStoreWithDB(keySupply, sdk.StoreTypeIAVL, db) - ms.MountStoreWithDB(keyParams, sdk.StoreTypeIAVL, db) - ms.MountStoreWithDB(tkeyParams, sdk.StoreTypeIAVL, db) - - if err := ms.LoadLatestVersion(); err != nil { - tmos.Exit(err.Error()) - } +func (suite *AnteTestSuite) SetupTest() { + checkTx := false - cdc := app.MakeCodec() - cdc.RegisterConcrete(&sdk.TestMsg{}, "test/TestMsg", nil) - - // Set params keeper and subspaces - paramsKeeper := params.NewKeeper(cdc, keyParams, tkeyParams) - authSubspace := paramsKeeper.Subspace(auth.DefaultParamspace) - - ctx := sdk.NewContext( - ms, - abci.Header{ChainID: "3", Time: time.Now().UTC()}, - true, - log.NewNopLogger(), - ) - - // Add keepers - accKeeper := auth.NewAccountKeeper(cdc, authCapKey, authSubspace, auth.ProtoBaseAccount) - accKeeper.SetParams(ctx, types.DefaultParams()) - supplyKeeper := mock.NewDummySupplyKeeper(accKeeper) - anteHandler := NewAnteHandler(accKeeper, supplyKeeper) - - return testSetup{ - ctx: ctx, - cdc: cdc, - accKeeper: accKeeper, - supplyKeeper: supplyKeeper, - anteHandler: anteHandler, - } + suite.app = app.Setup(checkTx) + suite.app.Codec().RegisterConcrete(&sdk.TestMsg{}, "test/TestMsg", nil) + + suite.ctx = suite.app.BaseApp.NewContext(checkTx, abci.Header{Height: 1, ChainID: "3", Time: time.Now().UTC()}) + suite.anteHandler = ante.NewAnteHandler(suite.app.AccountKeeper, suite.app.SupplyKeeper) +} + +func TestAnteTestSuite(t *testing.T) { + suite.Run(t, new(AnteTestSuite)) } func newTestMsg(addrs ...sdk.AccAddress) *sdk.TestMsg { @@ -87,7 +50,7 @@ func newTestMsg(addrs ...sdk.AccAddress) *sdk.TestMsg { } func newTestCoins() sdk.Coins { - return sdk.Coins{sdk.NewInt64Coin(emint.DenomDefault, 500000000)} + return sdk.NewCoins(sdk.NewInt64Coin(emint.DenomDefault, 500000000)) } func newTestStdFee() auth.StdFee { @@ -125,7 +88,7 @@ func newTestSDKTx( return auth.NewStdTx(msgs, fee, sigs, "") } -func newTestEthTx(ctx sdk.Context, msg *evmtypes.EthereumTxMsg, priv tmcrypto.PrivKey) sdk.Tx { +func newTestEthTx(ctx sdk.Context, msg *evmtypes.MsgEthereumTx, priv tmcrypto.PrivKey) sdk.Tx { chainID, ok := new(big.Int).SetString(ctx.ChainID(), 10) if !ok { panic(fmt.Sprintf("invalid chainID: %s", ctx.ChainID())) diff --git a/app/ethermint.go b/app/ethermint.go index 27e9e2eba..377e30357 100644 --- a/app/ethermint.go +++ b/app/ethermint.go @@ -31,7 +31,7 @@ import ( "github.com/cosmos/ethermint/x/evm" abci "github.com/tendermint/tendermint/abci/types" - log "github.com/tendermint/tendermint/libs/log" + "github.com/tendermint/tendermint/libs/log" tmos "github.com/tendermint/tendermint/libs/os" dbm "github.com/tendermint/tm-db" ) @@ -366,6 +366,21 @@ func (app *EthermintApp) SimulationManager() *module.SimulationManager { return app.sm } +// GetKey returns the KVStoreKey for the provided store key. +// +// NOTE: This is solely to be used for testing purposes. +func (app *EthermintApp) GetKey(storeKey string) *sdk.KVStoreKey { + return app.keys[storeKey] +} + +// Codec returns Ethermint's codec. +// +// NOTE: This is solely to be used for testing purposes as it may be desirable +// for modules to register their own custom testing types. +func (app *EthermintApp) Codec() *codec.Codec { + return app.cdc +} + // GetMaccPerms returns a copy of the module account permissions func GetMaccPerms() map[string][]string { dupMaccPerms := make(map[string][]string) diff --git a/app/test_helpers.go b/app/test_helpers.go new file mode 100644 index 000000000..f414121b6 --- /dev/null +++ b/app/test_helpers.go @@ -0,0 +1,34 @@ +package app + +import ( + abci "github.com/tendermint/tendermint/abci/types" + "github.com/tendermint/tendermint/libs/log" + dbm "github.com/tendermint/tm-db" + + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/simapp" +) + +// Setup initializes a new EthermintApp. A Nop logger is set in EthermintApp. +func Setup(isCheckTx bool) *EthermintApp { + db := dbm.NewMemDB() + app := NewEthermintApp(log.NewNopLogger(), db, nil, true, 0) + if !isCheckTx { + // init chain must be called to stop deliverState from being nil + genesisState := simapp.NewDefaultGenesisState() + stateBytes, err := codec.MarshalJSONIndent(app.Codec(), genesisState) + if err != nil { + panic(err) + } + + // Initialize the chain + app.InitChain( + abci.RequestInitChain{ + Validators: []abci.ValidatorUpdate{}, + AppStateBytes: stateBytes, + }, + ) + } + + return app +} diff --git a/go.mod b/go.mod index 16c5a7297..21273df43 100644 --- a/go.mod +++ b/go.mod @@ -32,22 +32,17 @@ require ( github.com/rcrowley/go-metrics v0.0.0-20190706150252-9beb055b7962 // indirect github.com/rjeczalik/notify v0.9.2 // indirect github.com/spf13/afero v1.2.2 // indirect - github.com/spf13/cobra v0.0.5 + github.com/spf13/cobra v0.0.6 github.com/spf13/viper v1.6.2 github.com/status-im/keycard-go v0.0.0-20190424133014-d95853db0f48 // indirect github.com/steakknife/bloomfilter v0.0.0-20180922174646-6819c0d2a570 // indirect github.com/steakknife/hamming v0.0.0-20180906055917-c99c65617cd3 // indirect github.com/stretchr/testify v1.4.0 - github.com/tendermint/ed25519 v0.0.0-20171027050219-d8387025d2b9 // indirect github.com/tendermint/go-amino v0.15.1 - github.com/tendermint/go-crypto v0.9.0 // indirect github.com/tendermint/tendermint v0.33.0 github.com/tendermint/tm-db v0.4.0 - github.com/tendermint/tmlibs v0.9.0 // indirect github.com/tyler-smith/go-bip39 v1.0.0 // indirect github.com/wsddn/go-ecdh v0.0.0-20161211032359-48726bab9208 // indirect - github.com/zondax/ledger-go v0.11.0 // indirect - github.com/zondax/ledger-goclient v0.9.9 // indirect golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413 golang.org/x/net v0.0.0-20200226121028-0de0cce0169b // indirect golang.org/x/text v0.3.2 // indirect diff --git a/go.sum b/go.sum index 0b3b41b45..b409398d3 100644 --- a/go.sum +++ b/go.sum @@ -60,6 +60,7 @@ github.com/cosmos/ledger-cosmos-go v0.11.1/go.mod h1:J8//BsAGTo3OC/vDLjMRFLW6q0W github.com/cosmos/ledger-go v0.9.2 h1:Nnao/dLwaVTk1Q5U9THldpUMMXU94BOTWPddSmVB6pI= github.com/cosmos/ledger-go v0.9.2/go.mod h1:oZJ2hHAZROdlHiwTg4t7kP+GKIIkBT+o6c9QWFanOyI= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= +github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/danieljoos/wincred v1.0.2 h1:zf4bhty2iLuwgjgpraD2E9UbvO+fe54XXGJbOwe23fU= github.com/danieljoos/wincred v1.0.2/go.mod h1:SnuYRW9lp1oJrZX/dXJqr0cPK5gYXqx3EJbmjhLdK9U= github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -287,6 +288,8 @@ github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6So github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= +github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.2.0 h1:juTguoYk5qI21pwyTXY3B3Y5cOTH3ZUyZCg1v/mihuo= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= @@ -308,6 +311,8 @@ github.com/spf13/cobra v0.0.1 h1:zZh3X5aZbdnoj+4XkaBxKfhO4ot82icYdhhREIAXIj8= github.com/spf13/cobra v0.0.1/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.5 h1:f0B+LkLX6DtmRH1isoNA9VTtNUK9K8xYd28JNNfOv/s= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= +github.com/spf13/cobra v0.0.6 h1:breEStsVwemnKh2/s6gMvSdMEkwW0sK8vGStnlVBMCs= +github.com/spf13/cobra v0.0.6/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= @@ -318,6 +323,7 @@ github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.3.2 h1:VUFqw5KcqRf7i70GOzW7N+Q7+gxVBkSSqiXB12+JQ4M= github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= +github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= github.com/spf13/viper v1.6.1 h1:VPZzIkznI1YhVMRi6vNFLHSwhnhReBfgTxIPccpfdZk= github.com/spf13/viper v1.6.1/go.mod h1:t3iDnF5Jlj76alVNuyFBk5oUMCvsrkbvZK0WQdfDi5k= github.com/spf13/viper v1.6.2 h1:7aKfF+e8/k68gda3LOjo5RxiUqddoFxVq4BKBPrxk5E= @@ -348,22 +354,16 @@ github.com/tendermint/btcd v0.1.1 h1:0VcxPfflS2zZ3RiOAHkBiFUcPvbtRj5O7zHmcJWHV7s github.com/tendermint/btcd v0.1.1/go.mod h1:DC6/m53jtQzr/NFmMNEu0rxf18/ktVoVtMrnDD5pN+U= github.com/tendermint/crypto v0.0.0-20191022145703-50d29ede1e15 h1:hqAk8riJvK4RMWx1aInLzndwxKalgi5rTqgfXxOxbEI= github.com/tendermint/crypto v0.0.0-20191022145703-50d29ede1e15/go.mod h1:z4YtwM70uOnk8h0pjJYlj3zdYwi9l03By6iAIF5j/Pk= -github.com/tendermint/ed25519 v0.0.0-20171027050219-d8387025d2b9 h1:zccWau0P8FELSb4HTDJ88hRo+WVNMbIbg27rFqDrhCE= -github.com/tendermint/ed25519 v0.0.0-20171027050219-d8387025d2b9/go.mod h1:nt45hbhDkWVdMBkr2TOgOzCrpBccXdN09WOiOYTHVEk= github.com/tendermint/go-amino v0.14.1 h1:o2WudxNfdLNBwMyl2dqOJxiro5rfrEaU0Ugs6offJMk= github.com/tendermint/go-amino v0.14.1/go.mod h1:i/UKE5Uocn+argJJBb12qTZsCDBcAYMbR92AaJVmKso= github.com/tendermint/go-amino v0.15.1 h1:D2uk35eT4iTsvJd9jWIetzthE5C0/k2QmMFkCN+4JgQ= github.com/tendermint/go-amino v0.15.1/go.mod h1:TQU0M1i/ImAo+tYpZi73AU3V/dKeCoMC9Sphe2ZwGME= -github.com/tendermint/go-crypto v0.9.0 h1:knZL34Ccy6BDjsPXwBslVTtyUpvOVAGbZMHcQriXulM= -github.com/tendermint/go-crypto v0.9.0/go.mod h1:bL+jG0FvO892QRYHtA/lEIQSMMq7anlRPTGbsWzQntU= github.com/tendermint/iavl v0.13.0 h1:r2sINvNFlJsLlLhGoqlqPlREWYkuK26BvMfkBt+XQnA= github.com/tendermint/iavl v0.13.0/go.mod h1:7nSUPdrsHEZ2nNZa+9gaIrcJciWd1jCQZXtcyARU82k= github.com/tendermint/tendermint v0.33.0 h1:TW1g9sQs3YSqKM8o1+opL3/VmBy4Ke/VKV9MxYpqNbI= github.com/tendermint/tendermint v0.33.0/go.mod h1:s5UoymnPIY+GcA3mMte4P9gpMP8vS7UH7HBXikT1pHI= github.com/tendermint/tm-db v0.4.0 h1:iPbCcLbf4nwDFhS39Zo1lpdS1X/cT9CkTlUx17FHQgA= github.com/tendermint/tm-db v0.4.0/go.mod h1:+Cwhgowrf7NBGXmsqFMbwEtbo80XmyrlY5Jsk95JubQ= -github.com/tendermint/tmlibs v0.9.0 h1:3aU/D2v3aecqpODOuBXCfi950bHTefD5Pps5X3XuJDc= -github.com/tendermint/tmlibs v0.9.0/go.mod h1:4L0tAKpLTioy14VnmbXYTLIJN0pCMiehxDMdN6zZfM8= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tyler-smith/go-bip39 v1.0.0 h1:FOHg9gaQLeBBRbHE/QrTLfEiBHy5pQ/yXzf9JG5pYFM= github.com/tyler-smith/go-bip39 v1.0.0/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs= @@ -375,10 +375,6 @@ github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/zondax/hid v0.9.0 h1:eiT3P6vNxAEVxXMw66eZUAAnU2zD33JBkfG/EnfAKl8= github.com/zondax/hid v0.9.0/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWpEM= -github.com/zondax/ledger-go v0.11.0 h1:EEqUh6eaZucWAaGo87G7sJiqRNJpzBZr+I9PpGgjjPg= -github.com/zondax/ledger-go v0.11.0/go.mod h1:NI6JDs8VWwgh+9Bf1vPZMm9Xufp2Q7Iwm2IzxJWzmus= -github.com/zondax/ledger-goclient v0.9.9 h1:XBvqkjluVda8dTYwPh2DPnlSGVEeoH1a1OprEAn8C98= -github.com/zondax/ledger-goclient v0.9.9/go.mod h1:ILyu7qO5zsod0bzyxY9NCMlFTb8AXZzJAJf0T85b2jA= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.3 h1:MUGmc65QhB3pIlaQ5bB4LwqSj6GIonVJXpZiaKNyaKk= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= diff --git a/rpc/eth_api.go b/rpc/eth_api.go index a84afaaa9..1cfe0dd29 100644 --- a/rpc/eth_api.go +++ b/rpc/eth_api.go @@ -314,7 +314,7 @@ func (e *PublicEthAPI) SendTransaction(args params.SendTxArgs) (common.Hash, err // SendRawTransaction send a raw Ethereum transaction. func (e *PublicEthAPI) SendRawTransaction(data hexutil.Bytes) (common.Hash, error) { - tx := new(types.EthereumTxMsg) + tx := new(types.MsgEthereumTx) // RLP decode raw transaction bytes if err := rlp.DecodeBytes(data, tx); err != nil { @@ -439,7 +439,7 @@ func (e *PublicEthAPI) doCall( } // Create new call message - msg := types.NewEmintMsg(0, &toAddr, sdk.NewIntFromBigInt(value), gas, + msg := types.NewMsgEthermint(0, &toAddr, sdk.NewIntFromBigInt(value), gas, sdk.NewIntFromBigInt(gasPrice), data, sdk.AccAddress(addr.Bytes())) // Generate tx to be used to simulate (signature isn't needed) @@ -606,10 +606,10 @@ type Transaction struct { S *hexutil.Big `json:"s"` } -func bytesToEthTx(cliCtx context.CLIContext, bz []byte) (*types.EthereumTxMsg, error) { +func bytesToEthTx(cliCtx context.CLIContext, bz []byte) (*types.MsgEthereumTx, error) { var stdTx sdk.Tx err := cliCtx.Codec.UnmarshalBinaryLengthPrefixed(bz, &stdTx) - ethTx, ok := stdTx.(*types.EthereumTxMsg) + ethTx, ok := stdTx.(*types.MsgEthereumTx) if !ok || err != nil { return nil, fmt.Errorf("invalid transaction type, must be an amino encoded Ethereum transaction") } @@ -618,7 +618,7 @@ func bytesToEthTx(cliCtx context.CLIContext, bz []byte) (*types.EthereumTxMsg, e // newRPCTransaction returns a transaction that will serialize to the RPC // representation, with the given location metadata set (if available). -func newRPCTransaction(tx *types.EthereumTxMsg, blockHash common.Hash, blockNumber *uint64, index uint64) *Transaction { +func newRPCTransaction(tx *types.MsgEthereumTx, blockHash common.Hash, blockNumber *uint64, index uint64) *Transaction { // Verify signature and retrieve sender address from, _ := tx.VerifySig(tx.ChainID()) @@ -891,7 +891,7 @@ func (e *PublicEthAPI) getGasLimit() (int64, error) { } // generateFromArgs populates tx message with args (used in RPC API) -func (e *PublicEthAPI) generateFromArgs(args params.SendTxArgs) (msg *types.EthereumTxMsg, err error) { +func (e *PublicEthAPI) generateFromArgs(args params.SendTxArgs) (msg *types.MsgEthereumTx, err error) { var ( nonce uint64 gasLimit uint64 @@ -954,5 +954,5 @@ func (e *PublicEthAPI) generateFromArgs(args params.SendTxArgs) (msg *types.Ethe gasLimit = (uint64)(*args.Gas) } - return types.NewEthereumTxMsg(nonce, args.To, amount, gasLimit, gasPrice, input), nil + return types.NewMsgEthereumTx(nonce, args.To, amount, gasLimit, gasPrice, input), nil } diff --git a/types/codec.go b/types/codec.go index de1808434..85a92d8c7 100644 --- a/types/codec.go +++ b/types/codec.go @@ -12,7 +12,7 @@ func init() { const ( // Amino encoding name - EthermintAccountName = "emint/Account" + EthermintAccountName = "ethermint/Account" ) // RegisterCodec registers all the necessary types with amino for the given diff --git a/types/context.go b/types/context.go deleted file mode 100644 index f9943fe40..000000000 --- a/types/context.go +++ /dev/null @@ -1,8 +0,0 @@ -package types - -// AppContext provides the ability for the application to pass around and -// obtain immutable objects easily. More importantly, it allows for the -// utilization of the object-capability model in which components gain access -// to other components for which they truly need. -type AppContext struct { -} diff --git a/x/evm/abci.go b/x/evm/abci.go new file mode 100644 index 000000000..f058e0bb2 --- /dev/null +++ b/x/evm/abci.go @@ -0,0 +1,42 @@ +package evm + +import ( + "math/big" + + abci "github.com/tendermint/tendermint/abci/types" + + sdk "github.com/cosmos/cosmos-sdk/types" + + ethtypes "github.com/ethereum/go-ethereum/core/types" +) + +// 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) { + // Consider removing this when using evm as module without web3 API + bloom := ethtypes.BytesToBloom(k.Bloom.Bytes()) + 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 +} + +// EndBlock updates the accounts and commits states objects to the KV Store +func EndBlock(k Keeper, ctx sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate { + // Gas costs are handled within msg handler so costs should be ignored + ctx = ctx.WithBlockGasMeter(sdk.NewInfiniteGasMeter()) + + // Update account balances before committing other parts of state + k.CommitStateDB.UpdateAccounts() + + // Commit state objects to KV store + _, err := k.CommitStateDB.WithContext(ctx).Commit(true) + if err != nil { + panic(err) + } + + // Clear accounts cache after account data has been committed + k.CommitStateDB.ClearStateObjects() + + return []abci.ValidatorUpdate{} +} diff --git a/x/evm/client/cli/tx.go b/x/evm/client/cli/tx.go index 16584e7ff..e15f5f0ff 100644 --- a/x/evm/client/cli/tx.go +++ b/x/evm/client/cli/tx.go @@ -86,7 +86,7 @@ func GetCmdGenTx(cdc *codec.Codec) *cobra.Command { } // TODO: Potentially allow overriding of gas price and gas limit - msg := types.NewEmintMsg(seq, &toAddr, sdk.NewInt(amount), txBldr.Gas(), + msg := types.NewMsgEthermint(seq, &toAddr, sdk.NewInt(amount), txBldr.Gas(), sdk.NewInt(emint.DefaultGasPrice), data, from) err = msg.ValidateBasic() @@ -138,7 +138,7 @@ func GetCmdGenCreateTx(cdc *codec.Codec) *cobra.Command { } // TODO: Potentially allow overriding of gas price and gas limit - msg := types.NewEmintMsg(seq, nil, sdk.NewInt(amount), txBldr.Gas(), + msg := types.NewMsgEthermint(seq, nil, sdk.NewInt(amount), txBldr.Gas(), sdk.NewInt(emint.DefaultGasPrice), data, from) err = msg.ValidateBasic() diff --git a/x/evm/handler.go b/x/evm/handler.go index c83f1a2c9..40c2fd91f 100644 --- a/x/evm/handler.go +++ b/x/evm/handler.go @@ -18,10 +18,10 @@ import ( func NewHandler(k Keeper) sdk.Handler { return func(ctx sdk.Context, msg sdk.Msg) (*sdk.Result, error) { switch msg := msg.(type) { - case types.EthereumTxMsg: + case types.MsgEthereumTx: return handleEthTxMsg(ctx, k, msg) - case *types.EmintMsg: - return handleEmintMsg(ctx, k, *msg) + case *types.MsgEthermint: + return handleMsgEthermint(ctx, k, *msg) default: return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized ethermint message type: %T", msg) } @@ -29,12 +29,7 @@ func NewHandler(k Keeper) sdk.Handler { } // handleEthTxMsg handles an Ethereum specific tx -func handleEthTxMsg(ctx sdk.Context, k Keeper, msg types.EthereumTxMsg) (*sdk.Result, error) { - // TODO: move to client - if err := msg.ValidateBasic(); err != nil { - return nil, err - } - +func handleEthTxMsg(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 { @@ -70,8 +65,8 @@ func handleEthTxMsg(ctx sdk.Context, k Keeper, msg types.EthereumTxMsg) (*sdk.Re Simulate: ctx.IsCheckTx(), } // Prepare db for logs - k.CommitStateDB.Prepare(ethHash, common.Hash{}, k.TxCount.Get()) - k.TxCount.Increment() + k.CommitStateDB.Prepare(ethHash, common.Hash{}, k.TxCount) + k.TxCount++ // TODO: move to keeper bloom, res, err := st.TransitionCSDB(ctx) @@ -82,14 +77,33 @@ func handleEthTxMsg(ctx sdk.Context, k Keeper, msg types.EthereumTxMsg) (*sdk.Re // update block bloom filter k.Bloom.Or(k.Bloom, bloom) + ctx.EventManager().EmitEvents(sdk.Events{ + sdk.NewEvent( + types.EventTypeEthereumTx, + sdk.NewAttribute(sdk.AttributeKeyAmount, msg.Data.Amount.String()), + ), + sdk.NewEvent( + sdk.EventTypeMessage, + sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory), + sdk.NewAttribute(sdk.AttributeKeySender, msg.GetSigners()[0].String()), + ), + }) + + if msg.Data.Recipient != nil { + ctx.EventManager().EmitEvent( + sdk.NewEvent( + types.EventTypeEthereumTx, + sdk.NewAttribute(types.AttributeKeyRecipient, msg.Data.Recipient.String()), + ), + ) + } + + // set the events to the result + res.Events = ctx.EventManager().Events() return res, nil } -func handleEmintMsg(ctx sdk.Context, k Keeper, msg types.EmintMsg) (*sdk.Result, error) { - if err := msg.ValidateBasic(); err != nil { - return nil, err - } - +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 { @@ -114,13 +128,36 @@ func handleEmintMsg(ctx sdk.Context, k Keeper, msg types.EmintMsg) (*sdk.Result, } // Prepare db for logs - k.CommitStateDB.Prepare(common.Hash{}, common.Hash{}, k.TxCount.Get()) // Cannot provide tx hash - k.TxCount.Increment() + k.CommitStateDB.Prepare(common.Hash{}, common.Hash{}, k.TxCount) // Cannot provide tx hash + k.TxCount++ _, res, err := st.TransitionCSDB(ctx) if err != nil { return nil, err } + ctx.EventManager().EmitEvents(sdk.Events{ + sdk.NewEvent( + types.EventTypeEthermint, + sdk.NewAttribute(sdk.AttributeKeyAmount, msg.Amount.String()), + ), + sdk.NewEvent( + sdk.EventTypeMessage, + sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory), + sdk.NewAttribute(sdk.AttributeKeySender, msg.From.String()), + ), + }) + + if msg.Recipient != nil { + ctx.EventManager().EmitEvent( + sdk.NewEvent( + types.EventTypeEthermint, + sdk.NewAttribute(types.AttributeKeyRecipient, msg.Recipient.String()), + ), + ) + } + + // set the events to the result + res.Events = ctx.EventManager().Events() return res, nil } diff --git a/x/evm/keeper/keeper.go b/x/evm/keeper/keeper.go index 08dcd9f86..d82aa0522 100644 --- a/x/evm/keeper/keeper.go +++ b/x/evm/keeper/keeper.go @@ -9,7 +9,6 @@ import ( ethvm "github.com/ethereum/go-ethereum/core/vm" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/x/auth" "github.com/cosmos/ethermint/x/evm/types" ethstate "github.com/ethereum/go-ethereum/core/state" ethtypes "github.com/ethereum/go-ethereum/core/types" @@ -26,34 +25,19 @@ type Keeper struct { // Web3 API blockKey sdk.StoreKey CommitStateDB *types.CommitStateDB - TxCount *count + TxCount int Bloom *big.Int } -// TODO: move to types -type count int - -func (c *count) Get() int { - return (int)(*c) -} - -func (c *count) Increment() { - *c++ -} - -func (c *count) Reset() { - *c = 0 -} - // NewKeeper generates new evm module keeper func NewKeeper( - cdc *codec.Codec, blockKey, codeKey, storeKey sdk.StoreKey, ak auth.AccountKeeper, + cdc *codec.Codec, blockKey, codeKey, storeKey sdk.StoreKey, ak types.AccountKeeper, ) Keeper { return Keeper{ cdc: cdc, blockKey: blockKey, CommitStateDB: types.NewCommitStateDB(sdk.Context{}, codeKey, storeKey, ak), - TxCount: new(count), + TxCount: 0, Bloom: big.NewInt(0), } } diff --git a/x/evm/keeper/keeper_test.go b/x/evm/keeper/keeper_test.go index 763d3f8fd..7cec75cc7 100644 --- a/x/evm/keeper/keeper_test.go +++ b/x/evm/keeper/keeper_test.go @@ -1,110 +1,76 @@ -package keeper +package keeper_test import ( "math/big" "testing" - "github.com/cosmos/cosmos-sdk/codec" - "github.com/cosmos/cosmos-sdk/store" + "github.com/stretchr/testify/suite" + sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/x/auth" - "github.com/cosmos/cosmos-sdk/x/params" - "github.com/cosmos/ethermint/types" - evmtypes "github.com/cosmos/ethermint/x/evm/types" + "github.com/cosmos/ethermint/app" + "github.com/cosmos/ethermint/x/evm/keeper" ethcmn "github.com/ethereum/go-ethereum/common" ethtypes "github.com/ethereum/go-ethereum/core/types" - "github.com/stretchr/testify/require" abci "github.com/tendermint/tendermint/abci/types" - tmlog "github.com/tendermint/tendermint/libs/log" - dbm "github.com/tendermint/tm-db" ) -var ( - address = ethcmn.HexToAddress("0x756F45E3FA69347A9A973A725E3C98bC4db0b4c1") +var address = ethcmn.HexToAddress("0x756F45E3FA69347A9A973A725E3C98bC4db0b4c1") - accKey = sdk.NewKVStoreKey("acc") - storeKey = sdk.NewKVStoreKey(evmtypes.StoreKey) - codeKey = sdk.NewKVStoreKey(evmtypes.CodeKey) - blockKey = sdk.NewKVStoreKey(evmtypes.BlockKey) +type KeeperTestSuite struct { + suite.Suite - logger = tmlog.NewNopLogger() -) + ctx sdk.Context + querier sdk.Querier + app *app.EthermintApp +} -func newTestCodec() *codec.Codec { - cdc := codec.New() +func (suite *KeeperTestSuite) SetupTest() { + checkTx := false - evmtypes.RegisterCodec(cdc) - types.RegisterCodec(cdc) - auth.RegisterCodec(cdc) - sdk.RegisterCodec(cdc) - codec.RegisterCrypto(cdc) + suite.app = app.Setup(checkTx) + suite.ctx = suite.app.BaseApp.NewContext(checkTx, abci.Header{Height: 1}) + suite.querier = keeper.NewQuerier(suite.app.EvmKeeper) +} - return cdc +func TestKeeperTestSuite(t *testing.T) { + suite.Run(t, new(KeeperTestSuite)) } -func TestDBStorage(t *testing.T) { - // create logger, codec and root multi-store - cdc := newTestCodec() - - // The ParamsKeeper handles parameter storage for the application - keyParams := sdk.NewKVStoreKey(params.StoreKey) - tkeyParams := sdk.NewTransientStoreKey(params.TStoreKey) - paramsKeeper := params.NewKeeper(cdc, keyParams, tkeyParams) - // Set specific supspaces - authSubspace := paramsKeeper.Subspace(auth.DefaultParamspace) - ak := auth.NewAccountKeeper(cdc, accKey, authSubspace, types.ProtoBaseAccount) - ek := NewKeeper(cdc, blockKey, codeKey, storeKey, ak) - - db := dbm.NewMemDB() - cms := store.NewCommitMultiStore(db) - // mount stores - keys := []*sdk.KVStoreKey{accKey, storeKey, codeKey, blockKey} - for _, key := range keys { - cms.MountStoreWithDB(key, sdk.StoreTypeIAVL, nil) - } - - // load latest version (root) - err := cms.LoadLatestVersion() - require.NoError(t, err) - - // First execution - ms := cms.CacheMultiStore() - ctx := sdk.NewContext(ms, abci.Header{}, false, logger) - ctx = ctx.WithBlockHeight(1) +func (suite *KeeperTestSuite) TestDBStorage() { + suite.app.Commit() // Perform state transitions - ek.SetBalance(ctx, address, big.NewInt(5)) - ek.SetNonce(ctx, address, 4) - ek.SetState(ctx, address, ethcmn.HexToHash("0x2"), ethcmn.HexToHash("0x3")) - ek.SetCode(ctx, address, []byte{0x1}) + suite.app.EvmKeeper.SetBalance(suite.ctx, address, big.NewInt(5)) + suite.app.EvmKeeper.SetNonce(suite.ctx, address, 4) + suite.app.EvmKeeper.SetState(suite.ctx, address, ethcmn.HexToHash("0x2"), ethcmn.HexToHash("0x3")) + suite.app.EvmKeeper.SetCode(suite.ctx, address, []byte{0x1}) // Test block hash mapping functionality - ek.SetBlockHashMapping(ctx, ethcmn.FromHex("0x0d87a3a5f73140f46aac1bf419263e4e94e87c292f25007700ab7f2060e2af68"), 7) - ek.SetBlockHashMapping(ctx, []byte{0x43, 0x32}, 8) + suite.app.EvmKeeper.SetBlockHashMapping(suite.ctx, ethcmn.FromHex("0x0d87a3a5f73140f46aac1bf419263e4e94e87c292f25007700ab7f2060e2af68"), 7) + suite.app.EvmKeeper.SetBlockHashMapping(suite.ctx, []byte{0x43, 0x32}, 8) // Test block height mapping functionality testBloom := ethtypes.BytesToBloom([]byte{0x1, 0x3}) - ek.SetBlockBloomMapping(ctx, testBloom, 4) + suite.app.EvmKeeper.SetBlockBloomMapping(suite.ctx, testBloom, 4) // Get those state transitions - require.Equal(t, ek.GetBalance(ctx, address).Cmp(big.NewInt(5)), 0) - require.Equal(t, ek.GetNonce(ctx, address), uint64(4)) - require.Equal(t, ek.GetState(ctx, address, ethcmn.HexToHash("0x2")), ethcmn.HexToHash("0x3")) - require.Equal(t, ek.GetCode(ctx, address), []byte{0x1}) + suite.Require().Equal(suite.app.EvmKeeper.GetBalance(suite.ctx, address).Cmp(big.NewInt(5)), 0) + suite.Require().Equal(suite.app.EvmKeeper.GetNonce(suite.ctx, address), uint64(4)) + suite.Require().Equal(suite.app.EvmKeeper.GetState(suite.ctx, address, ethcmn.HexToHash("0x2")), ethcmn.HexToHash("0x3")) + suite.Require().Equal(suite.app.EvmKeeper.GetCode(suite.ctx, address), []byte{0x1}) - require.Equal(t, ek.GetBlockHashMapping(ctx, ethcmn.FromHex("0x0d87a3a5f73140f46aac1bf419263e4e94e87c292f25007700ab7f2060e2af68")), int64(7)) - require.Equal(t, ek.GetBlockHashMapping(ctx, []byte{0x43, 0x32}), int64(8)) + suite.Require().Equal(suite.app.EvmKeeper.GetBlockHashMapping(suite.ctx, ethcmn.FromHex("0x0d87a3a5f73140f46aac1bf419263e4e94e87c292f25007700ab7f2060e2af68")), int64(7)) + suite.Require().Equal(suite.app.EvmKeeper.GetBlockHashMapping(suite.ctx, []byte{0x43, 0x32}), int64(8)) - require.Equal(t, ek.GetBlockBloomMapping(ctx, 4), testBloom) + suite.Require().Equal(suite.app.EvmKeeper.GetBlockBloomMapping(suite.ctx, 4), testBloom) // commit stateDB - _, err = ek.Commit(ctx, false) - require.NoError(t, err, "failed to commit StateDB") + _, err := suite.app.EvmKeeper.Commit(suite.ctx, false) + suite.Require().NoError(err, "failed to commit StateDB") // simulate BaseApp EndBlocker commitment - ms.Write() - cms.Commit() + suite.app.Commit() } diff --git a/x/evm/module.go b/x/evm/module.go index b8ef1b1b5..7b24e01b3 100644 --- a/x/evm/module.go +++ b/x/evm/module.go @@ -2,19 +2,20 @@ package evm import ( "encoding/json" - "math/big" + + "github.com/gorilla/mux" + "github.com/spf13/cobra" + + abci "github.com/tendermint/tendermint/abci/types" "github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/module" + "github.com/cosmos/ethermint/x/evm/client/cli" "github.com/cosmos/ethermint/x/evm/keeper" "github.com/cosmos/ethermint/x/evm/types" - ethtypes "github.com/ethereum/go-ethereum/core/types" - "github.com/gorilla/mux" - "github.com/spf13/cobra" - abci "github.com/tendermint/tendermint/abci/types" ) var _ module.AppModuleBasic = AppModuleBasic{} @@ -107,33 +108,13 @@ func (am AppModule) NewQuerierHandler() sdk.Querier { } // BeginBlock function for module at start of each block -func (am AppModule) BeginBlock(ctx sdk.Context, bl abci.RequestBeginBlock) { - // Consider removing this when using evm as module without web3 API - bloom := ethtypes.BytesToBloom(am.keeper.Bloom.Bytes()) - am.keeper.SetBlockBloomMapping(ctx, bloom, bl.Header.GetHeight()-1) - am.keeper.SetBlockHashMapping(ctx, bl.Header.LastBlockId.GetHash(), bl.Header.GetHeight()-1) - am.keeper.Bloom = big.NewInt(0) - am.keeper.TxCount.Reset() +func (am AppModule) BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock) { + BeginBlock(am.keeper, ctx, req) } // EndBlock function for module at end of block -func (am AppModule) EndBlock(ctx sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate { - // Gas costs are handled within msg handler so costs should be ignored - ebCtx := ctx.WithBlockGasMeter(sdk.NewInfiniteGasMeter()) - - // Update account balances before committing other parts of state - am.keeper.CommitStateDB.UpdateAccounts() - - // Commit state objects to KV store - _, err := am.keeper.CommitStateDB.WithContext(ebCtx).Commit(true) - if err != nil { - panic(err) - } - - // Clear accounts cache after account data has been committed - am.keeper.CommitStateDB.ClearStateObjects() - - return []abci.ValidatorUpdate{} +func (am AppModule) EndBlock(ctx sdk.Context, req abci.RequestEndBlock) []abci.ValidatorUpdate { + return EndBlock(am.keeper, ctx, req) } // InitGenesis instantiates the genesis state diff --git a/x/evm/types/codec.go b/x/evm/types/codec.go index a657b8454..e2200740b 100644 --- a/x/evm/types/codec.go +++ b/x/evm/types/codec.go @@ -9,14 +9,13 @@ var ModuleCdc = codec.New() func init() { cdc := codec.New() - codec.RegisterCrypto(cdc) - ModuleCdc = cdc.Seal() } // RegisterCodec registers concrete types and interfaces on the given codec. func RegisterCodec(cdc *codec.Codec) { - cdc.RegisterConcrete(&EthereumTxMsg{}, "ethermint/MsgEthereumTx", nil) - cdc.RegisterConcrete(&EmintMsg{}, "ethermint/MsgEmint", nil) + cdc.RegisterConcrete(&MsgEthereumTx{}, "ethermint/MsgEthereumTx", nil) + cdc.RegisterConcrete(&MsgEthermint{}, "ethermint/MsgEmint", nil) + cdc.RegisterConcrete(EncodableTxData{}, "ethermint/EncodedMessage", nil) } diff --git a/x/evm/types/dump.go b/x/evm/types/dump.go deleted file mode 100644 index ed9fd66b3..000000000 --- a/x/evm/types/dump.go +++ /dev/null @@ -1,12 +0,0 @@ -package types - -import ( - ethstate "github.com/ethereum/go-ethereum/core/state" -) - -// RawDump returns a raw state dump. -// -// TODO: Implement if we need it, especially for the RPC API. -func (csdb *CommitStateDB) RawDump() ethstate.Dump { - return ethstate.Dump{} -} diff --git a/x/evm/types/emint_msg.go b/x/evm/types/emint_msg.go index 343dc5d8e..3b3e76001 100644 --- a/x/evm/types/emint_msg.go +++ b/x/evm/types/emint_msg.go @@ -9,16 +9,16 @@ import ( ) var ( - _ sdk.Msg = EmintMsg{} + _ sdk.Msg = MsgEthermint{} ) const ( - // TypeEmintMsg defines the type string of Emint message - TypeEmintMsg = "emint_tx" + // TypeMsgEthermint defines the type string of Ethermint message + TypeMsgEthermint = "ethermint" ) -// EmintMsg implements a cosmos equivalent structure for Ethereum transactions -type EmintMsg struct { +// MsgEthermint implements a cosmos equivalent structure for Ethereum transactions +type MsgEthermint struct { AccountNonce uint64 `json:"nonce"` Price sdk.Int `json:"gasPrice"` GasLimit uint64 `json:"gas"` @@ -30,12 +30,12 @@ type EmintMsg struct { From sdk.AccAddress `json:"from"` } -// NewEmintMsg returns a reference to a new Ethermint transaction -func NewEmintMsg( +// NewMsgEthermint returns a reference to a new Ethermint transaction +func NewMsgEthermint( nonce uint64, to *sdk.AccAddress, amount sdk.Int, gasLimit uint64, gasPrice sdk.Int, payload []byte, from sdk.AccAddress, -) EmintMsg { - return EmintMsg{ +) MsgEthermint { + return MsgEthermint{ AccountNonce: nonce, Price: gasPrice, GasLimit: gasLimit, @@ -47,18 +47,18 @@ func NewEmintMsg( } // Route should return the name of the module -func (msg EmintMsg) Route() string { return RouterKey } +func (msg MsgEthermint) Route() string { return RouterKey } // Type returns the action of the message -func (msg EmintMsg) Type() string { return TypeEmintMsg } +func (msg MsgEthermint) Type() string { return TypeMsgEthermint } // GetSignBytes encodes the message for signing -func (msg EmintMsg) GetSignBytes() []byte { +func (msg MsgEthermint) GetSignBytes() []byte { return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(msg)) } // ValidateBasic runs stateless checks on the message -func (msg EmintMsg) ValidateBasic() error { +func (msg MsgEthermint) ValidateBasic() error { if msg.Price.Sign() != 1 { return sdkerrors.Wrap(types.ErrInvalidValue, "price must be positive") } @@ -72,13 +72,13 @@ func (msg EmintMsg) ValidateBasic() error { } // GetSigners defines whose signature is required -func (msg EmintMsg) GetSigners() []sdk.AccAddress { +func (msg MsgEthermint) GetSigners() []sdk.AccAddress { return []sdk.AccAddress{msg.From} } // To returns the recipient address of the transaction. It returns nil if the // transaction is a contract creation. -func (msg EmintMsg) To() *ethcmn.Address { +func (msg MsgEthermint) To() *ethcmn.Address { if msg.Recipient == nil { return nil } diff --git a/x/evm/types/emint_msg_test.go b/x/evm/types/emint_msg_test.go index f28f19474..d1886cea1 100644 --- a/x/evm/types/emint_msg_test.go +++ b/x/evm/types/emint_msg_test.go @@ -8,19 +8,19 @@ import ( "github.com/tendermint/tendermint/crypto/secp256k1" ) -func TestEmintMsg(t *testing.T) { +func TestMsgEthermint(t *testing.T) { addr := newSdkAddress() fromAddr := newSdkAddress() - msg := NewEmintMsg(0, &addr, sdk.NewInt(1), 100000, sdk.NewInt(2), []byte("test"), fromAddr) + msg := NewMsgEthermint(0, &addr, sdk.NewInt(1), 100000, sdk.NewInt(2), []byte("test"), fromAddr) require.NotNil(t, msg) require.Equal(t, msg.Recipient, &addr) require.Equal(t, msg.Route(), RouterKey) - require.Equal(t, msg.Type(), TypeEmintMsg) + require.Equal(t, msg.Type(), TypeMsgEthermint) } -func TestEmintMsgValidation(t *testing.T) { +func TestMsgEthermintValidation(t *testing.T) { testCases := []struct { nonce uint64 to *sdk.AccAddress @@ -38,7 +38,7 @@ func TestEmintMsgValidation(t *testing.T) { } for i, tc := range testCases { - msg := NewEmintMsg(tc.nonce, tc.to, tc.amount, tc.gasLimit, tc.gasPrice, tc.payload, tc.from) + msg := NewMsgEthermint(tc.nonce, tc.to, tc.amount, tc.gasLimit, tc.gasPrice, tc.payload, tc.from) if tc.expectPass { require.Nil(t, msg.ValidateBasic(), "test: %v", i) @@ -52,13 +52,13 @@ func TestEmintEncodingAndDecoding(t *testing.T) { addr := newSdkAddress() fromAddr := newSdkAddress() - msg := NewEmintMsg(0, &addr, sdk.NewInt(1), 100000, sdk.NewInt(2), []byte("test"), fromAddr) + msg := NewMsgEthermint(0, &addr, sdk.NewInt(1), 100000, sdk.NewInt(2), []byte("test"), fromAddr) - raw, err := cdc.MarshalBinaryBare(msg) + raw, err := ModuleCdc.MarshalBinaryBare(msg) require.NoError(t, err) - var msg2 EmintMsg - err = cdc.UnmarshalBinaryBare(raw, &msg2) + var msg2 MsgEthermint + err = ModuleCdc.UnmarshalBinaryBare(raw, &msg2) require.NoError(t, err) require.Equal(t, msg.AccountNonce, msg2.AccountNonce) diff --git a/x/evm/types/events.go b/x/evm/types/events.go new file mode 100644 index 000000000..e5dca425a --- /dev/null +++ b/x/evm/types/events.go @@ -0,0 +1,11 @@ +package types + +// Evm module events +const ( + EventTypeEthermint = TypeMsgEthermint + EventTypeEthereumTx = TypeMsgEthereumTx + + AttributeKeyContractAddress = "contract" + AttributeKeyRecipient = "recipient" + AttributeValueCategory = ModuleName +) diff --git a/x/evm/types/expected_keepers.go b/x/evm/types/expected_keepers.go new file mode 100644 index 000000000..5bcf05eed --- /dev/null +++ b/x/evm/types/expected_keepers.go @@ -0,0 +1,14 @@ +package types + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + authexported "github.com/cosmos/cosmos-sdk/x/auth/exported" +) + +// AccountKeeper defines the expected account keeper interface +type AccountKeeper interface { + NewAccountWithAddress(ctx sdk.Context, addr sdk.AccAddress) authexported.Account + GetAccount(ctx sdk.Context, addr sdk.AccAddress) authexported.Account + SetAccount(ctx sdk.Context, account authexported.Account) + RemoveAccount(ctx sdk.Context, account authexported.Account) +} diff --git a/x/evm/types/msg.go b/x/evm/types/msg.go index 78e4b8fd9..95ef52e99 100644 --- a/x/evm/types/msg.go +++ b/x/evm/types/msg.go @@ -20,20 +20,20 @@ import ( ) var ( - _ sdk.Msg = EthereumTxMsg{} - _ sdk.Tx = EthereumTxMsg{} + _ sdk.Msg = MsgEthereumTx{} + _ sdk.Tx = MsgEthereumTx{} ) var big8 = big.NewInt(8) // message type and route constants const ( - TypeEthereumTxMsg = "ethereum_tx" + TypeMsgEthereumTx = "ethereum_tx" ) -// EthereumTxMsg encapsulates an Ethereum transaction as an SDK message. +// MsgEthereumTx encapsulates an Ethereum transaction as an SDK message. type ( - EthereumTxMsg struct { + MsgEthereumTx struct { Data TxData // caches @@ -69,28 +69,28 @@ type ( } ) -// NewEthereumTxMsg returns a reference to a new Ethereum transaction message. -func NewEthereumTxMsg( +// NewMsgEthereumTx returns a reference to a new Ethereum transaction message. +func NewMsgEthereumTx( nonce uint64, to *ethcmn.Address, amount *big.Int, gasLimit uint64, gasPrice *big.Int, payload []byte, -) *EthereumTxMsg { +) *MsgEthereumTx { - return newEthereumTxMsg(nonce, to, amount, gasLimit, gasPrice, payload) + return newMsgEthereumTx(nonce, to, amount, gasLimit, gasPrice, payload) } -// NewEthereumTxMsgContract returns a reference to a new Ethereum transaction +// NewMsgEthereumTxContract returns a reference to a new Ethereum transaction // message designated for contract creation. -func NewEthereumTxMsgContract( +func NewMsgEthereumTxContract( nonce uint64, amount *big.Int, gasLimit uint64, gasPrice *big.Int, payload []byte, -) *EthereumTxMsg { +) *MsgEthereumTx { - return newEthereumTxMsg(nonce, nil, amount, gasLimit, gasPrice, payload) + return newMsgEthereumTx(nonce, nil, amount, gasLimit, gasPrice, payload) } -func newEthereumTxMsg( +func newMsgEthereumTx( nonce uint64, to *ethcmn.Address, amount *big.Int, gasLimit uint64, gasPrice *big.Int, payload []byte, -) *EthereumTxMsg { +) *MsgEthereumTx { if len(payload) > 0 { payload = ethcmn.CopyBytes(payload) @@ -115,18 +115,18 @@ func newEthereumTxMsg( txData.Price.Set(gasPrice) } - return &EthereumTxMsg{Data: txData} + return &MsgEthereumTx{Data: txData} } -// Route returns the route value of an EthereumTxMsg. -func (msg EthereumTxMsg) Route() string { return RouterKey } +// Route returns the route value of an MsgEthereumTx. +func (msg MsgEthereumTx) Route() string { return RouterKey } -// Type returns the type value of an EthereumTxMsg. -func (msg EthereumTxMsg) Type() string { return TypeEthereumTxMsg } +// Type returns the type value of an MsgEthereumTx. +func (msg MsgEthereumTx) Type() string { return TypeMsgEthereumTx } // ValidateBasic implements the sdk.Msg interface. It performs basic validation // checks of a Transaction. If returns an error if validation fails. -func (msg EthereumTxMsg) ValidateBasic() error { +func (msg MsgEthereumTx) ValidateBasic() error { if msg.Data.Price.Sign() != 1 { return sdkerrors.Wrap(types.ErrInvalidValue, "price must be positive") } @@ -141,12 +141,12 @@ func (msg EthereumTxMsg) ValidateBasic() error { // To returns the recipient address of the transaction. It returns nil if the // transaction is a contract creation. -func (msg EthereumTxMsg) To() *ethcmn.Address { +func (msg MsgEthereumTx) To() *ethcmn.Address { return msg.Data.Recipient } -// GetMsgs returns a single EthereumTxMsg as an sdk.Msg. -func (msg EthereumTxMsg) GetMsgs() []sdk.Msg { +// GetMsgs returns a single MsgEthereumTx as an sdk.Msg. +func (msg MsgEthereumTx) GetMsgs() []sdk.Msg { return []sdk.Msg{msg} } @@ -155,7 +155,7 @@ func (msg EthereumTxMsg) GetMsgs() []sdk.Msg { // // NOTE: This method cannot be used as a chain ID is needed to recover the signer // from the signature. Use 'VerifySig' instead. -func (msg EthereumTxMsg) GetSigners() []sdk.AccAddress { +func (msg MsgEthereumTx) GetSigners() []sdk.AccAddress { panic("must use 'VerifySig' with a chain ID to get the signer") } @@ -164,13 +164,13 @@ func (msg EthereumTxMsg) GetSigners() []sdk.AccAddress { // // NOTE: This method cannot be used as a chain ID is needed to create valid bytes // to sign over. Use 'RLPSignBytes' instead. -func (msg EthereumTxMsg) GetSignBytes() []byte { +func (msg MsgEthereumTx) GetSignBytes() []byte { panic("must use 'RLPSignBytes' with a chain ID to get the valid bytes to sign") } // RLPSignBytes returns the RLP hash of an Ethereum transaction message with a // given chainID used for signing. -func (msg EthereumTxMsg) RLPSignBytes(chainID *big.Int) ethcmn.Hash { +func (msg MsgEthereumTx) RLPSignBytes(chainID *big.Int) ethcmn.Hash { return rlpHash([]interface{}{ msg.Data.AccountNonce, msg.Data.Price, @@ -183,12 +183,12 @@ func (msg EthereumTxMsg) RLPSignBytes(chainID *big.Int) ethcmn.Hash { } // EncodeRLP implements the rlp.Encoder interface. -func (msg *EthereumTxMsg) EncodeRLP(w io.Writer) error { +func (msg *MsgEthereumTx) EncodeRLP(w io.Writer) error { return rlp.Encode(w, &msg.Data) } // DecodeRLP implements the rlp.Decoder interface. -func (msg *EthereumTxMsg) DecodeRLP(s *rlp.Stream) error { +func (msg *MsgEthereumTx) DecodeRLP(s *rlp.Stream) error { _, size, _ := s.Kind() err := s.Decode(&msg.Data) @@ -200,7 +200,7 @@ func (msg *EthereumTxMsg) DecodeRLP(s *rlp.Stream) error { } // Hash hashes the RLP encoding of a transaction. -func (msg *EthereumTxMsg) Hash() ethcmn.Hash { +func (msg *MsgEthereumTx) Hash() ethcmn.Hash { if hash := msg.hash.Load(); hash != nil { return hash.(ethcmn.Hash) } @@ -215,7 +215,7 @@ func (msg *EthereumTxMsg) Hash() ethcmn.Hash { // takes a private key and chainID to sign an Ethereum transaction according to // EIP155 standard. It mutates the transaction as it populates the V, R, S // fields of the Transaction's Signature. -func (msg *EthereumTxMsg) Sign(chainID *big.Int, priv *ecdsa.PrivateKey) { +func (msg *MsgEthereumTx) Sign(chainID *big.Int, priv *ecdsa.PrivateKey) { txHash := msg.RLPSignBytes(chainID) sig, err := ethcrypto.Sign(txHash[:], priv) @@ -248,7 +248,7 @@ func (msg *EthereumTxMsg) Sign(chainID *big.Int, priv *ecdsa.PrivateKey) { // VerifySig attempts to verify a Transaction's signature for a given chainID. // A derived address is returned upon success or an error if recovery fails. -func (msg *EthereumTxMsg) VerifySig(chainID *big.Int) (ethcmn.Address, error) { +func (msg *MsgEthereumTx) VerifySig(chainID *big.Int) (ethcmn.Address, error) { signer := ethtypes.NewEIP155Signer(chainID) if sc := msg.from.Load(); sc != nil { @@ -280,19 +280,19 @@ func (msg *EthereumTxMsg) VerifySig(chainID *big.Int) (ethcmn.Address, error) { } // Cost returns amount + gasprice * gaslimit. -func (msg EthereumTxMsg) Cost() *big.Int { +func (msg MsgEthereumTx) Cost() *big.Int { total := msg.Fee() total.Add(total, msg.Data.Amount) return total } // Fee returns gasprice * gaslimit. -func (msg EthereumTxMsg) Fee() *big.Int { +func (msg MsgEthereumTx) Fee() *big.Int { return new(big.Int).Mul(msg.Data.Price, new(big.Int).SetUint64(msg.Data.GasLimit)) } // ChainID returns which chain id this transaction was signed for (if at all) -func (msg *EthereumTxMsg) ChainID() *big.Int { +func (msg *MsgEthereumTx) ChainID() *big.Int { return deriveChainID(msg.Data.V) } @@ -313,7 +313,7 @@ func deriveChainID(v *big.Int) *big.Int { // Auxiliary // TxDecoder returns an sdk.TxDecoder that can decode both auth.StdTx and -// EthereumTxMsg transactions. +// MsgEthereumTx transactions. func TxDecoder(cdc *codec.Codec) sdk.TxDecoder { return func(txBytes []byte) (sdk.Tx, error) { var tx sdk.Tx diff --git a/x/evm/types/msg_encoding.go b/x/evm/types/msg_encoding.go index 5e62e4344..0a99a5393 100644 --- a/x/evm/types/msg_encoding.go +++ b/x/evm/types/msg_encoding.go @@ -1,23 +1,11 @@ package types import ( - "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/ethermint/utils" ethcmn "github.com/ethereum/go-ethereum/common" ) -var cdc = codec.New() - -func init() { - RegisterAmino(cdc) -} - -// RegisterAmino registers all crypto related types in the given (amino) codec. -func RegisterAmino(cdc *codec.Codec) { - cdc.RegisterConcrete(EncodableTxData{}, "ethermint/EncodedMessage", nil) -} - // EncodableTxData implements the Ethereum transaction data structure. It is used // solely as intended in Ethereum abiding by the protocol. type EncodableTxData struct { @@ -38,12 +26,12 @@ type EncodableTxData struct { } func marshalAmino(td EncodableTxData) (string, error) { - bz, err := cdc.MarshalBinaryBare(td) + bz, err := ModuleCdc.MarshalBinaryBare(td) return string(bz), err } func unmarshalAmino(td *EncodableTxData, text string) (err error) { - return cdc.UnmarshalBinaryBare([]byte(text), td) + return ModuleCdc.UnmarshalBinaryBare([]byte(text), td) } // MarshalAmino defines custom encoding scheme for TxData diff --git a/x/evm/types/msg_test.go b/x/evm/types/msg_test.go index 763dff152..87e06998c 100644 --- a/x/evm/types/msg_test.go +++ b/x/evm/types/msg_test.go @@ -19,17 +19,17 @@ import ( func TestMsgEthereumTx(t *testing.T) { addr := GenerateEthAddress() - msg1 := NewEthereumTxMsg(0, &addr, nil, 100000, nil, []byte("test")) + msg1 := NewMsgEthereumTx(0, &addr, nil, 100000, nil, []byte("test")) require.NotNil(t, msg1) require.Equal(t, *msg1.Data.Recipient, addr) - msg2 := NewEthereumTxMsgContract(0, nil, 100000, nil, []byte("test")) + msg2 := NewMsgEthereumTxContract(0, nil, 100000, nil, []byte("test")) require.NotNil(t, msg2) require.Nil(t, msg2.Data.Recipient) - msg3 := NewEthereumTxMsg(0, &addr, nil, 100000, nil, []byte("test")) + msg3 := NewMsgEthereumTx(0, &addr, nil, 100000, nil, []byte("test")) require.Equal(t, msg3.Route(), RouterKey) - require.Equal(t, msg3.Type(), TypeEthereumTxMsg) + require.Equal(t, msg3.Type(), TypeMsgEthereumTx) require.Panics(t, func() { msg3.GetSigners() }) require.Panics(t, func() { msg3.GetSignBytes() }) } @@ -50,7 +50,7 @@ func TestMsgEthereumTxValidation(t *testing.T) { } for i, tc := range testCases { - msg := NewEthereumTxMsg(tc.nonce, &tc.to, tc.amount, tc.gasLimit, tc.gasPrice, tc.payload) + msg := NewMsgEthereumTx(tc.nonce, &tc.to, tc.amount, tc.gasLimit, tc.gasPrice, tc.payload) if tc.expectPass { require.Nil(t, msg.ValidateBasic(), "test: %v", i) @@ -64,14 +64,14 @@ func TestMsgEthereumTxRLPSignBytes(t *testing.T) { addr := ethcmn.BytesToAddress([]byte("test_address")) chainID := big.NewInt(3) - msg := NewEthereumTxMsg(0, &addr, nil, 100000, nil, []byte("test")) + msg := NewMsgEthereumTx(0, &addr, nil, 100000, nil, []byte("test")) hash := msg.RLPSignBytes(chainID) require.Equal(t, "5BD30E35AD27449390B14C91E6BCFDCAADF8FE44EF33680E3BC200FC0DC083C7", fmt.Sprintf("%X", hash)) } func TestMsgEthereumTxRLPEncode(t *testing.T) { addr := ethcmn.BytesToAddress([]byte("test_address")) - msg := NewEthereumTxMsg(0, &addr, nil, 100000, nil, []byte("test")) + msg := NewMsgEthereumTx(0, &addr, nil, 100000, nil, []byte("test")) raw, err := rlp.EncodeToBytes(msg) require.NoError(t, err) @@ -79,11 +79,11 @@ func TestMsgEthereumTxRLPEncode(t *testing.T) { } func TestMsgEthereumTxRLPDecode(t *testing.T) { - var msg EthereumTxMsg + var msg MsgEthereumTx raw := ethcmn.FromHex("E48080830186A0940000000000000000746573745F61646472657373808474657374808080") addr := ethcmn.BytesToAddress([]byte("test_address")) - expectedMsg := NewEthereumTxMsg(0, &addr, nil, 100000, nil, []byte("test")) + expectedMsg := NewMsgEthereumTx(0, &addr, nil, 100000, nil, []byte("test")) err := rlp.Decode(bytes.NewReader(raw), &msg) require.NoError(t, err) @@ -92,7 +92,7 @@ func TestMsgEthereumTxRLPDecode(t *testing.T) { func TestMsgEthereumTxHash(t *testing.T) { addr := ethcmn.BytesToAddress([]byte("test_address")) - msg := NewEthereumTxMsg(0, &addr, nil, 100000, nil, []byte("test")) + msg := NewMsgEthereumTx(0, &addr, nil, 100000, nil, []byte("test")) hash := msg.Hash() require.Equal(t, "E2AA2E68E7586AE9700F1D3D643330866B6AC2B6CA4C804F7C85ECB11D0B0B29", fmt.Sprintf("%X", hash)) @@ -107,7 +107,7 @@ func TestMsgEthereumTxSig(t *testing.T) { addr2 := ethcmn.BytesToAddress(priv2.PubKey().Address().Bytes()) // require valid signature passes validation - msg := NewEthereumTxMsg(0, &addr1, nil, 100000, nil, []byte("test")) + msg := NewMsgEthereumTx(0, &addr1, nil, 100000, nil, []byte("test")) msg.Sign(chainID, priv1.ToECDSA()) signer, err := msg.VerifySig(chainID) @@ -116,7 +116,7 @@ func TestMsgEthereumTxSig(t *testing.T) { require.NotEqual(t, addr2, signer) // require invalid chain ID fail validation - msg = NewEthereumTxMsg(0, &addr1, nil, 100000, nil, []byte("test")) + msg = NewMsgEthereumTx(0, &addr1, nil, 100000, nil, []byte("test")) msg.Sign(chainID, priv1.ToECDSA()) signer, err = msg.VerifySig(big.NewInt(4)) @@ -126,7 +126,7 @@ func TestMsgEthereumTxSig(t *testing.T) { func TestMsgEthereumTxAmino(t *testing.T) { addr := GenerateEthAddress() - msg := NewEthereumTxMsg(5, &addr, big.NewInt(1), 100000, big.NewInt(3), []byte("test")) + msg := NewMsgEthereumTx(5, &addr, big.NewInt(1), 100000, big.NewInt(3), []byte("test")) msg.Data.V = big.NewInt(1) msg.Data.R = big.NewInt(2) @@ -135,7 +135,7 @@ func TestMsgEthereumTxAmino(t *testing.T) { raw, err := ModuleCdc.MarshalBinaryBare(msg) require.NoError(t, err) - var msg2 EthereumTxMsg + var msg2 MsgEthereumTx err = ModuleCdc.UnmarshalBinaryBare(raw, &msg2) require.NoError(t, err) diff --git a/x/evm/types/state_object.go b/x/evm/types/state_object.go index 911f47c68..e875e89d0 100644 --- a/x/evm/types/state_object.go +++ b/x/evm/types/state_object.go @@ -80,6 +80,7 @@ type ( func newObject(db *CommitStateDB, accProto authexported.Account) *stateObject { acc, ok := accProto.(*types.Account) if !ok { + fmt.Println(accProto) panic(fmt.Sprintf("invalid account type for state object: %T", accProto)) } diff --git a/x/evm/types/statedb.go b/x/evm/types/statedb.go index 78c7e93f0..4d4a66a38 100644 --- a/x/evm/types/statedb.go +++ b/x/evm/types/statedb.go @@ -7,7 +7,6 @@ import ( "sync" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/x/auth" emint "github.com/cosmos/ethermint/types" @@ -43,7 +42,7 @@ type CommitStateDB struct { codeKey sdk.StoreKey storeKey sdk.StoreKey // i.e storage key - accountKeeper auth.AccountKeeper + accountKeeper AccountKeeper // maps that hold 'live' objects, which will get modified while processing a // state transition @@ -84,7 +83,7 @@ type CommitStateDB struct { // // CONTRACT: Stores used for state must be cache-wrapped as the ordering of the // key/value space matters in determining the merkle root. -func NewCommitStateDB(ctx sdk.Context, codeKey, storeKey sdk.StoreKey, ak auth.AccountKeeper) *CommitStateDB { +func NewCommitStateDB(ctx sdk.Context, codeKey, storeKey sdk.StoreKey, ak AccountKeeper) *CommitStateDB { return &CommitStateDB{ ctx: ctx, codeKey: codeKey, @@ -747,3 +746,10 @@ func (csdb *CommitStateDB) getStateObject(addr ethcmn.Address) (stateObject *sta func (csdb *CommitStateDB) setStateObject(so *stateObject) { csdb.stateObjects[so.Address()] = so } + +// RawDump returns a raw state dump. +// +// TODO: Implement if we need it, especially for the RPC API. +func (csdb *CommitStateDB) RawDump() ethstate.Dump { + return ethstate.Dump{} +} diff --git a/x/evm/types/statedb_test.go b/x/evm/types/statedb_test.go index c7b9013dc..a46631bb0 100644 --- a/x/evm/types/statedb_test.go +++ b/x/evm/types/statedb_test.go @@ -1,81 +1,41 @@ -package types +package types_test import ( "math/big" - "testing" - "github.com/cosmos/cosmos-sdk/codec" - "github.com/cosmos/cosmos-sdk/store" - sdkstore "github.com/cosmos/cosmos-sdk/store/types" + "github.com/stretchr/testify/suite" + sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/x/auth" - "github.com/cosmos/cosmos-sdk/x/params" - "github.com/stretchr/testify/require" "github.com/ethereum/go-ethereum/common" ethcmn "github.com/ethereum/go-ethereum/common" ethtypes "github.com/ethereum/go-ethereum/core/types" - "github.com/cosmos/ethermint/types" + "github.com/cosmos/ethermint/app" + "github.com/cosmos/ethermint/x/evm/keeper" abci "github.com/tendermint/tendermint/abci/types" - tmlog "github.com/tendermint/tendermint/libs/log" - dbm "github.com/tendermint/tm-db" ) -func newTestCodec() *codec.Codec { - cdc := codec.New() - - RegisterCodec(cdc) - types.RegisterCodec(cdc) - auth.RegisterCodec(cdc) - sdk.RegisterCodec(cdc) - codec.RegisterCrypto(cdc) +// nolint: unused +type StateDBTestSuite struct { + suite.Suite - return cdc + ctx sdk.Context + querier sdk.Querier + app *app.EthermintApp } -func setupStateDB() (*CommitStateDB, error) { - accKey := sdk.NewKVStoreKey("acc") - storageKey := sdk.NewKVStoreKey(StoreKey) - codeKey := sdk.NewKVStoreKey(CodeKey) - logger := tmlog.NewNopLogger() - - db := dbm.NewMemDB() - - // create logger, codec and root multi-store - cdc := newTestCodec() - cms := store.NewCommitMultiStore(db) - - // The ParamsKeeper handles parameter storage for the application - keyParams := sdk.NewKVStoreKey(params.StoreKey) - tkeyParams := sdk.NewTransientStoreKey(params.TStoreKey) - paramsKeeper := params.NewKeeper(cdc, keyParams, tkeyParams) - // Set specific supspaces - authSubspace := paramsKeeper.Subspace(auth.DefaultParamspace) - ak := auth.NewAccountKeeper(cdc, accKey, authSubspace, types.ProtoBaseAccount) - - // mount stores - keys := []*sdk.KVStoreKey{accKey, storageKey, codeKey} - for _, key := range keys { - cms.MountStoreWithDB(key, sdk.StoreTypeIAVL, nil) - } - - cms.SetPruning(sdkstore.PruneNothing) - - // load latest version (root) - if err := cms.LoadLatestVersion(); err != nil { - return nil, err - } - - ms := cms.CacheMultiStore() - ctx := sdk.NewContext(ms, abci.Header{}, false, logger) - return NewCommitStateDB(ctx, codeKey, storageKey, ak), nil +func (suite *StateDBTestSuite) SetupTest() { + checkTx := false + + suite.app = app.Setup(checkTx) + suite.ctx = suite.app.BaseApp.NewContext(checkTx, abci.Header{Height: 1}) + suite.querier = keeper.NewQuerier(suite.app.EvmKeeper) } -func TestBloomFilter(t *testing.T) { - stateDB, err := setupStateDB() - require.NoError(t, err) +func (suite *StateDBTestSuite) TestBloomFilter() { + stateDB := suite.app.EvmKeeper.CommitStateDB // Prepare db for logs tHash := ethcmn.BytesToHash([]byte{0x1}) @@ -89,13 +49,13 @@ func TestBloomFilter(t *testing.T) { // Get log from db logs := stateDB.GetLogs(tHash) - require.Equal(t, len(logs), 1) + suite.Require().Equal(len(logs), 1) // get logs bloom from the log bloomInt := ethtypes.LogsBloom(logs) bloomFilter := ethtypes.BytesToBloom(bloomInt.Bytes()) // Check to make sure bloom filter will succeed on - require.True(t, ethtypes.BloomLookup(bloomFilter, contractAddress)) - require.False(t, ethtypes.BloomLookup(bloomFilter, ethcmn.BigToAddress(big.NewInt(2)))) + suite.Require().True(ethtypes.BloomLookup(bloomFilter, contractAddress)) + suite.Require().False(ethtypes.BloomLookup(bloomFilter, ethcmn.BigToAddress(big.NewInt(2)))) }