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

     1  package simulation
     2  
     3  import (
     4  	"errors"
     5  	"math/rand"
     6  
     7  	"github.com/Finschia/finschia-sdk/baseapp"
     8  	"github.com/Finschia/finschia-sdk/codec"
     9  	"github.com/Finschia/finschia-sdk/simapp/helpers"
    10  	simappparams "github.com/Finschia/finschia-sdk/simapp/params"
    11  	sdk "github.com/Finschia/finschia-sdk/types"
    12  	simtypes "github.com/Finschia/finschia-sdk/types/simulation"
    13  	"github.com/Finschia/finschia-sdk/x/simulation"
    14  	"github.com/Finschia/finschia-sdk/x/slashing/keeper"
    15  	"github.com/Finschia/finschia-sdk/x/slashing/types"
    16  	stakingkeeper "github.com/Finschia/finschia-sdk/x/staking/keeper"
    17  )
    18  
    19  // Simulation operation weights constants
    20  const (
    21  	OpWeightMsgUnjail = "op_weight_msg_unjail"
    22  )
    23  
    24  // WeightedOperations returns all the operations from the module with their respective weights
    25  func WeightedOperations(
    26  	appParams simtypes.AppParams, cdc codec.JSONCodec, ak types.AccountKeeper,
    27  	bk types.BankKeeper, k keeper.Keeper, sk types.StakingKeeper,
    28  ) simulation.WeightedOperations {
    29  	var weightMsgUnjail int
    30  	appParams.GetOrGenerate(cdc, OpWeightMsgUnjail, &weightMsgUnjail, nil,
    31  		func(_ *rand.Rand) {
    32  			weightMsgUnjail = simappparams.DefaultWeightMsgUnjail
    33  		},
    34  	)
    35  
    36  	return simulation.WeightedOperations{
    37  		simulation.NewWeightedOperation(
    38  			weightMsgUnjail,
    39  			SimulateMsgUnjail(ak, bk, k, sk.(stakingkeeper.Keeper)),
    40  		),
    41  	}
    42  }
    43  
    44  // SimulateMsgUnjail generates a MsgUnjail with random values
    45  func SimulateMsgUnjail(ak types.AccountKeeper, bk types.BankKeeper, k keeper.Keeper, sk stakingkeeper.Keeper) simtypes.Operation {
    46  	return func(
    47  		r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context,
    48  		accs []simtypes.Account, chainID string,
    49  	) (simtypes.OperationMsg, []simtypes.FutureOperation, error) {
    50  		validator, ok := stakingkeeper.RandomValidator(r, sk, ctx)
    51  		if !ok {
    52  			return simtypes.NoOpMsg(types.ModuleName, types.TypeMsgUnjail, "validator is not ok"), nil, nil // skip
    53  		}
    54  
    55  		simAccount, found := simtypes.FindAccount(accs, sdk.AccAddress(validator.GetOperator()))
    56  		if !found {
    57  			return simtypes.NoOpMsg(types.ModuleName, types.TypeMsgUnjail, "unable to find account"), nil, nil // skip
    58  		}
    59  
    60  		if !validator.IsJailed() {
    61  			// TODO: due to this condition this message is almost, if not always, skipped !
    62  			return simtypes.NoOpMsg(types.ModuleName, types.TypeMsgUnjail, "validator is not jailed"), nil, nil
    63  		}
    64  
    65  		consAddr, err := validator.GetConsAddr()
    66  		if err != nil {
    67  			return simtypes.NoOpMsg(types.ModuleName, types.TypeMsgUnjail, "unable to get validator consensus key"), nil, err
    68  		}
    69  		info, found := k.GetValidatorSigningInfo(ctx, consAddr)
    70  		if !found {
    71  			return simtypes.NoOpMsg(types.ModuleName, types.TypeMsgUnjail, "unable to find validator signing info"), nil, nil // skip
    72  		}
    73  
    74  		selfDel := sk.Delegation(ctx, simAccount.Address, validator.GetOperator())
    75  		if selfDel == nil {
    76  			return simtypes.NoOpMsg(types.ModuleName, types.TypeMsgUnjail, "self delegation is nil"), nil, nil // skip
    77  		}
    78  
    79  		account := ak.GetAccount(ctx, sdk.AccAddress(validator.GetOperator()))
    80  		spendable := bk.SpendableCoins(ctx, account.GetAddress())
    81  
    82  		fees, err := simtypes.RandomFees(r, ctx, spendable)
    83  		if err != nil {
    84  			return simtypes.NoOpMsg(types.ModuleName, types.TypeMsgUnjail, "unable to generate fees"), nil, err
    85  		}
    86  
    87  		msg := types.NewMsgUnjail(validator.GetOperator())
    88  
    89  		txGen := simappparams.MakeTestEncodingConfig().TxConfig
    90  		tx, err := helpers.GenSignedMockTx(
    91  			r,
    92  			txGen,
    93  			[]sdk.Msg{msg},
    94  			fees,
    95  			helpers.DefaultGenTxGas,
    96  			chainID,
    97  			[]uint64{account.GetAccountNumber()},
    98  			[]uint64{account.GetSequence()},
    99  			simAccount.PrivKey,
   100  		)
   101  		if err != nil {
   102  			return simtypes.NoOpMsg(types.ModuleName, msg.Type(), "unable to generate mock tx"), nil, err
   103  		}
   104  
   105  		_, res, err := app.Deliver(txGen.TxEncoder(), tx)
   106  
   107  		// result should fail if:
   108  		// - validator cannot be unjailed due to tombstone
   109  		// - validator is still in jailed period
   110  		// - self delegation too low
   111  		if info.Tombstoned ||
   112  			ctx.BlockHeader().Time.Before(info.JailedUntil) ||
   113  			validator.TokensFromShares(selfDel.GetShares()).TruncateInt().LT(validator.GetMinSelfDelegation()) {
   114  			if res != nil && err == nil {
   115  				if info.Tombstoned {
   116  					return simtypes.NewOperationMsg(msg, true, "", nil), nil, errors.New("validator should not have been unjailed if validator tombstoned")
   117  				}
   118  				if ctx.BlockHeader().Time.Before(info.JailedUntil) {
   119  					return simtypes.NewOperationMsg(msg, true, "", nil), nil, errors.New("validator unjailed while validator still in jail period")
   120  				}
   121  				if validator.TokensFromShares(selfDel.GetShares()).TruncateInt().LT(validator.GetMinSelfDelegation()) {
   122  					return simtypes.NewOperationMsg(msg, true, "", nil), nil, errors.New("validator unjailed even though self-delegation too low")
   123  				}
   124  			}
   125  			// msg failed as expected
   126  			return simtypes.NewOperationMsg(msg, false, "", nil), nil, nil
   127  		}
   128  
   129  		if err != nil {
   130  			return simtypes.NoOpMsg(types.ModuleName, msg.Type(), "unable to deliver tx"), nil, err
   131  		}
   132  
   133  		return simtypes.NewOperationMsg(msg, true, "", nil), nil, nil
   134  	}
   135  }