package simulation // import ( // "fmt" // "math/rand" // "github.com/cosmos/cosmos-sdk/baseapp" // "github.com/cosmos/cosmos-sdk/codec" // "github.com/cosmos/cosmos-sdk/simapp/helpers" // sdk "github.com/cosmos/cosmos-sdk/types" // "github.com/cosmos/cosmos-sdk/x/simulation" // simappparams "github.com/kava-labs/kava/app/params" // "github.com/kava-labs/kava/x/issuance/keeper" // "github.com/kava-labs/kava/x/issuance/types" // ) // // Simulation operation weights constants // const ( // OpWeightMsgIssue = "op_weight_msg_issue" // OpWeightMsgRedeem = "op_weight_msg_redeem" // OpWeightMsgBlock = "op_weight_msg_block" // OpWeightMsgPause = "op_weight_msg_pause" // ) // // WeightedOperations returns all the operations from the module with their respective weights // func WeightedOperations( // appParams simulation.AppParams, cdc *codec.Codec, ak types.AccountKeeper, k keeper.Keeper, // ) simulation.WeightedOperations { // var ( // weightMsgIssue int // weightMsgReedem int // weightMsgBlock int // weightMsgPause int // ) // appParams.GetOrGenerate(cdc, OpWeightMsgIssue, &weightMsgIssue, nil, // func(_ *rand.Rand) { // weightMsgIssue = simappparams.DefaultWeightMsgIssue // }, // ) // appParams.GetOrGenerate(cdc, OpWeightMsgRedeem, &weightMsgReedem, nil, // func(_ *rand.Rand) { // weightMsgReedem = simappparams.DefaultWeightMsgRedeem // }, // ) // appParams.GetOrGenerate(cdc, OpWeightMsgBlock, &weightMsgBlock, nil, // func(_ *rand.Rand) { // weightMsgBlock = simappparams.DefaultWeightMsgBlock // }, // ) // appParams.GetOrGenerate(cdc, OpWeightMsgPause, &weightMsgPause, nil, // func(_ *rand.Rand) { // weightMsgPause = simappparams.DefaultWeightMsgPause // }, // ) // return simulation.WeightedOperations{ // simulation.NewWeightedOperation( // weightMsgIssue, // SimulateMsgIssueTokens(ak, k), // ), // simulation.NewWeightedOperation( // weightMsgReedem, // SimulateMsgRedeemTokens(ak, k), // ), // simulation.NewWeightedOperation( // weightMsgBlock, // SimulateMsgBlockAddress(ak, k), // ), // simulation.NewWeightedOperation( // weightMsgPause, // SimulateMsgPause(ak, k), // ), // } // } // // SimulateMsgIssueTokens generates a MsgIssueTokens with random values // func SimulateMsgIssueTokens(ak types.AccountKeeper, k keeper.Keeper) simulation.Operation { // return func( // r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, accs []simulation.Account, chainID string, // ) (simulation.OperationMsg, []simulation.FutureOperation, error) { // // shuffle the assets and get a random one // assets := k.GetParams(ctx).Assets // r.Shuffle(len(assets), func(i, j int) { // assets[i], assets[j] = assets[j], assets[i] // }) // asset := assets[0] // if asset.Paused { // return simulation.NoOpMsg(types.ModuleName), nil, nil // } // // make sure owner account exists // ownerSimAcc, found := simulation.FindAccount(accs, asset.Owner) // if !found { // return simulation.NoOpMsg(types.ModuleName), nil, fmt.Errorf("asset owner not found: %s", asset) // } // // issue new tokens to the owner 50% of the time so we have funds to redeem // ownerAcc := ak.GetAccount(ctx, asset.Owner) // recipient := ownerAcc // if r.Intn(2) == 0 { // simAccount, _ := simulation.RandomAcc(r, accs) // recipient = ak.GetAccount(ctx, simAccount.Address) // } // if recipient == nil { // return simulation.NoOpMsg(types.ModuleName), nil, nil // } // for _, blockedAddr := range asset.BlockedAddresses { // if recipient.GetAddress().Equals(blockedAddr) { // return simulation.NoOpMsg(types.ModuleName), nil, nil // } // } // randomAmount := simulation.RandIntBetween(r, 10000000, 1000000000000) // if asset.RateLimit.Active { // supply, found := k.GetAssetSupply(ctx, asset.Denom) // if !found { // return simulation.NoOpMsg(types.ModuleName), nil, fmt.Errorf("issuance - no asset supply for %s", asset.Denom) // } // if asset.RateLimit.Limit.LT(supply.CurrentSupply.Amount.Add(sdk.NewInt(int64(randomAmount)))) { // maxAmount := asset.RateLimit.Limit.Sub(supply.CurrentSupply.Amount) // if maxAmount.IsPositive() && maxAmount.GT(sdk.OneInt()) { // randomAmount = simulation.RandIntBetween(r, 1, int(maxAmount.Int64())) // } else if maxAmount.Equal(sdk.OneInt()) { // randomAmount = 1 // } else { // return simulation.NoOpMsg(types.ModuleName), nil, nil // } // } // } // msg := types.NewMsgIssueTokens(asset.Owner, sdk.NewCoin(asset.Denom, sdk.NewInt(int64(randomAmount))), recipient.GetAddress()) // spendableCoins := ownerAcc.SpendableCoins(ctx.BlockTime()) // fees, err := simulation.RandomFees(r, ctx, spendableCoins) // if err != nil { // return simulation.NoOpMsg(types.ModuleName), nil, err // } // tx := helpers.GenTx( // []sdk.Msg{msg}, // fees, // helpers.DefaultGenTxGas, // chainID, // []uint64{ownerAcc.GetAccountNumber()}, // []uint64{ownerAcc.GetSequence()}, // ownerSimAcc.PrivKey, // ) // _, _, err = app.Deliver(tx) // if err != nil { // fmt.Printf("error on issue %s\n%s\n", msg, asset) // return simulation.NoOpMsg(types.ModuleName), nil, err // } // return simulation.NewOperationMsg(msg, true, ""), nil, nil // } // } // // SimulateMsgRedeemTokens generates a MsgRedeemTokens with random values // func SimulateMsgRedeemTokens(ak types.AccountKeeper, k keeper.Keeper) simulation.Operation { // return func( // r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, accs []simulation.Account, chainID string, // ) (simulation.OperationMsg, []simulation.FutureOperation, error) { // // shuffle the assets and get a random one // assets := k.GetParams(ctx).Assets // r.Shuffle(len(assets), func(i, j int) { // assets[i], assets[j] = assets[j], assets[i] // }) // asset := assets[0] // if asset.Paused { // return simulation.NoOpMsg(types.ModuleName), nil, nil // } // // make sure owner account exists // ownerSimAcc, found := simulation.FindAccount(accs, asset.Owner) // if !found { // return simulation.NoOpMsg(types.ModuleName), nil, fmt.Errorf("asset owner not found: %s", asset) // } // ownerAcc := ak.GetAccount(ctx, asset.Owner) // spendableCoinAmount := ownerAcc.SpendableCoins(ctx.BlockTime()).AmountOf(asset.Denom) // if spendableCoinAmount.IsZero() { // return simulation.NoOpMsg(types.ModuleName), nil, nil // } // var redeemAmount sdk.Int // if spendableCoinAmount.Equal(sdk.OneInt()) { // redeemAmount = sdk.OneInt() // } else { // redeemAmount = sdk.NewInt(int64(simulation.RandIntBetween(r, 1, int(spendableCoinAmount.Int64())))) // } // msg := types.NewMsgRedeemTokens(asset.Owner, sdk.NewCoin(asset.Denom, redeemAmount)) // spendableCoins := ownerAcc.SpendableCoins(ctx.BlockTime()).Sub(sdk.NewCoins(sdk.NewCoin(asset.Denom, redeemAmount))) // fees, err := simulation.RandomFees(r, ctx, spendableCoins) // if err != nil { // fmt.Printf("%s\n", msg) // return simulation.NoOpMsg(types.ModuleName), nil, err // } // tx := helpers.GenTx( // []sdk.Msg{msg}, // fees, // helpers.DefaultGenTxGas, // chainID, // []uint64{ownerAcc.GetAccountNumber()}, // []uint64{ownerAcc.GetSequence()}, // ownerSimAcc.PrivKey, // ) // _, _, err = app.Deliver(tx) // if err != nil { // fmt.Printf("error on redeem %s\n%s\n", msg, asset) // return simulation.NoOpMsg(types.ModuleName), nil, err // } // return simulation.NewOperationMsg(msg, true, ""), nil, nil // } // } // // SimulateMsgBlockAddress generates a MsgBlockAddress with random values // func SimulateMsgBlockAddress(ak types.AccountKeeper, k keeper.Keeper) simulation.Operation { // return func( // r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, accs []simulation.Account, chainID string, // ) (simulation.OperationMsg, []simulation.FutureOperation, error) { // // shuffle the assets and get a random one // assets := k.GetParams(ctx).Assets // r.Shuffle(len(assets), func(i, j int) { // assets[i], assets[j] = assets[j], assets[i] // }) // asset := assets[0] // // make sure owner account exists // ownerSimAcc, found := simulation.FindAccount(accs, asset.Owner) // if !found { // return simulation.NoOpMsg(types.ModuleName), nil, fmt.Errorf("asset owner not found: %s", asset) // } // ownerAcc := ak.GetAccount(ctx, asset.Owner) // // find an account to block // simAccount, _ := simulation.RandomAcc(r, accs) // blockedAccount := ak.GetAccount(ctx, simAccount.Address) // if blockedAccount.GetAddress().Equals(asset.Owner) { // return simulation.NoOpMsg(types.ModuleName), nil, nil // } // for _, blockedAddr := range asset.BlockedAddresses { // if blockedAccount.GetAddress().Equals(blockedAddr) { // return simulation.NoOpMsg(types.ModuleName), nil, nil // } // } // msg := types.NewMsgBlockAddress(asset.Owner, asset.Denom, blockedAccount.GetAddress()) // spendableCoins := ownerAcc.SpendableCoins(ctx.BlockTime()) // fees, err := simulation.RandomFees(r, ctx, spendableCoins) // if err != nil { // return simulation.NoOpMsg(types.ModuleName), nil, err // } // tx := helpers.GenTx( // []sdk.Msg{msg}, // fees, // helpers.DefaultGenTxGas*2, // chainID, // []uint64{ownerAcc.GetAccountNumber()}, // []uint64{ownerAcc.GetSequence()}, // ownerSimAcc.PrivKey, // ) // _, _, err = app.Deliver(tx) // if err != nil { // fmt.Printf("error on block %s\n%s\n", msg, asset) // return simulation.NoOpMsg(types.ModuleName), nil, err // } // return simulation.NewOperationMsg(msg, true, ""), nil, nil // } // } // // SimulateMsgPause generates a MsgChangePauseStatus with random values // func SimulateMsgPause(ak types.AccountKeeper, k keeper.Keeper) simulation.Operation { // return func( // r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, accs []simulation.Account, chainID string, // ) (simulation.OperationMsg, []simulation.FutureOperation, error) { // // shuffle the assets and get a random one // assets := k.GetParams(ctx).Assets // r.Shuffle(len(assets), func(i, j int) { // assets[i], assets[j] = assets[j], assets[i] // }) // asset := assets[0] // // make sure owner account exists // ownerSimAcc, found := simulation.FindAccount(accs, asset.Owner) // if !found { // return simulation.NoOpMsg(types.ModuleName), nil, fmt.Errorf("asset owner not found: %s", asset) // } // ownerAcc := ak.GetAccount(ctx, asset.Owner) // // set status to paused/un-paused // status := r.Intn(2) == 0 // msg := types.NewMsgSetPauseStatus(asset.Owner, asset.Denom, status) // spendableCoins := ownerAcc.SpendableCoins(ctx.BlockTime()) // fees, err := simulation.RandomFees(r, ctx, spendableCoins) // if err != nil { // return simulation.NoOpMsg(types.ModuleName), nil, err // } // tx := helpers.GenTx( // []sdk.Msg{msg}, // fees, // helpers.DefaultGenTxGas*2, // chainID, // []uint64{ownerAcc.GetAccountNumber()}, // []uint64{ownerAcc.GetSequence()}, // ownerSimAcc.PrivKey, // ) // _, _, err = app.Deliver(tx) // if err != nil { // fmt.Printf("error on pause %s\n%s\n", msg, asset) // return simulation.NoOpMsg(types.ModuleName), nil, err // } // return simulation.NewOperationMsg(msg, true, ""), nil, nil // } // }