cosmos-sdk/x/distribution/simulation/msg_factory.go
2025-04-14 17:30:59 +00:00

126 lines
4.2 KiB
Go

package simulation
import (
"context"
"errors"
"cosmossdk.io/collections"
sdkmath "cosmossdk.io/math"
"github.com/cosmos/cosmos-sdk/testutil/simsx"
"github.com/cosmos/cosmos-sdk/x/distribution/keeper"
"github.com/cosmos/cosmos-sdk/x/distribution/types"
)
func MsgSetWithdrawAddressFactory(k keeper.Keeper) simsx.SimMsgFactoryFn[*types.MsgSetWithdrawAddress] {
return func(ctx context.Context, testData *simsx.ChainDataSource, reporter simsx.SimulationReporter) ([]simsx.SimAccount, *types.MsgSetWithdrawAddress) {
switch enabled, err := k.GetWithdrawAddrEnabled(ctx); {
case err != nil:
reporter.Skip("error getting params")
return nil, nil
case !enabled:
reporter.Skip("withdrawal is not enabled")
return nil, nil
}
delegator := testData.AnyAccount(reporter)
withdrawer := testData.AnyAccount(reporter, simsx.ExcludeAccounts(delegator))
msg := types.NewMsgSetWithdrawAddress(delegator.Address, withdrawer.Address)
return []simsx.SimAccount{delegator}, msg
}
}
func MsgWithdrawDelegatorRewardFactory(k keeper.Keeper, sk types.StakingKeeper) simsx.SimMsgFactoryFn[*types.MsgWithdrawDelegatorReward] {
return func(ctx context.Context, testData *simsx.ChainDataSource, reporter simsx.SimulationReporter) ([]simsx.SimAccount, *types.MsgWithdrawDelegatorReward) {
delegator := testData.AnyAccount(reporter)
delegations, err := sk.GetAllDelegatorDelegations(ctx, delegator.Address)
switch {
case err != nil:
reporter.Skipf("error getting delegations: %v", err)
return nil, nil
case len(delegations) == 0:
reporter.Skip("no delegations found")
return nil, nil
}
delegation := delegations[testData.Rand().Intn(len(delegations))]
valAddr, err := sk.ValidatorAddressCodec().StringToBytes(delegation.GetValidatorAddr())
if err != nil {
reporter.Skip(err.Error())
return nil, nil
}
var valOper string
switch validator, err := sk.Validator(ctx, valAddr); {
case err != nil:
reporter.Skip(err.Error())
return nil, nil
case validator == nil:
reporter.Skipf("validator %s not found", delegation.GetValidatorAddr())
return nil, nil
default:
valOper = validator.GetOperator()
}
// get outstanding rewards so we can first check if the withdrawable coins are sendable
outstanding, err := k.GetValidatorOutstandingRewardsCoins(ctx, valAddr)
if err != nil {
reporter.Skipf("get outstanding rewards: %v", err)
return nil, nil
}
for _, v := range outstanding {
if !testData.IsSendEnabledDenom(v.Denom) {
reporter.Skipf("denom send not enabled: " + v.Denom)
return nil, nil
}
}
msg := types.NewMsgWithdrawDelegatorReward(delegator.AddressBech32, valOper)
return []simsx.SimAccount{delegator}, msg
}
}
func MsgWithdrawValidatorCommissionFactory(k keeper.Keeper, sk types.StakingKeeper) simsx.SimMsgFactoryFn[*types.MsgWithdrawValidatorCommission] {
return func(ctx context.Context, testData *simsx.ChainDataSource, reporter simsx.SimulationReporter) ([]simsx.SimAccount, *types.MsgWithdrawValidatorCommission) {
allVals, err := sk.GetAllValidators(ctx)
if err != nil {
reporter.Skip(err.Error())
return nil, nil
}
val := simsx.OneOf(testData.Rand(), allVals)
valAddrBz, err := sk.ValidatorAddressCodec().StringToBytes(val.GetOperator())
if err != nil {
reporter.Skip(err.Error())
return nil, nil
}
commission, err := k.GetValidatorAccumulatedCommission(ctx, valAddrBz)
if err != nil && !errors.Is(err, collections.ErrNotFound) {
reporter.Skip(err.Error())
return nil, nil
}
if commission.Commission.IsZero() {
reporter.Skip("validator commission is zero")
return nil, nil
}
msg := types.NewMsgWithdrawValidatorCommission(val.GetOperator())
valAccount := testData.GetAccountbyAccAddr(reporter, valAddrBz)
return []simsx.SimAccount{valAccount}, msg
}
}
func MsgUpdateParamsFactory() simsx.SimMsgFactoryFn[*types.MsgUpdateParams] {
return func(_ context.Context, testData *simsx.ChainDataSource, reporter simsx.SimulationReporter) ([]simsx.SimAccount, *types.MsgUpdateParams) {
r := testData.Rand()
params := types.DefaultParams()
params.CommunityTax = r.DecN(sdkmath.LegacyNewDec(1))
params.WithdrawAddrEnabled = r.Intn(2) == 0
return nil, &types.MsgUpdateParams{
Authority: testData.ModuleAccountAddress(reporter, "gov"),
Params: params,
}
}
}