2019-10-23 02:14:45 -07:00
package simulation
import (
"fmt"
"math/rand"
"github.com/cosmos/cosmos-sdk/baseapp"
2019-12-05 01:29:54 -08:00
"github.com/cosmos/cosmos-sdk/codec"
2019-10-23 02:14:45 -07:00
"github.com/cosmos/cosmos-sdk/simapp/helpers"
2019-12-05 01:29:54 -08:00
simappparams "github.com/cosmos/cosmos-sdk/simapp/params"
2019-10-23 02:14:45 -07:00
sdk "github.com/cosmos/cosmos-sdk/types"
2020-03-23 04:55:44 -07:00
simtypes "github.com/cosmos/cosmos-sdk/types/simulation"
2019-10-23 02:14:45 -07:00
"github.com/cosmos/cosmos-sdk/x/simulation"
"github.com/cosmos/cosmos-sdk/x/staking/keeper"
"github.com/cosmos/cosmos-sdk/x/staking/types"
)
2019-12-05 01:29:54 -08:00
// Simulation operation weights constants
const (
OpWeightMsgCreateValidator = "op_weight_msg_create_validator"
OpWeightMsgEditValidator = "op_weight_msg_edit_validator"
OpWeightMsgDelegate = "op_weight_msg_delegate"
OpWeightMsgUndelegate = "op_weight_msg_undelegate"
OpWeightMsgBeginRedelegate = "op_weight_msg_begin_redelegate"
)
// WeightedOperations returns all the operations from the module with their respective weights
func WeightedOperations (
2020-08-13 06:20:02 -07:00
appParams simtypes . AppParams , cdc codec . JSONMarshaler , ak types . AccountKeeper ,
2020-01-30 13:31:16 -08:00
bk types . BankKeeper , k keeper . Keeper ,
2019-12-05 01:29:54 -08:00
) simulation . WeightedOperations {
var (
weightMsgCreateValidator int
weightMsgEditValidator int
weightMsgDelegate int
weightMsgUndelegate int
weightMsgBeginRedelegate int
)
appParams . GetOrGenerate ( cdc , OpWeightMsgCreateValidator , & weightMsgCreateValidator , nil ,
func ( _ * rand . Rand ) {
weightMsgCreateValidator = simappparams . DefaultWeightMsgCreateValidator
} ,
)
appParams . GetOrGenerate ( cdc , OpWeightMsgEditValidator , & weightMsgEditValidator , nil ,
func ( _ * rand . Rand ) {
weightMsgEditValidator = simappparams . DefaultWeightMsgEditValidator
} ,
)
appParams . GetOrGenerate ( cdc , OpWeightMsgDelegate , & weightMsgDelegate , nil ,
func ( _ * rand . Rand ) {
weightMsgDelegate = simappparams . DefaultWeightMsgDelegate
} ,
)
appParams . GetOrGenerate ( cdc , OpWeightMsgUndelegate , & weightMsgUndelegate , nil ,
func ( _ * rand . Rand ) {
weightMsgUndelegate = simappparams . DefaultWeightMsgUndelegate
} ,
)
appParams . GetOrGenerate ( cdc , OpWeightMsgBeginRedelegate , & weightMsgBeginRedelegate , nil ,
func ( _ * rand . Rand ) {
weightMsgBeginRedelegate = simappparams . DefaultWeightMsgBeginRedelegate
} ,
)
return simulation . WeightedOperations {
simulation . NewWeightedOperation (
weightMsgCreateValidator ,
2020-01-30 13:31:16 -08:00
SimulateMsgCreateValidator ( ak , bk , k ) ,
2019-12-05 01:29:54 -08:00
) ,
simulation . NewWeightedOperation (
weightMsgEditValidator ,
2020-01-30 13:31:16 -08:00
SimulateMsgEditValidator ( ak , bk , k ) ,
2019-12-05 01:29:54 -08:00
) ,
simulation . NewWeightedOperation (
weightMsgDelegate ,
2020-01-30 13:31:16 -08:00
SimulateMsgDelegate ( ak , bk , k ) ,
2019-12-05 01:29:54 -08:00
) ,
simulation . NewWeightedOperation (
weightMsgUndelegate ,
2020-01-30 13:31:16 -08:00
SimulateMsgUndelegate ( ak , bk , k ) ,
2019-12-05 01:29:54 -08:00
) ,
simulation . NewWeightedOperation (
weightMsgBeginRedelegate ,
2020-01-30 13:31:16 -08:00
SimulateMsgBeginRedelegate ( ak , bk , k ) ,
2019-12-05 01:29:54 -08:00
) ,
}
}
2019-10-23 02:14:45 -07:00
// SimulateMsgCreateValidator generates a MsgCreateValidator with random values
2020-02-05 11:32:45 -08:00
// nolint: interfacer
2020-03-23 04:55:44 -07:00
func SimulateMsgCreateValidator ( ak types . AccountKeeper , bk types . BankKeeper , k keeper . Keeper ) simtypes . Operation {
2019-10-23 02:14:45 -07:00
return func (
2020-03-23 04:55:44 -07:00
r * rand . Rand , app * baseapp . BaseApp , ctx sdk . Context , accs [ ] simtypes . Account , chainID string ,
) ( simtypes . OperationMsg , [ ] simtypes . FutureOperation , error ) {
simAccount , _ := simtypes . RandomAcc ( r , accs )
2019-10-23 02:14:45 -07:00
address := sdk . ValAddress ( simAccount . Address )
// ensure the validator doesn't exist already
_ , found := k . GetValidator ( ctx , address )
if found {
2020-05-26 09:52:23 -07:00
return simtypes . NoOpMsg ( types . ModuleName , types . TypeMsgCreateValidator , "unable to find validator" ) , nil , nil
2019-10-23 02:14:45 -07:00
}
denom := k . GetParams ( ctx ) . BondDenom
2020-01-30 13:31:16 -08:00
balance := bk . GetBalance ( ctx , simAccount . Address , denom ) . Amount
if ! balance . IsPositive ( ) {
2020-05-26 09:52:23 -07:00
return simtypes . NoOpMsg ( types . ModuleName , types . TypeMsgCreateValidator , "balance is negative" ) , nil , nil
2019-10-23 02:14:45 -07:00
}
2020-03-23 04:55:44 -07:00
amount , err := simtypes . RandPositiveInt ( r , balance )
2019-10-23 02:14:45 -07:00
if err != nil {
2020-05-26 09:52:23 -07:00
return simtypes . NoOpMsg ( types . ModuleName , types . TypeMsgCreateValidator , "unable to generate positive amount" ) , nil , err
2019-10-23 02:14:45 -07:00
}
selfDelegation := sdk . NewCoin ( denom , amount )
account := ak . GetAccount ( ctx , simAccount . Address )
2020-01-30 13:31:16 -08:00
spendable := bk . SpendableCoins ( ctx , account . GetAddress ( ) )
2019-10-23 02:14:45 -07:00
var fees sdk . Coins
2020-05-02 12:26:59 -07:00
2020-01-30 13:31:16 -08:00
coins , hasNeg := spendable . SafeSub ( sdk . Coins { selfDelegation } )
2019-10-23 02:14:45 -07:00
if ! hasNeg {
2020-03-23 04:55:44 -07:00
fees , err = simtypes . RandomFees ( r , ctx , coins )
2019-10-23 02:14:45 -07:00
if err != nil {
2020-05-26 09:52:23 -07:00
return simtypes . NoOpMsg ( types . ModuleName , types . TypeMsgCreateValidator , "unable to generate fees" ) , nil , err
2019-10-23 02:14:45 -07:00
}
}
description := types . NewDescription (
2020-03-23 04:55:44 -07:00
simtypes . RandStringOfLength ( r , 10 ) ,
simtypes . RandStringOfLength ( r , 10 ) ,
simtypes . RandStringOfLength ( r , 10 ) ,
simtypes . RandStringOfLength ( r , 10 ) ,
simtypes . RandStringOfLength ( r , 10 ) ,
2019-10-23 02:14:45 -07:00
)
2020-03-23 04:55:44 -07:00
maxCommission := sdk . NewDecWithPrec ( int64 ( simtypes . RandIntBetween ( r , 0 , 100 ) ) , 2 )
2019-10-23 02:14:45 -07:00
commission := types . NewCommissionRates (
2020-03-23 04:55:44 -07:00
simtypes . RandomDecAmount ( r , maxCommission ) ,
2019-10-23 02:14:45 -07:00
maxCommission ,
2020-03-23 04:55:44 -07:00
simtypes . RandomDecAmount ( r , maxCommission ) ,
2019-10-23 02:14:45 -07:00
)
2020-10-19 06:04:55 -07:00
msg , err := types . NewMsgCreateValidator ( address , simAccount . ConsKey . PubKey ( ) , selfDelegation , description , commission , sdk . OneInt ( ) )
if err != nil {
return simtypes . NoOpMsg ( types . ModuleName , msg . Type ( ) , "unable to create CreateValidator message" ) , nil , err
}
2019-10-23 02:14:45 -07:00
2020-10-27 04:33:48 -07:00
txGen := simappparams . MakeTestEncodingConfig ( ) . TxConfig
2020-07-14 10:33:31 -07:00
tx , err := helpers . GenTx (
txGen ,
2019-10-23 02:14:45 -07:00
[ ] sdk . Msg { msg } ,
fees ,
2019-12-18 06:48:22 -08:00
helpers . DefaultGenTxGas ,
2019-10-23 02:14:45 -07:00
chainID ,
[ ] uint64 { account . GetAccountNumber ( ) } ,
[ ] uint64 { account . GetSequence ( ) } ,
simAccount . PrivKey ,
)
2020-07-14 10:33:31 -07:00
if err != nil {
return simtypes . NoOpMsg ( types . ModuleName , msg . Type ( ) , "unable to generate mock tx" ) , nil , err
}
2019-10-23 02:14:45 -07:00
2020-10-19 11:04:44 -07:00
_ , _ , err = app . Deliver ( txGen . TxEncoder ( ) , tx )
2019-12-27 09:57:54 -08:00
if err != nil {
2020-05-26 09:52:23 -07:00
return simtypes . NoOpMsg ( types . ModuleName , msg . Type ( ) , "unable to deliver tx" ) , nil , err
2019-10-23 02:14:45 -07:00
}
2020-03-23 04:55:44 -07:00
return simtypes . NewOperationMsg ( msg , true , "" ) , nil , nil
2019-10-23 02:14:45 -07:00
}
}
// SimulateMsgEditValidator generates a MsgEditValidator with random values
2020-02-05 11:32:45 -08:00
// nolint: interfacer
2020-03-23 04:55:44 -07:00
func SimulateMsgEditValidator ( ak types . AccountKeeper , bk types . BankKeeper , k keeper . Keeper ) simtypes . Operation {
2019-10-23 02:14:45 -07:00
return func (
2020-03-23 04:55:44 -07:00
r * rand . Rand , app * baseapp . BaseApp , ctx sdk . Context , accs [ ] simtypes . Account , chainID string ,
) ( simtypes . OperationMsg , [ ] simtypes . FutureOperation , error ) {
2019-10-23 02:14:45 -07:00
if len ( k . GetAllValidators ( ctx ) ) == 0 {
2020-05-26 09:52:23 -07:00
return simtypes . NoOpMsg ( types . ModuleName , types . TypeMsgEditValidator , "number of validators equal zero" ) , nil , nil
2019-10-23 02:14:45 -07:00
}
val , ok := keeper . RandomValidator ( r , k , ctx )
if ! ok {
2020-05-26 09:52:23 -07:00
return simtypes . NoOpMsg ( types . ModuleName , types . TypeMsgEditValidator , "unable to pick a validator" ) , nil , nil
2019-10-23 02:14:45 -07:00
}
address := val . GetOperator ( )
2020-03-23 04:55:44 -07:00
newCommissionRate := simtypes . RandomDecAmount ( r , val . Commission . MaxRate )
2019-10-23 02:14:45 -07:00
if err := val . Commission . ValidateNewRate ( newCommissionRate , ctx . BlockHeader ( ) . Time ) ; err != nil {
// skip as the commission is invalid
2020-05-26 09:52:23 -07:00
return simtypes . NoOpMsg ( types . ModuleName , types . TypeMsgEditValidator , "invalid commission rate" ) , nil , nil
2019-10-23 02:14:45 -07:00
}
2020-03-23 04:55:44 -07:00
simAccount , found := simtypes . FindAccount ( accs , sdk . AccAddress ( val . GetOperator ( ) ) )
2019-10-23 02:14:45 -07:00
if ! found {
2020-05-26 09:52:23 -07:00
return simtypes . NoOpMsg ( types . ModuleName , types . TypeMsgEditValidator , "unable to find account" ) , nil , fmt . Errorf ( "validator %s not found" , val . GetOperator ( ) )
2019-10-23 02:14:45 -07:00
}
account := ak . GetAccount ( ctx , simAccount . Address )
2020-01-30 13:31:16 -08:00
spendable := bk . SpendableCoins ( ctx , account . GetAddress ( ) )
2020-03-23 04:55:44 -07:00
fees , err := simtypes . RandomFees ( r , ctx , spendable )
2019-10-23 02:14:45 -07:00
if err != nil {
2020-05-26 09:52:23 -07:00
return simtypes . NoOpMsg ( types . ModuleName , types . TypeMsgEditValidator , "unable to generate fees" ) , nil , err
2019-10-23 02:14:45 -07:00
}
description := types . NewDescription (
2020-03-23 04:55:44 -07:00
simtypes . RandStringOfLength ( r , 10 ) ,
simtypes . RandStringOfLength ( r , 10 ) ,
simtypes . RandStringOfLength ( r , 10 ) ,
simtypes . RandStringOfLength ( r , 10 ) ,
simtypes . RandStringOfLength ( r , 10 ) ,
2019-10-23 02:14:45 -07:00
)
msg := types . NewMsgEditValidator ( address , description , & newCommissionRate , nil )
2020-10-27 04:33:48 -07:00
txGen := simappparams . MakeTestEncodingConfig ( ) . TxConfig
2020-07-14 10:33:31 -07:00
tx , err := helpers . GenTx (
txGen ,
2019-10-23 02:14:45 -07:00
[ ] sdk . Msg { msg } ,
fees ,
2019-12-18 06:48:22 -08:00
helpers . DefaultGenTxGas ,
2019-10-23 02:14:45 -07:00
chainID ,
[ ] uint64 { account . GetAccountNumber ( ) } ,
[ ] uint64 { account . GetSequence ( ) } ,
simAccount . PrivKey ,
)
2020-07-14 10:33:31 -07:00
if err != nil {
return simtypes . NoOpMsg ( types . ModuleName , msg . Type ( ) , "unable to generate mock tx" ) , nil , err
}
2019-10-23 02:14:45 -07:00
2020-10-19 11:04:44 -07:00
_ , _ , err = app . Deliver ( txGen . TxEncoder ( ) , tx )
2019-12-27 09:57:54 -08:00
if err != nil {
2020-05-26 09:52:23 -07:00
return simtypes . NoOpMsg ( types . ModuleName , msg . Type ( ) , "unable to deliver tx" ) , nil , err
2019-10-23 02:14:45 -07:00
}
2020-03-23 04:55:44 -07:00
return simtypes . NewOperationMsg ( msg , true , "" ) , nil , nil
2019-10-23 02:14:45 -07:00
}
}
// SimulateMsgDelegate generates a MsgDelegate with random values
2020-02-05 11:32:45 -08:00
// nolint: interfacer
2020-03-23 04:55:44 -07:00
func SimulateMsgDelegate ( ak types . AccountKeeper , bk types . BankKeeper , k keeper . Keeper ) simtypes . Operation {
2019-10-23 02:14:45 -07:00
return func (
2020-03-23 04:55:44 -07:00
r * rand . Rand , app * baseapp . BaseApp , ctx sdk . Context , accs [ ] simtypes . Account , chainID string ,
) ( simtypes . OperationMsg , [ ] simtypes . FutureOperation , error ) {
2019-10-23 02:14:45 -07:00
denom := k . GetParams ( ctx ) . BondDenom
2020-05-02 12:26:59 -07:00
2019-10-23 02:14:45 -07:00
if len ( k . GetAllValidators ( ctx ) ) == 0 {
2020-05-26 09:52:23 -07:00
return simtypes . NoOpMsg ( types . ModuleName , types . TypeMsgDelegate , "number of validators equal zero" ) , nil , nil
2019-10-23 02:14:45 -07:00
}
2020-03-23 04:55:44 -07:00
simAccount , _ := simtypes . RandomAcc ( r , accs )
2019-10-23 02:14:45 -07:00
val , ok := keeper . RandomValidator ( r , k , ctx )
if ! ok {
2020-05-26 09:52:23 -07:00
return simtypes . NoOpMsg ( types . ModuleName , types . TypeMsgDelegate , "unable to pick a validator" ) , nil , nil
2019-10-23 02:14:45 -07:00
}
if val . InvalidExRate ( ) {
2020-05-26 09:52:23 -07:00
return simtypes . NoOpMsg ( types . ModuleName , types . TypeMsgDelegate , "validator's invalid echange rate" ) , nil , nil
2019-10-23 02:14:45 -07:00
}
2020-01-30 13:31:16 -08:00
amount := bk . GetBalance ( ctx , simAccount . Address , denom ) . Amount
2019-10-23 02:14:45 -07:00
if ! amount . IsPositive ( ) {
2020-05-26 09:52:23 -07:00
return simtypes . NoOpMsg ( types . ModuleName , types . TypeMsgDelegate , "balance is negative" ) , nil , nil
2019-10-23 02:14:45 -07:00
}
2020-03-23 04:55:44 -07:00
amount , err := simtypes . RandPositiveInt ( r , amount )
2019-10-23 02:14:45 -07:00
if err != nil {
2020-05-26 09:52:23 -07:00
return simtypes . NoOpMsg ( types . ModuleName , types . TypeMsgDelegate , "unable to generate positive amount" ) , nil , err
2019-10-23 02:14:45 -07:00
}
bondAmt := sdk . NewCoin ( denom , amount )
account := ak . GetAccount ( ctx , simAccount . Address )
2020-01-30 13:31:16 -08:00
spendable := bk . SpendableCoins ( ctx , account . GetAddress ( ) )
2019-10-23 02:14:45 -07:00
var fees sdk . Coins
2020-05-02 12:26:59 -07:00
2020-01-30 13:31:16 -08:00
coins , hasNeg := spendable . SafeSub ( sdk . Coins { bondAmt } )
2019-10-23 02:14:45 -07:00
if ! hasNeg {
2020-03-23 04:55:44 -07:00
fees , err = simtypes . RandomFees ( r , ctx , coins )
2019-10-23 02:14:45 -07:00
if err != nil {
2020-05-26 09:52:23 -07:00
return simtypes . NoOpMsg ( types . ModuleName , types . TypeMsgDelegate , "unable to generate fees" ) , nil , err
2019-10-23 02:14:45 -07:00
}
}
msg := types . NewMsgDelegate ( simAccount . Address , val . GetOperator ( ) , bondAmt )
2020-10-27 04:33:48 -07:00
txGen := simappparams . MakeTestEncodingConfig ( ) . TxConfig
2020-07-14 10:33:31 -07:00
tx , err := helpers . GenTx (
txGen ,
2019-10-23 02:14:45 -07:00
[ ] sdk . Msg { msg } ,
fees ,
2019-12-18 06:48:22 -08:00
helpers . DefaultGenTxGas ,
2019-10-23 02:14:45 -07:00
chainID ,
[ ] uint64 { account . GetAccountNumber ( ) } ,
[ ] uint64 { account . GetSequence ( ) } ,
simAccount . PrivKey ,
)
2020-07-14 10:33:31 -07:00
if err != nil {
return simtypes . NoOpMsg ( types . ModuleName , msg . Type ( ) , "unable to generate mock tx" ) , nil , err
}
2019-10-23 02:14:45 -07:00
2020-10-19 11:04:44 -07:00
_ , _ , err = app . Deliver ( txGen . TxEncoder ( ) , tx )
2019-12-27 09:57:54 -08:00
if err != nil {
2020-05-26 09:52:23 -07:00
return simtypes . NoOpMsg ( types . ModuleName , msg . Type ( ) , "unable to deliver tx" ) , nil , err
2019-10-23 02:14:45 -07:00
}
2020-03-23 04:55:44 -07:00
return simtypes . NewOperationMsg ( msg , true , "" ) , nil , nil
2019-10-23 02:14:45 -07:00
}
}
// SimulateMsgUndelegate generates a MsgUndelegate with random values
2020-02-05 11:32:45 -08:00
// nolint: interfacer
2020-03-23 04:55:44 -07:00
func SimulateMsgUndelegate ( ak types . AccountKeeper , bk types . BankKeeper , k keeper . Keeper ) simtypes . Operation {
2019-10-23 02:14:45 -07:00
return func (
2020-03-23 04:55:44 -07:00
r * rand . Rand , app * baseapp . BaseApp , ctx sdk . Context , accs [ ] simtypes . Account , chainID string ,
) ( simtypes . OperationMsg , [ ] simtypes . FutureOperation , error ) {
2019-10-23 02:14:45 -07:00
// get random validator
validator , ok := keeper . RandomValidator ( r , k , ctx )
if ! ok {
2020-05-26 09:52:23 -07:00
return simtypes . NoOpMsg ( types . ModuleName , types . TypeMsgUndelegate , "validator is not ok" ) , nil , nil
2019-10-23 02:14:45 -07:00
}
2020-05-02 12:26:59 -07:00
valAddr := validator . GetOperator ( )
2020-09-25 03:25:37 -07:00
delegations := k . GetValidatorDelegations ( ctx , validator . GetOperator ( ) )
2020-07-11 18:56:28 -07:00
if delegations == nil {
return simtypes . NoOpMsg ( types . ModuleName , types . TypeMsgUndelegate , "keeper does have any delegation entries" ) , nil , nil
}
2019-10-23 02:14:45 -07:00
// get random delegator from validator
delegation := delegations [ r . Intn ( len ( delegations ) ) ]
delAddr := delegation . GetDelegatorAddr ( )
if k . HasMaxUnbondingDelegationEntries ( ctx , delAddr , valAddr ) {
2020-05-26 09:52:23 -07:00
return simtypes . NoOpMsg ( types . ModuleName , types . TypeMsgUndelegate , "keeper does have a max unbonding delegation entries" ) , nil , nil
2019-10-23 02:14:45 -07:00
}
totalBond := validator . TokensFromShares ( delegation . GetShares ( ) ) . TruncateInt ( )
if ! totalBond . IsPositive ( ) {
2020-05-26 09:52:23 -07:00
return simtypes . NoOpMsg ( types . ModuleName , types . TypeMsgUndelegate , "total bond is negative" ) , nil , nil
2019-10-23 02:14:45 -07:00
}
2020-03-23 04:55:44 -07:00
unbondAmt , err := simtypes . RandPositiveInt ( r , totalBond )
2019-10-23 02:14:45 -07:00
if err != nil {
2020-05-26 09:52:23 -07:00
return simtypes . NoOpMsg ( types . ModuleName , types . TypeMsgUndelegate , "invalid unbond amount" ) , nil , err
2019-10-23 02:14:45 -07:00
}
if unbondAmt . IsZero ( ) {
2020-05-26 09:52:23 -07:00
return simtypes . NoOpMsg ( types . ModuleName , types . TypeMsgUndelegate , "unbond amount is zero" ) , nil , nil
2019-10-23 02:14:45 -07:00
}
msg := types . NewMsgUndelegate (
delAddr , valAddr , sdk . NewCoin ( k . BondDenom ( ctx ) , unbondAmt ) ,
)
// need to retrieve the simulation account associated with delegation to retrieve PrivKey
2020-03-23 04:55:44 -07:00
var simAccount simtypes . Account
2020-05-02 12:26:59 -07:00
2019-10-23 02:14:45 -07:00
for _ , simAcc := range accs {
if simAcc . Address . Equals ( delAddr ) {
simAccount = simAcc
break
}
}
// if simaccount.PrivKey == nil, delegation address does not exist in accs. Return error
if simAccount . PrivKey == nil {
2020-05-26 09:52:23 -07:00
return simtypes . NoOpMsg ( types . ModuleName , msg . Type ( ) , "account private key is nil" ) , nil , fmt . Errorf ( "delegation addr: %s does not exist in simulation accounts" , delAddr )
2019-10-23 02:14:45 -07:00
}
account := ak . GetAccount ( ctx , delAddr )
2020-01-30 13:31:16 -08:00
spendable := bk . SpendableCoins ( ctx , account . GetAddress ( ) )
2020-03-23 04:55:44 -07:00
fees , err := simtypes . RandomFees ( r , ctx , spendable )
2019-10-23 02:14:45 -07:00
if err != nil {
2020-05-26 09:52:23 -07:00
return simtypes . NoOpMsg ( types . ModuleName , msg . Type ( ) , "unable to generate fees" ) , nil , err
2019-10-23 02:14:45 -07:00
}
2020-10-27 04:33:48 -07:00
txGen := simappparams . MakeTestEncodingConfig ( ) . TxConfig
2020-07-14 10:33:31 -07:00
tx , err := helpers . GenTx (
txGen ,
2019-10-23 02:14:45 -07:00
[ ] sdk . Msg { msg } ,
fees ,
2019-12-18 06:48:22 -08:00
helpers . DefaultGenTxGas ,
2019-10-23 02:14:45 -07:00
chainID ,
[ ] uint64 { account . GetAccountNumber ( ) } ,
[ ] uint64 { account . GetSequence ( ) } ,
simAccount . PrivKey ,
)
2020-07-14 10:33:31 -07:00
if err != nil {
return simtypes . NoOpMsg ( types . ModuleName , msg . Type ( ) , "unable to generate mock tx" ) , nil , err
}
2019-10-23 02:14:45 -07:00
2020-10-19 11:04:44 -07:00
_ , _ , err = app . Deliver ( txGen . TxEncoder ( ) , tx )
2019-12-27 09:57:54 -08:00
if err != nil {
2020-05-26 09:52:23 -07:00
return simtypes . NoOpMsg ( types . ModuleName , msg . Type ( ) , "unable to deliver tx" ) , nil , err
2019-10-23 02:14:45 -07:00
}
2020-03-23 04:55:44 -07:00
return simtypes . NewOperationMsg ( msg , true , "" ) , nil , nil
2019-10-23 02:14:45 -07:00
}
}
// SimulateMsgBeginRedelegate generates a MsgBeginRedelegate with random values
2020-02-05 11:32:45 -08:00
// nolint: interfacer
2020-03-23 04:55:44 -07:00
func SimulateMsgBeginRedelegate ( ak types . AccountKeeper , bk types . BankKeeper , k keeper . Keeper ) simtypes . Operation {
2019-10-23 02:14:45 -07:00
return func (
2020-03-23 04:55:44 -07:00
r * rand . Rand , app * baseapp . BaseApp , ctx sdk . Context , accs [ ] simtypes . Account , chainID string ,
) ( simtypes . OperationMsg , [ ] simtypes . FutureOperation , error ) {
2019-10-23 02:14:45 -07:00
// get random source validator
srcVal , ok := keeper . RandomValidator ( r , k , ctx )
if ! ok {
2020-05-26 09:52:23 -07:00
return simtypes . NoOpMsg ( types . ModuleName , types . TypeMsgBeginRedelegate , "unable to pick validator" ) , nil , nil
2019-10-23 02:14:45 -07:00
}
2020-01-30 13:31:16 -08:00
srcAddr := srcVal . GetOperator ( )
2019-10-23 02:14:45 -07:00
delegations := k . GetValidatorDelegations ( ctx , srcAddr )
2020-07-11 18:56:28 -07:00
if delegations == nil {
return simtypes . NoOpMsg ( types . ModuleName , types . TypeMsgBeginRedelegate , "keeper does have any delegation entries" ) , nil , nil
}
2019-10-23 02:14:45 -07:00
// get random delegator from src validator
delegation := delegations [ r . Intn ( len ( delegations ) ) ]
delAddr := delegation . GetDelegatorAddr ( )
if k . HasReceivingRedelegation ( ctx , delAddr , srcAddr ) {
2020-05-26 09:52:23 -07:00
return simtypes . NoOpMsg ( types . ModuleName , types . TypeMsgBeginRedelegate , "receveing redelegation is not allowed" ) , nil , nil // skip
2019-10-23 02:14:45 -07:00
}
// get random destination validator
destVal , ok := keeper . RandomValidator ( r , k , ctx )
if ! ok {
2020-05-26 09:52:23 -07:00
return simtypes . NoOpMsg ( types . ModuleName , types . TypeMsgBeginRedelegate , "unable to pick validator" ) , nil , nil
2019-10-23 02:14:45 -07:00
}
2020-05-02 12:26:59 -07:00
destAddr := destVal . GetOperator ( )
if srcAddr . Equals ( destAddr ) || destVal . InvalidExRate ( ) || k . HasMaxRedelegationEntries ( ctx , delAddr , srcAddr , destAddr ) {
2020-05-26 09:52:23 -07:00
return simtypes . NoOpMsg ( types . ModuleName , types . TypeMsgBeginRedelegate , "checks failed" ) , nil , nil
2019-10-23 02:14:45 -07:00
}
totalBond := srcVal . TokensFromShares ( delegation . GetShares ( ) ) . TruncateInt ( )
if ! totalBond . IsPositive ( ) {
2020-05-26 09:52:23 -07:00
return simtypes . NoOpMsg ( types . ModuleName , types . TypeMsgBeginRedelegate , "total bond is negative" ) , nil , nil
2019-10-23 02:14:45 -07:00
}
2020-03-23 04:55:44 -07:00
redAmt , err := simtypes . RandPositiveInt ( r , totalBond )
2019-10-23 02:14:45 -07:00
if err != nil {
2020-05-26 09:52:23 -07:00
return simtypes . NoOpMsg ( types . ModuleName , types . TypeMsgBeginRedelegate , "unable to generate positive amount" ) , nil , err
2019-10-23 02:14:45 -07:00
}
if redAmt . IsZero ( ) {
2020-05-26 09:52:23 -07:00
return simtypes . NoOpMsg ( types . ModuleName , types . TypeMsgBeginRedelegate , "amount is zero" ) , nil , nil
2019-10-23 02:14:45 -07:00
}
// check if the shares truncate to zero
shares , err := srcVal . SharesFromTokens ( redAmt )
if err != nil {
2020-05-26 09:52:23 -07:00
return simtypes . NoOpMsg ( types . ModuleName , types . TypeMsgBeginRedelegate , "invalid shares" ) , nil , err
2019-10-23 02:14:45 -07:00
}
if srcVal . TokensFromShares ( shares ) . TruncateInt ( ) . IsZero ( ) {
2020-05-26 09:52:23 -07:00
return simtypes . NoOpMsg ( types . ModuleName , types . TypeMsgBeginRedelegate , "shares truncate to zero" ) , nil , nil // skip
2019-10-23 02:14:45 -07:00
}
// need to retrieve the simulation account associated with delegation to retrieve PrivKey
2020-03-23 04:55:44 -07:00
var simAccount simtypes . Account
2020-05-02 12:26:59 -07:00
2019-10-23 02:14:45 -07:00
for _ , simAcc := range accs {
if simAcc . Address . Equals ( delAddr ) {
simAccount = simAcc
break
}
}
2020-01-30 13:31:16 -08:00
2019-10-23 02:14:45 -07:00
// if simaccount.PrivKey == nil, delegation address does not exist in accs. Return error
if simAccount . PrivKey == nil {
2020-05-26 09:52:23 -07:00
return simtypes . NoOpMsg ( types . ModuleName , types . TypeMsgBeginRedelegate , "account private key is nil" ) , nil , fmt . Errorf ( "delegation addr: %s does not exist in simulation accounts" , delAddr )
2019-10-23 02:14:45 -07:00
}
account := ak . GetAccount ( ctx , delAddr )
2020-01-30 13:31:16 -08:00
spendable := bk . SpendableCoins ( ctx , account . GetAddress ( ) )
2020-03-23 04:55:44 -07:00
fees , err := simtypes . RandomFees ( r , ctx , spendable )
2019-10-23 02:14:45 -07:00
if err != nil {
2020-05-26 09:52:23 -07:00
return simtypes . NoOpMsg ( types . ModuleName , types . TypeMsgBeginRedelegate , "unable to generate fees" ) , nil , err
2019-10-23 02:14:45 -07:00
}
msg := types . NewMsgBeginRedelegate (
delAddr , srcAddr , destAddr ,
sdk . NewCoin ( k . BondDenom ( ctx ) , redAmt ) ,
)
2020-10-27 04:33:48 -07:00
txGen := simappparams . MakeTestEncodingConfig ( ) . TxConfig
2020-07-14 10:33:31 -07:00
tx , err := helpers . GenTx (
txGen ,
2019-10-23 02:14:45 -07:00
[ ] sdk . Msg { msg } ,
fees ,
2019-12-18 06:48:22 -08:00
helpers . DefaultGenTxGas ,
2019-10-23 02:14:45 -07:00
chainID ,
[ ] uint64 { account . GetAccountNumber ( ) } ,
[ ] uint64 { account . GetSequence ( ) } ,
simAccount . PrivKey ,
)
2020-07-14 10:33:31 -07:00
if err != nil {
return simtypes . NoOpMsg ( types . ModuleName , msg . Type ( ) , "unable to generate mock tx" ) , nil , err
}
2019-10-23 02:14:45 -07:00
2020-10-19 11:04:44 -07:00
_ , _ , err = app . Deliver ( txGen . TxEncoder ( ) , tx )
2019-12-27 09:57:54 -08:00
if err != nil {
2020-05-26 09:52:23 -07:00
return simtypes . NoOpMsg ( types . ModuleName , msg . Type ( ) , "unable to deliver tx" ) , nil , err
2019-10-23 02:14:45 -07:00
}
2020-03-23 04:55:44 -07:00
return simtypes . NewOperationMsg ( msg , true , "" ) , nil , nil
2019-10-23 02:14:45 -07:00
}
}