Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ValSet-Pref] Simulator Fix for RedelegateValSet & UndelegateFromValset #4073

Merged
merged 12 commits into from
Jan 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion x/valset-pref/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
152 changes: 93 additions & 59 deletions x/valset-pref/simulation/sim_msgs.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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")
stackman27 marked this conversation as resolved.
Show resolved Hide resolved
}
Comment on lines +143 to +145
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are they not allowed to receive redelegations?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

because this is the clause in redelegation. For ex:
ValA --- redelegation --> ValB
Val --redelegation --> ValC (ERROR: because ValB is receiving redelegation)

}

return &types.MsgWithdrawDelegationRewards{
Delegator: delegator.Address.String(),
return &types.MsgRedelegateValidatorSet{
Delegator: delAddr.String(),
Preferences: preferences,
}, nil
}

Expand Down Expand Up @@ -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
Expand Down
25 changes: 11 additions & 14 deletions x/valset-pref/valpref-module/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
)

Expand Down Expand Up @@ -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),
}
}