github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/app/innertx_test.go (about)

     1  package app
     2  
     3  import (
     4  	"math/big"
     5  	"testing"
     6  	"time"
     7  
     8  	"github.com/ethereum/go-ethereum/common"
     9  
    10  	"github.com/fibonacci-chain/fbc/app/crypto/ethsecp256k1"
    11  	ethermint "github.com/fibonacci-chain/fbc/app/types"
    12  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/codec"
    13  	sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types"
    14  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/auth"
    15  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/bank"
    16  	abci "github.com/fibonacci-chain/fbc/libs/tendermint/abci/types"
    17  	"github.com/fibonacci-chain/fbc/libs/tendermint/crypto/ed25519"
    18  	"github.com/fibonacci-chain/fbc/libs/tendermint/crypto/secp256k1"
    19  	distr "github.com/fibonacci-chain/fbc/x/distribution"
    20  	"github.com/fibonacci-chain/fbc/x/distribution/keeper"
    21  	"github.com/fibonacci-chain/fbc/x/evm"
    22  	evm_types "github.com/fibonacci-chain/fbc/x/evm/types"
    23  	"github.com/fibonacci-chain/fbc/x/gov"
    24  	"github.com/fibonacci-chain/fbc/x/gov/types"
    25  	"github.com/fibonacci-chain/fbc/x/staking"
    26  	staking_keeper "github.com/fibonacci-chain/fbc/x/staking/keeper"
    27  	staking_types "github.com/fibonacci-chain/fbc/x/staking/types"
    28  
    29  	"github.com/stretchr/testify/suite"
    30  )
    31  
    32  var (
    33  	coin10  = sdk.NewInt64Coin(sdk.DefaultBondDenom, 10)
    34  	coin20  = sdk.NewInt64Coin(sdk.DefaultBondDenom, 20)
    35  	coin30  = sdk.NewInt64Coin(sdk.DefaultBondDenom, 30)
    36  	coin40  = sdk.NewInt64Coin(sdk.DefaultBondDenom, 40)
    37  	coin50  = sdk.NewInt64Coin(sdk.DefaultBondDenom, 50)
    38  	coin60  = sdk.NewInt64Coin(sdk.DefaultBondDenom, 60)
    39  	coin70  = sdk.NewInt64Coin(sdk.DefaultBondDenom, 70)
    40  	coin80  = sdk.NewInt64Coin(sdk.DefaultBondDenom, 80)
    41  	coin90  = sdk.NewInt64Coin(sdk.DefaultBondDenom, 90)
    42  	coin100 = sdk.NewInt64Coin(sdk.DefaultBondDenom, 100)
    43  	fees    = auth.NewStdFee(21000, sdk.NewCoins(coin10))
    44  )
    45  
    46  type InnerTxTestSuite struct {
    47  	suite.Suite
    48  
    49  	ctx     sdk.Context
    50  	app     *FBChainApp
    51  	stateDB *evm_types.CommitStateDB
    52  	codec   *codec.Codec
    53  
    54  	handler sdk.Handler
    55  }
    56  
    57  func (suite *InnerTxTestSuite) SetupTest() {
    58  	checkTx := false
    59  	chain_id := "ethermint-3"
    60  
    61  	suite.app = Setup(checkTx)
    62  	suite.ctx = suite.app.BaseApp.NewContext(checkTx, abci.Header{Height: 1, ChainID: chain_id, Time: time.Now().UTC()})
    63  	suite.ctx.SetDeliver()
    64  	suite.stateDB = evm_types.CreateEmptyCommitStateDB(suite.app.EvmKeeper.GenerateCSDBParams(), suite.ctx)
    65  	suite.codec = codec.New()
    66  
    67  	err := ethermint.SetChainId(chain_id)
    68  	suite.Nil(err)
    69  
    70  	params := evm_types.DefaultParams()
    71  	params.EnableCreate = true
    72  	params.EnableCall = true
    73  	suite.app.EvmKeeper.SetParams(suite.ctx, params)
    74  }
    75  
    76  func TestInnerTxTestSuite(t *testing.T) {
    77  	suite.Run(t, new(InnerTxTestSuite))
    78  }
    79  
    80  func (suite *InnerTxTestSuite) TestMsgSend() {
    81  	var (
    82  		tx          sdk.Tx
    83  		privFrom, _ = ethsecp256k1.GenerateKey()
    84  		//ethFrom     = common.HexToAddress(privFrom.PubKey().Address().String())
    85  		cmFrom = sdk.AccAddress(privFrom.PubKey().Address())
    86  		privTo = secp256k1.GenPrivKeySecp256k1([]byte("private key to"))
    87  		ethTo  = common.HexToAddress(privTo.PubKey().Address().String())
    88  		cmTo   = sdk.AccAddress(privTo.PubKey().Address())
    89  
    90  		valPriv      = ed25519.GenPrivKeyFromSecret([]byte("ed25519 private key"))
    91  		valpub       = valPriv.PubKey()
    92  		valopaddress = sdk.ValAddress(valpub.Address())
    93  		valcmaddress = sdk.AccAddress(valpub.Address())
    94  
    95  		privFrom1 = secp256k1.GenPrivKeySecp256k1([]byte("from1"))
    96  		cmFrom1   = sdk.AccAddress(privFrom1.PubKey().Address())
    97  		privTo1   = secp256k1.GenPrivKeySecp256k1([]byte("to1"))
    98  		cmTo1     = sdk.AccAddress(privTo1.PubKey().Address())
    99  	)
   100  	normal := func() {
   101  		err := suite.app.BankKeeper.SetCoins(suite.ctx, cmFrom, sdk.NewCoins(coin100))
   102  		suite.Require().NoError(err)
   103  	}
   104  	testCases := []struct {
   105  		msg        string
   106  		prepare    func()
   107  		expPass    bool
   108  		expectfunc func()
   109  	}{
   110  		{
   111  			"send msg(bank)",
   112  			func() {
   113  				suite.handler = bank.NewHandler(suite.app.BankKeeper)
   114  
   115  				msg := bank.NewMsgSend(cmFrom, cmTo, sdk.NewCoins(coin10))
   116  				tx = auth.NewStdTx([]sdk.Msg{msg}, fees, nil, "")
   117  			},
   118  			true,
   119  			func() {
   120  				fromBalance := suite.app.AccountKeeper.GetAccount(suite.ctx, cmFrom).GetCoins()
   121  				suite.Require().True(fromBalance.IsEqual(sdk.NewDecCoins(sdk.NewDecCoinFromCoin(coin90))))
   122  
   123  				toBalance := suite.app.AccountKeeper.GetAccount(suite.ctx, cmTo).GetCoins()
   124  				suite.Require().True(toBalance.IsEqual(sdk.NewDecCoins(sdk.NewDecCoinFromCoin(coin10))))
   125  			},
   126  		},
   127  		{
   128  			"send msgs(bank)",
   129  			func() {
   130  				suite.handler = bank.NewHandler(suite.app.BankKeeper)
   131  
   132  				msg := bank.NewMsgSend(cmFrom, cmTo, sdk.NewCoins(coin10))
   133  				tx = auth.NewStdTx([]sdk.Msg{msg, msg}, fees, nil, "")
   134  			},
   135  			true,
   136  			func() {
   137  				fromBalance := suite.app.AccountKeeper.GetAccount(suite.ctx, cmFrom).GetCoins()
   138  				suite.Require().True(fromBalance.IsEqual(sdk.NewDecCoins(sdk.NewDecCoinFromCoin(coin80))))
   139  
   140  				toBalance := suite.app.AccountKeeper.GetAccount(suite.ctx, cmTo).GetCoins()
   141  				suite.Require().True(toBalance.IsEqual(sdk.NewDecCoins(sdk.NewDecCoinFromCoin(coin20))))
   142  			},
   143  		},
   144  		{
   145  			"multi msg(bank)",
   146  			func() {
   147  				suite.handler = bank.NewHandler(suite.app.BankKeeper)
   148  				suite.app.BankKeeper.SetCoins(suite.ctx, cmFrom, sdk.NewCoins(coin100))
   149  				suite.app.BankKeeper.SetCoins(suite.ctx, cmFrom1, sdk.NewCoins(coin100))
   150  				inputCoin1 := sdk.NewCoins(coin20)
   151  				inputCoin2 := sdk.NewCoins(coin10)
   152  				outputCoin1 := sdk.NewCoins(coin10)
   153  				outputCoin2 := sdk.NewCoins(coin20)
   154  				input1 := bank.NewInput(cmFrom, inputCoin1)
   155  				input2 := bank.NewInput(cmFrom1, inputCoin2)
   156  				output1 := bank.NewOutput(cmTo, outputCoin1)
   157  				output2 := bank.NewOutput(cmTo1, outputCoin2)
   158  
   159  				msg := bank.NewMsgMultiSend([]bank.Input{input1, input2}, []bank.Output{output1, output2})
   160  				tx = auth.NewStdTx([]sdk.Msg{msg}, fees, nil, "")
   161  			},
   162  			true,
   163  			func() {
   164  				fromBalance := suite.app.AccountKeeper.GetAccount(suite.ctx, cmFrom).GetCoins()
   165  				suite.Require().True(fromBalance.IsEqual(sdk.NewDecCoins(sdk.NewDecCoinFromCoin(coin80))))
   166  				fromBalance = suite.app.AccountKeeper.GetAccount(suite.ctx, cmFrom1).GetCoins()
   167  				suite.Require().True(fromBalance.IsEqual(sdk.NewDecCoins(sdk.NewDecCoinFromCoin(coin90))))
   168  
   169  				toBalance := suite.app.AccountKeeper.GetAccount(suite.ctx, cmTo).GetCoins()
   170  				suite.Require().True(toBalance.IsEqual(sdk.NewDecCoins(sdk.NewDecCoinFromCoin(coin10))))
   171  				toBalance = suite.app.AccountKeeper.GetAccount(suite.ctx, cmTo1).GetCoins()
   172  				suite.Require().True(toBalance.IsEqual(sdk.NewDecCoins(sdk.NewDecCoinFromCoin(coin20))))
   173  			},
   174  		},
   175  		{
   176  			"evm send msg(evm)",
   177  			func() {
   178  				suite.handler = evm.NewHandler(suite.app.EvmKeeper)
   179  				tx = evm_types.NewMsgEthereumTx(0, &ethTo, coin10.Amount.BigInt(), 3000000, big.NewInt(0), nil)
   180  
   181  				// parse context chain ID to big.Int
   182  				chainID, err := ethermint.ParseChainID(suite.ctx.ChainID())
   183  				suite.Require().NoError(err)
   184  
   185  				// sign transaction
   186  				ethTx, ok := tx.(*evm_types.MsgEthereumTx)
   187  				suite.Require().True(ok)
   188  
   189  				err = ethTx.Sign(chainID, privFrom.ToECDSA())
   190  				suite.Require().NoError(err)
   191  				tx = ethTx
   192  			},
   193  			true,
   194  			func() {
   195  				fromBalance := suite.app.AccountKeeper.GetAccount(suite.ctx, cmFrom).GetCoins()
   196  				suite.Require().True(fromBalance.IsEqual(sdk.NewDecCoins(sdk.NewDecCoinFromCoin(coin90))))
   197  
   198  				toBalance := suite.app.AccountKeeper.GetAccount(suite.ctx, cmTo).GetCoins()
   199  				suite.Require().True(toBalance.IsEqual(sdk.NewDecCoins(sdk.NewDecCoinFromCoin(coin10))))
   200  			},
   201  		},
   202  		{
   203  			"create validator(staking)",
   204  			func() {
   205  				suite.handler = staking.NewHandler(suite.app.StakingKeeper)
   206  
   207  				err := suite.app.BankKeeper.SetCoins(suite.ctx, valcmaddress, sdk.NewCoins(sdk.NewInt64Coin(sdk.DefaultBondDenom, 20000)))
   208  				suite.Require().NoError(err)
   209  
   210  				msg := staking_keeper.NewTestMsgCreateValidator(valopaddress, valpub, coin10.Amount)
   211  				tx = auth.NewStdTx([]sdk.Msg{msg}, fees, nil, "")
   212  			},
   213  			true,
   214  			func() {
   215  				fromBalance := suite.app.AccountKeeper.GetAccount(suite.ctx, valcmaddress).GetCoins()
   216  				suite.Require().True(fromBalance.IsEqual(sdk.NewDecCoins(sdk.NewDecCoinFromCoin(sdk.NewInt64Coin(sdk.DefaultBondDenom, 10000)))))
   217  
   218  				suite.app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(suite.ctx)
   219  				val, ok := suite.app.StakingKeeper.GetValidator(suite.ctx, valopaddress)
   220  				suite.Require().True(ok)
   221  				suite.Require().Equal(valopaddress, val.OperatorAddress)
   222  				suite.Require().True(val.MinSelfDelegation.Equal(sdk.NewDec(10000)))
   223  			},
   224  		},
   225  		{
   226  			"destroy validator(staking)",
   227  			func() {
   228  				suite.handler = staking.NewHandler(suite.app.StakingKeeper)
   229  
   230  				err := suite.app.BankKeeper.SetCoins(suite.ctx, valcmaddress, sdk.NewCoins(sdk.NewInt64Coin(sdk.DefaultBondDenom, 20000)))
   231  				suite.Require().NoError(err)
   232  
   233  				msg := staking_keeper.NewTestMsgCreateValidator(valopaddress, valpub, coin10.Amount)
   234  
   235  				destroyValMsg := staking_types.NewMsgDestroyValidator([]byte(valopaddress))
   236  				tx = auth.NewStdTx([]sdk.Msg{msg, destroyValMsg}, fees, nil, "")
   237  			},
   238  			true,
   239  			func() {
   240  				fromBalance := suite.app.AccountKeeper.GetAccount(suite.ctx, valcmaddress).GetCoins()
   241  				suite.Require().True(fromBalance.IsEqual(sdk.NewDecCoins(sdk.NewDecCoinFromCoin(sdk.NewInt64Coin(sdk.DefaultBondDenom, 10000)))))
   242  
   243  				suite.app.EndBlocker(suite.ctx.WithBlockTime(time.Now().Add(staking_types.DefaultUnbondingTime)), abci.RequestEndBlock{Height: 2})
   244  				_, ok := suite.app.StakingKeeper.GetValidator(suite.ctx, valopaddress)
   245  				suite.Require().False(ok)
   246  				fromBalance = suite.app.AccountKeeper.GetAccount(suite.ctx, valcmaddress).GetCoins()
   247  				suite.Require().True(fromBalance.IsEqual(sdk.NewDecCoins(sdk.NewDecCoinFromCoin(sdk.NewInt64Coin(sdk.DefaultBondDenom, 20000)))))
   248  
   249  			},
   250  		},
   251  		{
   252  			"deposit msg(staking)",
   253  			func() {
   254  				suite.handler = staking.NewHandler(suite.app.StakingKeeper)
   255  				err := suite.app.BankKeeper.SetCoins(suite.ctx, cmFrom, sdk.NewCoins(sdk.NewInt64Coin(sdk.DefaultBondDenom, 10000)))
   256  				suite.Require().NoError(err)
   257  				err = suite.app.BankKeeper.SetCoins(suite.ctx, valcmaddress, sdk.NewCoins(sdk.NewInt64Coin(sdk.DefaultBondDenom, 20000)))
   258  				suite.Require().NoError(err)
   259  
   260  				msg := staking_keeper.NewTestMsgCreateValidator(valopaddress, valpub, coin10.Amount)
   261  
   262  				depositMsg := staking_types.NewMsgDeposit(cmFrom, keeper.NewTestSysCoin(10000, 0))
   263  				tx = auth.NewStdTx([]sdk.Msg{msg, depositMsg}, fees, nil, "")
   264  			},
   265  			true,
   266  			func() {
   267  				fromBalance := suite.app.AccountKeeper.GetAccount(suite.ctx, cmFrom).GetCoins()
   268  				suite.Require().True(fromBalance.IsEqual(sdk.NewDecCoins(sdk.NewDecCoinFromCoin(sdk.NewInt64Coin(sdk.DefaultBondDenom, 0)))))
   269  
   270  			},
   271  		},
   272  		{
   273  			"withdraw msg(staking)",
   274  			func() {
   275  				suite.handler = staking.NewHandler(suite.app.StakingKeeper)
   276  				err := suite.app.BankKeeper.SetCoins(suite.ctx, cmFrom, sdk.NewCoins(sdk.NewInt64Coin(sdk.DefaultBondDenom, 10000)))
   277  				suite.Require().NoError(err)
   278  				err = suite.app.BankKeeper.SetCoins(suite.ctx, valcmaddress, sdk.NewCoins(sdk.NewInt64Coin(sdk.DefaultBondDenom, 20000)))
   279  				suite.Require().NoError(err)
   280  
   281  				msg := staking_keeper.NewTestMsgCreateValidator(valopaddress, valpub, coin10.Amount)
   282  
   283  				depositMsg := staking_types.NewMsgDeposit(cmFrom, keeper.NewTestSysCoin(10000, 0))
   284  
   285  				withdrawMsg := staking_types.NewMsgWithdraw(cmFrom, keeper.NewTestSysCoin(10000, 0))
   286  				tx = auth.NewStdTx([]sdk.Msg{msg, depositMsg, withdrawMsg}, fees, nil, "")
   287  			},
   288  			true,
   289  			func() {
   290  				fromBalance := suite.app.AccountKeeper.GetAccount(suite.ctx, cmFrom).GetCoins()
   291  				suite.Require().True(fromBalance.IsEqual(sdk.NewDecCoins(sdk.NewDecCoinFromCoin(sdk.NewInt64Coin(sdk.DefaultBondDenom, 0)))))
   292  				suite.app.EndBlocker(suite.ctx.WithBlockTime(time.Now().Add(staking_types.DefaultUnbondingTime)), abci.RequestEndBlock{Height: 2})
   293  				fromBalance = suite.app.AccountKeeper.GetAccount(suite.ctx, cmFrom).GetCoins()
   294  				suite.Require().True(fromBalance.IsEqual(sdk.NewDecCoins(sdk.NewDecCoinFromCoin(sdk.NewInt64Coin(sdk.DefaultBondDenom, 10000)))))
   295  			},
   296  		},
   297  		{
   298  			"addshare msg(staking)",
   299  			func() {
   300  				suite.handler = staking.NewHandler(suite.app.StakingKeeper)
   301  				err := suite.app.BankKeeper.SetCoins(suite.ctx, cmFrom, sdk.NewCoins(sdk.NewInt64Coin(sdk.DefaultBondDenom, 10000)))
   302  				suite.Require().NoError(err)
   303  				err = suite.app.BankKeeper.SetCoins(suite.ctx, valcmaddress, sdk.NewCoins(sdk.NewInt64Coin(sdk.DefaultBondDenom, 20000)))
   304  				suite.Require().NoError(err)
   305  
   306  				msg := staking_keeper.NewTestMsgCreateValidator(valopaddress, valpub, coin10.Amount)
   307  
   308  				depositMsg := staking_types.NewMsgDeposit(cmFrom, keeper.NewTestSysCoin(10000, 0))
   309  				addShareMsg := staking_types.NewMsgAddShares(cmFrom, []sdk.ValAddress{valopaddress})
   310  				tx = auth.NewStdTx([]sdk.Msg{msg, depositMsg, addShareMsg}, fees, nil, "")
   311  			},
   312  			true,
   313  			func() {
   314  				fromBalance := suite.app.AccountKeeper.GetAccount(suite.ctx, cmFrom).GetCoins()
   315  				suite.Require().True(fromBalance.IsEqual(sdk.NewDecCoins(sdk.NewDecCoinFromCoin(sdk.NewInt64Coin(sdk.DefaultBondDenom, 0)))))
   316  
   317  			},
   318  		},
   319  		{
   320  			"proxy reg msg(staking)",
   321  			func() {
   322  				suite.handler = staking.NewHandler(suite.app.StakingKeeper)
   323  				err := suite.app.BankKeeper.SetCoins(suite.ctx, cmFrom, sdk.NewCoins(sdk.NewInt64Coin(sdk.DefaultBondDenom, 10000)))
   324  				suite.Require().NoError(err)
   325  				err = suite.app.BankKeeper.SetCoins(suite.ctx, valcmaddress, sdk.NewCoins(sdk.NewInt64Coin(sdk.DefaultBondDenom, 20000)))
   326  				suite.Require().NoError(err)
   327  
   328  				msg := staking_keeper.NewTestMsgCreateValidator(valopaddress, valpub, coin10.Amount)
   329  
   330  				depositMsg := staking_types.NewMsgDeposit(cmFrom, keeper.NewTestSysCoin(10000, 0))
   331  				regMsg := staking_types.NewMsgRegProxy(cmFrom, true)
   332  				tx = auth.NewStdTx([]sdk.Msg{msg, depositMsg, regMsg}, fees, nil, "")
   333  			},
   334  			true,
   335  			func() {
   336  				fromBalance := suite.app.AccountKeeper.GetAccount(suite.ctx, cmFrom).GetCoins()
   337  				suite.Require().True(fromBalance.IsEqual(sdk.NewDecCoins(sdk.NewDecCoinFromCoin(sdk.NewInt64Coin(sdk.DefaultBondDenom, 0)))))
   338  
   339  			},
   340  		},
   341  		{
   342  			"proxy unreg msg(staking)",
   343  			func() {
   344  				suite.handler = staking.NewHandler(suite.app.StakingKeeper)
   345  				err := suite.app.BankKeeper.SetCoins(suite.ctx, cmFrom, sdk.NewCoins(sdk.NewInt64Coin(sdk.DefaultBondDenom, 10000)))
   346  				suite.Require().NoError(err)
   347  				err = suite.app.BankKeeper.SetCoins(suite.ctx, valcmaddress, sdk.NewCoins(sdk.NewInt64Coin(sdk.DefaultBondDenom, 20000)))
   348  				suite.Require().NoError(err)
   349  
   350  				msg := staking_keeper.NewTestMsgCreateValidator(valopaddress, valpub, coin10.Amount)
   351  
   352  				depositMsg := staking_types.NewMsgDeposit(cmFrom, keeper.NewTestSysCoin(10000, 0))
   353  				regMsg := staking_types.NewMsgRegProxy(cmFrom, true)
   354  				unregMsg := staking_types.NewMsgRegProxy(cmFrom, false)
   355  				tx = auth.NewStdTx([]sdk.Msg{msg, depositMsg, regMsg, unregMsg}, fees, nil, "")
   356  			},
   357  			true,
   358  			func() {
   359  				fromBalance := suite.app.AccountKeeper.GetAccount(suite.ctx, cmFrom).GetCoins()
   360  				suite.Require().True(fromBalance.IsEqual(sdk.NewDecCoins(sdk.NewDecCoinFromCoin(sdk.NewInt64Coin(sdk.DefaultBondDenom, 0)))))
   361  
   362  			},
   363  		},
   364  		{
   365  			"proxy bind msg(staking)",
   366  			func() {
   367  				suite.handler = staking.NewHandler(suite.app.StakingKeeper)
   368  
   369  				err := suite.app.BankKeeper.SetCoins(suite.ctx, cmFrom1, sdk.NewCoins(sdk.NewInt64Coin(sdk.DefaultBondDenom, 10000)))
   370  				suite.Require().NoError(err)
   371  				err = suite.app.BankKeeper.SetCoins(suite.ctx, cmFrom, sdk.NewCoins(sdk.NewInt64Coin(sdk.DefaultBondDenom, 10000)))
   372  				suite.Require().NoError(err)
   373  				err = suite.app.BankKeeper.SetCoins(suite.ctx, valcmaddress, sdk.NewCoins(sdk.NewInt64Coin(sdk.DefaultBondDenom, 20000)))
   374  				suite.Require().NoError(err)
   375  
   376  				msg := staking_keeper.NewTestMsgCreateValidator(valopaddress, valpub, coin10.Amount)
   377  				depositMsg := staking_types.NewMsgDeposit(cmFrom, keeper.NewTestSysCoin(10000, 0))
   378  				regMsg := staking_types.NewMsgRegProxy(cmFrom, true)
   379  				depositMsg1 := staking_types.NewMsgDeposit(cmFrom1, keeper.NewTestSysCoin(10000, 0))
   380  				bindMsg := staking_types.NewMsgBindProxy(cmFrom1, cmFrom)
   381  
   382  				tx = auth.NewStdTx([]sdk.Msg{msg, depositMsg, regMsg, depositMsg1, bindMsg}, fees, nil, "")
   383  			},
   384  			true,
   385  			func() {
   386  				fromBalance := suite.app.AccountKeeper.GetAccount(suite.ctx, cmFrom).GetCoins()
   387  				suite.Require().True(fromBalance.IsEqual(sdk.NewDecCoins(sdk.NewDecCoinFromCoin(sdk.NewInt64Coin(sdk.DefaultBondDenom, 0)))))
   388  
   389  				fromBalance = suite.app.AccountKeeper.GetAccount(suite.ctx, cmFrom1).GetCoins()
   390  				suite.Require().True(fromBalance.IsEqual(sdk.NewDecCoins(sdk.NewDecCoinFromCoin(sdk.NewInt64Coin(sdk.DefaultBondDenom, 0)))))
   391  
   392  			},
   393  		},
   394  		{
   395  			"proxy unbind msg(staking)",
   396  			func() {
   397  				suite.handler = staking.NewHandler(suite.app.StakingKeeper)
   398  
   399  				err := suite.app.BankKeeper.SetCoins(suite.ctx, cmFrom1, sdk.NewCoins(sdk.NewInt64Coin(sdk.DefaultBondDenom, 10000)))
   400  				suite.Require().NoError(err)
   401  				err = suite.app.BankKeeper.SetCoins(suite.ctx, cmFrom, sdk.NewCoins(sdk.NewInt64Coin(sdk.DefaultBondDenom, 10000)))
   402  				suite.Require().NoError(err)
   403  				err = suite.app.BankKeeper.SetCoins(suite.ctx, valcmaddress, sdk.NewCoins(sdk.NewInt64Coin(sdk.DefaultBondDenom, 20000)))
   404  				suite.Require().NoError(err)
   405  
   406  				msg := staking_keeper.NewTestMsgCreateValidator(valopaddress, valpub, coin10.Amount)
   407  				depositMsg := staking_types.NewMsgDeposit(cmFrom, keeper.NewTestSysCoin(10000, 0))
   408  				regMsg := staking_types.NewMsgRegProxy(cmFrom, true)
   409  				depositMsg1 := staking_types.NewMsgDeposit(cmFrom1, keeper.NewTestSysCoin(10000, 0))
   410  				bindMsg := staking_types.NewMsgBindProxy(cmFrom1, cmFrom)
   411  				ubindMsg := staking_types.NewMsgUnbindProxy(cmFrom1)
   412  				tx = auth.NewStdTx([]sdk.Msg{msg, depositMsg, regMsg, depositMsg1, bindMsg, ubindMsg}, fees, nil, "")
   413  			},
   414  			true,
   415  			func() {
   416  				fromBalance := suite.app.AccountKeeper.GetAccount(suite.ctx, cmFrom).GetCoins()
   417  				suite.Require().True(fromBalance.IsEqual(sdk.NewDecCoins(sdk.NewDecCoinFromCoin(sdk.NewInt64Coin(sdk.DefaultBondDenom, 0)))))
   418  
   419  				fromBalance = suite.app.AccountKeeper.GetAccount(suite.ctx, cmFrom1).GetCoins()
   420  				suite.Require().True(fromBalance.IsEqual(sdk.NewDecCoins(sdk.NewDecCoinFromCoin(sdk.NewInt64Coin(sdk.DefaultBondDenom, 0)))))
   421  
   422  			},
   423  		},
   424  		{
   425  			"withdraw validator(staking)",
   426  			func() {
   427  				suite.handler = staking.NewHandler(suite.app.StakingKeeper)
   428  
   429  				err := suite.app.BankKeeper.SetCoins(suite.ctx, valcmaddress, sdk.NewCoins(sdk.NewInt64Coin(sdk.DefaultBondDenom, 20000)))
   430  				suite.Require().NoError(err)
   431  
   432  				msg := staking_keeper.NewTestMsgCreateValidator(valopaddress, valpub, coin10.Amount)
   433  				_, err = suite.handler(suite.ctx, msg)
   434  				suite.Require().NoError(err)
   435  				fromBalance := suite.app.AccountKeeper.GetAccount(suite.ctx, valcmaddress).GetCoins()
   436  				suite.Require().True(fromBalance.IsEqual(sdk.NewDecCoins(sdk.NewDecCoinFromCoin(sdk.NewInt64Coin(sdk.DefaultBondDenom, 10000)))))
   437  				suite.app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(suite.ctx)
   438  				val, ok := suite.app.StakingKeeper.GetValidator(suite.ctx, valopaddress)
   439  				suite.Require().True(ok)
   440  				suite.Require().Equal(valopaddress, val.OperatorAddress)
   441  				suite.Require().True(val.MinSelfDelegation.Equal(sdk.NewDec(10000)))
   442  
   443  				suite.app.Commit(abci.RequestCommit{})
   444  				votes := []abci.VoteInfo{
   445  					{Validator: abci.Validator{Address: valpub.Address(), Power: 1}, SignedLastBlock: true},
   446  				}
   447  				for i := 0; i < 100; i++ {
   448  					header := abci.Header{Height: int64(i + 2), ProposerAddress: sdk.ConsAddress(valpub.Address())}
   449  					req := abci.RequestBeginBlock{Header: header,
   450  						LastCommitInfo: abci.LastCommitInfo{Votes: votes}}
   451  					suite.ctx.SetBlockHeader(header)
   452  					suite.app.BeginBlocker(suite.ctx, req)
   453  					suite.app.EndBlocker(suite.ctx, abci.RequestEndBlock{})
   454  				}
   455  				commision := suite.app.DistrKeeper.GetValidatorAccumulatedCommission(suite.ctx, valopaddress)
   456  				suite.Require().True(commision.IsEqual(sdk.NewDecCoins(sdk.NewDecCoinFromDec(sdk.DefaultBondDenom, sdk.NewDecWithPrec(98, 0)))))
   457  
   458  				suite.handler = distr.NewHandler(suite.app.DistrKeeper)
   459  				withdrawMsg := distr.NewMsgWithdrawValidatorCommission(valopaddress)
   460  				tx = auth.NewStdTx([]sdk.Msg{withdrawMsg}, fees, nil, "")
   461  			},
   462  			true,
   463  			func() {
   464  				fromBalance := suite.app.AccountKeeper.GetAccount(suite.ctx, valcmaddress).GetCoins()
   465  				expectCommision := sdk.NewDecCoins(sdk.NewDecCoinFromDec(sdk.DefaultBondDenom, sdk.NewDecWithPrec(98, 0)))
   466  				suite.Require().True(fromBalance.IsEqual(sdk.NewDecCoins(sdk.NewDecCoinFromCoin(sdk.NewInt64Coin(sdk.DefaultBondDenom, 10000))).Add2(expectCommision)))
   467  			},
   468  		},
   469  		{
   470  			"set withdraw address(staking)",
   471  			func() {
   472  				suite.handler = staking.NewHandler(suite.app.StakingKeeper)
   473  
   474  				err := suite.app.BankKeeper.SetCoins(suite.ctx, valcmaddress, sdk.NewCoins(sdk.NewInt64Coin(sdk.DefaultBondDenom, 20000)))
   475  				suite.Require().NoError(err)
   476  
   477  				msg := staking_keeper.NewTestMsgCreateValidator(valopaddress, valpub, coin10.Amount)
   478  				_, err = suite.handler(suite.ctx, msg)
   479  				suite.Require().NoError(err)
   480  				fromBalance := suite.app.AccountKeeper.GetAccount(suite.ctx, valcmaddress).GetCoins()
   481  				suite.Require().True(fromBalance.IsEqual(sdk.NewDecCoins(sdk.NewDecCoinFromCoin(sdk.NewInt64Coin(sdk.DefaultBondDenom, 10000)))))
   482  				suite.app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(suite.ctx)
   483  				val, ok := suite.app.StakingKeeper.GetValidator(suite.ctx, valopaddress)
   484  				suite.Require().True(ok)
   485  				suite.Require().Equal(valopaddress, val.OperatorAddress)
   486  				suite.Require().True(val.MinSelfDelegation.Equal(sdk.NewDec(10000)))
   487  
   488  				suite.app.Commit(abci.RequestCommit{})
   489  				votes := []abci.VoteInfo{
   490  					{Validator: abci.Validator{Address: valpub.Address(), Power: 1}, SignedLastBlock: true},
   491  				}
   492  
   493  				for i := 0; i < 100; i++ {
   494  					header := abci.Header{Height: int64(i + 2), ProposerAddress: sdk.ConsAddress(valpub.Address())}
   495  					req := abci.RequestBeginBlock{Header: header,
   496  						LastCommitInfo: abci.LastCommitInfo{Votes: votes}}
   497  					suite.ctx.SetBlockHeader(header)
   498  					suite.app.BeginBlocker(suite.ctx, req)
   499  					suite.app.EndBlocker(suite.ctx, abci.RequestEndBlock{})
   500  
   501  					//minter := suite.app.MintKeeper.GetMinterCustom(suite.ctx)
   502  					//fmt.Println("minter reward: ", minter.MintedPerBlock) //1fibo per block common pool 0.2
   503  				}
   504  				commision := suite.app.DistrKeeper.GetValidatorAccumulatedCommission(suite.ctx, valopaddress)
   505  				suite.Require().True(commision.IsEqual(sdk.NewDecCoins(sdk.NewDecCoinFromDec(sdk.DefaultBondDenom, sdk.NewDecWithPrec(98, 0)))))
   506  
   507  				suite.handler = distr.NewHandler(suite.app.DistrKeeper)
   508  				setwithdrawMsg := distr.NewMsgSetWithdrawAddress(valcmaddress, cmFrom1)
   509  				withdrawMsg := distr.NewMsgWithdrawValidatorCommission(valopaddress)
   510  				tx = auth.NewStdTx([]sdk.Msg{setwithdrawMsg, withdrawMsg}, fees, nil, "")
   511  			},
   512  			true,
   513  			func() {
   514  				fromBalance := suite.app.AccountKeeper.GetAccount(suite.ctx, valcmaddress).GetCoins()
   515  				suite.Require().True(fromBalance.IsEqual(sdk.NewDecCoins(sdk.NewDecCoinFromCoin(sdk.NewInt64Coin(sdk.DefaultBondDenom, 10000)))))
   516  				fromBalance = suite.app.AccountKeeper.GetAccount(suite.ctx, cmFrom1).GetCoins()
   517  				expectCommision := sdk.NewDecCoins(sdk.NewDecCoinFromDec(sdk.DefaultBondDenom, sdk.NewDecWithPrec(98, 0)))
   518  				suite.Require().True(fromBalance.IsEqual(expectCommision))
   519  			},
   520  		},
   521  		{
   522  			"submit proposal(gov)",
   523  			func() {
   524  				suite.handler = gov.NewHandler(suite.app.GovKeeper)
   525  
   526  				content := gov.NewTextProposal("Test", "description")
   527  				newProposalMsg := gov.NewMsgSubmitProposal(content, keeper.NewTestSysCoins(100, 0), cmFrom)
   528  				tx = auth.NewStdTx([]sdk.Msg{newProposalMsg}, fees, nil, "")
   529  			},
   530  			true,
   531  			func() {
   532  				fromBalance := suite.app.AccountKeeper.GetAccount(suite.ctx, cmFrom).GetCoins()
   533  				suite.Require().True(fromBalance.IsZero())
   534  			},
   535  		},
   536  		{
   537  			"deposit proposal(gov)",
   538  			func() {
   539  				suite.handler = gov.NewHandler(suite.app.GovKeeper)
   540  
   541  				content := gov.NewTextProposal("Test", "description")
   542  				newProposalMsg := gov.NewMsgSubmitProposal(content, keeper.NewTestSysCoins(10, 0), cmFrom)
   543  				depositMsg := gov.NewMsgDeposit(cmFrom, 1, keeper.NewTestSysCoins(90, 0))
   544  				tx = auth.NewStdTx([]sdk.Msg{newProposalMsg, depositMsg}, fees, nil, "")
   545  			},
   546  			true,
   547  			func() {
   548  				fromBalance := suite.app.AccountKeeper.GetAccount(suite.ctx, cmFrom).GetCoins()
   549  				suite.Require().True(fromBalance.IsZero())
   550  			},
   551  		},
   552  		{
   553  			"vote proposal(gov)",
   554  			func() {
   555  				suite.handler = gov.NewHandler(suite.app.GovKeeper)
   556  
   557  				validator := staking_types.NewValidator(valopaddress, valpub, staking_types.NewDescription("test description", "", "", ""), staking_types.DefaultMinDelegation)
   558  				suite.app.StakingKeeper.SetValidator(suite.ctx, validator)
   559  				content := gov.NewTextProposal("Test", "description")
   560  				newProposalMsg := gov.NewMsgSubmitProposal(content, keeper.NewTestSysCoins(10, 0), cmFrom)
   561  				depositMsg := gov.NewMsgDeposit(cmFrom, 1, keeper.NewTestSysCoins(90, 0))
   562  				voteMsg := gov.NewMsgVote(valcmaddress, 1, types.OptionYes)
   563  				tx = auth.NewStdTx([]sdk.Msg{newProposalMsg, depositMsg, voteMsg}, fees, nil, "")
   564  			},
   565  			true,
   566  			func() {
   567  				fromBalance := suite.app.AccountKeeper.GetAccount(suite.ctx, cmFrom).GetCoins()
   568  				suite.Require().True(fromBalance.IsEqual(sdk.NewDecCoins(sdk.NewDecCoinFromCoin(coin100))))
   569  			},
   570  		},
   571  	}
   572  
   573  	for _, tc := range testCases {
   574  		suite.Run(tc.msg, func() {
   575  			suite.SetupTest() // reset
   576  			normal()
   577  			//nolint
   578  			tc.prepare()
   579  			suite.ctx.SetGasMeter(sdk.NewInfiniteGasMeter())
   580  			msgs := tx.GetMsgs()
   581  			for _, msg := range msgs {
   582  				_, err := suite.handler(suite.ctx, msg)
   583  
   584  				//nolint
   585  				if tc.expPass {
   586  					suite.Require().NoError(err)
   587  				} else {
   588  					suite.Require().Error(err)
   589  				}
   590  			}
   591  			tc.expectfunc()
   592  		})
   593  	}
   594  }