diff --git a/x/valset-pref/keeper.go b/x/valset-pref/keeper.go index b740f209b2c..482c2d4a162 100644 --- a/x/valset-pref/keeper.go +++ b/x/valset-pref/keeper.go @@ -98,7 +98,6 @@ func (k Keeper) GetExistingStakingDelegations(ctx sdk.Context, delAddr sdk.AccAd } existingTotalShares := sdk.NewDec(0) - // calculate total shares that currently exists for _, existingDelegation := range existingDelegations { existingTotalShares = existingTotalShares.Add(existingDelegation.Shares) diff --git a/x/valset-pref/simulation/sim_msgs.go b/x/valset-pref/simulation/sim_msgs.go index c995ecedcf6..92705ae982d 100644 --- a/x/valset-pref/simulation/sim_msgs.go +++ b/x/valset-pref/simulation/sim_msgs.go @@ -2,12 +2,12 @@ package simulation import ( "fmt" - "math" "math/rand" "time" sdk "github.com/cosmos/cosmos-sdk/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + osmosimtypes "github.com/osmosis-labs/osmosis/v14/simulation/simtypes" valsetkeeper "github.com/osmosis-labs/osmosis/v14/x/valset-pref" "github.com/osmosis-labs/osmosis/v14/x/valset-pref/types" @@ -31,88 +31,123 @@ func RandomMsgSetValSetPreference(k valsetkeeper.Keeper, sim *osmosimtypes.SimCt func RandomMsgDelegateToValSet(k valsetkeeper.Keeper, sim *osmosimtypes.SimCtx, ctx sdk.Context) (*types.MsgDelegateToValidatorSet, error) { delegator := sim.RandomSimAccount() // check if the delegator valset created - err := GetRandomExistingValSet(ctx, k, sim, delegator.Address) + _, err := GetRandomDelegations(ctx, k, sim, delegator.Address) if err != nil { return nil, err } - delegationCoin := sim.RandExponentialCoin(ctx, delegator.Address) + amount := sim.BankKeeper().GetBalance(ctx, delegator.Address, sdk.DefaultBondDenom).Amount + if !amount.IsPositive() { + return nil, fmt.Errorf("%s is not present", sdk.DefaultBondDenom) + } + + delegationCoin := rand.Intn(int(amount.Int64())) return &types.MsgDelegateToValidatorSet{ Delegator: delegator.Address.String(), - Coin: delegationCoin, + Coin: sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(int64(delegationCoin))), }, nil } func RandomMsgUnDelegateFromValSet(k valsetkeeper.Keeper, sim *osmosimtypes.SimCtx, ctx sdk.Context) (*types.MsgUndelegateFromValidatorSet, error) { + // random delegator account delegator := sim.RandomSimAccount() - // check if the delegator valset created - err := GetRandomExistingValSet(ctx, k, sim, delegator.Address) + delAddr := delegator.Address + + // get delegator valset preferences + preferences, err := k.GetDelegationPreferences(ctx, delAddr.String()) if err != nil { - return nil, err + return nil, fmt.Errorf("no delegations found") } - // check that the delegator has delegated tokens - _, err = GetRandomExistingDelegation(ctx, k, sim, delegator.Address) + delegation := preferences.Preferences[rand.Intn(len(preferences.Preferences))] + val, err := sdk.ValAddressFromBech32(delegation.ValOperAddress) if err != nil { - return nil, err + return nil, fmt.Errorf("validator address not formatted") + } + + validator, found := sim.StakingKeeper().GetValidator(ctx, val) + if !found { + return nil, fmt.Errorf("Validator not found") + } + + // check if the user has delegated tokens to the valset + del, found := sim.StakingKeeper().GetDelegation(ctx, delAddr, val) + if !found { + return nil, fmt.Errorf("user hasn't delegated tokens to the validator, %s", val.String()) + } + + totalBond := validator.TokensFromShares(del.GetShares()).TruncateInt() + if !totalBond.IsPositive() { + return nil, fmt.Errorf("%s is not present", sdk.DefaultBondDenom) } - undelegationCoin := sim.RandExponentialCoin(ctx, delegator.Address) + undelegationCoin := rand.Intn(int(totalBond.Int64())) + return &types.MsgUndelegateFromValidatorSet{ - Delegator: delegator.Address.String(), - Coin: undelegationCoin, + Delegator: delAddr.String(), + Coin: sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(int64(undelegationCoin))), }, nil } func RandomMsgReDelegateToValSet(k valsetkeeper.Keeper, sim *osmosimtypes.SimCtx, ctx sdk.Context) (*types.MsgRedelegateValidatorSet, error) { + // random delegator account delegator := sim.RandomSimAccount() - // check if the delegator valset created - err := GetRandomExistingValSet(ctx, k, sim, delegator.Address) - if err != nil { - return nil, err - } + delAddr := delegator.Address - // check that the delegator has delegated tokens - _, err = GetRandomExistingDelegation(ctx, k, sim, delegator.Address) + // existing delegations + delegations, err := k.GetDelegationPreferences(ctx, delAddr.String()) if err != nil { - return nil, err + return nil, fmt.Errorf("no delegations found") } - remainingWeight := sdk.NewDec(1) - preferences, err := GetRandomValAndWeights(ctx, k, sim, remainingWeight) - if err != nil { - return nil, err - } + for _, dels := range delegations.Preferences { + val, err := sdk.ValAddressFromBech32(dels.ValOperAddress) + if err != nil { + return nil, fmt.Errorf("validator address not formatted") + } - return &types.MsgRedelegateValidatorSet{ - Delegator: delegator.Address.String(), - Preferences: preferences, - }, nil -} + if sim.StakingKeeper().HasReceivingRedelegation(ctx, delAddr, val) { + return nil, fmt.Errorf("receiving redelegation is not allowed for source validators") + } -func RandomMsgWithdrawRewardsFromValSet(k valsetkeeper.Keeper, sim *osmosimtypes.SimCtx, ctx sdk.Context) (*types.MsgWithdrawDelegationRewards, error) { - delegator := sim.RandomSimAccount() + if sim.StakingKeeper().HasMaxUnbondingDelegationEntries(ctx, delAddr, val) { + return nil, fmt.Errorf("keeper does have a max unbonding delegation entries") + } - err := GetRandomExistingValSet(ctx, k, sim, delegator.Address) - if err != nil { - return nil, err + // check if the user has delegated tokens to the valset + _, found := sim.StakingKeeper().GetDelegation(ctx, delAddr, val) + if !found { + return nil, fmt.Errorf("user hasn't delegated tokens to the validator, %s", val.String()) + } } - // check that the delegator has delegated tokens - delegations, err := GetRandomExistingDelegation(ctx, k, sim, delegator.Address) + // new delegations to redelegate to + remainingWeight := sdk.NewDec(1) + preferences, err := GetRandomValAndWeights(ctx, k, sim, remainingWeight) if err != nil { return nil, err } - delegation := delegations[rand.Intn(len(delegations))] - validator := sim.StakingKeeper().Validator(ctx, delegation.GetValidatorAddr()) - if validator == nil { - return nil, fmt.Errorf("validator not found") + // check if redelegation is possible to new validators + for _, vals := range preferences { + val, err := sdk.ValAddressFromBech32(vals.ValOperAddress) + if err != nil { + return nil, fmt.Errorf("validator address not formatted") + } + + if sim.StakingKeeper().HasMaxUnbondingDelegationEntries(ctx, delAddr, val) { + return nil, fmt.Errorf("keeper does have a max unbonding delegation entries") + } + + if sim.StakingKeeper().HasReceivingRedelegation(ctx, delAddr, val) { + return nil, fmt.Errorf("receveing redelegation is not allowed for target validators") + } } - return &types.MsgWithdrawDelegationRewards{ - Delegator: delegator.Address.String(), + return &types.MsgRedelegateValidatorSet{ + Delegator: delAddr.String(), + Preferences: preferences, }, nil } @@ -151,28 +186,27 @@ func GetRandomValAndWeights(ctx sdk.Context, k valsetkeeper.Keeper, sim *osmosim } } - return preferences, nil -} + totalWeight := sdk.ZeroDec() + // check if all the weights in preferences equal 1 + for _, prefs := range preferences { + totalWeight = totalWeight.Add(prefs.Weight) + } -// TODO: Change this to user GetDelegations() once #3857 gets merged, issue created -func GetRandomExistingValSet(ctx sdk.Context, k valsetkeeper.Keeper, sim *osmosimtypes.SimCtx, delegatorAddr sdk.AccAddress) error { - // Get Valset delegations - _, found := k.GetValidatorSetPreference(ctx, delegatorAddr.String()) - if !found { - return fmt.Errorf("No val set preference") + if !totalWeight.Equal(sdk.OneDec()) { + return nil, fmt.Errorf("generated weights donot equal 1 got: %d", totalWeight) } - return nil + return preferences, nil } -func GetRandomExistingDelegation(ctx sdk.Context, k valsetkeeper.Keeper, sim *osmosimtypes.SimCtx, delegatorAddr sdk.AccAddress) ([]stakingtypes.Delegation, error) { - // gets the existing delegation - existingDelegations := sim.StakingKeeper().GetDelegatorDelegations(ctx, delegatorAddr, math.MaxUint16) - if len(existingDelegations) == 0 { - return nil, fmt.Errorf("No existing delegation") +func GetRandomDelegations(ctx sdk.Context, k valsetkeeper.Keeper, sim *osmosimtypes.SimCtx, delegatorAddr sdk.AccAddress) ([]types.ValidatorPreference, error) { + // Get Valset delegations + delegations, err := k.GetDelegationPreferences(ctx, delegatorAddr.String()) + if err != nil { + return nil, fmt.Errorf("No delegations found") } - return existingDelegations, nil + return delegations.Preferences, err } // Random float point from 0-1 diff --git a/x/valset-pref/valpref-module/module.go b/x/valset-pref/valpref-module/module.go index 0e0352cb616..db49752761f 100644 --- a/x/valset-pref/valpref-module/module.go +++ b/x/valset-pref/valpref-module/module.go @@ -17,11 +17,13 @@ import ( "github.com/spf13/cobra" abci "github.com/tendermint/tendermint/abci/types" + "github.com/osmosis-labs/osmosis/v14/simulation/simtypes" keeper "github.com/osmosis-labs/osmosis/v14/x/valset-pref" validatorprefclient "github.com/osmosis-labs/osmosis/v14/x/valset-pref/client" valsetprefcli "github.com/osmosis-labs/osmosis/v14/x/valset-pref/client/cli" "github.com/osmosis-labs/osmosis/v14/x/valset-pref/client/grpc" "github.com/osmosis-labs/osmosis/v14/x/valset-pref/client/queryproto" + "github.com/osmosis-labs/osmosis/v14/x/valset-pref/simulation" "github.com/osmosis-labs/osmosis/v14/x/valset-pref/types" ) @@ -165,17 +167,12 @@ func (AppModule) ConsensusVersion() uint64 { return 1 } // AppModuleSimulation functions -// // GenerateGenesisState creates a randomized GenState of the valset module. -// func (am AppModule) GenerateGenesisState(simState *module.SimulationState, s *simtypes.SimCtx) { -// } - -// // WeightedOperations returns the all the valset module operations with their respective weights. -// func (am AppModule) Actions() []simtypes.Action { -// return []simtypes.Action{ -// simtypes.NewMsgBasedAction("SetValidatorSetPreference", am.keeper, simulation.RandomMsgSetValSetPreference), -// simtypes.NewMsgBasedAction("MsgDelegateToValidatorSet", am.keeper, simulation.RandomMsgDelegateToValSet), -// simtypes.NewMsgBasedAction("MsgUndelegateFromValidatorSet", am.keeper, simulation.RandomMsgUnDelegateFromValSet), -// simtypes.NewMsgBasedAction("MsgRedelegateValSet", am.keeper, simulation.RandomMsgReDelegateToValSet), -// simtypes.NewMsgBasedAction("MsgWithdrawDelegationRewards", am.keeper, simulation.RandomMsgWithdrawRewardsFromValSet), -// } -// } +// WeightedOperations returns the all the valset module operations with their respective weights. +func (am AppModule) Actions() []simtypes.Action { + return []simtypes.Action{ + simtypes.NewMsgBasedAction("SetValidatorSetPreference", am.keeper, simulation.RandomMsgSetValSetPreference), + simtypes.NewMsgBasedAction("MsgDelegateToValidatorSet", am.keeper, simulation.RandomMsgDelegateToValSet), + simtypes.NewMsgBasedAction("MsgUndelegateFromValidatorSet", am.keeper, simulation.RandomMsgUnDelegateFromValSet), + simtypes.NewMsgBasedAction("MsgRedelegateValSet", am.keeper, simulation.RandomMsgReDelegateToValSet), + } +}