Skip to content

Commit

Permalink
chore: Add UnbondingType index to know which type of unbonding to des…
Browse files Browse the repository at this point in the history
…erialize to (#13367)

* Add UnbondingType index to know which type of unbonding to
deserialize to

* start attempting to port tests
  • Loading branch information
jtremback authored Sep 28, 2022
1 parent 12bcfeb commit b45dd5f
Show file tree
Hide file tree
Showing 3 changed files with 362 additions and 258 deletions.
185 changes: 110 additions & 75 deletions x/staking/keeper/unbonding.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,27 @@ func (k Keeper) DeleteUnbondingIndex(ctx sdk.Context, id uint64) {
store.Delete(types.GetUnbondingIndexKey(id))
}

func (k Keeper) GetUnbondingType(ctx sdk.Context, id uint64) (unbondingType types.UnbondingType, found bool) {
store := ctx.KVStore(k.storeKey)

bz := store.Get(types.GetUnbondingTypeKey(id))
if bz == nil {
return unbondingType, false
}

return types.UnbondingType(binary.BigEndian.Uint64(bz)), true
}

func (k Keeper) SetUnbondingType(ctx sdk.Context, id uint64, unbondingType types.UnbondingType) {
store := ctx.KVStore(k.storeKey)

// Convert into bytes for storage
bz := make([]byte, 8)
binary.BigEndian.PutUint64(bz, uint64(unbondingType))

store.Set(types.GetUnbondingTypeKey(id), bz)
}

// return a unbonding delegation that has an unbonding delegation entry with a certain ID
func (k Keeper) GetUnbondingDelegationByUnbondingId(
ctx sdk.Context, id uint64,
Expand Down Expand Up @@ -112,7 +133,9 @@ func (k Keeper) GetValidatorByUnbondingId(
}

// Set an index to look up an UnbondingDelegation by the unbondingId of an UnbondingDelegationEntry that it contains
func (k Keeper) SetUnbondingDelegationByUnbondingId(ctx sdk.Context, ubd types.UnbondingDelegation, id uint64) {
func (k Keeper) SetUnbondingDelegationByUnbondingId(
ctx sdk.Context, ubd types.UnbondingDelegation, id uint64,
) {
store := ctx.KVStore(k.storeKey)

delAddr, err := sdk.AccAddressFromBech32(ubd.DelegatorAddress)
Expand All @@ -127,6 +150,9 @@ func (k Keeper) SetUnbondingDelegationByUnbondingId(ctx sdk.Context, ubd types.U

ubdKey := types.GetUBDKey(delAddr, valAddr)
store.Set(types.GetUnbondingIndexKey(id), ubdKey)

// Set unbonding type so that we know how to deserialize it later
k.SetUnbondingType(ctx, id, types.UnbondingType_UnbondingDelegation)
}

// Set an index to look up an Redelegation by the unbondingId of an RedelegationEntry that it contains
Expand All @@ -150,6 +176,9 @@ func (k Keeper) SetRedelegationByUnbondingId(ctx sdk.Context, red types.Redelega

redKey := types.GetREDKey(delAddr, valSrcAddr, valDstAddr)
store.Set(types.GetUnbondingIndexKey(id), redKey)

// Set unbonding type so that we know how to deserialize it later
k.SetUnbondingType(ctx, id, types.UnbondingType_Redelegation)
}

// Set an index to look up a Validator by the unbondingId corresponding to its current unbonding
Expand All @@ -163,6 +192,9 @@ func (k Keeper) SetValidatorByUnbondingId(ctx sdk.Context, val types.Validator,

valKey := types.GetValidatorKey(valAddr)
store.Set(types.GetUnbondingIndexKey(id), valKey)

// Set unbonding type so that we know how to deserialize it later
k.SetUnbondingType(ctx, id, types.UnbondingType_ValidatorUnbonding)
}

// unbondingDelegationEntryArrayIndex and redelegationEntryArrayIndex are utilities to find
Expand Down Expand Up @@ -198,54 +230,52 @@ func redelegationEntryArrayIndex(red types.Redelegation, id uint64) (index int,
// ----------------------------------------------------------------------------------------

func (k Keeper) UnbondingCanComplete(ctx sdk.Context, id uint64) error {
found, err := k.unbondingDelegationEntryCanComplete(ctx, id)
if err != nil {
return err
}
if found {
return nil
}

found, err = k.redelegationEntryCanComplete(ctx, id)
if err != nil {
return err
}
if found {
return nil
unbondingType, found := k.GetUnbondingType(ctx, id)
if !found {
return types.ErrUnbondingNotFound
}

found, err = k.validatorUnbondingCanComplete(ctx, id)
if err != nil {
return err
}
if found {
return nil
switch unbondingType {
case types.UnbondingType_UnbondingDelegation:
err := k.unbondingDelegationEntryCanComplete(ctx, id)
if err != nil {
return err
}
case types.UnbondingType_Redelegation:
err := k.redelegationEntryCanComplete(ctx, id)
if err != nil {
return err
}
case types.UnbondingType_ValidatorUnbonding:
err := k.validatorUnbondingCanComplete(ctx, id)
if err != nil {
return err
}
}

// If an entry was not found
return types.ErrUnbondingNotFound
}

func (k Keeper) unbondingDelegationEntryCanComplete(ctx sdk.Context, id uint64) (found bool, err error) {
func (k Keeper) unbondingDelegationEntryCanComplete(ctx sdk.Context, id uint64) error {
ubd, found := k.GetUnbondingDelegationByUnbondingId(ctx, id)
if !found {
return false, nil
return types.ErrUnbondingNotFound
}

i, found := unbondingDelegationEntryArrayIndex(ubd, id)

if !found {
return false, nil
return types.ErrUnbondingNotFound
}

// The entry must be on hold
if !ubd.Entries[i].OnHold() {
return true,
sdkerrors.Wrapf(
types.ErrUnbondingOnHoldRefCountNegative,
"undelegation unbondingId(%d), expecting UnbondingOnHoldRefCount > 0, got %T",
id, ubd.Entries[i].UnbondingOnHoldRefCount,
)
return sdkerrors.Wrapf(
types.ErrUnbondingOnHoldRefCountNegative,
"undelegation unbondingId(%d), expecting UnbondingOnHoldRefCount > 0, got %T",
id, ubd.Entries[i].UnbondingOnHoldRefCount,
)
}
ubd.Entries[i].UnbondingOnHoldRefCount--

Expand All @@ -254,7 +284,7 @@ func (k Keeper) unbondingDelegationEntryCanComplete(ctx sdk.Context, id uint64)
// If matured, complete it.
delegatorAddress, err := sdk.AccAddressFromBech32(ubd.DelegatorAddress)
if err != nil {
return false, err
return err
}

bondDenom := k.GetParams(ctx).BondDenom
Expand All @@ -265,7 +295,7 @@ func (k Keeper) unbondingDelegationEntryCanComplete(ctx sdk.Context, id uint64)
if err := k.bankKeeper.UndelegateCoinsFromModuleToAccount(
ctx, types.NotBondedPoolName, delegatorAddress, sdk.NewCoins(amt),
); err != nil {
return false, err
return err
}
}

Expand All @@ -283,28 +313,27 @@ func (k Keeper) unbondingDelegationEntryCanComplete(ctx sdk.Context, id uint64)
}

// Successfully completed unbonding
return true, nil
return nil
}

func (k Keeper) redelegationEntryCanComplete(ctx sdk.Context, id uint64) (found bool, err error) {
func (k Keeper) redelegationEntryCanComplete(ctx sdk.Context, id uint64) error {
red, found := k.GetRedelegationByUnbondingId(ctx, id)
if !found {
return false, nil
return types.ErrUnbondingNotFound
}

i, found := redelegationEntryArrayIndex(red, id)
if !found {
return false, nil
return types.ErrUnbondingNotFound
}

// The entry must be on hold
if !red.Entries[i].OnHold() {
return true,
sdkerrors.Wrapf(
types.ErrUnbondingOnHoldRefCountNegative,
"redelegation unbondingId(%d), expecting UnbondingOnHoldRefCount > 0, got %T",
id, red.Entries[i].UnbondingOnHoldRefCount,
)
return sdkerrors.Wrapf(
types.ErrUnbondingOnHoldRefCountNegative,
"redelegation unbondingId(%d), expecting UnbondingOnHoldRefCount > 0, got %T",
id, red.Entries[i].UnbondingOnHoldRefCount,
)
}
red.Entries[i].UnbondingOnHoldRefCount--

Expand All @@ -324,27 +353,26 @@ func (k Keeper) redelegationEntryCanComplete(ctx sdk.Context, id uint64) (found
}

// Successfully completed unbonding
return true, nil
return nil
}

func (k Keeper) validatorUnbondingCanComplete(ctx sdk.Context, id uint64) (found bool, err error) {
func (k Keeper) validatorUnbondingCanComplete(ctx sdk.Context, id uint64) error {
val, found := k.GetValidatorByUnbondingId(ctx, id)
if !found {
return false, nil
return types.ErrUnbondingNotFound
}

if val.UnbondingOnHoldRefCount <= 0 {
return true,
sdkerrors.Wrapf(
types.ErrUnbondingOnHoldRefCountNegative,
"val(%s), expecting UnbondingOnHoldRefCount > 0, got %T",
val.OperatorAddress, val.UnbondingOnHoldRefCount,
)
return sdkerrors.Wrapf(
types.ErrUnbondingOnHoldRefCountNegative,
"val(%s), expecting UnbondingOnHoldRefCount > 0, got %T",
val.OperatorAddress, val.UnbondingOnHoldRefCount,
)
}
val.UnbondingOnHoldRefCount--
k.SetValidator(ctx, val)

return true, nil
return nil
}

// PutUnbondingOnHold allows an external module to stop an unbonding operation,
Expand All @@ -353,67 +381,74 @@ func (k Keeper) validatorUnbondingCanComplete(ctx sdk.Context, id uint64) (found
// to PutUnbondingOnHold(id) must be matched by a call to UnbondingCanComplete(id).
// ----------------------------------------------------------------------------------------
func (k Keeper) PutUnbondingOnHold(ctx sdk.Context, id uint64) error {
found := k.putUnbondingDelegationEntryOnHold(ctx, id)
if found {
return nil
}

found = k.putRedelegationEntryOnHold(ctx, id)
if found {
return nil
unbondingType, found := k.GetUnbondingType(ctx, id)
if !found {
return types.ErrUnbondingNotFound
}

found = k.putValidatorOnHold(ctx, id)
if found {
return nil
switch unbondingType {
case types.UnbondingType_UnbondingDelegation:
err := k.putUnbondingDelegationEntryOnHold(ctx, id)
if err != nil {
return err
}
case types.UnbondingType_Redelegation:
err := k.putRedelegationEntryOnHold(ctx, id)
if err != nil {
return err
}
case types.UnbondingType_ValidatorUnbonding:
err := k.putValidatorOnHold(ctx, id)
if err != nil {
return err
}
}

// If an entry was not found
return types.ErrUnbondingNotFound
}

func (k Keeper) putUnbondingDelegationEntryOnHold(ctx sdk.Context, id uint64) (found bool) {
func (k Keeper) putUnbondingDelegationEntryOnHold(ctx sdk.Context, id uint64) error {
ubd, found := k.GetUnbondingDelegationByUnbondingId(ctx, id)
if !found {
return false
return types.ErrUnbondingNotFound
}

i, found := unbondingDelegationEntryArrayIndex(ubd, id)
if !found {
return false
return types.ErrUnbondingNotFound
}

ubd.Entries[i].UnbondingOnHoldRefCount++
k.SetUnbondingDelegation(ctx, ubd)

return true
return nil
}

func (k Keeper) putRedelegationEntryOnHold(ctx sdk.Context, id uint64) (found bool) {
func (k Keeper) putRedelegationEntryOnHold(ctx sdk.Context, id uint64) error {
red, found := k.GetRedelegationByUnbondingId(ctx, id)
if !found {
return false
return types.ErrUnbondingNotFound
}

i, found := redelegationEntryArrayIndex(red, id)
if !found {
return false
return types.ErrUnbondingNotFound
}

red.Entries[i].UnbondingOnHoldRefCount++
k.SetRedelegation(ctx, red)

return true
return nil
}

func (k Keeper) putValidatorOnHold(ctx sdk.Context, id uint64) (found bool) {
func (k Keeper) putValidatorOnHold(ctx sdk.Context, id uint64) error {
val, found := k.GetValidatorByUnbondingId(ctx, id)
if !found {
return false
return types.ErrUnbondingNotFound
}

val.UnbondingOnHoldRefCount++
k.SetValidator(ctx, val)

return true
return nil
}
Loading

0 comments on commit b45dd5f

Please sign in to comment.