package types_test import ( "math/big" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/ethermint/crypto" ethermint "github.com/cosmos/ethermint/types" "github.com/cosmos/ethermint/x/evm/types" ethcmn "github.com/ethereum/go-ethereum/common" ethcrypto "github.com/ethereum/go-ethereum/crypto" ) func (suite *StateDBTestSuite) TestTransitionDb() { suite.stateDB.SetNonce(suite.address, 123) addr := sdk.AccAddress(suite.address.Bytes()) balance := sdk.NewCoin(ethermint.DenomDefault, sdk.NewInt(5000)) suite.app.BankKeeper.SetBalance(suite.ctx, addr, balance) priv, err := crypto.GenerateKey() suite.Require().NoError(err) recipient := ethcrypto.PubkeyToAddress(priv.ToECDSA().PublicKey) testCase := []struct { name string malleate func() state types.StateTransition expPass bool }{ { "passing state transition", func() {}, types.StateTransition{ AccountNonce: 123, Price: big.NewInt(10), GasLimit: 11, Recipient: &recipient, Amount: big.NewInt(50), Payload: []byte("data"), ChainID: big.NewInt(1), Csdb: suite.stateDB, TxHash: ðcmn.Hash{}, Sender: suite.address, Simulate: suite.ctx.IsCheckTx(), }, true, }, { "contract creation", func() {}, types.StateTransition{ AccountNonce: 123, Price: big.NewInt(10), GasLimit: 11, Recipient: nil, Amount: big.NewInt(10), Payload: []byte("data"), ChainID: big.NewInt(1), Csdb: suite.stateDB, TxHash: ðcmn.Hash{}, Sender: suite.address, Simulate: true, }, true, }, { "state transition simulation", func() {}, types.StateTransition{ AccountNonce: 123, Price: big.NewInt(10), GasLimit: 11, Recipient: &recipient, Amount: big.NewInt(10), Payload: []byte("data"), ChainID: big.NewInt(1), Csdb: suite.stateDB, TxHash: ðcmn.Hash{}, Sender: suite.address, Simulate: true, }, true, }, { "fail by sending more than balance", func() {}, types.StateTransition{ AccountNonce: 123, Price: big.NewInt(10), GasLimit: 11, Recipient: &recipient, Amount: big.NewInt(4951), Payload: []byte("data"), ChainID: big.NewInt(1), Csdb: suite.stateDB, TxHash: ðcmn.Hash{}, Sender: suite.address, Simulate: suite.ctx.IsCheckTx(), }, false, }, { "failed to Finalize", func() {}, types.StateTransition{ AccountNonce: 123, Price: big.NewInt(10), GasLimit: 11, Recipient: &recipient, Amount: big.NewInt(-5000), Payload: []byte("data"), ChainID: big.NewInt(1), Csdb: suite.stateDB, TxHash: ðcmn.Hash{}, Sender: suite.address, Simulate: false, }, false, }, { "nil gas price", func() { invalidGas := sdk.DecCoins{ {Denom: ethermint.DenomDefault}, } suite.ctx = suite.ctx.WithMinGasPrices(invalidGas) }, types.StateTransition{ AccountNonce: 123, Price: big.NewInt(10), GasLimit: 11, Recipient: &recipient, Amount: big.NewInt(10), Payload: []byte("data"), ChainID: big.NewInt(1), Csdb: suite.stateDB, TxHash: ðcmn.Hash{}, Sender: suite.address, Simulate: suite.ctx.IsCheckTx(), }, false, }, } for _, tc := range testCase { tc.malleate() _, err = tc.state.TransitionDb(suite.ctx) if tc.expPass { suite.Require().NoError(err, tc.name) fromBalance := suite.app.EvmKeeper.GetBalance(suite.ctx, suite.address) toBalance := suite.app.EvmKeeper.GetBalance(suite.ctx, recipient) suite.Require().Equal(fromBalance, big.NewInt(4950), tc.name) suite.Require().Equal(toBalance, big.NewInt(50), tc.name) } else { suite.Require().Error(err, tc.name) } } }