diff --git a/CHANGELOG.md b/CHANGELOG.md index 8cd1265333ba..3df3f0388cff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -49,7 +49,8 @@ Ref: https://keepachangelog.com/en/1.0.0/ ### API Breaking Changes -* (simapp) [#XXXXX](https://github.com/cosmos/cosmos-sdk/pull/XXXXX) Move `simapp.ConvertAddrsToValAddrs` and `simapp.CreateTestPubKeys ` to respectively `simtestutil.ConvertAddrsToValAddrs` and `simtestutil.CreateTestPubKeys` (`testutil/sims`) +* (simapp) [#12343](https://github.com/cosmos/cosmos-sdk/pull/12343) Move `simapp.CheckBalance` and `simapp.SignCheckDeliver` to `simtestutil.CheckBalance` and `simtestutil.SignCheckDeliver` (`testutil/sims`) +* (simapp) [#12334](https://github.com/cosmos/cosmos-sdk/pull/12334) Move `simapp.ConvertAddrsToValAddrs` and `simapp.CreateTestPubKeys ` to respectively `simtestutil.ConvertAddrsToValAddrs` and `simtestutil.CreateTestPubKeys` (`testutil/sims`) * (simapp) [#12312](https://github.com/cosmos/cosmos-sdk/pull/12312) Move `simapp.EmptyAppOptions` to `simtestutil.EmptyAppOptions` (`testutil/sims`) * (simapp) [#12312](https://github.com/cosmos/cosmos-sdk/pull/12312) Remove `skipUpgradeHeights map[int64]bool` and `homePath string` from `NewSimApp` constructor as per migration of `x/upgrade` to app-wiring. * (testutil) [#12278](https://github.com/cosmos/cosmos-sdk/pull/12278) Move all functions from `simapp/helpers` to `testutil/sims` diff --git a/simapp/test_helpers.go b/simapp/test_helpers.go index 4cdc47f3abad..fdc1b7ad2c5f 100644 --- a/simapp/test_helpers.go +++ b/simapp/test_helpers.go @@ -14,7 +14,6 @@ import ( dbm "github.com/tendermint/tm-db" "cosmossdk.io/math" - bam "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" @@ -242,63 +241,6 @@ func initAccountWithCoins(app *SimApp, ctx sdk.Context, addr sdk.AccAddress, coi } } -// CheckBalance checks the balance of an account. -func CheckBalance(t *testing.T, app *SimApp, addr sdk.AccAddress, balances sdk.Coins) { - ctxCheck := app.BaseApp.NewContext(true, tmproto.Header{}) - require.True(t, balances.IsEqual(app.BankKeeper.GetAllBalances(ctxCheck, addr))) -} - -// SignCheckDeliver checks a generated signed transaction and simulates a -// block commitment with the given transaction. A test assertion is made using -// the parameter 'expPass' against the result. A corresponding result is -// returned. -func SignCheckDeliver( - t *testing.T, txCfg client.TxConfig, app *bam.BaseApp, header tmproto.Header, msgs []sdk.Msg, - chainID string, accNums, accSeqs []uint64, expSimPass, expPass bool, priv ...cryptotypes.PrivKey, -) (sdk.GasInfo, *sdk.Result, error) { - tx, err := simtestutil.GenSignedMockTx( - txCfg, - msgs, - sdk.Coins{sdk.NewInt64Coin(sdk.DefaultBondDenom, 0)}, - simtestutil.DefaultGenTxGas, - chainID, - accNums, - accSeqs, - priv..., - ) - require.NoError(t, err) - txBytes, err := txCfg.TxEncoder()(tx) - require.Nil(t, err) - - // Must simulate now as CheckTx doesn't run Msgs anymore - _, res, err := app.Simulate(txBytes) - - if expSimPass { - require.NoError(t, err) - require.NotNil(t, res) - } else { - require.Error(t, err) - require.Nil(t, res) - } - - // Simulate a sending a transaction and committing a block - app.BeginBlock(abci.RequestBeginBlock{Header: header}) - gInfo, res, err := app.SimDeliver(txCfg.TxEncoder(), tx) - - if expPass { - require.NoError(t, err) - require.NotNil(t, res) - } else { - require.Error(t, err) - require.Nil(t, res) - } - - app.EndBlock(abci.RequestEndBlock{}) - app.Commit() - - return gInfo, res, err -} - // GenSequenceOfTxs generates a set of signed transactions of messages, such // that they differ only by having the sequence numbers incremented between // every transaction. diff --git a/testutil/sims/address_helpers.go b/testutil/sims/address_helpers.go index 9e0a4023bf05..4e5a1b064659 100644 --- a/testutil/sims/address_helpers.go +++ b/testutil/sims/address_helpers.go @@ -7,6 +7,7 @@ import ( "strconv" "cosmossdk.io/math" + "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" sdk "github.com/cosmos/cosmos-sdk/types" @@ -14,6 +15,7 @@ import ( bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper" minttypes "github.com/cosmos/cosmos-sdk/x/mint/types" stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper" + tmproto "github.com/tendermint/tendermint/proto/tendermint/types" ) type GenerateAccountStrategy func(int) []sdk.AccAddress @@ -113,6 +115,12 @@ func TestAddr(addr string, bech string) (sdk.AccAddress, error) { return res, nil } +// CheckBalance checks the balance of an account. +func CheckBalance(ba *baseapp.BaseApp, bankKeeper bankkeeper.Keeper, addr sdk.AccAddress, balances sdk.Coins) bool { + ctxCheck := ba.NewContext(true, tmproto.Header{}) + return balances.IsEqual(bankKeeper.GetAllBalances(ctxCheck, addr)) +} + // ConvertAddrsToValAddrs converts the provided addresses to ValAddress. func ConvertAddrsToValAddrs(addrs []sdk.AccAddress) []sdk.ValAddress { valAddrs := make([]sdk.ValAddress, len(addrs)) diff --git a/testutil/sims/tx_helpers.go b/testutil/sims/tx_helpers.go index ef79b9e393b4..ec5b97196950 100644 --- a/testutil/sims/tx_helpers.go +++ b/testutil/sims/tx_helpers.go @@ -1,9 +1,14 @@ package sims import ( + "fmt" "math/rand" "time" + abci "github.com/tendermint/tendermint/abci/types" + tmproto "github.com/tendermint/tendermint/proto/tendermint/types" + + "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/client" cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" sdk "github.com/cosmos/cosmos-sdk/types" @@ -74,3 +79,76 @@ func GenSignedMockTx(txConfig client.TxConfig, msgs []sdk.Msg, feeAmt sdk.Coins, return tx.GetTx(), nil } + +// SignCheckDeliver checks a generated signed transaction and simulates a +// block commitment with the given transaction. A test assertion is made using +// the parameter 'expPass' against the result. A corresponding result is +// returned. +func SignCheckDeliver(txConfig client.TxConfig, ba *baseapp.BaseApp, header tmproto.Header, msgs []sdk.Msg, + chainID string, accNums, accSeqs []uint64, expSimPass, expPass bool, priv ...cryptotypes.PrivKey, +) (sdk.GasInfo, *sdk.Result, error) { + tx, err := GenSignedMockTx( + txConfig, + msgs, + sdk.Coins{sdk.NewInt64Coin(sdk.DefaultBondDenom, 0)}, + DefaultGenTxGas, + chainID, + accNums, + accSeqs, + priv..., + ) + if err != nil { + return sdk.GasInfo{}, nil, err + } + + txBytes, err := txConfig.TxEncoder()(tx) + if err != nil { + return sdk.GasInfo{}, nil, err + } + + // Must simulate now as CheckTx doesn't run Msgs anymore + _, res, err := ba.Simulate(txBytes) + if expSimPass { + if err != nil { + return sdk.GasInfo{}, nil, err + } + + if res == nil { + return sdk.GasInfo{}, nil, fmt.Errorf("Simulate() returned no result") + } + } else { + if err == nil { + return sdk.GasInfo{}, nil, fmt.Errorf("Simulate() passed but should have failed") + } + + if res != nil { + return sdk.GasInfo{}, nil, fmt.Errorf("Simulate() returned a result") + } + } + + // Simulate a sending a transaction and committing a block + ba.BeginBlock(abci.RequestBeginBlock{Header: header}) + gInfo, res, err := ba.SimDeliver(txConfig.TxEncoder(), tx) + if expPass { + if err != nil { + return gInfo, nil, err + } + + if res == nil { + return gInfo, nil, fmt.Errorf("SimDeliver() returned no result") + } + } else { + if err == nil { + return gInfo, nil, fmt.Errorf("SimDeliver() passed but should have failed") + } + + if res != nil { + return gInfo, nil, fmt.Errorf("SimDeliver() returned a result") + } + } + + ba.EndBlock(abci.RequestEndBlock{}) + ba.Commit() + + return gInfo, res, err +} diff --git a/x/bank/app_test.go b/x/bank/app_test.go index d1e810277edd..f3ae6d7a06d7 100644 --- a/x/bank/app_test.go +++ b/x/bank/app_test.go @@ -9,6 +9,7 @@ import ( "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" "github.com/cosmos/cosmos-sdk/simapp" + simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims" sdk "github.com/cosmos/cosmos-sdk/types" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" "github.com/cosmos/cosmos-sdk/x/bank/testutil" @@ -109,10 +110,10 @@ func TestSendNotEnoughBalance(t *testing.T) { sendMsg := types.NewMsgSend(addr1, addr2, sdk.Coins{sdk.NewInt64Coin("foocoin", 100)}) header := tmproto.Header{Height: app.LastBlockHeight() + 1} txGen := simapp.MakeTestEncodingConfig().TxConfig - _, _, err := simapp.SignCheckDeliver(t, txGen, app.BaseApp, header, []sdk.Msg{sendMsg}, "", []uint64{origAccNum}, []uint64{origSeq}, false, false, priv1) + _, _, err := simtestutil.SignCheckDeliver(txGen, app.BaseApp, header, []sdk.Msg{sendMsg}, "", []uint64{origAccNum}, []uint64{origSeq}, false, false, priv1) require.Error(t, err) - simapp.CheckBalance(t, app, addr1, sdk.Coins{sdk.NewInt64Coin("foocoin", 67)}) + require.True(t, simtestutil.CheckBalance(app.BaseApp, app.BankKeeper, addr1, sdk.Coins{sdk.NewInt64Coin("foocoin", 67)})) res2 := app.AccountKeeper.GetAccount(app.NewContext(true, tmproto.Header{}), addr1) require.NotNil(t, res2) @@ -175,7 +176,7 @@ func TestMsgMultiSendWithAccounts(t *testing.T) { for _, tc := range testCases { header := tmproto.Header{Height: app.LastBlockHeight() + 1} txGen := simapp.MakeTestEncodingConfig().TxConfig - _, _, err := simapp.SignCheckDeliver(t, txGen, app.BaseApp, header, tc.msgs, "", tc.accNums, tc.accSeqs, tc.expSimPass, tc.expPass, tc.privKeys...) + _, _, err := simtestutil.SignCheckDeliver(txGen, app.BaseApp, header, tc.msgs, "", tc.accNums, tc.accSeqs, tc.expSimPass, tc.expPass, tc.privKeys...) if tc.expPass { require.NoError(t, err) } else { @@ -183,7 +184,7 @@ func TestMsgMultiSendWithAccounts(t *testing.T) { } for _, eb := range tc.expectedBalances { - simapp.CheckBalance(t, app, eb.addr, eb.coins) + require.True(t, simtestutil.CheckBalance(app.BaseApp, app.BankKeeper, eb.addr, eb.coins)) } } } @@ -225,11 +226,11 @@ func TestMsgMultiSendMultipleOut(t *testing.T) { for _, tc := range testCases { header := tmproto.Header{Height: app.LastBlockHeight() + 1} txGen := simapp.MakeTestEncodingConfig().TxConfig - _, _, err := simapp.SignCheckDeliver(t, txGen, app.BaseApp, header, tc.msgs, "", tc.accNums, tc.accSeqs, tc.expSimPass, tc.expPass, tc.privKeys...) + _, _, err := simtestutil.SignCheckDeliver(txGen, app.BaseApp, header, tc.msgs, "", tc.accNums, tc.accSeqs, tc.expSimPass, tc.expPass, tc.privKeys...) require.NoError(t, err) for _, eb := range tc.expectedBalances { - simapp.CheckBalance(t, app, eb.addr, eb.coins) + require.True(t, simtestutil.CheckBalance(app.BaseApp, app.BankKeeper, eb.addr, eb.coins)) } } } @@ -277,11 +278,11 @@ func TestMsgMultiSendMultipleInOut(t *testing.T) { for _, tc := range testCases { header := tmproto.Header{Height: app.LastBlockHeight() + 1} txGen := simapp.MakeTestEncodingConfig().TxConfig - _, _, err := simapp.SignCheckDeliver(t, txGen, app.BaseApp, header, tc.msgs, "", tc.accNums, tc.accSeqs, tc.expSimPass, tc.expPass, tc.privKeys...) + _, _, err := simtestutil.SignCheckDeliver(txGen, app.BaseApp, header, tc.msgs, "", tc.accNums, tc.accSeqs, tc.expSimPass, tc.expPass, tc.privKeys...) require.NoError(t, err) for _, eb := range tc.expectedBalances { - simapp.CheckBalance(t, app, eb.addr, eb.coins) + require.True(t, simtestutil.CheckBalance(app.BaseApp, app.BankKeeper, eb.addr, eb.coins)) } } } @@ -329,11 +330,11 @@ func TestMsgMultiSendDependent(t *testing.T) { for _, tc := range testCases { header := tmproto.Header{Height: app.LastBlockHeight() + 1} txGen := simapp.MakeTestEncodingConfig().TxConfig - _, _, err := simapp.SignCheckDeliver(t, txGen, app.BaseApp, header, tc.msgs, "", tc.accNums, tc.accSeqs, tc.expSimPass, tc.expPass, tc.privKeys...) + _, _, err := simtestutil.SignCheckDeliver(txGen, app.BaseApp, header, tc.msgs, "", tc.accNums, tc.accSeqs, tc.expSimPass, tc.expPass, tc.privKeys...) require.NoError(t, err) for _, eb := range tc.expectedBalances { - simapp.CheckBalance(t, app, eb.addr, eb.coins) + require.True(t, simtestutil.CheckBalance(app.BaseApp, app.BankKeeper, eb.addr, eb.coins)) } } } diff --git a/x/slashing/app_test.go b/x/slashing/app_test.go index e9ece2c690a1..9d37a649aadc 100644 --- a/x/slashing/app_test.go +++ b/x/slashing/app_test.go @@ -11,6 +11,7 @@ import ( "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" "github.com/cosmos/cosmos-sdk/simapp" + simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims" sdk "github.com/cosmos/cosmos-sdk/types" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" @@ -58,7 +59,7 @@ func TestSlashingMsgs(t *testing.T) { } app := simapp.SetupWithGenesisAccounts(t, accs, balances...) - simapp.CheckBalance(t, app, addr1, sdk.Coins{genCoin}) + require.True(t, simtestutil.CheckBalance(app.BaseApp, app.BankKeeper, addr1, sdk.Coins{genCoin})) description := stakingtypes.NewDescription("foo_moniker", "", "", "", "") commission := stakingtypes.NewCommissionRates(sdk.ZeroDec(), sdk.ZeroDec(), sdk.ZeroDec()) @@ -70,9 +71,9 @@ func TestSlashingMsgs(t *testing.T) { header := tmproto.Header{Height: app.LastBlockHeight() + 1} txGen := simapp.MakeTestEncodingConfig().TxConfig - _, _, err = simapp.SignCheckDeliver(t, txGen, app.BaseApp, header, []sdk.Msg{createValidatorMsg}, "", []uint64{0}, []uint64{0}, true, true, priv1) + _, _, err = simtestutil.SignCheckDeliver(txGen, app.BaseApp, header, []sdk.Msg{createValidatorMsg}, "", []uint64{0}, []uint64{0}, true, true, priv1) require.NoError(t, err) - simapp.CheckBalance(t, app, addr1, sdk.Coins{genCoin.Sub(bondCoin)}) + require.True(t, simtestutil.CheckBalance(app.BaseApp, app.BankKeeper, addr1, sdk.Coins{genCoin.Sub(bondCoin)})) header = tmproto.Header{Height: app.LastBlockHeight() + 1} app.BeginBlock(abci.RequestBeginBlock{Header: header}) @@ -87,7 +88,7 @@ func TestSlashingMsgs(t *testing.T) { // unjail should fail with unknown validator header = tmproto.Header{Height: app.LastBlockHeight() + 1} - _, res, err := simapp.SignCheckDeliver(t, txGen, app.BaseApp, header, []sdk.Msg{unjailMsg}, "", []uint64{0}, []uint64{1}, false, false, priv1) + _, res, err := simtestutil.SignCheckDeliver(txGen, app.BaseApp, header, []sdk.Msg{unjailMsg}, "", []uint64{0}, []uint64{1}, false, false, priv1) require.Error(t, err) require.Nil(t, res) require.True(t, errors.Is(types.ErrValidatorNotJailed, err)) diff --git a/x/staking/app_test.go b/x/staking/app_test.go index 5a3bd723cb9c..4862bfb96ce4 100644 --- a/x/staking/app_test.go +++ b/x/staking/app_test.go @@ -7,27 +7,31 @@ import ( abci "github.com/tendermint/tendermint/abci/types" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" - "github.com/cosmos/cosmos-sdk/simapp" + "github.com/cosmos/cosmos-sdk/baseapp" + "github.com/cosmos/cosmos-sdk/client" + simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims" sdk "github.com/cosmos/cosmos-sdk/types" - authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" - banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper" + banktestutil "github.com/cosmos/cosmos-sdk/x/bank/testutil" + "github.com/cosmos/cosmos-sdk/x/staking/keeper" + "github.com/cosmos/cosmos-sdk/x/staking/testutil" "github.com/cosmos/cosmos-sdk/x/staking/types" ) -func checkValidator(t *testing.T, app *simapp.SimApp, addr sdk.ValAddress, expFound bool) types.Validator { - ctxCheck := app.BaseApp.NewContext(true, tmproto.Header{}) - validator, found := app.StakingKeeper.GetValidator(ctxCheck, addr) +func checkValidator(t *testing.T, ba *baseapp.BaseApp, stakingKeeper *keeper.Keeper, addr sdk.ValAddress, expFound bool) types.Validator { + ctxCheck := ba.NewContext(true, tmproto.Header{}) + validator, found := stakingKeeper.GetValidator(ctxCheck, addr) require.Equal(t, expFound, found) return validator } func checkDelegation( - t *testing.T, app *simapp.SimApp, delegatorAddr sdk.AccAddress, + t *testing.T, ba *baseapp.BaseApp, stakingKeeper *keeper.Keeper, delegatorAddr sdk.AccAddress, validatorAddr sdk.ValAddress, expFound bool, expShares sdk.Dec, ) { - ctxCheck := app.BaseApp.NewContext(true, tmproto.Header{}) - delegation, found := app.StakingKeeper.GetDelegation(ctxCheck, delegatorAddr, validatorAddr) + ctxCheck := ba.NewContext(true, tmproto.Header{}) + delegation, found := stakingKeeper.GetDelegation(ctxCheck, delegatorAddr, validatorAddr) if expFound { require.True(t, found) require.True(sdk.DecEq(t, expShares, delegation.Shares)) @@ -44,23 +48,26 @@ func TestStakingMsgs(t *testing.T) { genCoin := sdk.NewCoin(sdk.DefaultBondDenom, genTokens) bondCoin := sdk.NewCoin(sdk.DefaultBondDenom, bondTokens) - acc1 := &authtypes.BaseAccount{Address: addr1.String()} - acc2 := &authtypes.BaseAccount{Address: addr2.String()} - accs := authtypes.GenesisAccounts{acc1, acc2} - balances := []banktypes.Balance{ - { - Address: addr1.String(), - Coins: sdk.Coins{genCoin}, - }, - { - Address: addr2.String(), - Coins: sdk.Coins{genCoin}, - }, - } + var ( + txConfig client.TxConfig + bankKeeper bankkeeper.Keeper + stakingKeeper *keeper.Keeper + ) - app := simapp.SetupWithGenesisAccounts(t, accs, balances...) - simapp.CheckBalance(t, app, addr1, sdk.Coins{genCoin}) - simapp.CheckBalance(t, app, addr2, sdk.Coins{genCoin}) + app, err := simtestutil.Setup(testutil.AppConfig, + &txConfig, + &bankKeeper, + &stakingKeeper, + ) + require.NoError(t, err) + + ctx := app.BaseApp.NewContext(false, tmproto.Header{}) + banktestutil.FundAccount(bankKeeper, ctx, addr1, sdk.Coins{genCoin}) + banktestutil.FundAccount(bankKeeper, ctx, addr2, sdk.Coins{genCoin}) + app.Commit() + + require.True(t, simtestutil.CheckBalance(app.BaseApp, bankKeeper, addr1, sdk.Coins{genCoin})) + require.True(t, simtestutil.CheckBalance(app.BaseApp, bankKeeper, addr2, sdk.Coins{genCoin})) // create validator description := types.NewDescription("foo_moniker", "", "", "", "") @@ -70,15 +77,15 @@ func TestStakingMsgs(t *testing.T) { require.NoError(t, err) header := tmproto.Header{Height: app.LastBlockHeight() + 1} - txGen := simapp.MakeTestEncodingConfig().TxConfig - _, _, err = simapp.SignCheckDeliver(t, txGen, app.BaseApp, header, []sdk.Msg{createValidatorMsg}, "", []uint64{0}, []uint64{0}, true, true, priv1) + + _, _, err = simtestutil.SignCheckDeliver(txConfig, app.BaseApp, header, []sdk.Msg{createValidatorMsg}, "", []uint64{0}, []uint64{0}, true, true, priv1) require.NoError(t, err) - simapp.CheckBalance(t, app, addr1, sdk.Coins{genCoin.Sub(bondCoin)}) + require.True(t, simtestutil.CheckBalance(app.BaseApp, bankKeeper, addr1, sdk.Coins{genCoin.Sub(bondCoin)})) header = tmproto.Header{Height: app.LastBlockHeight() + 1} app.BeginBlock(abci.RequestBeginBlock{Header: header}) - validator := checkValidator(t, app, sdk.ValAddress(addr1), true) + validator := checkValidator(t, app.BaseApp, stakingKeeper, sdk.ValAddress(addr1), true) require.Equal(t, sdk.ValAddress(addr1).String(), validator.OperatorAddress) require.Equal(t, types.Bonded, validator.Status) require.True(sdk.IntEq(t, bondTokens, validator.BondedTokens())) @@ -91,32 +98,32 @@ func TestStakingMsgs(t *testing.T) { editValidatorMsg := types.NewMsgEditValidator(sdk.ValAddress(addr1), description, nil, nil) header = tmproto.Header{Height: app.LastBlockHeight() + 1} - _, _, err = simapp.SignCheckDeliver(t, txGen, app.BaseApp, header, []sdk.Msg{editValidatorMsg}, "", []uint64{0}, []uint64{1}, true, true, priv1) + _, _, err = simtestutil.SignCheckDeliver(txConfig, app.BaseApp, header, []sdk.Msg{editValidatorMsg}, "", []uint64{0}, []uint64{1}, true, true, priv1) require.NoError(t, err) - validator = checkValidator(t, app, sdk.ValAddress(addr1), true) + validator = checkValidator(t, app.BaseApp, stakingKeeper, sdk.ValAddress(addr1), true) require.Equal(t, description, validator.Description) // delegate - simapp.CheckBalance(t, app, addr2, sdk.Coins{genCoin}) + require.True(t, simtestutil.CheckBalance(app.BaseApp, bankKeeper, addr2, sdk.Coins{genCoin})) delegateMsg := types.NewMsgDelegate(addr2, sdk.ValAddress(addr1), bondCoin) header = tmproto.Header{Height: app.LastBlockHeight() + 1} - _, _, err = simapp.SignCheckDeliver(t, txGen, app.BaseApp, header, []sdk.Msg{delegateMsg}, "", []uint64{1}, []uint64{0}, true, true, priv2) + _, _, err = simtestutil.SignCheckDeliver(txConfig, app.BaseApp, header, []sdk.Msg{delegateMsg}, "", []uint64{1}, []uint64{0}, true, true, priv2) require.NoError(t, err) - simapp.CheckBalance(t, app, addr2, sdk.Coins{genCoin.Sub(bondCoin)}) - checkDelegation(t, app, addr2, sdk.ValAddress(addr1), true, sdk.NewDecFromInt(bondTokens)) + require.True(t, simtestutil.CheckBalance(app.BaseApp, bankKeeper, addr2, sdk.Coins{genCoin.Sub(bondCoin)})) + checkDelegation(t, app.BaseApp, stakingKeeper, addr2, sdk.ValAddress(addr1), true, sdk.NewDecFromInt(bondTokens)) // begin unbonding beginUnbondingMsg := types.NewMsgUndelegate(addr2, sdk.ValAddress(addr1), bondCoin) header = tmproto.Header{Height: app.LastBlockHeight() + 1} - _, _, err = simapp.SignCheckDeliver(t, txGen, app.BaseApp, header, []sdk.Msg{beginUnbondingMsg}, "", []uint64{1}, []uint64{1}, true, true, priv2) + _, _, err = simtestutil.SignCheckDeliver(txConfig, app.BaseApp, header, []sdk.Msg{beginUnbondingMsg}, "", []uint64{1}, []uint64{1}, true, true, priv2) require.NoError(t, err) // delegation should exist anymore - checkDelegation(t, app, addr2, sdk.ValAddress(addr1), false, sdk.Dec{}) + checkDelegation(t, app.BaseApp, stakingKeeper, addr2, sdk.ValAddress(addr1), false, sdk.Dec{}) // balance should be the same because bonding not yet complete - simapp.CheckBalance(t, app, addr2, sdk.Coins{genCoin.Sub(bondCoin)}) + require.True(t, simtestutil.CheckBalance(app.BaseApp, bankKeeper, addr2, sdk.Coins{genCoin.Sub(bondCoin)})) } diff --git a/x/staking/simulation/operations_test.go b/x/staking/simulation/operations_test.go index 757567d79df9..3b30cb737d48 100644 --- a/x/staking/simulation/operations_test.go +++ b/x/staking/simulation/operations_test.go @@ -1,28 +1,28 @@ package simulation_test import ( - "math/big" "math/rand" "testing" "time" - cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/runtime" - "github.com/cosmos/cosmos-sdk/simapp" simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims" "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" abci "github.com/tendermint/tendermint/abci/types" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" - tmtypes "github.com/tendermint/tendermint/types" - "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" sdk "github.com/cosmos/cosmos-sdk/types" simtypes "github.com/cosmos/cosmos-sdk/types/simulation" - authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper" + bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper" banktestutil "github.com/cosmos/cosmos-sdk/x/bank/testutil" - banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + distributionkeeper "github.com/cosmos/cosmos-sdk/x/distribution/keeper" distrkeeper "github.com/cosmos/cosmos-sdk/x/distribution/keeper" distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types" + mintkeeper "github.com/cosmos/cosmos-sdk/x/mint/keeper" minttypes "github.com/cosmos/cosmos-sdk/x/mint/types" "github.com/cosmos/cosmos-sdk/x/staking/keeper" "github.com/cosmos/cosmos-sdk/x/staking/simulation" @@ -31,19 +31,75 @@ import ( "github.com/cosmos/cosmos-sdk/x/staking/types" ) -// TestWeightedOperations tests the weights of the operations. -func TestWeightedOperations(t *testing.T) { +type SimTestSuite struct { + suite.Suite + + r *rand.Rand + ctx sdk.Context + + app *runtime.App + codec codec.Codec + txConfig client.TxConfig + + accountKeeper authkeeper.AccountKeeper + bankKeeper bankkeeper.Keeper + stakingKeeper *keeper.Keeper + distrKeeper distributionkeeper.Keeper + mintKeeper mintkeeper.Keeper + + accs []simtypes.Account +} + +func (suite *SimTestSuite) SetupTest() { + app, err := simtestutil.Setup( + testutil.AppConfig, + &suite.codec, + &suite.txConfig, + &suite.accountKeeper, + &suite.bankKeeper, + &suite.stakingKeeper, + &suite.mintKeeper, + &suite.distrKeeper, + ) + + suite.Require().NoError(err) + suite.app = app + suite.ctx = app.BaseApp.NewContext(false, tmproto.Header{}) + s := rand.NewSource(1) - r := rand.New(s) - app, ctx, accs := createTestApp(t, false, r, 3) + suite.r = rand.New(s) + suite.accs = simtypes.RandomAccounts(suite.r, 4) - ctx.WithChainID("test-chain") + ctx := app.BaseApp.NewContext(false, tmproto.Header{}) + initAmt := suite.stakingKeeper.TokensFromConsensusPower(ctx, 200) + initCoins := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, initAmt)) + + suite.mintKeeper.SetParams(ctx, minttypes.DefaultParams()) + suite.mintKeeper.SetMinter(ctx, minttypes.DefaultInitialMinter()) + + // add coins to the accounts + for _, account := range suite.accs { + acc := suite.accountKeeper.NewAccountWithAddress(ctx, account.Address) + suite.accountKeeper.SetAccount(ctx, acc) + suite.Require().NoError(banktestutil.FundAccount(suite.bankKeeper, ctx, account.Address, initCoins)) + } +} + +func TestSimTestSuite(t *testing.T) { + suite.Run(t, new(SimTestSuite)) +} + +// TestWeightedOperations tests the weights of the operations. +func (suite *SimTestSuite) TestWeightedOperations() { + suite.ctx.WithChainID("test-chain") - cdc := app.AppCodec() appParams := make(simtypes.AppParams) - weightesOps := simulation.WeightedOperations(appParams, cdc, accountKeeper, - bankKeeper, stakingKeeper, + weightesOps := simulation.WeightedOperations(appParams, + suite.codec, + suite.accountKeeper, + suite.bankKeeper, + suite.stakingKeeper, ) expected := []struct { @@ -60,313 +116,245 @@ func TestWeightedOperations(t *testing.T) { } for i, w := range weightesOps { - operationMsg, _, _ := w.Op()(r, app.BaseApp, ctx, accs, ctx.ChainID()) - // require.NoError(t, err) // TODO check if it should be NoError + operationMsg, _, err := w.Op()(suite.r, suite.app.BaseApp, suite.ctx, suite.accs, suite.ctx.ChainID()) + suite.Require().NoError(err) // the following checks are very much dependent from the ordering of the output given // by WeightedOperations. if the ordering in WeightedOperations changes some tests // will fail - require.Equal(t, expected[i].weight, w.Weight(), "weight should be the same") - require.Equal(t, expected[i].opMsgRoute, operationMsg.Route, "route should be the same") - require.Equal(t, expected[i].opMsgName, operationMsg.Name, "operation Msg name should be the same") + suite.Require().Equal(expected[i].weight, w.Weight(), "weight should be the same") + suite.Require().Equal(expected[i].opMsgRoute, operationMsg.Route, "route should be the same") + suite.Require().Equal(expected[i].opMsgName, operationMsg.Name, "operation Msg name should be the same") } } // TestSimulateMsgCreateValidator tests the normal scenario of a valid message of type TypeMsgCreateValidator. // Abonormal scenarios, where the message are created by an errors are not tested here. -func TestSimulateMsgCreateValidator(t *testing.T) { - s := rand.NewSource(1) - r := rand.New(s) - app, ctx, accounts := createTestApp(t, false, r, 3) +func (suite *SimTestSuite) TestSimulateMsgCreateValidator() { + app, ctx, accounts := suite.app, suite.ctx, suite.accs // begin a new block app.BeginBlock(abci.RequestBeginBlock{Header: tmproto.Header{Height: app.LastBlockHeight() + 1, AppHash: app.LastCommitID().Hash}}) // execute operation - op := simulation.SimulateMsgCreateValidator(accountKeeper, bankKeeper, stakingKeeper) - operationMsg, futureOperations, err := op(r, app.BaseApp, ctx, accounts, "") - require.NoError(t, err) + op := simulation.SimulateMsgCreateValidator(suite.txConfig, suite.accountKeeper, suite.bankKeeper, suite.stakingKeeper) + operationMsg, futureOperations, err := op(suite.r, app.BaseApp, ctx, accounts, "") + suite.Require().NoError(err) var msg types.MsgCreateValidator types.ModuleCdc.UnmarshalJSON(operationMsg.Msg, &msg) - require.True(t, operationMsg.OK) - require.Equal(t, "0.080000000000000000", msg.Commission.MaxChangeRate.String()) - require.Equal(t, "0.080000000000000000", msg.Commission.MaxRate.String()) - require.Equal(t, "0.019527679037870745", msg.Commission.Rate.String()) - require.Equal(t, types.TypeMsgCreateValidator, msg.Type()) - require.Equal(t, []byte{0xa, 0x20, 0x51, 0xde, 0xbd, 0xe8, 0xfa, 0xdf, 0x4e, 0xfc, 0x33, 0xa5, 0x16, 0x94, 0xf6, 0xee, 0xd3, 0x69, 0x7a, 0x7a, 0x1c, 0x2d, 0x50, 0xb6, 0x2, 0xf7, 0x16, 0x4e, 0x66, 0x9f, 0xff, 0x38, 0x91, 0x9b}, msg.Pubkey.Value) - require.Equal(t, "cosmos1ghekyjucln7y67ntx7cf27m9dpuxxemn4c8g4r", msg.DelegatorAddress) - require.Equal(t, "cosmosvaloper1ghekyjucln7y67ntx7cf27m9dpuxxemnsvnaes", msg.ValidatorAddress) - require.Len(t, futureOperations, 0) + suite.Require().True(operationMsg.OK) + suite.Require().Equal("0.080000000000000000", msg.Commission.MaxChangeRate.String()) + suite.Require().Equal("0.080000000000000000", msg.Commission.MaxRate.String()) + suite.Require().Equal("0.019527679037870745", msg.Commission.Rate.String()) + suite.Require().Equal(types.TypeMsgCreateValidator, msg.Type()) + suite.Require().Equal([]byte{0xa, 0x20, 0x51, 0xde, 0xbd, 0xe8, 0xfa, 0xdf, 0x4e, 0xfc, 0x33, 0xa5, 0x16, 0x94, 0xf6, 0xee, 0xd3, 0x69, 0x7a, 0x7a, 0x1c, 0x2d, 0x50, 0xb6, 0x2, 0xf7, 0x16, 0x4e, 0x66, 0x9f, 0xff, 0x38, 0x91, 0x9b}, msg.Pubkey.Value) + suite.Require().Equal("cosmos1ghekyjucln7y67ntx7cf27m9dpuxxemn4c8g4r", msg.DelegatorAddress) + suite.Require().Equal("cosmosvaloper1ghekyjucln7y67ntx7cf27m9dpuxxemnsvnaes", msg.ValidatorAddress) + suite.Require().Len(futureOperations, 0) } // TestSimulateMsgCancelUnbondingDelegation tests the normal scenario of a valid message of type TypeMsgCancelUnbondingDelegation. // Abonormal scenarios, where the message is -func TestSimulateMsgCancelUnbondingDelegation(t *testing.T) { - s := rand.NewSource(1) - r := rand.New(s) - app, ctx, accounts := createTestApp(t, false, r, 3) +func (suite *SimTestSuite) TestSimulateMsgCancelUnbondingDelegation() { + app, ctx, accounts := suite.app, suite.ctx, suite.accs blockTime := time.Now().UTC() ctx = ctx.WithBlockTime(blockTime) - // remove genesis validator account - accounts = accounts[1:] - // setup accounts[0] as validator - validator0 := getTestingValidator0(t, app, ctx, accounts) + validator0 := getTestingValidator0(suite.T(), suite.stakingKeeper, ctx, accounts) // setup delegation - delTokens := stakingKeeper.TokensFromConsensusPower(ctx, 2) + delTokens := suite.stakingKeeper.TokensFromConsensusPower(ctx, 2) validator0, issuedShares := validator0.AddTokensFromDel(delTokens) delegator := accounts[1] delegation := types.NewDelegation(delegator.Address, validator0.GetOperator(), issuedShares) - stakingKeeper.SetDelegation(ctx, delegation) - distrKeeper.SetDelegatorStartingInfo(ctx, validator0.GetOperator(), delegator.Address, distrtypes.NewDelegatorStartingInfo(2, sdk.OneDec(), 200)) + suite.stakingKeeper.SetDelegation(ctx, delegation) + suite.distrKeeper.SetDelegatorStartingInfo(ctx, validator0.GetOperator(), delegator.Address, distrtypes.NewDelegatorStartingInfo(2, sdk.OneDec(), 200)) - setupValidatorRewards(distrKeeper, ctx, validator0.GetOperator()) + setupValidatorRewards(suite.distrKeeper, ctx, validator0.GetOperator()) // unbonding delegation udb := types.NewUnbondingDelegation(delegator.Address, validator0.GetOperator(), app.LastBlockHeight(), blockTime.Add(2*time.Minute), delTokens) - stakingKeeper.SetUnbondingDelegation(ctx, udb) - setupValidatorRewards(distrKeeper, ctx, validator0.GetOperator()) + suite.stakingKeeper.SetUnbondingDelegation(ctx, udb) + setupValidatorRewards(suite.distrKeeper, ctx, validator0.GetOperator()) // begin a new block app.BeginBlock(abci.RequestBeginBlock{Header: tmproto.Header{Height: app.LastBlockHeight() + 1, AppHash: app.LastCommitID().Hash, Time: blockTime}}) // execute operation - op := simulation.SimulateMsgCancelUnbondingDelegate(accountKeeper, bankKeeper, stakingKeeper) + op := simulation.SimulateMsgCancelUnbondingDelegate(suite.txConfig, suite.accountKeeper, suite.bankKeeper, suite.stakingKeeper) accounts = []simtypes.Account{accounts[1]} - operationMsg, futureOperations, err := op(r, app.BaseApp, ctx, accounts, "") - require.NoError(t, err) + operationMsg, futureOperations, err := op(suite.r, app.BaseApp, ctx, accounts, "") + suite.Require().NoError(err) var msg types.MsgCancelUnbondingDelegation types.ModuleCdc.UnmarshalJSON(operationMsg.Msg, &msg) - require.True(t, operationMsg.OK) - require.Equal(t, types.TypeMsgCancelUnbondingDelegation, msg.Type()) - require.Equal(t, delegator.Address.String(), msg.DelegatorAddress) - require.Equal(t, validator0.GetOperator().String(), msg.ValidatorAddress) - require.Len(t, futureOperations, 0) + suite.Require().True(operationMsg.OK) + suite.Require().Equal(types.TypeMsgCancelUnbondingDelegation, msg.Type()) + suite.Require().Equal(delegator.Address.String(), msg.DelegatorAddress) + suite.Require().Equal(validator0.GetOperator().String(), msg.ValidatorAddress) + suite.Require().Len(futureOperations, 0) } // TestSimulateMsgEditValidator tests the normal scenario of a valid message of type TypeMsgEditValidator. // Abonormal scenarios, where the message is created by an errors are not tested here. -func TestSimulateMsgEditValidator(t *testing.T) { - s := rand.NewSource(1) - r := rand.New(s) - app, ctx, accounts := createTestApp(t, false, r, 3) +func (suite *SimTestSuite) TestSimulateMsgEditValidator() { + app, ctx, accounts := suite.app, suite.ctx, suite.accs + blockTime := time.Now().UTC() ctx = ctx.WithBlockTime(blockTime) - // remove genesis validator account - accounts = accounts[1:] - // setup accounts[0] as validator - _ = getTestingValidator0(t, app, ctx, accounts) + _ = getTestingValidator0(suite.T(), suite.stakingKeeper, ctx, accounts) // begin a new block app.BeginBlock(abci.RequestBeginBlock{Header: tmproto.Header{Height: app.LastBlockHeight() + 1, AppHash: app.LastCommitID().Hash, Time: blockTime}}) // execute operation - op := simulation.SimulateMsgEditValidator(accountKeeper, bankKeeper, stakingKeeper) - operationMsg, futureOperations, err := op(r, app.BaseApp, ctx, accounts, "") - require.NoError(t, err) + op := simulation.SimulateMsgEditValidator(suite.txConfig, suite.accountKeeper, suite.bankKeeper, suite.stakingKeeper) + operationMsg, futureOperations, err := op(suite.r, app.BaseApp, ctx, accounts, "") + suite.Require().NoError(err) var msg types.MsgEditValidator types.ModuleCdc.UnmarshalJSON(operationMsg.Msg, &msg) - require.True(t, operationMsg.OK) - require.Equal(t, "0.280623462081924936", msg.CommissionRate.String()) - require.Equal(t, "xKGLwQvuyN", msg.Description.Moniker) - require.Equal(t, "SlcxgdXhhu", msg.Description.Identity) - require.Equal(t, "WeLrQKjLxz", msg.Description.Website) - require.Equal(t, "rBqDOTtGTO", msg.Description.SecurityContact) - require.Equal(t, types.TypeMsgEditValidator, msg.Type()) - require.Equal(t, "cosmosvaloper1p8wcgrjr4pjju90xg6u9cgq55dxwq8j7epjs3u", msg.ValidatorAddress) - require.Len(t, futureOperations, 0) + suite.Require().True(operationMsg.OK) + suite.Require().Equal("0.280623462081924936", msg.CommissionRate.String()) + suite.Require().Equal("xKGLwQvuyN", msg.Description.Moniker) + suite.Require().Equal("SlcxgdXhhu", msg.Description.Identity) + suite.Require().Equal("WeLrQKjLxz", msg.Description.Website) + suite.Require().Equal("rBqDOTtGTO", msg.Description.SecurityContact) + suite.Require().Equal(types.TypeMsgEditValidator, msg.Type()) + suite.Require().Equal("cosmosvaloper1tnh2q55v8wyygtt9srz5safamzdengsn9dsd7z", msg.ValidatorAddress) + suite.Require().Len(futureOperations, 0) } // TestSimulateMsgDelegate tests the normal scenario of a valid message of type TypeMsgDelegate. // Abonormal scenarios, where the message is created by an errors are not tested here. -func TestSimulateMsgDelegate(t *testing.T) { - s := rand.NewSource(1) - r := rand.New(s) - app, ctx, accounts := createTestApp(t, false, r, 3) +func (suite *SimTestSuite) TestSimulateMsgDelegate() { + app, ctx, accounts := suite.app, suite.ctx, suite.accs blockTime := time.Now().UTC() ctx = ctx.WithBlockTime(blockTime) // execute operation - op := simulation.SimulateMsgDelegate(accountKeeper, bankKeeper, stakingKeeper) - operationMsg, futureOperations, err := op(r, app.BaseApp, ctx, accounts, "") - require.NoError(t, err) + op := simulation.SimulateMsgDelegate(suite.txConfig, suite.accountKeeper, suite.bankKeeper, suite.stakingKeeper) + operationMsg, futureOperations, err := op(suite.r, app.BaseApp, ctx, accounts, "") + suite.Require().NoError(err) var msg types.MsgDelegate types.ModuleCdc.UnmarshalJSON(operationMsg.Msg, &msg) - require.True(t, operationMsg.OK) - require.Equal(t, "cosmos1ghekyjucln7y67ntx7cf27m9dpuxxemn4c8g4r", msg.DelegatorAddress) - require.Equal(t, "98100858108421259236", msg.Amount.Amount.String()) - require.Equal(t, "stake", msg.Amount.Denom) - require.Equal(t, types.TypeMsgDelegate, msg.Type()) - require.Equal(t, "cosmosvaloper1tnh2q55v8wyygtt9srz5safamzdengsn9dsd7z", msg.ValidatorAddress) - require.Len(t, futureOperations, 0) + suite.Require().True(operationMsg.OK) + suite.Require().Equal("cosmos1ghekyjucln7y67ntx7cf27m9dpuxxemn4c8g4r", msg.DelegatorAddress) + suite.Require().Equal("98100858108421259236", msg.Amount.Amount.String()) + suite.Require().Equal("stake", msg.Amount.Denom) + suite.Require().Equal(types.TypeMsgDelegate, msg.Type()) + suite.Require().Equal("cosmosvaloper1msauaqegzvluk6wsypnrlckkr70r57aga6ldyh", msg.ValidatorAddress) + suite.Require().Len(futureOperations, 0) } // TestSimulateMsgUndelegate tests the normal scenario of a valid message of type TypeMsgUndelegate. // Abonormal scenarios, where the message is created by an errors are not tested here. -func TestSimulateMsgUndelegate(t *testing.T) { - s := rand.NewSource(1) - r := rand.New(s) - app, ctx, accounts := createTestApp(t, false, r, 3) +func (suite *SimTestSuite) TestSimulateMsgUndelegate() { + app, ctx, accounts := suite.app, suite.ctx, suite.accs blockTime := time.Now().UTC() ctx = ctx.WithBlockTime(blockTime) - // remove genesis validator account - accounts = accounts[1:] - // setup accounts[0] as validator - validator0 := getTestingValidator0(t, app, ctx, accounts) + validator0 := getTestingValidator0(suite.T(), suite.stakingKeeper, ctx, accounts) // setup delegation - delTokens := stakingKeeper.TokensFromConsensusPower(ctx, 2) + delTokens := suite.stakingKeeper.TokensFromConsensusPower(ctx, 2) validator0, issuedShares := validator0.AddTokensFromDel(delTokens) delegator := accounts[1] delegation := types.NewDelegation(delegator.Address, validator0.GetOperator(), issuedShares) - stakingKeeper.SetDelegation(ctx, delegation) - distrKeeper.SetDelegatorStartingInfo(ctx, validator0.GetOperator(), delegator.Address, distrtypes.NewDelegatorStartingInfo(2, sdk.OneDec(), 200)) + suite.stakingKeeper.SetDelegation(ctx, delegation) + suite.distrKeeper.SetDelegatorStartingInfo(ctx, validator0.GetOperator(), delegator.Address, distrtypes.NewDelegatorStartingInfo(2, sdk.OneDec(), 200)) - setupValidatorRewards(app, ctx, validator0.GetOperator()) + setupValidatorRewards(suite.distrKeeper, ctx, validator0.GetOperator()) // begin a new block app.BeginBlock(abci.RequestBeginBlock{Header: tmproto.Header{Height: app.LastBlockHeight() + 1, AppHash: app.LastCommitID().Hash, Time: blockTime}}) // execute operation - op := simulation.SimulateMsgUndelegate(accountKeeper, bankKeeper, stakingKeeper) - operationMsg, futureOperations, err := op(r, app.BaseApp, ctx, accounts, "") - require.NoError(t, err) + op := simulation.SimulateMsgUndelegate(suite.txConfig, suite.accountKeeper, suite.bankKeeper, suite.stakingKeeper) + operationMsg, futureOperations, err := op(suite.r, app.BaseApp, ctx, accounts, "") + suite.Require().NoError(err) var msg types.MsgUndelegate types.ModuleCdc.UnmarshalJSON(operationMsg.Msg, &msg) - require.True(t, operationMsg.OK) - require.Equal(t, "cosmos1ghekyjucln7y67ntx7cf27m9dpuxxemn4c8g4r", msg.DelegatorAddress) - require.Equal(t, "280623462081924937", msg.Amount.Amount.String()) - require.Equal(t, "stake", msg.Amount.Denom) - require.Equal(t, types.TypeMsgUndelegate, msg.Type()) - require.Equal(t, "cosmosvaloper1p8wcgrjr4pjju90xg6u9cgq55dxwq8j7epjs3u", msg.ValidatorAddress) - require.Len(t, futureOperations, 0) + suite.Require().True(operationMsg.OK) + suite.Require().Equal("cosmos1ghekyjucln7y67ntx7cf27m9dpuxxemn4c8g4r", msg.DelegatorAddress) + suite.Require().Equal("280623462081924937", msg.Amount.Amount.String()) + suite.Require().Equal("stake", msg.Amount.Denom) + suite.Require().Equal(types.TypeMsgUndelegate, msg.Type()) + suite.Require().Equal("cosmosvaloper1p8wcgrjr4pjju90xg6u9cgq55dxwq8j7epjs3u", msg.ValidatorAddress) + suite.Require().Len(futureOperations, 0) } // TestSimulateMsgBeginRedelegate tests the normal scenario of a valid message of type TypeMsgBeginRedelegate. // Abonormal scenarios, where the message is created by an errors, are not tested here. -func TestSimulateMsgBeginRedelegate(t *testing.T) { - s := rand.NewSource(12) - r := rand.New(s) - app, ctx, accounts := createTestApp(t, false, r, 4) +func (suite *SimTestSuite) TestSimulateMsgBeginRedelegate() { + app, ctx, accounts := suite.app, suite.ctx, suite.accs blockTime := time.Now().UTC() ctx = ctx.WithBlockTime(blockTime) - // remove genesis validator account - accounts = accounts[1:] - // setup accounts[0] as validator0 and accounts[1] as validator1 - validator0 := getTestingValidator0(t, stakingKeeper, ctx, accounts) - validator1 := getTestingValidator1(t, stakingKeeper, ctx, accounts) + validator0 := getTestingValidator0(suite.T(), suite.stakingKeeper, ctx, accounts) + validator1 := getTestingValidator1(suite.T(), suite.stakingKeeper, ctx, accounts) - delTokens := stakingKeeper.TokensFromConsensusPower(ctx, 2) + delTokens := suite.stakingKeeper.TokensFromConsensusPower(ctx, 2) validator0, issuedShares := validator0.AddTokensFromDel(delTokens) // setup accounts[2] as delegator delegator := accounts[2] delegation := types.NewDelegation(delegator.Address, validator1.GetOperator(), issuedShares) - stakingKeeper.SetDelegation(ctx, delegation) - distrKeeper.SetDelegatorStartingInfo(ctx, validator1.GetOperator(), delegator.Address, distrtypes.NewDelegatorStartingInfo(2, sdk.OneDec(), 200)) + suite.stakingKeeper.SetDelegation(ctx, delegation) + suite.distrKeeper.SetDelegatorStartingInfo(ctx, validator1.GetOperator(), delegator.Address, distrtypes.NewDelegatorStartingInfo(2, sdk.OneDec(), 200)) - setupValidatorRewards(distrKeeper, ctx, validator0.GetOperator()) - setupValidatorRewards(distrKeeper, ctx, validator1.GetOperator()) + setupValidatorRewards(suite.distrKeeper, ctx, validator0.GetOperator()) + setupValidatorRewards(suite.distrKeeper, ctx, validator1.GetOperator()) // begin a new block app.BeginBlock(abci.RequestBeginBlock{Header: tmproto.Header{Height: app.LastBlockHeight() + 1, AppHash: app.LastCommitID().Hash, Time: blockTime}}) // execute operation - op := simulation.SimulateMsgBeginRedelegate(accountKeeper, bankKeeper, stakingKeeper) - operationMsg, futureOperations, err := op(r, app.BaseApp, ctx, accounts, "") - require.NoError(t, err) + op := simulation.SimulateMsgBeginRedelegate(suite.txConfig, suite.accountKeeper, suite.bankKeeper, suite.stakingKeeper) + operationMsg, futureOperations, err := op(suite.r, app.BaseApp, ctx, accounts, "") + suite.Require().NoError(err) var msg types.MsgBeginRedelegate types.ModuleCdc.UnmarshalJSON(operationMsg.Msg, &msg) - require.True(t, operationMsg.OK) - require.Equal(t, "cosmos1092v0qgulpejj8y8hs6dmlw82x9gv8f7jfc7jl", msg.DelegatorAddress) - require.Equal(t, "1883752832348281252", msg.Amount.Amount.String()) - require.Equal(t, "stake", msg.Amount.Denom) - require.Equal(t, types.TypeMsgBeginRedelegate, msg.Type()) - require.Equal(t, "cosmosvaloper1gnkw3uqzflagcqn6ekjwpjanlne928qhruemah", msg.ValidatorDstAddress) - require.Equal(t, "cosmosvaloper1kk653svg7ksj9fmu85x9ygj4jzwlyrgs89nnn2", msg.ValidatorSrcAddress) - require.Len(t, futureOperations, 0) -} - -// returns context and an app with updated mint keeper -func createTestApp(t *testing.T, isCheckTx bool, r *rand.Rand, n int) (*runtime.App, sdk.Context, []simtypes.Account) { - sdk.DefaultPowerReduction = sdk.NewIntFromBigInt(new(big.Int).Exp(big.NewInt(10), big.NewInt(18), nil)) - - accounts := simtypes.RandomAccounts(r, n) - // create validator set with single validator - account := accounts[0] - tmPk, err := cryptocodec.ToTmPubKeyInterface(account.PubKey) - require.NoError(t, err) - validator := tmtypes.NewValidator(tmPk, 1) - - valSet := tmtypes.NewValidatorSet([]*tmtypes.Validator{validator}) - - // generate genesis account - senderPrivKey := secp256k1.GenPrivKey() - acc := authtypes.NewBaseAccount(senderPrivKey.PubKey().Address().Bytes(), senderPrivKey.PubKey(), 0, 0) - balance := banktypes.Balance{ - Address: acc.GetAddress().String(), - Coins: sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100000000000000))), - } - - app := simapp.SetupWithGenesisValSet(t, valSet, []authtypes.GenesisAccount{acc}, balance) - - app, err = simtestutil.SetupAtGenesis(testutil.AppConfig) - - ctx := app.BaseApp.NewContext(isCheckTx, tmproto.Header{}) - app.MintKeeper.SetParams(ctx, minttypes.DefaultParams()) - app.MintKeeper.SetMinter(ctx, minttypes.DefaultInitialMinter()) - - initAmt := stakingKeeper.TokensFromConsensusPower(ctx, 200) - initCoins := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, initAmt)) - - // remove genesis validator account - accs := accounts[1:] - - // add coins to the accounts - for _, account := range accs { - acc := accountKeeper.NewAccountWithAddress(ctx, account.Address) - accountKeeper.SetAccount(ctx, acc) - require.NoError(t, banktestutil.FundAccount(bankKeeper, ctx, account.Address, initCoins)) - } - - return app, ctx, accounts + suite.Require().True(operationMsg.OK) + suite.Require().Equal("cosmos1092v0qgulpejj8y8hs6dmlw82x9gv8f7jfc7jl", msg.DelegatorAddress) + suite.Require().Equal("1883752832348281252", msg.Amount.Amount.String()) + suite.Require().Equal("stake", msg.Amount.Denom) + suite.Require().Equal(types.TypeMsgBeginRedelegate, msg.Type()) + suite.Require().Equal("cosmosvaloper1gnkw3uqzflagcqn6ekjwpjanlne928qhruemah", msg.ValidatorDstAddress) + suite.Require().Equal("cosmosvaloper1kk653svg7ksj9fmu85x9ygj4jzwlyrgs89nnn2", msg.ValidatorSrcAddress) + suite.Require().Len(futureOperations, 0) } -func getTestingValidator0(t *testing.T, stakingKeeper keeper.Keeper, ctx sdk.Context, accounts []simtypes.Account) types.Validator { +func getTestingValidator0(t *testing.T, stakingKeeper *keeper.Keeper, ctx sdk.Context, accounts []simtypes.Account) types.Validator { commission0 := types.NewCommission(sdk.ZeroDec(), sdk.OneDec(), sdk.OneDec()) return getTestingValidator(t, stakingKeeper, ctx, accounts, commission0, 0) } -func getTestingValidator1(t *testing.T, stakingKeeper keeper.Keeper, ctx sdk.Context, accounts []simtypes.Account) types.Validator { +func getTestingValidator1(t *testing.T, stakingKeeper *keeper.Keeper, ctx sdk.Context, accounts []simtypes.Account) types.Validator { commission1 := types.NewCommission(sdk.ZeroDec(), sdk.ZeroDec(), sdk.ZeroDec()) return getTestingValidator(t, stakingKeeper, ctx, accounts, commission1, 1) } -func getTestingValidator(t *testing.T, stakingKeeper keeper.Keeper, ctx sdk.Context, accounts []simtypes.Account, commission types.Commission, n int) types.Validator { +func getTestingValidator(t *testing.T, stakingKeeper *keeper.Keeper, ctx sdk.Context, accounts []simtypes.Account, commission types.Commission, n int) types.Validator { account := accounts[n] valPubKey := account.PubKey valAddr := sdk.ValAddress(account.PubKey.Address().Bytes()) diff --git a/x/staking/testutil/app.yaml b/x/staking/testutil/app.yaml index cf0fd2042a5b..3ad1851354cc 100644 --- a/x/staking/testutil/app.yaml +++ b/x/staking/testutil/app.yaml @@ -5,9 +5,9 @@ modules: app_name: StakingApp - begin_blockers: [mint, staking, auth, bank, genutil, params] - end_blockers: [staking, auth, bank, mint, genutil, params] - init_genesis: [auth, bank, staking, mint, genutil, params] + begin_blockers: [mint, distribution, staking, auth, bank, genutil, params] + end_blockers: [staking, auth, bank, distribution, mint, genutil, params] + init_genesis: [auth, bank, distribution, staking, mint, genutil, params] - name: auth config: @@ -15,6 +15,7 @@ modules: bech32_prefix: cosmos module_account_permissions: - account: fee_collector + - account: distribution - account: mint permissions: [minter] - account: bonded_tokens_pool @@ -45,3 +46,7 @@ modules: - name: mint config: "@type": cosmos.mint.module.v1.Module + + - name: distribution + config: + "@type": cosmos.distribution.module.v1.Module diff --git a/x/staking/testutil/app_config.go b/x/staking/testutil/app_config.go index 5e01e53cb496..c3d70daa5dbc 100644 --- a/x/staking/testutil/app_config.go +++ b/x/staking/testutil/app_config.go @@ -7,6 +7,7 @@ import ( _ "github.com/cosmos/cosmos-sdk/x/auth" _ "github.com/cosmos/cosmos-sdk/x/auth/tx/module" _ "github.com/cosmos/cosmos-sdk/x/bank" + _ "github.com/cosmos/cosmos-sdk/x/distribution" _ "github.com/cosmos/cosmos-sdk/x/genutil" _ "github.com/cosmos/cosmos-sdk/x/mint" _ "github.com/cosmos/cosmos-sdk/x/params"