github.com/cosmos/cosmos-sdk@v0.50.10/x/gov/simulation/operations_test.go (about) 1 package simulation_test 2 3 import ( 4 "fmt" 5 "math/rand" 6 "testing" 7 "time" 8 9 abci "github.com/cometbft/cometbft/abci/types" 10 "github.com/cosmos/gogoproto/proto" 11 "github.com/stretchr/testify/require" 12 13 "cosmossdk.io/depinject" 14 "cosmossdk.io/log" 15 16 "github.com/cosmos/cosmos-sdk/client" 17 "github.com/cosmos/cosmos-sdk/runtime" 18 "github.com/cosmos/cosmos-sdk/testutil/configurator" 19 simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims" 20 sdk "github.com/cosmos/cosmos-sdk/types" 21 simtypes "github.com/cosmos/cosmos-sdk/types/simulation" 22 _ "github.com/cosmos/cosmos-sdk/x/auth" 23 authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper" 24 _ "github.com/cosmos/cosmos-sdk/x/auth/tx/config" 25 _ "github.com/cosmos/cosmos-sdk/x/bank" 26 bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper" 27 "github.com/cosmos/cosmos-sdk/x/bank/testutil" 28 _ "github.com/cosmos/cosmos-sdk/x/consensus" 29 _ "github.com/cosmos/cosmos-sdk/x/distribution" 30 dk "github.com/cosmos/cosmos-sdk/x/distribution/keeper" 31 _ "github.com/cosmos/cosmos-sdk/x/gov" 32 "github.com/cosmos/cosmos-sdk/x/gov/keeper" 33 "github.com/cosmos/cosmos-sdk/x/gov/simulation" 34 "github.com/cosmos/cosmos-sdk/x/gov/types" 35 v1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1" 36 "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1" 37 _ "github.com/cosmos/cosmos-sdk/x/params" 38 _ "github.com/cosmos/cosmos-sdk/x/staking" 39 stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper" 40 ) 41 42 var ( 43 _ simtypes.WeightedProposalMsg = MockWeightedProposals{} 44 _ simtypes.WeightedProposalContent = MockWeightedProposals{} //nolint:staticcheck // testing legacy code path 45 ) 46 47 type MockWeightedProposals struct { 48 n int 49 } 50 51 func (m MockWeightedProposals) AppParamsKey() string { 52 return fmt.Sprintf("AppParamsKey-%d", m.n) 53 } 54 55 func (m MockWeightedProposals) DefaultWeight() int { 56 return m.n 57 } 58 59 func (m MockWeightedProposals) MsgSimulatorFn() simtypes.MsgSimulatorFn { 60 return func(r *rand.Rand, _ sdk.Context, _ []simtypes.Account) sdk.Msg { 61 return nil 62 } 63 } 64 65 func (m MockWeightedProposals) ContentSimulatorFn() simtypes.ContentSimulatorFn { //nolint:staticcheck // testing legacy code path 66 return func(r *rand.Rand, _ sdk.Context, _ []simtypes.Account) simtypes.Content { //nolint:staticcheck // testing legacy code path 67 return v1beta1.NewTextProposal( 68 fmt.Sprintf("title-%d: %s", m.n, simtypes.RandStringOfLength(r, 100)), 69 fmt.Sprintf("description-%d: %s", m.n, simtypes.RandStringOfLength(r, 4000)), 70 ) 71 } 72 } 73 74 func mockWeightedProposalMsg(n int) []simtypes.WeightedProposalMsg { 75 wpc := make([]simtypes.WeightedProposalMsg, n) 76 for i := 0; i < n; i++ { 77 wpc[i] = MockWeightedProposals{i} 78 } 79 return wpc 80 } 81 82 func mockWeightedLegacyProposalContent(n int) []simtypes.WeightedProposalContent { //nolint:staticcheck // testing legacy code path 83 wpc := make([]simtypes.WeightedProposalContent, n) //nolint:staticcheck // testing legacy code path 84 for i := 0; i < n; i++ { 85 wpc[i] = MockWeightedProposals{i} 86 } 87 return wpc 88 } 89 90 // TestWeightedOperations tests the weights of the operations. 91 func TestWeightedOperations(t *testing.T) { 92 suite, ctx := createTestSuite(t, false) 93 app := suite.App 94 ctx.WithChainID("test-chain") 95 appParams := make(simtypes.AppParams) 96 97 weightesOps := simulation.WeightedOperations(appParams, suite.TxConfig, suite.AccountKeeper, 98 suite.BankKeeper, suite.GovKeeper, mockWeightedProposalMsg(3), mockWeightedLegacyProposalContent(1), 99 ) 100 101 // setup 3 accounts 102 s := rand.NewSource(1) 103 r := rand.New(s) 104 accs := getTestingAccounts(t, r, suite.AccountKeeper, suite.BankKeeper, suite.StakingKeeper, ctx, 3) 105 106 expected := []struct { 107 weight int 108 opMsgRoute string 109 opMsgName string 110 }{ 111 {simulation.DefaultWeightMsgDeposit, types.ModuleName, simulation.TypeMsgDeposit}, 112 {simulation.DefaultWeightMsgVote, types.ModuleName, simulation.TypeMsgVote}, 113 {simulation.DefaultWeightMsgVoteWeighted, types.ModuleName, simulation.TypeMsgVoteWeighted}, 114 {simulation.DefaultWeightMsgCancelProposal, types.ModuleName, simulation.TypeMsgCancelProposal}, 115 {0, types.ModuleName, simulation.TypeMsgSubmitProposal}, 116 {1, types.ModuleName, simulation.TypeMsgSubmitProposal}, 117 {2, types.ModuleName, simulation.TypeMsgSubmitProposal}, 118 {0, types.ModuleName, simulation.TypeMsgSubmitProposal}, 119 } 120 121 require.Equal(t, len(weightesOps), len(expected), "number of operations should be the same") 122 for i, w := range weightesOps { 123 operationMsg, _, err := w.Op()(r, app.BaseApp, ctx, accs, ctx.ChainID()) 124 require.NoError(t, err) 125 126 // the following checks are very much dependent from the ordering of the output given 127 // by WeightedOperations. if the ordering in WeightedOperations changes some tests 128 // will fail 129 require.Equal(t, expected[i].weight, w.Weight(), "weight should be the same") 130 require.Equal(t, expected[i].opMsgRoute, operationMsg.Route, "route should be the same") 131 require.Equal(t, expected[i].opMsgName, operationMsg.Name, "operation Msg name should be the same") 132 } 133 } 134 135 // TestSimulateMsgSubmitProposal tests the normal scenario of a valid message of type TypeMsgSubmitProposal. 136 // Abnormal scenarios, where errors occur, are not tested here. 137 func TestSimulateMsgSubmitProposal(t *testing.T) { 138 suite, ctx := createTestSuite(t, false) 139 app := suite.App 140 141 // setup 3 accounts 142 s := rand.NewSource(1) 143 r := rand.New(s) 144 accounts := getTestingAccounts(t, r, suite.AccountKeeper, suite.BankKeeper, suite.StakingKeeper, ctx, 3) 145 146 app.FinalizeBlock(&abci.RequestFinalizeBlock{ 147 Height: app.LastBlockHeight() + 1, 148 Hash: app.LastCommitID().Hash, 149 }) 150 151 // execute operation 152 op := simulation.SimulateMsgSubmitProposal(suite.TxConfig, suite.AccountKeeper, suite.BankKeeper, suite.GovKeeper, MockWeightedProposals{3}.MsgSimulatorFn()) 153 operationMsg, _, err := op(r, app.BaseApp, ctx, accounts, "") 154 require.NoError(t, err) 155 156 var msg v1.MsgSubmitProposal 157 err = proto.Unmarshal(operationMsg.Msg, &msg) 158 require.NoError(t, err) 159 require.True(t, operationMsg.OK) 160 require.Equal(t, "cosmos1ghekyjucln7y67ntx7cf27m9dpuxxemn4c8g4r", msg.Proposer) 161 require.NotEqual(t, len(msg.InitialDeposit), 0) 162 require.Equal(t, "47841094stake", msg.InitialDeposit[0].String()) 163 require.Equal(t, simulation.TypeMsgSubmitProposal, sdk.MsgTypeURL(&msg)) 164 } 165 166 // TestSimulateMsgSubmitProposal tests the normal scenario of a valid message of type TypeMsgSubmitProposal. 167 // Abnormal scenarios, where errors occur, are not tested here. 168 func TestSimulateMsgSubmitLegacyProposal(t *testing.T) { 169 suite, ctx := createTestSuite(t, false) 170 app := suite.App 171 172 // setup 3 accounts 173 s := rand.NewSource(1) 174 r := rand.New(s) 175 accounts := getTestingAccounts(t, r, suite.AccountKeeper, suite.BankKeeper, suite.StakingKeeper, ctx, 3) 176 177 app.FinalizeBlock(&abci.RequestFinalizeBlock{ 178 Height: app.LastBlockHeight() + 1, 179 Hash: app.LastCommitID().Hash, 180 }) 181 182 // execute operation 183 op := simulation.SimulateMsgSubmitLegacyProposal(suite.TxConfig, suite.AccountKeeper, suite.BankKeeper, suite.GovKeeper, MockWeightedProposals{3}.ContentSimulatorFn()) 184 operationMsg, _, err := op(r, app.BaseApp, ctx, accounts, "") 185 require.NoError(t, err) 186 187 var msg v1.MsgSubmitProposal 188 err = proto.Unmarshal(operationMsg.Msg, &msg) 189 require.NoError(t, err) 190 var msgLegacyContent v1.MsgExecLegacyContent 191 err = proto.Unmarshal(msg.Messages[0].Value, &msgLegacyContent) 192 require.NoError(t, err) 193 var textProposal v1beta1.TextProposal 194 err = proto.Unmarshal(msgLegacyContent.Content.Value, &textProposal) 195 require.NoError(t, err) 196 197 require.True(t, operationMsg.OK) 198 require.Equal(t, "cosmos1p8wcgrjr4pjju90xg6u9cgq55dxwq8j7u4x9a0", msg.Proposer) 199 require.NotEqual(t, len(msg.InitialDeposit), 0) 200 require.Equal(t, "25166256stake", msg.InitialDeposit[0].String()) 201 require.Equal(t, "title-3: ZBSpYuLyYggwexjxusrBqDOTtGTOWeLrQKjLxzIivHSlcxgdXhhuTSkuxKGLwQvuyNhYFmBZHeAerqyNEUzXPFGkqEGqiQWIXnku", 202 textProposal.GetTitle()) 203 require.Equal(t, "description-3: NJWzHdBNpAXKJPHWQdrGYcAHSctgVlqwqHoLfHsXUdStwfefwzqLuKEhmMyYLdbZrcPgYqjNHxPexsruwEGStAneKbWkQDDIlCWBLSiAASNhZqNFlPtfqPJoxKsgMdzjWqLWdqKQuJqWPMvwPQWZUtVMOTMYKJbfdlZsjdsomuScvDmbDkgRualsxDvRJuCAmPOXitIbcyWsKGSdrEunFAOdmXnsuyFVgJqEjbklvmwrUlsxjRSfKZxGcpayDdgoFcnVSutxjRgOSFzPwidAjubMncNweqpbxhXGchpZUxuFDOtpnhNUycJICRYqsPhPSCjPTWZFLkstHWJxvdPEAyEIxXgLwbNOjrgzmaujiBABBIXvcXpLrbcEWNNQsbjvgJFgJkflpRohHUutvnaUqoopuKjTDaemDeSdqbnOzcfJpcTuAQtZoiLZOoAIlboFDAeGmSNwkvObPRvRWQgWkGkxwtPauYgdkmypLjbqhlHJIQTntgWjXwZdOyYEdQRRLfMSdnxqppqUofqLbLQDUjwKVKfZJUJQPsWIPwIVaSTrmKskoAhvmZyJgeRpkaTfGgrJzAigcxtfshmiDCFkuiluqtMOkidknnTBtumyJYlIsWLnCQclqdVmikUoMOPdPWwYbJxXyqUVicNxFxyqJTenNblyyKSdlCbiXxUiYUiMwXZASYfvMDPFgxniSjWaZTjHkqlJvtBsXqwPpyVxnJVGFWhfSxgOcduoxkiopJvFjMmFabrGYeVtTXLhxVUEiGwYUvndjFGzDVntUvibiyZhfMQdMhgsiuysLMiePBNXifRLMsSmXPkwlPloUbJveCvUlaalhZHuvdkCnkSHbMbmOnrfEGPwQiACiPlnihiaOdbjPqPiTXaHDoJXjSlZmltGqNHHNrcKdlFSCdmVOuvDcBLdSklyGJmcLTbSFtALdGlPkqqecJrpLCXNPWefoTJNgEJlyMEPneVaxxduAAEqQpHWZodWyRkDAxzyMnFMcjSVqeRXLqsNyNtQBbuRvunZflWSbbvXXdkyLikYqutQhLPONXbvhcQZJPSWnOulqQaXmbfFxAkqfYeseSHOQidHwbcsOaMnSrrmGjjRmEMQNuknupMxJiIeVjmgZvbmjPIQTEhQFULQLBMPrxcFPvBinaOPYWGvYGRKxLZdwamfRQQFngcdSlvwjfaPbURasIsGJVHtcEAxnIIrhSriiXLOlbEBLXFElXJFGxHJczRBIxAuPKtBisjKBwfzZFagdNmjdwIRvwzLkFKWRTDPxJCmpzHUcrPiiXXHnOIlqNVoGSXZewdnCRhuxeYGPVTfrNTQNOxZmxInOazUYNTNDgzsxlgiVEHPKMfbesvPHUqpNkUqbzeuzfdrsuLDpKHMUbBMKczKKWOdYoIXoPYtEjfOnlQLoGnbQUCuERdEFaptwnsHzTJDsuZkKtzMpFaZobynZdzNydEeJJHDYaQcwUxcqvwfWwNUsCiLvkZQiSfzAHftYgAmVsXgtmcYgTqJIawstRYJrZdSxlfRiqTufgEQVambeZZmaAyRQbcmdjVUZZCgqDrSeltJGXPMgZnGDZqISrGDOClxXCxMjmKqEPwKHoOfOeyGmqWqihqjINXLqnyTesZePQRqaWDQNqpLgNrAUKulklmckTijUltQKuWQDwpLmDyxLppPVMwsmBIpOwQttYFMjgJQZLYFPmxWFLIeZihkRNnkzoypBICIxgEuYsVWGIGRbbxqVasYnstWomJnHwmtOhAFSpttRYYzBmyEtZXiCthvKvWszTXDbiJbGXMcrYpKAgvUVFtdKUfvdMfhAryctklUCEdjetjuGNfJjajZtvzdYaqInKtFPPLYmRaXPdQzxdSQfmZDEVHlHGEGNSPRFJuIfKLLfUmnHxHnRjmzQPNlqrXgifUdzAGKVabYqvcDeYoTYgPsBUqehrBhmQUgTvDnsdpuhUoxskDdppTsYMcnDIPSwKIqhXDCIxOuXrywahvVavvHkPuaenjLmEbMgrkrQLHEAwrhHkPRNvonNQKqprqOFVZKAtpRSpvQUxMoXCMZLSSbnLEFsjVfANdQNQVwTmGxqVjVqRuxREAhuaDrFgEZpYKhwWPEKBevBfsOIcaZKyykQafzmGPLRAKDtTcJxJVgiiuUkmyMYuDUNEUhBEdoBLJnamtLmMJQgmLiUELIhLpiEvpOXOvXCPUeldLFqkKOwfacqIaRcnnZvERKRMCKUkMABbDHytQqQblrvoxOZkwzosQfDKGtIdfcXRJNqlBNwOCWoQBcEWyqrMlYZIAXYJmLfnjoJepgSFvrgajaBAIksoyeHqgqbGvpAstMIGmIhRYGGNPRIfOQKsGoKgxtsidhTaAePRCBFqZgPDWCIkqOJezGVkjfYUCZTlInbxBXwUAVRsxHTQtJFnnpmMvXDYCVlEmnZBKhmmxQOIQzxFWpJQkQoSAYzTEiDWEOsVLNrbfzeHFRyeYATakQQWmFDLPbVMCJcWjFGJjfqCoVzlbNNEsqxdSmNPjTjHYOkuEMFLkXYGaoJlraLqayMeCsTjWNRDPBywBJLAPVkGQqTwApVVwYAetlwSbzsdHWsTwSIcctkyKDuRWYDQikRqsKTMJchrliONJeaZIzwPQrNbTwxsGdwuduvibtYndRwpdsvyCktRHFalvUuEKMqXbItfGcNGWsGzubdPMYayOUOINjpcFBeESdwpdlTYmrPsLsVDhpTzoMegKrytNVZkfJRPuDCUXxSlSthOohmsuxmIZUedzxKmowKOdXTMcEtdpHaPWgIsIjrViKrQOCONlSuazmLuCUjLltOGXeNgJKedTVrrVCpWYWHyVrdXpKgNaMJVjbXxnVMSChdWKuZdqpisvrkBJPoURDYxWOtpjzZoOpWzyUuYNhCzRoHsMjmmWDcXzQiHIyjwdhPNwiPqFxeUfMVFQGImhykFgMIlQEoZCaRoqSBXTSWAeDumdbsOGtATwEdZlLfoBKiTvodQBGOEcuATWXfiinSjPmJKcWgQrTVYVrwlyMWhxqNbCMpIQNoSMGTiWfPTCezUjYcdWppnsYJihLQCqbNLRGgqrwHuIvsazapTpoPZIyZyeeSueJuTIhpHMEJfJpScshJubJGfkusuVBgfTWQoywSSliQQSfbvaHKiLnyjdSbpMkdBgXepoSsHnCQaYuHQqZsoEOmJCiuQUpJkmfyfbIShzlZpHFmLCsbknEAkKXKfRTRnuwdBeuOGgFbJLbDksHVapaRayWzwoYBEpmrlAxrUxYMUekKbpjPNfjUCjhbdMAnJmYQVZBQZkFVweHDAlaqJjRqoQPoOMLhyvYCzqEuQsAFoxWrzRnTVjStPadhsESlERnKhpEPsfDxNvxqcOyIulaCkmPdambLHvGhTZzysvqFauEgkFRItPfvisehFmoBhQqmkfbHVsgfHXDPJVyhwPllQpuYLRYvGodxKjkarnSNgsXoKEMlaSKxKdcVgvOkuLcfLFfdtXGTclqfPOfeoVLbqcjcXCUEBgAGplrkgsmIEhWRZLlGPGCwKWRaCKMkBHTAcypUrYjWwCLtOPVygMwMANGoQwFnCqFrUGMCRZUGJKTZIGPyldsifauoMnJPLTcDHmilcmahlqOELaAUYDBuzsVywnDQfwRLGIWozYaOAilMBcObErwgTDNGWnwQMUgFFSKtPDMEoEQCTKVREqrXZSGLqwTMcxHfWotDllNkIJPMbXzjDVjPOOjCFuIvTyhXKLyhUScOXvYthRXpPfKwMhptXaxIxgqBoUqzrWbaoLTVpQoottZyPFfNOoMioXHRuFwMRYUiKvcWPkrayyTLOCFJlAyslDameIuqVAuxErqFPEWIScKpBORIuZqoXlZuTvAjEdlEWDODFRregDTqGNoFBIHxvimmIZwLfFyKUfEWAnNBdtdzDmTPXtpHRGdIbuucfTjOygZsTxPjfweXhSUkMhPjMaxKlMIJMOXcnQfyzeOcbWwNbeH", 204 textProposal.GetDescription()) 205 require.Equal(t, simulation.TypeMsgSubmitProposal, sdk.MsgTypeURL(&msg)) 206 } 207 208 // TestSimulateMsgCancelProposal tests the normal scenario of a valid message of type TypeMsgCancelProposal. 209 // Abnormal scenarios, where errors occur, are not tested here. 210 func TestSimulateMsgCancelProposal(t *testing.T) { 211 suite, ctx := createTestSuite(t, false) 212 app := suite.App 213 blockTime := time.Now().UTC() 214 ctx = ctx.WithBlockTime(blockTime) 215 216 // setup 3 accounts 217 s := rand.NewSource(1) 218 r := rand.New(s) 219 accounts := getTestingAccounts(t, r, suite.AccountKeeper, suite.BankKeeper, suite.StakingKeeper, ctx, 3) 220 // setup a proposal 221 proposer := accounts[0].Address 222 content := v1beta1.NewTextProposal("Test", "description") 223 contentMsg, err := v1.NewLegacyContent(content, suite.GovKeeper.GetGovernanceAccount(ctx).GetAddress().String()) 224 require.NoError(t, err) 225 226 submitTime := ctx.BlockHeader().Time 227 params, _ := suite.GovKeeper.Params.Get(ctx) 228 depositPeriod := params.MaxDepositPeriod 229 230 proposal, err := v1.NewProposal([]sdk.Msg{contentMsg}, 1, submitTime, submitTime.Add(*depositPeriod), "", "title", "summary", proposer, false) 231 require.NoError(t, err) 232 233 suite.GovKeeper.SetProposal(ctx, proposal) 234 235 app.FinalizeBlock(&abci.RequestFinalizeBlock{ 236 Height: app.LastBlockHeight() + 1, 237 Hash: app.LastCommitID().Hash, 238 }) 239 240 // execute operation 241 op := simulation.SimulateMsgCancelProposal(suite.TxConfig, suite.AccountKeeper, suite.BankKeeper, suite.GovKeeper) 242 operationMsg, _, err := op(r, app.BaseApp, ctx, accounts, "") 243 require.NoError(t, err) 244 245 var msg v1.MsgCancelProposal 246 err = proto.Unmarshal(operationMsg.Msg, &msg) 247 require.NoError(t, err) 248 require.NoError(t, err) 249 require.True(t, operationMsg.OK) 250 require.Equal(t, uint64(1), msg.ProposalId) 251 require.Equal(t, proposer.String(), msg.Proposer) 252 require.Equal(t, simulation.TypeMsgCancelProposal, sdk.MsgTypeURL(&msg)) 253 } 254 255 // TestSimulateMsgDeposit tests the normal scenario of a valid message of type TypeMsgDeposit. 256 // Abnormal scenarios, where errors occur, are not tested here. 257 func TestSimulateMsgDeposit(t *testing.T) { 258 suite, ctx := createTestSuite(t, false) 259 app := suite.App 260 blockTime := time.Now().UTC() 261 ctx = ctx.WithBlockTime(blockTime) 262 263 // setup 3 accounts 264 s := rand.NewSource(1) 265 r := rand.New(s) 266 accounts := getTestingAccounts(t, r, suite.AccountKeeper, suite.BankKeeper, suite.StakingKeeper, ctx, 3) 267 268 // setup a proposal 269 content := v1beta1.NewTextProposal("Test", "description") 270 contentMsg, err := v1.NewLegacyContent(content, suite.GovKeeper.GetGovernanceAccount(ctx).GetAddress().String()) 271 require.NoError(t, err) 272 273 submitTime := ctx.BlockHeader().Time 274 params, _ := suite.GovKeeper.Params.Get(ctx) 275 depositPeriod := params.MaxDepositPeriod 276 277 proposal, err := v1.NewProposal([]sdk.Msg{contentMsg}, 1, submitTime, submitTime.Add(*depositPeriod), "", "text proposal", "description", sdk.AccAddress("cosmos1ghekyjucln7y67ntx7cf27m9dpuxxemn4c8g4r"), false) 278 require.NoError(t, err) 279 280 suite.GovKeeper.SetProposal(ctx, proposal) 281 282 app.FinalizeBlock(&abci.RequestFinalizeBlock{ 283 Height: app.LastBlockHeight() + 1, 284 Hash: app.LastCommitID().Hash, 285 }) 286 287 // execute operation 288 op := simulation.SimulateMsgDeposit(suite.TxConfig, suite.AccountKeeper, suite.BankKeeper, suite.GovKeeper) 289 operationMsg, _, err := op(r, app.BaseApp, ctx, accounts, "") 290 require.NoError(t, err) 291 292 var msg v1.MsgDeposit 293 err = proto.Unmarshal(operationMsg.Msg, &msg) 294 require.NoError(t, err) 295 require.True(t, operationMsg.OK) 296 require.Equal(t, uint64(1), msg.ProposalId) 297 require.Equal(t, "cosmos1ghekyjucln7y67ntx7cf27m9dpuxxemn4c8g4r", msg.Depositor) 298 require.NotEqual(t, len(msg.Amount), 0) 299 require.Equal(t, "560969stake", msg.Amount[0].String()) 300 require.Equal(t, simulation.TypeMsgDeposit, sdk.MsgTypeURL(&msg)) 301 } 302 303 // TestSimulateMsgVote tests the normal scenario of a valid message of type TypeMsgVote. 304 // Abnormal scenarios, where errors occur, are not tested here. 305 func TestSimulateMsgVote(t *testing.T) { 306 suite, ctx := createTestSuite(t, false) 307 app := suite.App 308 blockTime := time.Now().UTC() 309 ctx = ctx.WithBlockTime(blockTime) 310 311 // setup 3 accounts 312 s := rand.NewSource(1) 313 r := rand.New(s) 314 accounts := getTestingAccounts(t, r, suite.AccountKeeper, suite.BankKeeper, suite.StakingKeeper, ctx, 3) 315 316 // setup a proposal 317 govAcc := suite.GovKeeper.GetGovernanceAccount(ctx).GetAddress().String() 318 contentMsg, err := v1.NewLegacyContent(v1beta1.NewTextProposal("Test", "description"), govAcc) 319 require.NoError(t, err) 320 321 submitTime := ctx.BlockHeader().Time 322 params, _ := suite.GovKeeper.Params.Get(ctx) 323 depositPeriod := params.MaxDepositPeriod 324 325 proposal, err := v1.NewProposal([]sdk.Msg{contentMsg}, 1, submitTime, submitTime.Add(*depositPeriod), "", "text proposal", "description", sdk.AccAddress("cosmos1ghekyjucln7y67ntx7cf27m9dpuxxemn4c8g4r"), false) 326 require.NoError(t, err) 327 328 suite.GovKeeper.ActivateVotingPeriod(ctx, proposal) 329 330 app.FinalizeBlock(&abci.RequestFinalizeBlock{ 331 Height: app.LastBlockHeight() + 1, 332 Hash: app.LastCommitID().Hash, 333 }) 334 335 // execute operation 336 op := simulation.SimulateMsgVote(suite.TxConfig, suite.AccountKeeper, suite.BankKeeper, suite.GovKeeper) 337 operationMsg, _, err := op(r, app.BaseApp, ctx, accounts, "") 338 require.NoError(t, err) 339 340 var msg v1.MsgVote 341 err = proto.Unmarshal(operationMsg.Msg, &msg) 342 require.NoError(t, err) 343 require.True(t, operationMsg.OK) 344 require.Equal(t, uint64(1), msg.ProposalId) 345 require.Equal(t, "cosmos1ghekyjucln7y67ntx7cf27m9dpuxxemn4c8g4r", msg.Voter) 346 require.Equal(t, v1.OptionYes, msg.Option) 347 require.Equal(t, simulation.TypeMsgVote, sdk.MsgTypeURL(&msg)) 348 } 349 350 // TestSimulateMsgVoteWeighted tests the normal scenario of a valid message of type TypeMsgVoteWeighted. 351 // Abnormal scenarios, where errors occur, are not tested here. 352 func TestSimulateMsgVoteWeighted(t *testing.T) { 353 suite, ctx := createTestSuite(t, false) 354 app := suite.App 355 blockTime := time.Now().UTC() 356 ctx = ctx.WithBlockTime(blockTime) 357 358 // setup 3 accounts 359 s := rand.NewSource(1) 360 r := rand.New(s) 361 accounts := getTestingAccounts(t, r, suite.AccountKeeper, suite.BankKeeper, suite.StakingKeeper, ctx, 3) 362 363 // setup a proposal 364 govAcc := suite.GovKeeper.GetGovernanceAccount(ctx).GetAddress().String() 365 contentMsg, err := v1.NewLegacyContent(v1beta1.NewTextProposal("Test", "description"), govAcc) 366 require.NoError(t, err) 367 submitTime := ctx.BlockHeader().Time 368 params, _ := suite.GovKeeper.Params.Get(ctx) 369 depositPeriod := params.MaxDepositPeriod 370 371 proposal, err := v1.NewProposal([]sdk.Msg{contentMsg}, 1, submitTime, submitTime.Add(*depositPeriod), "", "text proposal", "test", sdk.AccAddress("cosmos1ghekyjucln7y67ntx7cf27m9dpuxxemn4c8g4r"), false) 372 require.NoError(t, err) 373 374 suite.GovKeeper.ActivateVotingPeriod(ctx, proposal) 375 376 app.FinalizeBlock(&abci.RequestFinalizeBlock{ 377 Height: app.LastBlockHeight() + 1, 378 Hash: app.LastCommitID().Hash, 379 }) 380 381 // execute operation 382 op := simulation.SimulateMsgVoteWeighted(suite.TxConfig, suite.AccountKeeper, suite.BankKeeper, suite.GovKeeper) 383 operationMsg, _, err := op(r, app.BaseApp, ctx, accounts, "") 384 require.NoError(t, err) 385 386 var msg v1.MsgVoteWeighted 387 err = proto.Unmarshal(operationMsg.Msg, &msg) 388 require.NoError(t, err) 389 require.True(t, operationMsg.OK) 390 require.Equal(t, uint64(1), msg.ProposalId) 391 require.Equal(t, "cosmos1ghekyjucln7y67ntx7cf27m9dpuxxemn4c8g4r", msg.Voter) 392 require.True(t, len(msg.Options) >= 1) 393 require.Equal(t, simulation.TypeMsgVoteWeighted, sdk.MsgTypeURL(&msg)) 394 } 395 396 type suite struct { 397 TxConfig client.TxConfig 398 AccountKeeper authkeeper.AccountKeeper 399 BankKeeper bankkeeper.Keeper 400 GovKeeper *keeper.Keeper 401 StakingKeeper *stakingkeeper.Keeper 402 DistributionKeeper dk.Keeper 403 App *runtime.App 404 } 405 406 // returns context and an app with updated mint keeper 407 func createTestSuite(t *testing.T, isCheckTx bool) (suite, sdk.Context) { 408 res := suite{} 409 410 app, err := simtestutil.Setup( 411 depinject.Configs( 412 configurator.NewAppConfig( 413 configurator.AuthModule(), 414 configurator.TxModule(), 415 configurator.ParamsModule(), 416 configurator.BankModule(), 417 configurator.StakingModule(), 418 configurator.ConsensusModule(), 419 configurator.DistributionModule(), 420 configurator.GovModule(), 421 ), 422 depinject.Supply(log.NewNopLogger()), 423 ), 424 &res.TxConfig, &res.AccountKeeper, &res.BankKeeper, &res.GovKeeper, &res.StakingKeeper, &res.DistributionKeeper) 425 require.NoError(t, err) 426 427 ctx := app.BaseApp.NewContext(isCheckTx) 428 429 res.App = app 430 return res, ctx 431 } 432 433 func getTestingAccounts( 434 t *testing.T, r *rand.Rand, 435 accountKeeper authkeeper.AccountKeeper, bankKeeper bankkeeper.Keeper, stakingKeeper *stakingkeeper.Keeper, 436 ctx sdk.Context, n int, 437 ) []simtypes.Account { 438 accounts := simtypes.RandomAccounts(r, n) 439 440 initAmt := stakingKeeper.TokensFromConsensusPower(ctx, 200) 441 initCoins := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, initAmt)) 442 443 // add coins to the accounts 444 for _, account := range accounts { 445 acc := accountKeeper.NewAccountWithAddress(ctx, account.Address) 446 accountKeeper.SetAccount(ctx, acc) 447 require.NoError(t, testutil.FundAccount(ctx, bankKeeper, account.Address, initCoins)) 448 } 449 450 return accounts 451 }