github.com/Finschia/finschia-sdk@v0.49.1/x/feegrant/simulation/operations.go (about)

     1  package simulation
     2  
     3  import (
     4  	"math/rand"
     5  
     6  	"github.com/Finschia/finschia-sdk/baseapp"
     7  	"github.com/Finschia/finschia-sdk/codec"
     8  	simappparams "github.com/Finschia/finschia-sdk/simapp/params"
     9  	sdk "github.com/Finschia/finschia-sdk/types"
    10  	simtypes "github.com/Finschia/finschia-sdk/types/simulation"
    11  	"github.com/Finschia/finschia-sdk/x/feegrant"
    12  	"github.com/Finschia/finschia-sdk/x/feegrant/keeper"
    13  	"github.com/Finschia/finschia-sdk/x/simulation"
    14  )
    15  
    16  // Simulation operation weights constants
    17  const (
    18  	OpWeightMsgGrantAllowance  = "op_weight_msg_grant_fee_allowance"
    19  	OpWeightMsgRevokeAllowance = "op_weight_msg_grant_revoke_allowance"
    20  )
    21  
    22  var (
    23  	TypeMsgGrantAllowance  = sdk.MsgTypeURL(&feegrant.MsgGrantAllowance{})
    24  	TypeMsgRevokeAllowance = sdk.MsgTypeURL(&feegrant.MsgRevokeAllowance{})
    25  )
    26  
    27  func WeightedOperations(
    28  	appParams simtypes.AppParams, cdc codec.JSONCodec,
    29  	ak feegrant.AccountKeeper, bk feegrant.BankKeeper, k keeper.Keeper,
    30  ) simulation.WeightedOperations {
    31  	var (
    32  		weightMsgGrantAllowance  int
    33  		weightMsgRevokeAllowance int
    34  	)
    35  
    36  	appParams.GetOrGenerate(cdc, OpWeightMsgGrantAllowance, &weightMsgGrantAllowance, nil,
    37  		func(_ *rand.Rand) {
    38  			weightMsgGrantAllowance = simappparams.DefaultWeightGrantAllowance
    39  		},
    40  	)
    41  
    42  	appParams.GetOrGenerate(cdc, OpWeightMsgRevokeAllowance, &weightMsgRevokeAllowance, nil,
    43  		func(_ *rand.Rand) {
    44  			weightMsgRevokeAllowance = simappparams.DefaultWeightRevokeAllowance
    45  		},
    46  	)
    47  
    48  	return simulation.WeightedOperations{
    49  		simulation.NewWeightedOperation(
    50  			weightMsgGrantAllowance,
    51  			SimulateMsgGrantAllowance(ak, bk, k),
    52  		),
    53  		simulation.NewWeightedOperation(
    54  			weightMsgRevokeAllowance,
    55  			SimulateMsgRevokeAllowance(ak, bk, k),
    56  		),
    57  	}
    58  }
    59  
    60  // SimulateMsgGrantAllowance generates MsgGrantAllowance with random values.
    61  func SimulateMsgGrantAllowance(ak feegrant.AccountKeeper, bk feegrant.BankKeeper, k keeper.Keeper) simtypes.Operation {
    62  	return func(
    63  		r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, accs []simtypes.Account, chainID string,
    64  	) (simtypes.OperationMsg, []simtypes.FutureOperation, error) {
    65  		granter, _ := simtypes.RandomAcc(r, accs)
    66  		grantee, _ := simtypes.RandomAcc(r, accs)
    67  		if grantee.Address.String() == granter.Address.String() {
    68  			return simtypes.NoOpMsg(feegrant.ModuleName, TypeMsgGrantAllowance, "grantee and granter cannot be same"), nil, nil
    69  		}
    70  
    71  		if f, _ := k.GetAllowance(ctx, granter.Address, grantee.Address); f != nil {
    72  			return simtypes.NoOpMsg(feegrant.ModuleName, TypeMsgGrantAllowance, "fee allowance exists"), nil, nil
    73  		}
    74  
    75  		account := ak.GetAccount(ctx, granter.Address)
    76  
    77  		spendableCoins := bk.SpendableCoins(ctx, account.GetAddress())
    78  		if spendableCoins.Empty() {
    79  			return simtypes.NoOpMsg(feegrant.ModuleName, TypeMsgGrantAllowance, "unable to grant empty coins as SpendLimit"), nil, nil
    80  		}
    81  
    82  		oneYear := ctx.BlockTime().AddDate(1, 0, 0)
    83  		msg, err := feegrant.NewMsgGrantAllowance(&feegrant.BasicAllowance{
    84  			SpendLimit: spendableCoins,
    85  			Expiration: &oneYear,
    86  		}, granter.Address, grantee.Address)
    87  		if err != nil {
    88  			return simtypes.NoOpMsg(feegrant.ModuleName, TypeMsgGrantAllowance, err.Error()), nil, err
    89  		}
    90  
    91  		txCtx := simulation.OperationInput{
    92  			R:               r,
    93  			App:             app,
    94  			TxGen:           simappparams.MakeTestEncodingConfig().TxConfig,
    95  			Cdc:             nil,
    96  			Msg:             msg,
    97  			MsgType:         TypeMsgGrantAllowance,
    98  			Context:         ctx,
    99  			SimAccount:      granter,
   100  			AccountKeeper:   ak,
   101  			Bankkeeper:      bk,
   102  			ModuleName:      feegrant.ModuleName,
   103  			CoinsSpentInMsg: spendableCoins,
   104  		}
   105  
   106  		return simulation.GenAndDeliverTxWithRandFees(txCtx)
   107  	}
   108  }
   109  
   110  // SimulateMsgRevokeAllowance generates a MsgRevokeAllowance with random values.
   111  func SimulateMsgRevokeAllowance(ak feegrant.AccountKeeper, bk feegrant.BankKeeper, k keeper.Keeper) simtypes.Operation {
   112  	return func(
   113  		r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, accs []simtypes.Account, chainID string,
   114  	) (simtypes.OperationMsg, []simtypes.FutureOperation, error) {
   115  		hasGrant := false
   116  		var granterAddr sdk.AccAddress
   117  		var granteeAddr sdk.AccAddress
   118  		err := k.IterateAllFeeAllowances(ctx, func(grant feegrant.Grant) bool {
   119  			granter := sdk.MustAccAddressFromBech32(grant.Granter)
   120  			grantee := sdk.MustAccAddressFromBech32(grant.Grantee)
   121  			granterAddr = granter
   122  			granteeAddr = grantee
   123  			hasGrant = true
   124  			return true
   125  		})
   126  		if err != nil {
   127  			panic(err)
   128  		}
   129  
   130  		if !hasGrant {
   131  			return simtypes.NoOpMsg(feegrant.ModuleName, TypeMsgRevokeAllowance, "no grants"), nil, nil
   132  		}
   133  		granter, ok := simtypes.FindAccount(accs, granterAddr)
   134  
   135  		if !ok {
   136  			return simtypes.NoOpMsg(feegrant.ModuleName, TypeMsgRevokeAllowance, "Account not found"), nil, nil
   137  		}
   138  
   139  		account := ak.GetAccount(ctx, granter.Address)
   140  		spendableCoins := bk.SpendableCoins(ctx, account.GetAddress())
   141  
   142  		msg := feegrant.NewMsgRevokeAllowance(granterAddr, granteeAddr)
   143  
   144  		txCtx := simulation.OperationInput{
   145  			R:               r,
   146  			App:             app,
   147  			TxGen:           simappparams.MakeTestEncodingConfig().TxConfig,
   148  			Cdc:             nil,
   149  			Msg:             &msg,
   150  			MsgType:         TypeMsgRevokeAllowance,
   151  			Context:         ctx,
   152  			SimAccount:      granter,
   153  			AccountKeeper:   ak,
   154  			Bankkeeper:      bk,
   155  			ModuleName:      feegrant.ModuleName,
   156  			CoinsSpentInMsg: spendableCoins,
   157  		}
   158  
   159  		return simulation.GenAndDeliverTxWithRandFees(txCtx)
   160  	}
   161  }