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  }