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/distribution/keeper"
"github.com/cosmos/cosmos-sdk/x/distribution/types"
"github.com/cosmos/cosmos-sdk/x/simulation"
stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper"
)
2019-12-05 01:29:54 -08:00
// Simulation operation weights constants
const (
OpWeightMsgSetWithdrawAddress = "op_weight_msg_set_withdraw_address"
OpWeightMsgWithdrawDelegationReward = "op_weight_msg_withdraw_delegation_reward"
OpWeightMsgWithdrawValidatorCommission = "op_weight_msg_withdraw_validator_commission"
2019-12-10 20:02:15 -08:00
OpWeightMsgFundCommunityPool = "op_weight_msg_fund_community_pool"
2019-12-05 01:29:54 -08:00
)
// 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 , sk stakingkeeper . Keeper ,
2019-12-05 01:29:54 -08:00
) simulation . WeightedOperations {
var weightMsgSetWithdrawAddress int
appParams . GetOrGenerate ( cdc , OpWeightMsgSetWithdrawAddress , & weightMsgSetWithdrawAddress , nil ,
func ( _ * rand . Rand ) {
weightMsgSetWithdrawAddress = simappparams . DefaultWeightMsgSetWithdrawAddress
} ,
)
var weightMsgWithdrawDelegationReward int
appParams . GetOrGenerate ( cdc , OpWeightMsgWithdrawDelegationReward , & weightMsgWithdrawDelegationReward , nil ,
func ( _ * rand . Rand ) {
weightMsgWithdrawDelegationReward = simappparams . DefaultWeightMsgWithdrawDelegationReward
} ,
)
var weightMsgWithdrawValidatorCommission int
appParams . GetOrGenerate ( cdc , OpWeightMsgWithdrawValidatorCommission , & weightMsgWithdrawValidatorCommission , nil ,
func ( _ * rand . Rand ) {
weightMsgWithdrawValidatorCommission = simappparams . DefaultWeightMsgWithdrawValidatorCommission
} ,
)
2019-12-10 20:02:15 -08:00
var weightMsgFundCommunityPool int
appParams . GetOrGenerate ( cdc , OpWeightMsgFundCommunityPool , & weightMsgFundCommunityPool , nil ,
func ( _ * rand . Rand ) {
weightMsgFundCommunityPool = simappparams . DefaultWeightMsgFundCommunityPool
} ,
)
2019-12-05 01:29:54 -08:00
return simulation . WeightedOperations {
simulation . NewWeightedOperation (
weightMsgSetWithdrawAddress ,
2020-01-30 13:31:16 -08:00
SimulateMsgSetWithdrawAddress ( ak , bk , k ) ,
2019-12-05 01:29:54 -08:00
) ,
simulation . NewWeightedOperation (
weightMsgWithdrawDelegationReward ,
2020-01-30 13:31:16 -08:00
SimulateMsgWithdrawDelegatorReward ( ak , bk , k , sk ) ,
2019-12-05 01:29:54 -08:00
) ,
simulation . NewWeightedOperation (
weightMsgWithdrawValidatorCommission ,
2020-01-30 13:31:16 -08:00
SimulateMsgWithdrawValidatorCommission ( ak , bk , k , sk ) ,
2019-12-05 01:29:54 -08:00
) ,
2019-12-10 20:02:15 -08:00
simulation . NewWeightedOperation (
weightMsgFundCommunityPool ,
2020-01-30 13:31:16 -08:00
SimulateMsgFundCommunityPool ( ak , bk , k , sk ) ,
2019-12-10 20:02:15 -08:00
) ,
2019-12-05 01:29:54 -08:00
}
}
2019-10-23 02:14:45 -07:00
// SimulateMsgSetWithdrawAddress generates a MsgSetWithdrawAddress with random values.
2020-03-23 04:55:44 -07:00
func SimulateMsgSetWithdrawAddress ( 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 ! k . GetWithdrawAddrEnabled ( ctx ) {
2020-05-26 09:52:23 -07:00
return simtypes . NoOpMsg ( types . ModuleName , types . TypeMsgSetWithdrawAddress , "withdrawal is not enabled" ) , nil , nil
2019-10-23 02:14:45 -07:00
}
2020-03-23 04:55:44 -07:00
simAccount , _ := simtypes . RandomAcc ( r , accs )
simToAccount , _ := simtypes . RandomAcc ( r , accs )
2020-01-30 13:31:16 -08:00
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 ( ) )
2019-10-23 02:14:45 -07:00
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 . TypeMsgSetWithdrawAddress , "unable to generate fees" ) , nil , err
2019-10-23 02:14:45 -07:00
}
msg := types . NewMsgSetWithdrawAddress ( simAccount . Address , simToAccount . Address )
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
}
}
// SimulateMsgWithdrawDelegatorReward generates a MsgWithdrawDelegatorReward with random values.
2020-03-23 04:55:44 -07:00
func SimulateMsgWithdrawDelegatorReward ( ak types . AccountKeeper , bk types . BankKeeper , k keeper . Keeper , sk stakingkeeper . Keeper ) simtypes . Operation {
2019-12-05 01:29:54 -08: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
delegations := sk . GetAllDelegatorDelegations ( ctx , simAccount . Address )
if len ( delegations ) == 0 {
2020-05-26 09:52:23 -07:00
return simtypes . NoOpMsg ( types . ModuleName , types . TypeMsgWithdrawDelegatorReward , "number of delegators equal 0" ) , nil , nil
2019-10-23 02:14:45 -07:00
}
delegation := delegations [ r . Intn ( len ( delegations ) ) ]
validator := sk . Validator ( ctx , delegation . GetValidatorAddr ( ) )
if validator == nil {
2020-05-26 09:52:23 -07:00
return simtypes . NoOpMsg ( types . ModuleName , types . TypeMsgWithdrawDelegatorReward , "validator is nil" ) , nil , fmt . Errorf ( "validator %s not found" , delegation . GetValidatorAddr ( ) )
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 . TypeMsgWithdrawDelegatorReward , "unable to generate fees" ) , nil , err
2019-10-23 02:14:45 -07:00
}
msg := types . NewMsgWithdrawDelegatorReward ( simAccount . Address , validator . GetOperator ( ) )
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
}
}
// SimulateMsgWithdrawValidatorCommission generates a MsgWithdrawValidatorCommission with random values.
2020-03-23 04:55:44 -07:00
func SimulateMsgWithdrawValidatorCommission ( ak types . AccountKeeper , bk types . BankKeeper , k keeper . Keeper , sk stakingkeeper . 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
validator , ok := stakingkeeper . RandomValidator ( r , sk , ctx )
if ! ok {
2020-05-26 09:52:23 -07:00
return simtypes . NoOpMsg ( types . ModuleName , types . TypeMsgWithdrawValidatorCommission , "random validator is not ok" ) , nil , nil
2019-10-23 02:14:45 -07:00
}
commission := k . GetValidatorAccumulatedCommission ( ctx , validator . GetOperator ( ) )
2020-02-11 06:58:37 -08:00
if commission . Commission . IsZero ( ) {
2020-05-26 09:52:23 -07:00
return simtypes . NoOpMsg ( types . ModuleName , types . TypeMsgWithdrawValidatorCommission , "validator commission is zero" ) , 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 ( validator . 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 . TypeMsgWithdrawValidatorCommission , "could not find account" ) , nil , fmt . Errorf ( "validator %s not found" , validator . 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 . TypeMsgWithdrawValidatorCommission , "unable to generate fees" ) , nil , err
2019-10-23 02:14:45 -07:00
}
msg := types . NewMsgWithdrawValidatorCommission ( validator . GetOperator ( ) )
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
}
}
2019-12-10 20:02:15 -08:00
// SimulateMsgFundCommunityPool simulates MsgFundCommunityPool execution where
// a random account sends a random amount of its funds to the community pool.
2020-03-23 04:55:44 -07:00
func SimulateMsgFundCommunityPool ( ak types . AccountKeeper , bk types . BankKeeper , k keeper . Keeper , sk stakingkeeper . Keeper ) simtypes . Operation {
2019-12-10 20:02:15 -08: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-12-10 20:02:15 -08:00
2020-03-23 04:55:44 -07:00
funder , _ := simtypes . RandomAcc ( r , accs )
2019-12-10 20:02:15 -08:00
account := ak . GetAccount ( ctx , funder . Address )
2020-01-30 13:31:16 -08:00
spendable := bk . SpendableCoins ( ctx , account . GetAddress ( ) )
2019-12-10 20:02:15 -08:00
2020-03-23 04:55:44 -07:00
fundAmount := simtypes . RandSubsetCoins ( r , spendable )
2019-12-10 20:02:15 -08:00
if fundAmount . Empty ( ) {
2020-05-26 09:52:23 -07:00
return simtypes . NoOpMsg ( types . ModuleName , types . TypeMsgFundCommunityPool , "fund amount is empty" ) , nil , nil
2019-12-10 20:02:15 -08:00
}
var (
fees sdk . Coins
err error
)
2020-01-30 13:31:16 -08:00
coins , hasNeg := spendable . SafeSub ( fundAmount )
2019-12-10 20:02:15 -08:00
if ! hasNeg {
2020-03-23 04:55:44 -07:00
fees , err = simtypes . RandomFees ( r , ctx , coins )
2019-12-10 20:02:15 -08:00
if err != nil {
2020-05-26 09:52:23 -07:00
return simtypes . NoOpMsg ( types . ModuleName , types . TypeMsgFundCommunityPool , "unable to generate fees" ) , nil , err
2019-12-10 20:02:15 -08:00
}
}
msg := types . NewMsgFundCommunityPool ( fundAmount , funder . Address )
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-12-10 20:02:15 -08:00
[ ] sdk . Msg { msg } ,
fees ,
2019-12-18 06:48:22 -08:00
helpers . DefaultGenTxGas ,
2019-12-10 20:02:15 -08:00
chainID ,
[ ] uint64 { account . GetAccountNumber ( ) } ,
[ ] uint64 { account . GetSequence ( ) } ,
funder . 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-12-10 20:02:15 -08: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-12-10 20:02:15 -08:00
}
2020-03-23 04:55:44 -07:00
return simtypes . NewOperationMsg ( msg , true , "" ) , nil , nil
2019-12-10 20:02:15 -08:00
}
}