package simulation import ( "math/rand" "cosmossdk.io/x/protocolpool/keeper" "cosmossdk.io/x/protocolpool/types" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" simtypes "github.com/cosmos/cosmos-sdk/types/simulation" "github.com/cosmos/cosmos-sdk/x/simulation" ) // Simulation operation weights constants const ( OpWeightMsgFundCommunityPool = "op_weight_msg_fund_community_pool" DefaultWeightMsgFundCommunityPool int = 50 ) // WeightedOperations returns all the operations from the module with their respective weights func WeightedOperations( appParams simtypes.AppParams, cdc codec.JSONCodec, txConfig client.TxConfig, ak types.AccountKeeper, bk types.BankKeeper, k keeper.Keeper, ) simulation.WeightedOperations { var weightMsgFundCommunityPool int appParams.GetOrGenerate(OpWeightMsgFundCommunityPool, &weightMsgFundCommunityPool, nil, func(_ *rand.Rand) { weightMsgFundCommunityPool = DefaultWeightMsgFundCommunityPool }) return simulation.WeightedOperations{ simulation.NewWeightedOperation( weightMsgFundCommunityPool, SimulateMsgFundCommunityPool(txConfig, ak, bk, k), ), } } // SimulateMsgFundCommunityPool simulates MsgFundCommunityPool execution where // a random account sends a random amount of its funds to the community pool. func SimulateMsgFundCommunityPool(txConfig client.TxConfig, ak types.AccountKeeper, bk types.BankKeeper, k keeper.Keeper) simtypes.Operation { return func( r *rand.Rand, app simtypes.AppEntrypoint, ctx sdk.Context, accs []simtypes.Account, chainID string, ) (simtypes.OperationMsg, []simtypes.FutureOperation, error) { funder, _ := simtypes.RandomAcc(r, accs) account := ak.GetAccount(ctx, funder.Address) spendable := bk.SpendableCoins(ctx, account.GetAddress()) fundAmount := simtypes.RandSubsetCoins(r, spendable) if fundAmount.Empty() { return simtypes.NoOpMsg(types.ModuleName, sdk.MsgTypeURL(&types.MsgFundCommunityPool{}), "fund amount is empty"), nil, nil } var ( fees sdk.Coins err error ) coins, hasNeg := spendable.SafeSub(fundAmount...) if !hasNeg { fees, err = simtypes.RandomFees(r, coins) if err != nil { return simtypes.NoOpMsg(types.ModuleName, sdk.MsgTypeURL(&types.MsgFundCommunityPool{}), "unable to generate fees"), nil, err } } funderAddr, err := ak.AddressCodec().BytesToString(funder.Address) if err != nil { return simtypes.NoOpMsg(types.ModuleName, sdk.MsgTypeURL(&types.MsgFundCommunityPool{}), "unable to get funder address"), nil, err } msg := types.NewMsgFundCommunityPool(fundAmount, funderAddr) txCtx := simulation.OperationInput{ R: r, App: app, TxGen: txConfig, Cdc: nil, Msg: msg, Context: ctx, SimAccount: funder, AccountKeeper: ak, ModuleName: types.ModuleName, } return simulation.GenAndDeliverTx(txCtx, fees) } }