refactor(x/staking)!: removing unbonding queue index (#22795)
This commit is contained in:
@@ -104,6 +104,8 @@ Ref: https://keepachangelog.com/en/1.0.0/
|
||||
* [#21315](https://github.com/cosmos/cosmos-sdk/pull/21315) New struct `Metadata` to store extra validator information.
|
||||
* New field `Metadata` introduced in `types`: `Description`.
|
||||
* The signature of `NewDescription` has changed to accept an extra argument of type `Metadata`.
|
||||
* [#22795](https://github.com/cosmos/cosmos-sdk/pull/22795) `NewUnbondingDelegationEntry`, `NewUnbondingDelegation`, `AddEntry`, `NewRedelegationEntry`, `NewRedelegation` and `NewRedelegationEntryResponse` no longer take an ID in there function signatures.
|
||||
* [#22795](https://github.com/cosmos/cosmos-sdk/pull/22795) AfterUnbondingInitiated hook has been removed as it is no longer required by ICS.
|
||||
|
||||
### State Breaking changes
|
||||
|
||||
@@ -111,3 +113,4 @@ Ref: https://keepachangelog.com/en/1.0.0/
|
||||
* [#18142](https://github.com/cosmos/cosmos-sdk/pull/18142) Introduce `key_rotation_fee` param to calculate fees while rotating the keys
|
||||
* [#19740](https://github.com/cosmos/cosmos-sdk/pull/19740) `InitGenesis` and `ExportGenesis` module code and keeper code do not panic but return errors.
|
||||
* [#20845](https://github.com/cosmoc/cosmos-sdk/pull/20845) Remove HistoricalInfo from the staking modules storage
|
||||
* [#22795](https://github.com/cosmos/cosmos-sdk/pull/22795) Keys `stakingtypes.UnbondingIDKey, stakingtypes.UnbondingIndexKey, stakingtypes.UnbondingTypeKey` have been removed as they are no longer required by ICS.
|
||||
|
||||
@@ -310,17 +310,11 @@ func (k Keeper) SetUnbondingDelegationEntry(
|
||||
ctx context.Context, delegatorAddr sdk.AccAddress, validatorAddr sdk.ValAddress,
|
||||
creationHeight int64, minTime time.Time, balance math.Int,
|
||||
) (types.UnbondingDelegation, error) {
|
||||
id, err := k.IncrementUnbondingID(ctx)
|
||||
if err != nil {
|
||||
return types.UnbondingDelegation{}, err
|
||||
}
|
||||
|
||||
isNewUbdEntry := true
|
||||
ubd, err := k.GetUnbondingDelegation(ctx, delegatorAddr, validatorAddr)
|
||||
if err == nil {
|
||||
isNewUbdEntry = ubd.AddEntry(creationHeight, minTime, balance, id)
|
||||
ubd.AddEntry(creationHeight, minTime, balance)
|
||||
} else if errors.Is(err, types.ErrNoUnbondingDelegation) {
|
||||
ubd = types.NewUnbondingDelegation(delegatorAddr, validatorAddr, creationHeight, minTime, balance, id, k.validatorAddressCodec, k.authKeeper.AddressCodec())
|
||||
ubd = types.NewUnbondingDelegation(delegatorAddr, validatorAddr, creationHeight, minTime, balance, k.validatorAddressCodec, k.authKeeper.AddressCodec())
|
||||
} else {
|
||||
return ubd, err
|
||||
}
|
||||
@@ -329,18 +323,6 @@ func (k Keeper) SetUnbondingDelegationEntry(
|
||||
return ubd, err
|
||||
}
|
||||
|
||||
// only call the hook for new entries since
|
||||
// calls to AfterUnbondingInitiated are not idempotent
|
||||
if isNewUbdEntry {
|
||||
// Add to the UBDByUnbondingOp index to look up the UBD by the UBDE ID
|
||||
if err = k.SetUnbondingDelegationByUnbondingID(ctx, ubd, id); err != nil {
|
||||
return ubd, err
|
||||
}
|
||||
|
||||
if err := k.Hooks().AfterUnbondingInitiated(ctx, id); err != nil {
|
||||
return ubd, fmt.Errorf("failed to call after unbonding initiated hook: %w", err)
|
||||
}
|
||||
}
|
||||
return ubd, nil
|
||||
}
|
||||
|
||||
@@ -528,17 +510,12 @@ func (k Keeper) SetRedelegationEntry(ctx context.Context,
|
||||
minTime time.Time, balance math.Int,
|
||||
sharesSrc, sharesDst math.LegacyDec,
|
||||
) (types.Redelegation, error) {
|
||||
id, err := k.IncrementUnbondingID(ctx)
|
||||
if err != nil {
|
||||
return types.Redelegation{}, err
|
||||
}
|
||||
|
||||
red, err := k.Redelegations.Get(ctx, collections.Join3(delegatorAddr.Bytes(), validatorSrcAddr.Bytes(), validatorDstAddr.Bytes()))
|
||||
if err == nil {
|
||||
red.AddEntry(creationHeight, minTime, balance, sharesDst, id)
|
||||
red.AddEntry(creationHeight, minTime, balance, sharesDst)
|
||||
} else if errors.Is(err, collections.ErrNotFound) {
|
||||
red = types.NewRedelegation(delegatorAddr, validatorSrcAddr,
|
||||
validatorDstAddr, creationHeight, minTime, balance, sharesDst, id, k.validatorAddressCodec, k.authKeeper.AddressCodec())
|
||||
validatorDstAddr, creationHeight, minTime, balance, sharesDst, k.validatorAddressCodec, k.authKeeper.AddressCodec())
|
||||
} else {
|
||||
return types.Redelegation{}, err
|
||||
}
|
||||
@@ -547,15 +524,6 @@ func (k Keeper) SetRedelegationEntry(ctx context.Context,
|
||||
return types.Redelegation{}, err
|
||||
}
|
||||
|
||||
// Add to the UBDByEntry index to look up the UBD by the UBDE ID
|
||||
if err = k.SetRedelegationByUnbondingID(ctx, red, id); err != nil {
|
||||
return types.Redelegation{}, err
|
||||
}
|
||||
|
||||
if err := k.Hooks().AfterUnbondingInitiated(ctx, id); err != nil {
|
||||
return types.Redelegation{}, fmt.Errorf("failed to call after unbonding initiated hook: %w", err)
|
||||
}
|
||||
|
||||
return red, nil
|
||||
}
|
||||
|
||||
@@ -996,12 +964,9 @@ func (k Keeper) CompleteUnbonding(ctx context.Context, delAddr sdk.AccAddress, v
|
||||
// loop through all the entries and complete unbonding mature entries
|
||||
for i := 0; i < len(ubd.Entries); i++ {
|
||||
entry := ubd.Entries[i]
|
||||
if entry.IsMature(ctxTime) && !entry.OnHold() {
|
||||
if entry.IsMature(ctxTime) {
|
||||
ubd.RemoveEntry(int64(i))
|
||||
i--
|
||||
if err = k.DeleteUnbondingIndex(ctx, entry.UnbondingId); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// track undelegation only when remaining or truncated shares are non-zero
|
||||
if !entry.Balance.IsZero() {
|
||||
@@ -1136,12 +1101,9 @@ func (k Keeper) CompleteRedelegation(
|
||||
// loop through all the entries and complete mature redelegation entries
|
||||
for i := 0; i < len(red.Entries); i++ {
|
||||
entry := red.Entries[i]
|
||||
if entry.IsMature(ctxTime) && !entry.OnHold() {
|
||||
if entry.IsMature(ctxTime) {
|
||||
red.RemoveEntry(int64(i))
|
||||
i--
|
||||
if err = k.DeleteUnbondingIndex(ctx, entry.UnbondingId); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if !entry.InitialBalance.IsZero() {
|
||||
balances = balances.Add(sdk.NewCoin(bondDenom, entry.InitialBalance))
|
||||
|
||||
@@ -286,7 +286,6 @@ func (s *KeeperTestSuite) TestUnbondingDelegation() {
|
||||
0,
|
||||
time.Unix(0, 0).UTC(),
|
||||
math.NewInt(5),
|
||||
0,
|
||||
address.NewBech32Codec("cosmosvaloper"), address.NewBech32Codec("cosmos"),
|
||||
)
|
||||
|
||||
@@ -343,8 +342,8 @@ func (s *KeeperTestSuite) TestUnbondingDelegationsFromValidator() {
|
||||
0,
|
||||
time.Unix(0, 0).UTC(),
|
||||
math.NewInt(5),
|
||||
0,
|
||||
address.NewBech32Codec("cosmosvaloper"), address.NewBech32Codec("cosmos"),
|
||||
address.NewBech32Codec("cosmosvaloper"),
|
||||
address.NewBech32Codec("cosmos"),
|
||||
)
|
||||
|
||||
// set and retrieve a record
|
||||
@@ -716,7 +715,7 @@ func (s *KeeperTestSuite) TestGetRedelegationsFromSrcValidator() {
|
||||
|
||||
rd := stakingtypes.NewRedelegation(addrDels[0], addrVals[0], addrVals[1], 0,
|
||||
time.Unix(0, 0), math.NewInt(5),
|
||||
math.LegacyNewDec(5), 0, address.NewBech32Codec("cosmosvaloper"), address.NewBech32Codec("cosmos"))
|
||||
math.LegacyNewDec(5), address.NewBech32Codec("cosmosvaloper"), address.NewBech32Codec("cosmos"))
|
||||
|
||||
// set and retrieve a record
|
||||
err := keeper.SetRedelegation(ctx, rd)
|
||||
@@ -746,7 +745,7 @@ func (s *KeeperTestSuite) TestRedelegation() {
|
||||
|
||||
rd := stakingtypes.NewRedelegation(addrDels[0], addrVals[0], addrVals[1], 0,
|
||||
time.Unix(0, 0).UTC(), math.NewInt(5),
|
||||
math.LegacyNewDec(5), 0, address.NewBech32Codec("cosmosvaloper"), address.NewBech32Codec("cosmos"))
|
||||
math.LegacyNewDec(5), address.NewBech32Codec("cosmosvaloper"), address.NewBech32Codec("cosmos"))
|
||||
|
||||
// test shouldn't have and redelegations
|
||||
has, err := keeper.HasReceivingRedelegation(ctx, addrDels[0], addrVals[1])
|
||||
@@ -1107,14 +1106,14 @@ func (s *KeeperTestSuite) TestUnbondingDelegationAddEntry() {
|
||||
creationHeight,
|
||||
time.Unix(0, 0).UTC(),
|
||||
math.NewInt(10),
|
||||
0,
|
||||
address.NewBech32Codec("cosmosvaloper"), address.NewBech32Codec("cosmos"),
|
||||
address.NewBech32Codec("cosmosvaloper"),
|
||||
address.NewBech32Codec("cosmos"),
|
||||
)
|
||||
var initialEntries []stakingtypes.UnbondingDelegationEntry
|
||||
initialEntries = append(initialEntries, ubd.Entries...)
|
||||
require.Len(initialEntries, 1)
|
||||
|
||||
isNew := ubd.AddEntry(creationHeight, time.Unix(0, 0).UTC(), math.NewInt(5), 1)
|
||||
isNew := ubd.AddEntry(creationHeight, time.Unix(0, 0).UTC(), math.NewInt(5))
|
||||
require.False(isNew)
|
||||
require.Len(ubd.Entries, 1) // entry was merged
|
||||
require.NotEqual(initialEntries, ubd.Entries)
|
||||
@@ -1123,7 +1122,7 @@ func (s *KeeperTestSuite) TestUnbondingDelegationAddEntry() {
|
||||
require.Equal(ubd.Entries[0].Balance, math.NewInt(15)) // 10 from previous + 5 from merged
|
||||
|
||||
newCreationHeight := int64(11)
|
||||
isNew = ubd.AddEntry(newCreationHeight, time.Unix(1, 0).UTC(), math.NewInt(5), 2)
|
||||
isNew = ubd.AddEntry(newCreationHeight, time.Unix(1, 0).UTC(), math.NewInt(5))
|
||||
require.True(isNew)
|
||||
require.Len(ubd.Entries, 2) // entry was appended
|
||||
require.NotEqual(initialEntries, ubd.Entries)
|
||||
@@ -1131,7 +1130,6 @@ func (s *KeeperTestSuite) TestUnbondingDelegationAddEntry() {
|
||||
require.Equal(newCreationHeight, ubd.Entries[1].CreationHeight)
|
||||
require.Equal(ubd.Entries[0].Balance, math.NewInt(15))
|
||||
require.Equal(ubd.Entries[1].Balance, math.NewInt(5))
|
||||
require.NotEqual(ubd.Entries[0].UnbondingId, ubd.Entries[1].UnbondingId) // appended entry has a new unbondingID
|
||||
}
|
||||
|
||||
func (s *KeeperTestSuite) TestSetUnbondingDelegationEntry() {
|
||||
@@ -1149,8 +1147,8 @@ func (s *KeeperTestSuite) TestSetUnbondingDelegationEntry() {
|
||||
creationHeight,
|
||||
time.Unix(0, 0).UTC(),
|
||||
math.NewInt(5),
|
||||
0,
|
||||
address.NewBech32Codec("cosmosvaloper"), address.NewBech32Codec("cosmos"),
|
||||
address.NewBech32Codec("cosmosvaloper"),
|
||||
address.NewBech32Codec("cosmos"),
|
||||
)
|
||||
|
||||
// set and retrieve a record
|
||||
@@ -1180,8 +1178,7 @@ func (s *KeeperTestSuite) TestSetUnbondingDelegationEntry() {
|
||||
require.Len(resUnbonding.Entries, 1)
|
||||
require.NotEqual(initialEntries, resUnbonding.Entries)
|
||||
require.Equal(creationHeight, resUnbonding.Entries[0].CreationHeight)
|
||||
require.Equal(initialEntries[0].UnbondingId, resUnbonding.Entries[0].UnbondingId) // initial unbondingID remains unchanged
|
||||
require.Equal(resUnbonding.Entries[0].Balance, math.NewInt(10)) // 5 from previous entry + 5 from merged entry
|
||||
require.Equal(resUnbonding.Entries[0].Balance, math.NewInt(10)) // 5 from previous entry + 5 from merged entry
|
||||
|
||||
// set unbonding delegation entry for newCreationHeight
|
||||
// new entry is expected to be appended to the existing entries
|
||||
@@ -1202,11 +1199,6 @@ func (s *KeeperTestSuite) TestSetUnbondingDelegationEntry() {
|
||||
require.NotEqual(resUnbonding.Entries[0], resUnbonding.Entries[1])
|
||||
require.Equal(creationHeight, resUnbonding.Entries[0].CreationHeight)
|
||||
require.Equal(newCreationHeight, resUnbonding.Entries[1].CreationHeight)
|
||||
|
||||
// unbondingID is incremented on every call to SetUnbondingDelegationEntry
|
||||
// unbondingID == 1 was skipped because the entry was merged with the existing entry with unbondingID == 0
|
||||
// unbondingID comes from a global counter -> gaps in unbondingIDs are OK as long as every unbondingID is unique
|
||||
require.Equal(uint64(2), resUnbonding.Entries[1].UnbondingId)
|
||||
}
|
||||
|
||||
func (s *KeeperTestSuite) TestUndelegateWithDustShare() {
|
||||
|
||||
@@ -648,7 +648,6 @@ func redelegationsToRedelegationResponses(ctx context.Context, k *Keeper, redels
|
||||
entry.SharesDst,
|
||||
entry.InitialBalance,
|
||||
val.TokensFromShares(entry.SharesDst).TruncateInt(),
|
||||
entry.UnbondingId,
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -70,17 +70,12 @@ type Keeper struct {
|
||||
LastTotalPower collections.Item[math.Int]
|
||||
// DelegationsByValidator key: valAddr+delAddr | value: none used (index key for delegations by validator index)
|
||||
DelegationsByValidator collections.Map[collections.Pair[sdk.ValAddress, sdk.AccAddress], []byte]
|
||||
UnbondingID collections.Sequence
|
||||
// ValidatorByConsensusAddress key: consAddr | value: valAddr
|
||||
ValidatorByConsensusAddress collections.Map[sdk.ConsAddress, sdk.ValAddress]
|
||||
// UnbondingType key: unbondingID | value: index of UnbondingType
|
||||
UnbondingType collections.Map[uint64, uint64]
|
||||
// Redelegations key: AccAddr+SrcValAddr+DstValAddr | value: Redelegation
|
||||
Redelegations collections.Map[collections.Triple[[]byte, []byte, []byte], types.Redelegation]
|
||||
// Delegations key: AccAddr+valAddr | value: Delegation
|
||||
Delegations collections.Map[collections.Pair[sdk.AccAddress, sdk.ValAddress], types.Delegation]
|
||||
// UnbondingIndex key:UnbondingID | value: ubdKey (ubdKey = [UnbondingDelegationKey(Prefix)+len(delAddr)+delAddr+len(valAddr)+valAddr])
|
||||
UnbondingIndex collections.Map[uint64, []byte]
|
||||
// UnbondingQueue key: Timestamp | value: DVPairs [delAddr+valAddr]
|
||||
UnbondingQueue collections.Map[time.Time, types.DVPairs]
|
||||
// Validators key: valAddr | value: Validator
|
||||
@@ -178,14 +173,12 @@ func NewKeeper(
|
||||
),
|
||||
collections.BytesValue,
|
||||
),
|
||||
UnbondingID: collections.NewSequence(sb, types.UnbondingIDKey, "unbonding_id"),
|
||||
ValidatorByConsensusAddress: collections.NewMap(
|
||||
sb, types.ValidatorsByConsAddrKey,
|
||||
"validator_by_cons_addr",
|
||||
sdk.LengthPrefixedAddressKey(sdk.ConsAddressKey).WithName("cons_address"), //nolint: staticcheck // sdk.LengthPrefixedAddressKey is needed to retain state compatibility
|
||||
collcodec.KeyToValueCodec(sdk.ValAddressKey),
|
||||
),
|
||||
UnbondingType: collections.NewMap(sb, types.UnbondingTypeKey, "unbonding_type", collections.Uint64Key.WithName("unbonding_id"), collections.Uint64Value),
|
||||
// key format is: 52 | lengthPrefixedBytes(AccAddr) | lengthPrefixedBytes(SrcValAddr) | lengthPrefixedBytes(DstValAddr)
|
||||
Redelegations: collections.NewMap(
|
||||
sb, types.RedelegationKey,
|
||||
@@ -200,7 +193,6 @@ func NewKeeper(
|
||||
),
|
||||
codec.CollValue[types.Redelegation](cdc),
|
||||
),
|
||||
UnbondingIndex: collections.NewMap(sb, types.UnbondingIndexKey, "unbonding_index", collections.Uint64Key.WithName("index"), collections.BytesValue.WithName("ubd_key")),
|
||||
UnbondingDelegationByValIndex: collections.NewMap(
|
||||
sb, types.UnbondingDelegationByValIndexKey,
|
||||
"unbonding_delegation_by_val_index",
|
||||
|
||||
@@ -939,7 +939,7 @@ func (s *KeeperTestSuite) TestMsgCancelUnbondingDelegation() {
|
||||
require.NoError(err)
|
||||
require.Equal(del, resDel)
|
||||
|
||||
ubd := types.NewUnbondingDelegation(Addr, ValAddr, 10, ctx.HeaderInfo().Time.Add(time.Minute*10), shares.RoundInt(), 0, keeper.ValidatorAddressCodec(), ak.AddressCodec())
|
||||
ubd := types.NewUnbondingDelegation(Addr, ValAddr, 10, ctx.HeaderInfo().Time.Add(time.Minute*10), shares.RoundInt(), keeper.ValidatorAddressCodec(), ak.AddressCodec())
|
||||
require.NoError(keeper.SetUnbondingDelegation(ctx, ubd))
|
||||
resUnbond, err := keeper.GetUnbondingDelegation(ctx, Addr, ValAddr)
|
||||
require.NoError(err)
|
||||
|
||||
@@ -254,7 +254,7 @@ func (k Keeper) SlashUnbondingDelegation(ctx context.Context, unbondingDelegatio
|
||||
continue
|
||||
}
|
||||
|
||||
if entry.IsMature(now) && !entry.OnHold() {
|
||||
if entry.IsMature(now) {
|
||||
// Unbonding delegation no longer eligible for slashing, skip it
|
||||
continue
|
||||
}
|
||||
@@ -346,7 +346,7 @@ func (k Keeper) SlashRedelegation(ctx context.Context, srcValidator types.Valida
|
||||
case entry.CreationHeight < infractionHeight:
|
||||
continue
|
||||
// Unbonding delegation no longer eligible for slashing, skip it
|
||||
case entry.IsMature(now) && !entry.OnHold():
|
||||
case entry.IsMature(now):
|
||||
continue
|
||||
// Slash the unbonding delegation
|
||||
default:
|
||||
|
||||
@@ -1,450 +0,0 @@
|
||||
package keeper
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
|
||||
"cosmossdk.io/collections"
|
||||
errorsmod "cosmossdk.io/errors"
|
||||
"cosmossdk.io/x/staking/types"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
|
||||
// IncrementUnbondingID increments and returns a unique ID for an unbonding operation
|
||||
func (k Keeper) IncrementUnbondingID(ctx context.Context) (unbondingID uint64, err error) {
|
||||
unbondingID, err = k.UnbondingID.Next(ctx)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
unbondingID++
|
||||
|
||||
return unbondingID, err
|
||||
}
|
||||
|
||||
// DeleteUnbondingIndex removes a mapping from UnbondingId to unbonding operation
|
||||
func (k Keeper) DeleteUnbondingIndex(ctx context.Context, id uint64) error {
|
||||
return k.UnbondingIndex.Remove(ctx, id)
|
||||
}
|
||||
|
||||
// GetUnbondingType returns the enum type of unbonding which is any of
|
||||
// {UnbondingDelegation | Redelegation | ValidatorUnbonding}
|
||||
func (k Keeper) GetUnbondingType(ctx context.Context, id uint64) (unbondingType types.UnbondingType, err error) {
|
||||
ubdType, err := k.UnbondingType.Get(ctx, id)
|
||||
if errors.Is(err, collections.ErrNotFound) {
|
||||
return unbondingType, types.ErrNoUnbondingType
|
||||
}
|
||||
return types.UnbondingType(ubdType), err
|
||||
}
|
||||
|
||||
// SetUnbondingType sets the enum type of unbonding which is any of
|
||||
// {UnbondingDelegation | Redelegation | ValidatorUnbonding}
|
||||
func (k Keeper) SetUnbondingType(ctx context.Context, id uint64, unbondingType types.UnbondingType) error {
|
||||
return k.UnbondingType.Set(ctx, id, uint64(unbondingType))
|
||||
}
|
||||
|
||||
// GetUnbondingDelegationByUnbondingID returns a unbonding delegation that has an unbonding delegation entry with a certain ID
|
||||
func (k Keeper) GetUnbondingDelegationByUnbondingID(ctx context.Context, id uint64) (ubd types.UnbondingDelegation, err error) {
|
||||
ubdKey, err := k.UnbondingIndex.Get(ctx, id) // ubdKey => [UnbondingDelegationKey(Prefix)+len(delAddr)+delAddr+len(valAddr)+valAddr]
|
||||
if err != nil {
|
||||
if errors.Is(err, collections.ErrNotFound) {
|
||||
return types.UnbondingDelegation{}, types.ErrNoUnbondingDelegation
|
||||
}
|
||||
return types.UnbondingDelegation{}, err
|
||||
}
|
||||
|
||||
if ubdKey == nil {
|
||||
return types.UnbondingDelegation{}, types.ErrNoUnbondingDelegation
|
||||
}
|
||||
|
||||
// remove prefix bytes and length bytes (since ubdKey obtained is prefixed by UnbondingDelegationKey prefix and length of the address)
|
||||
delAddr := ubdKey[2 : (len(ubdKey)/2)+1]
|
||||
// remove prefix length bytes
|
||||
valAddr := ubdKey[2+len(ubdKey)/2:]
|
||||
|
||||
ubd, err = k.UnbondingDelegations.Get(ctx, collections.Join(delAddr, valAddr))
|
||||
if err != nil {
|
||||
if errors.Is(err, collections.ErrNotFound) {
|
||||
return types.UnbondingDelegation{}, types.ErrNoUnbondingDelegation
|
||||
}
|
||||
return types.UnbondingDelegation{}, err
|
||||
}
|
||||
|
||||
return ubd, nil
|
||||
}
|
||||
|
||||
// GetRedelegationByUnbondingID returns a unbonding delegation that has an unbonding delegation entry with a certain ID
|
||||
func (k Keeper) GetRedelegationByUnbondingID(ctx context.Context, id uint64) (red types.Redelegation, err error) {
|
||||
store := k.KVStoreService.OpenKVStore(ctx)
|
||||
|
||||
redKey, err := k.UnbondingIndex.Get(ctx, id)
|
||||
if err != nil {
|
||||
if errors.Is(err, collections.ErrNotFound) {
|
||||
return types.Redelegation{}, types.ErrNoRedelegation
|
||||
}
|
||||
return types.Redelegation{}, err
|
||||
}
|
||||
|
||||
if redKey == nil {
|
||||
return types.Redelegation{}, types.ErrNoRedelegation
|
||||
}
|
||||
|
||||
value, err := store.Get(redKey)
|
||||
if err != nil {
|
||||
return types.Redelegation{}, err
|
||||
}
|
||||
|
||||
if value == nil {
|
||||
return types.Redelegation{}, types.ErrNoRedelegation
|
||||
}
|
||||
|
||||
red, err = types.UnmarshalRED(k.cdc, value)
|
||||
// An error here means that what we got wasn't the right type
|
||||
if err != nil {
|
||||
return types.Redelegation{}, err
|
||||
}
|
||||
|
||||
return red, nil
|
||||
}
|
||||
|
||||
// GetValidatorByUnbondingID returns the validator that is unbonding with a certain unbonding op ID
|
||||
func (k Keeper) GetValidatorByUnbondingID(ctx context.Context, id uint64) (val types.Validator, err error) {
|
||||
store := k.KVStoreService.OpenKVStore(ctx)
|
||||
|
||||
valKey, err := k.UnbondingIndex.Get(ctx, id)
|
||||
if err != nil {
|
||||
if errors.Is(err, collections.ErrNotFound) {
|
||||
return types.Validator{}, types.ErrNoValidatorFound
|
||||
}
|
||||
return types.Validator{}, err
|
||||
}
|
||||
|
||||
if valKey == nil {
|
||||
return types.Validator{}, types.ErrNoValidatorFound
|
||||
}
|
||||
|
||||
value, err := store.Get(valKey)
|
||||
if err != nil {
|
||||
return types.Validator{}, err
|
||||
}
|
||||
|
||||
if value == nil {
|
||||
return types.Validator{}, types.ErrNoValidatorFound
|
||||
}
|
||||
|
||||
val, err = types.UnmarshalValidator(k.cdc, value)
|
||||
// An error here means that what we got wasn't the right type
|
||||
if err != nil {
|
||||
return types.Validator{}, err
|
||||
}
|
||||
|
||||
return val, nil
|
||||
}
|
||||
|
||||
// SetUnbondingDelegationByUnbondingID sets an index to look up an UnbondingDelegation
|
||||
// by the unbondingID of an UnbondingDelegationEntry that it contains Note, it does not
|
||||
// set the unbonding delegation itself, use SetUnbondingDelegation(ctx, ubd) for that
|
||||
func (k Keeper) SetUnbondingDelegationByUnbondingID(ctx context.Context, ubd types.UnbondingDelegation, id uint64) error {
|
||||
delAddr, err := k.authKeeper.AddressCodec().StringToBytes(ubd.DelegatorAddress)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
valAddr, err := k.validatorAddressCodec.StringToBytes(ubd.ValidatorAddress)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ubdKey := types.GetUBDKey(delAddr, valAddr)
|
||||
if err = k.UnbondingIndex.Set(ctx, id, ubdKey); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Set unbonding type so that we know how to deserialize it later
|
||||
return k.SetUnbondingType(ctx, id, types.UnbondingType_UnbondingDelegation)
|
||||
}
|
||||
|
||||
// SetRedelegationByUnbondingID sets an index to look up a Redelegation by the unbondingID of a RedelegationEntry that it contains
|
||||
// Note, it does not set the redelegation itself, use SetRedelegation(ctx, red) for that
|
||||
func (k Keeper) SetRedelegationByUnbondingID(ctx context.Context, red types.Redelegation, id uint64) error {
|
||||
delAddr, err := k.authKeeper.AddressCodec().StringToBytes(red.DelegatorAddress)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
valSrcAddr, err := k.validatorAddressCodec.StringToBytes(red.ValidatorSrcAddress)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
valDstAddr, err := k.validatorAddressCodec.StringToBytes(red.ValidatorDstAddress)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
redKey := types.GetREDKey(delAddr, valSrcAddr, valDstAddr)
|
||||
if err = k.UnbondingIndex.Set(ctx, id, redKey); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Set unbonding type so that we know how to deserialize it later
|
||||
return k.SetUnbondingType(ctx, id, types.UnbondingType_Redelegation)
|
||||
}
|
||||
|
||||
// SetValidatorByUnbondingID sets an index to look up a Validator by the unbondingID corresponding to its current unbonding
|
||||
// Note, it does not set the validator itself, use SetValidator(ctx, val) for that
|
||||
func (k Keeper) SetValidatorByUnbondingID(ctx context.Context, val types.Validator, id uint64) error {
|
||||
valAddr, err := k.validatorAddressCodec.StringToBytes(val.OperatorAddress)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
valKey := types.GetValidatorKey(valAddr)
|
||||
if err = k.UnbondingIndex.Set(ctx, id, valKey); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Set unbonding type so that we know how to deserialize it later
|
||||
return k.SetUnbondingType(ctx, id, types.UnbondingType_ValidatorUnbonding)
|
||||
}
|
||||
|
||||
// unbondingDelegationEntryArrayIndex and redelegationEntryArrayIndex are utilities to find
|
||||
// at which position in the Entries array the entry with a given id is
|
||||
func unbondingDelegationEntryArrayIndex(ubd types.UnbondingDelegation, id uint64) (index int, err error) {
|
||||
for i, entry := range ubd.Entries {
|
||||
// we find the entry with the right ID
|
||||
if entry.UnbondingId == id {
|
||||
return i, nil
|
||||
}
|
||||
}
|
||||
|
||||
return 0, types.ErrNoUnbondingDelegation
|
||||
}
|
||||
|
||||
func redelegationEntryArrayIndex(red types.Redelegation, id uint64) (index int, err error) {
|
||||
for i, entry := range red.Entries {
|
||||
// we find the entry with the right ID
|
||||
if entry.UnbondingId == id {
|
||||
return i, nil
|
||||
}
|
||||
}
|
||||
|
||||
return 0, types.ErrNoRedelegation
|
||||
}
|
||||
|
||||
// UnbondingCanComplete allows a stopped unbonding operation, such as an
|
||||
// unbonding delegation, a redelegation, or a validator unbonding to complete.
|
||||
// In order for the unbonding operation with `id` to eventually complete, every call
|
||||
// to PutUnbondingOnHold(id) must be matched by a call to UnbondingCanComplete(id).
|
||||
func (k Keeper) UnbondingCanComplete(ctx context.Context, id uint64) error {
|
||||
unbondingType, err := k.GetUnbondingType(ctx, id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
switch unbondingType {
|
||||
case types.UnbondingType_UnbondingDelegation:
|
||||
if err := k.unbondingDelegationEntryCanComplete(ctx, id); err != nil {
|
||||
return err
|
||||
}
|
||||
case types.UnbondingType_Redelegation:
|
||||
if err := k.redelegationEntryCanComplete(ctx, id); err != nil {
|
||||
return err
|
||||
}
|
||||
case types.UnbondingType_ValidatorUnbonding:
|
||||
if err := k.validatorUnbondingCanComplete(ctx, id); err != nil {
|
||||
return err
|
||||
}
|
||||
default:
|
||||
return types.ErrUnbondingNotFound
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (k Keeper) unbondingDelegationEntryCanComplete(ctx context.Context, id uint64) error {
|
||||
ubd, err := k.GetUnbondingDelegationByUnbondingID(ctx, id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
i, err := unbondingDelegationEntryArrayIndex(ubd, id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// The entry must be on hold
|
||||
if !ubd.Entries[i].OnHold() {
|
||||
return errorsmod.Wrapf(
|
||||
types.ErrUnbondingOnHoldRefCountNegative,
|
||||
"undelegation unbondingID(%d), expecting UnbondingOnHoldRefCount > 0, got %T",
|
||||
id, ubd.Entries[i].UnbondingOnHoldRefCount,
|
||||
)
|
||||
}
|
||||
ubd.Entries[i].UnbondingOnHoldRefCount--
|
||||
|
||||
// Check if entry is matured.
|
||||
if !ubd.Entries[i].OnHold() && ubd.Entries[i].IsMature(k.HeaderService.HeaderInfo(ctx).Time) {
|
||||
// If matured, complete it.
|
||||
delegatorAddress, err := k.authKeeper.AddressCodec().StringToBytes(ubd.DelegatorAddress)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
bondDenom, err := k.BondDenom(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// track undelegation only when remaining or truncated shares are non-zero
|
||||
if !ubd.Entries[i].Balance.IsZero() {
|
||||
amt := sdk.NewCoin(bondDenom, ubd.Entries[i].Balance)
|
||||
if err := k.bankKeeper.UndelegateCoinsFromModuleToAccount(
|
||||
ctx, types.NotBondedPoolName, delegatorAddress, sdk.NewCoins(amt),
|
||||
); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Remove entry
|
||||
ubd.RemoveEntry(int64(i))
|
||||
// Remove from the UnbondingIndex
|
||||
err = k.DeleteUnbondingIndex(ctx, id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// set the unbonding delegation or remove it if there are no more entries
|
||||
if len(ubd.Entries) == 0 {
|
||||
return k.RemoveUnbondingDelegation(ctx, ubd)
|
||||
}
|
||||
|
||||
return k.SetUnbondingDelegation(ctx, ubd)
|
||||
}
|
||||
|
||||
func (k Keeper) redelegationEntryCanComplete(ctx context.Context, id uint64) error {
|
||||
red, err := k.GetRedelegationByUnbondingID(ctx, id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
i, err := redelegationEntryArrayIndex(red, id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// The entry must be on hold
|
||||
if !red.Entries[i].OnHold() {
|
||||
return errorsmod.Wrapf(
|
||||
types.ErrUnbondingOnHoldRefCountNegative,
|
||||
"redelegation unbondingID(%d), expecting UnbondingOnHoldRefCount > 0, got %T",
|
||||
id, red.Entries[i].UnbondingOnHoldRefCount,
|
||||
)
|
||||
}
|
||||
red.Entries[i].UnbondingOnHoldRefCount--
|
||||
|
||||
headerInfo := k.HeaderService.HeaderInfo(ctx)
|
||||
if !red.Entries[i].OnHold() && red.Entries[i].IsMature(headerInfo.Time) {
|
||||
// If matured, complete it.
|
||||
// Remove entry
|
||||
red.RemoveEntry(int64(i))
|
||||
// Remove from the Unbonding index
|
||||
if err = k.DeleteUnbondingIndex(ctx, id); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// set the redelegation or remove it if there are no more entries
|
||||
if len(red.Entries) == 0 {
|
||||
return k.RemoveRedelegation(ctx, red)
|
||||
}
|
||||
|
||||
return k.SetRedelegation(ctx, red)
|
||||
}
|
||||
|
||||
func (k Keeper) validatorUnbondingCanComplete(ctx context.Context, id uint64) error {
|
||||
val, err := k.GetValidatorByUnbondingID(ctx, id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if val.UnbondingOnHoldRefCount <= 0 {
|
||||
return errorsmod.Wrapf(
|
||||
types.ErrUnbondingOnHoldRefCountNegative,
|
||||
"val(%s), expecting UnbondingOnHoldRefCount > 0, got %T",
|
||||
val.OperatorAddress, val.UnbondingOnHoldRefCount,
|
||||
)
|
||||
}
|
||||
val.UnbondingOnHoldRefCount--
|
||||
return k.SetValidator(ctx, val)
|
||||
}
|
||||
|
||||
// PutUnbondingOnHold allows an external module to stop an unbonding operation,
|
||||
// such as an unbonding delegation, a redelegation, or a validator unbonding.
|
||||
// In order for the unbonding operation with `id` to eventually complete, every call
|
||||
// to PutUnbondingOnHold(id) must be matched by a call to UnbondingCanComplete(id).
|
||||
func (k Keeper) PutUnbondingOnHold(ctx context.Context, id uint64) error {
|
||||
unbondingType, err := k.GetUnbondingType(ctx, id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
switch unbondingType {
|
||||
case types.UnbondingType_UnbondingDelegation:
|
||||
if err := k.putUnbondingDelegationEntryOnHold(ctx, id); err != nil {
|
||||
return err
|
||||
}
|
||||
case types.UnbondingType_Redelegation:
|
||||
if err := k.putRedelegationEntryOnHold(ctx, id); err != nil {
|
||||
return err
|
||||
}
|
||||
case types.UnbondingType_ValidatorUnbonding:
|
||||
if err := k.putValidatorOnHold(ctx, id); err != nil {
|
||||
return err
|
||||
}
|
||||
default:
|
||||
return types.ErrUnbondingNotFound
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (k Keeper) putUnbondingDelegationEntryOnHold(ctx context.Context, id uint64) error {
|
||||
ubd, err := k.GetUnbondingDelegationByUnbondingID(ctx, id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
i, err := unbondingDelegationEntryArrayIndex(ubd, id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ubd.Entries[i].UnbondingOnHoldRefCount++
|
||||
return k.SetUnbondingDelegation(ctx, ubd)
|
||||
}
|
||||
|
||||
func (k Keeper) putRedelegationEntryOnHold(ctx context.Context, id uint64) error {
|
||||
red, err := k.GetRedelegationByUnbondingID(ctx, id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
i, err := redelegationEntryArrayIndex(red, id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
red.Entries[i].UnbondingOnHoldRefCount++
|
||||
return k.SetRedelegation(ctx, red)
|
||||
}
|
||||
|
||||
func (k Keeper) putValidatorOnHold(ctx context.Context, id uint64) error {
|
||||
val, err := k.GetValidatorByUnbondingID(ctx, id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
val.UnbondingOnHoldRefCount++
|
||||
return k.SetValidator(ctx, val)
|
||||
}
|
||||
@@ -1,346 +0,0 @@
|
||||
package keeper_test
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"cosmossdk.io/math"
|
||||
"cosmossdk.io/x/staking/testutil"
|
||||
"cosmossdk.io/x/staking/types"
|
||||
|
||||
addresscodec "github.com/cosmos/cosmos-sdk/codec/address"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
|
||||
func (s *KeeperTestSuite) TestIncrementUnbondingID() {
|
||||
for i := 1; i < 10; i++ {
|
||||
id, err := s.stakingKeeper.IncrementUnbondingID(s.ctx)
|
||||
s.Require().NoError(err)
|
||||
s.Require().Equal(uint64(i), id)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *KeeperTestSuite) TestUnbondingTypeAccessors() {
|
||||
require := s.Require()
|
||||
cases := []struct {
|
||||
exists bool
|
||||
name string
|
||||
expected types.UnbondingType
|
||||
}{
|
||||
{
|
||||
name: "existing 1",
|
||||
exists: true,
|
||||
expected: types.UnbondingType_UnbondingDelegation,
|
||||
},
|
||||
{
|
||||
name: "existing 2",
|
||||
exists: true,
|
||||
expected: types.UnbondingType_Redelegation,
|
||||
},
|
||||
{
|
||||
name: "not existing",
|
||||
exists: false,
|
||||
},
|
||||
}
|
||||
|
||||
for i, tc := range cases {
|
||||
s.Run(tc.name, func() {
|
||||
if tc.exists {
|
||||
require.NoError(s.stakingKeeper.SetUnbondingType(s.ctx, uint64(i), tc.expected))
|
||||
}
|
||||
|
||||
unbondingType, err := s.stakingKeeper.GetUnbondingType(s.ctx, uint64(i))
|
||||
if tc.exists {
|
||||
require.NoError(err)
|
||||
require.Equal(tc.expected, unbondingType)
|
||||
} else {
|
||||
require.ErrorIs(err, types.ErrNoUnbondingType)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (s *KeeperTestSuite) TestUnbondingDelegationByUnbondingIDAccessors() {
|
||||
delAddrs, valAddrs := createValAddrs(2)
|
||||
require := s.Require()
|
||||
|
||||
type exists struct {
|
||||
setUnbondingDelegation bool
|
||||
setUnbondingDelegationByUnbondingID bool
|
||||
}
|
||||
|
||||
cases := []struct {
|
||||
exists exists
|
||||
name string
|
||||
expected types.UnbondingDelegation
|
||||
}{
|
||||
{
|
||||
name: "existing 1",
|
||||
exists: exists{true, true},
|
||||
expected: types.NewUnbondingDelegation(
|
||||
delAddrs[0],
|
||||
valAddrs[0],
|
||||
0,
|
||||
time.Unix(0, 0).UTC(),
|
||||
math.NewInt(5),
|
||||
0,
|
||||
addresscodec.NewBech32Codec("cosmosvaloper"), addresscodec.NewBech32Codec("cosmos"),
|
||||
),
|
||||
},
|
||||
{
|
||||
name: "not existing 1",
|
||||
exists: exists{false, true},
|
||||
expected: types.NewUnbondingDelegation(
|
||||
delAddrs[1],
|
||||
valAddrs[1],
|
||||
0,
|
||||
time.Unix(0, 0).UTC(),
|
||||
math.NewInt(5),
|
||||
0,
|
||||
addresscodec.NewBech32Codec("cosmosvaloper"), addresscodec.NewBech32Codec("cosmos"),
|
||||
),
|
||||
},
|
||||
{
|
||||
name: "not existing 2",
|
||||
exists: exists{false, false},
|
||||
expected: types.NewUnbondingDelegation(
|
||||
delAddrs[0],
|
||||
valAddrs[0],
|
||||
0,
|
||||
time.Unix(0, 0).UTC(),
|
||||
math.NewInt(5),
|
||||
0,
|
||||
addresscodec.NewBech32Codec("cosmosvaloper"), addresscodec.NewBech32Codec("cosmos"),
|
||||
),
|
||||
},
|
||||
}
|
||||
|
||||
for i, tc := range cases {
|
||||
s.Run(tc.name, func() {
|
||||
if tc.exists.setUnbondingDelegation {
|
||||
require.NoError(s.stakingKeeper.SetUnbondingDelegation(s.ctx, tc.expected))
|
||||
}
|
||||
|
||||
if tc.exists.setUnbondingDelegationByUnbondingID {
|
||||
require.NoError(s.stakingKeeper.SetUnbondingDelegationByUnbondingID(s.ctx, tc.expected, uint64(i)))
|
||||
}
|
||||
|
||||
ubd, err := s.stakingKeeper.GetUnbondingDelegationByUnbondingID(s.ctx, uint64(i))
|
||||
if tc.exists.setUnbondingDelegation && tc.exists.setUnbondingDelegationByUnbondingID {
|
||||
require.NoError(err)
|
||||
require.Equal(tc.expected, ubd)
|
||||
} else {
|
||||
require.ErrorIs(err, types.ErrNoUnbondingDelegation)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (s *KeeperTestSuite) TestRedelegationByUnbondingIDAccessors() {
|
||||
delAddrs, valAddrs := createValAddrs(2)
|
||||
require := s.Require()
|
||||
|
||||
type exists struct {
|
||||
setRedelegation bool
|
||||
setRedelegationByUnbondingID bool
|
||||
}
|
||||
|
||||
cases := []struct {
|
||||
exists exists
|
||||
name string
|
||||
expected types.Redelegation
|
||||
}{
|
||||
{
|
||||
name: "existing 1",
|
||||
exists: exists{true, true},
|
||||
expected: types.NewRedelegation(
|
||||
delAddrs[0],
|
||||
valAddrs[0],
|
||||
valAddrs[1],
|
||||
0,
|
||||
time.Unix(5, 0).UTC(),
|
||||
math.NewInt(10),
|
||||
math.LegacyNewDec(10),
|
||||
0,
|
||||
addresscodec.NewBech32Codec("cosmosvaloper"), addresscodec.NewBech32Codec("cosmos"),
|
||||
),
|
||||
},
|
||||
{
|
||||
name: "not existing 1",
|
||||
exists: exists{false, true},
|
||||
expected: types.NewRedelegation(
|
||||
delAddrs[1],
|
||||
valAddrs[0],
|
||||
valAddrs[1],
|
||||
0,
|
||||
time.Unix(5, 0).UTC(),
|
||||
math.NewInt(10),
|
||||
math.LegacyNewDec(10),
|
||||
0,
|
||||
addresscodec.NewBech32Codec("cosmosvaloper"), addresscodec.NewBech32Codec("cosmos"),
|
||||
),
|
||||
},
|
||||
{
|
||||
name: "not existing 2",
|
||||
exists: exists{false, false},
|
||||
expected: types.NewRedelegation(
|
||||
delAddrs[1],
|
||||
valAddrs[1],
|
||||
valAddrs[0],
|
||||
0,
|
||||
time.Unix(5, 0).UTC(),
|
||||
math.NewInt(10),
|
||||
math.LegacyNewDec(10),
|
||||
0,
|
||||
addresscodec.NewBech32Codec("cosmosvaloper"), addresscodec.NewBech32Codec("cosmos"),
|
||||
),
|
||||
},
|
||||
}
|
||||
|
||||
for i, tc := range cases {
|
||||
s.Run(tc.name, func() {
|
||||
if tc.exists.setRedelegation {
|
||||
require.NoError(s.stakingKeeper.SetRedelegation(s.ctx, tc.expected))
|
||||
}
|
||||
|
||||
if tc.exists.setRedelegationByUnbondingID {
|
||||
require.NoError(s.stakingKeeper.SetRedelegationByUnbondingID(s.ctx, tc.expected, uint64(i)))
|
||||
}
|
||||
|
||||
red, err := s.stakingKeeper.GetRedelegationByUnbondingID(s.ctx, uint64(i))
|
||||
if tc.exists.setRedelegation && tc.exists.setRedelegationByUnbondingID {
|
||||
require.NoError(err)
|
||||
require.Equal(tc.expected, red)
|
||||
} else {
|
||||
require.ErrorIs(err, types.ErrNoRedelegation)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (s *KeeperTestSuite) TestValidatorByUnbondingIDAccessors() {
|
||||
_, valAddrs := createValAddrs(3)
|
||||
require := s.Require()
|
||||
|
||||
type exists struct {
|
||||
setValidator bool
|
||||
setValidatorByUnbondingID bool
|
||||
}
|
||||
|
||||
cases := []struct {
|
||||
exists exists
|
||||
name string
|
||||
validator types.Validator
|
||||
}{
|
||||
{
|
||||
name: "existing 1",
|
||||
exists: exists{true, true},
|
||||
validator: testutil.NewValidator(s.T(), valAddrs[0], PKs[0]),
|
||||
},
|
||||
{
|
||||
name: "not existing 1",
|
||||
exists: exists{false, true},
|
||||
validator: testutil.NewValidator(s.T(), valAddrs[1], PKs[1]),
|
||||
},
|
||||
{
|
||||
name: "not existing 2",
|
||||
exists: exists{false, false},
|
||||
validator: testutil.NewValidator(s.T(), valAddrs[2], PKs[0]),
|
||||
},
|
||||
}
|
||||
|
||||
for i, tc := range cases {
|
||||
s.Run(tc.name, func() {
|
||||
if tc.exists.setValidator {
|
||||
require.NoError(s.stakingKeeper.SetValidator(s.ctx, tc.validator))
|
||||
}
|
||||
|
||||
if tc.exists.setValidatorByUnbondingID {
|
||||
require.NoError(s.stakingKeeper.SetValidatorByUnbondingID(s.ctx, tc.validator, uint64(i)))
|
||||
}
|
||||
|
||||
val, err := s.stakingKeeper.GetValidatorByUnbondingID(s.ctx, uint64(i))
|
||||
if tc.exists.setValidator && tc.exists.setValidatorByUnbondingID {
|
||||
require.NoError(err)
|
||||
require.Equal(tc.validator, val)
|
||||
} else {
|
||||
require.ErrorIs(err, types.ErrNoValidatorFound)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (s *KeeperTestSuite) TestUnbondingCanComplete() {
|
||||
delAddrs, valAddrs := createValAddrs(3)
|
||||
require := s.Require()
|
||||
|
||||
unbondingID := uint64(1)
|
||||
|
||||
// no unbondingID set
|
||||
err := s.stakingKeeper.UnbondingCanComplete(s.ctx, unbondingID)
|
||||
require.ErrorIs(err, types.ErrNoUnbondingType)
|
||||
|
||||
// unbonding delegation
|
||||
require.NoError(s.stakingKeeper.SetUnbondingType(s.ctx, unbondingID, types.UnbondingType_UnbondingDelegation))
|
||||
err = s.stakingKeeper.UnbondingCanComplete(s.ctx, unbondingID)
|
||||
require.ErrorIs(err, types.ErrNoUnbondingDelegation)
|
||||
|
||||
ubd := types.NewUnbondingDelegation(
|
||||
delAddrs[0],
|
||||
valAddrs[0],
|
||||
0,
|
||||
time.Unix(0, 0).UTC(),
|
||||
math.NewInt(5),
|
||||
unbondingID,
|
||||
addresscodec.NewBech32Codec("cosmosvaloper"), addresscodec.NewBech32Codec("cosmos"),
|
||||
)
|
||||
require.NoError(s.stakingKeeper.SetUnbondingDelegation(s.ctx, ubd))
|
||||
require.NoError(s.stakingKeeper.SetUnbondingDelegationByUnbondingID(s.ctx, ubd, unbondingID))
|
||||
err = s.stakingKeeper.UnbondingCanComplete(s.ctx, unbondingID)
|
||||
require.ErrorIs(err, types.ErrUnbondingOnHoldRefCountNegative)
|
||||
|
||||
err = s.stakingKeeper.PutUnbondingOnHold(s.ctx, unbondingID)
|
||||
require.NoError(err)
|
||||
s.bankKeeper.EXPECT().UndelegateCoinsFromModuleToAccount(s.ctx, types.NotBondedPoolName, delAddrs[0], sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, math.NewInt(5)))).Return(nil)
|
||||
err = s.stakingKeeper.UnbondingCanComplete(s.ctx, unbondingID)
|
||||
require.NoError(err)
|
||||
|
||||
// redelegation
|
||||
unbondingID++
|
||||
require.NoError(s.stakingKeeper.SetUnbondingType(s.ctx, unbondingID, types.UnbondingType_Redelegation))
|
||||
err = s.stakingKeeper.UnbondingCanComplete(s.ctx, unbondingID)
|
||||
require.ErrorIs(err, types.ErrNoRedelegation)
|
||||
|
||||
red := types.NewRedelegation(
|
||||
delAddrs[0],
|
||||
valAddrs[0],
|
||||
valAddrs[1],
|
||||
0,
|
||||
time.Unix(5, 0).UTC(),
|
||||
math.NewInt(10),
|
||||
math.LegacyNewDec(10),
|
||||
unbondingID,
|
||||
addresscodec.NewBech32Codec("cosmosvaloper"), addresscodec.NewBech32Codec("cosmos"),
|
||||
)
|
||||
require.NoError(s.stakingKeeper.SetRedelegation(s.ctx, red))
|
||||
require.NoError(s.stakingKeeper.SetRedelegationByUnbondingID(s.ctx, red, unbondingID))
|
||||
err = s.stakingKeeper.UnbondingCanComplete(s.ctx, unbondingID)
|
||||
require.ErrorIs(err, types.ErrUnbondingOnHoldRefCountNegative)
|
||||
|
||||
require.NoError(s.stakingKeeper.PutUnbondingOnHold(s.ctx, unbondingID))
|
||||
require.NoError(s.stakingKeeper.UnbondingCanComplete(s.ctx, unbondingID))
|
||||
|
||||
// validator unbonding
|
||||
unbondingID++
|
||||
require.NoError(s.stakingKeeper.SetUnbondingType(s.ctx, unbondingID, types.UnbondingType_ValidatorUnbonding))
|
||||
err = s.stakingKeeper.UnbondingCanComplete(s.ctx, unbondingID)
|
||||
require.ErrorIs(err, types.ErrNoValidatorFound)
|
||||
|
||||
val := testutil.NewValidator(s.T(), valAddrs[0], PKs[0])
|
||||
require.NoError(s.stakingKeeper.SetValidator(s.ctx, val))
|
||||
require.NoError(s.stakingKeeper.SetValidatorByUnbondingID(s.ctx, val, unbondingID))
|
||||
err = s.stakingKeeper.UnbondingCanComplete(s.ctx, unbondingID)
|
||||
require.ErrorIs(err, types.ErrUnbondingOnHoldRefCountNegative)
|
||||
|
||||
require.NoError(s.stakingKeeper.PutUnbondingOnHold(s.ctx, unbondingID))
|
||||
require.NoError(s.stakingKeeper.UnbondingCanComplete(s.ctx, unbondingID))
|
||||
}
|
||||
@@ -456,11 +456,6 @@ func (k Keeper) BeginUnbondingValidator(ctx context.Context, validator types.Val
|
||||
return validator, fmt.Errorf("should not already be unbonded or unbonding, validator: %v", validator)
|
||||
}
|
||||
|
||||
id, err := k.IncrementUnbondingID(ctx)
|
||||
if err != nil {
|
||||
return validator, err
|
||||
}
|
||||
|
||||
validator = validator.UpdateStatus(types.Unbonding)
|
||||
|
||||
headerInfo := k.HeaderService.HeaderInfo(ctx)
|
||||
@@ -468,8 +463,6 @@ func (k Keeper) BeginUnbondingValidator(ctx context.Context, validator types.Val
|
||||
validator.UnbondingTime = headerInfo.Time.Add(params.UnbondingTime)
|
||||
validator.UnbondingHeight = headerInfo.Height
|
||||
|
||||
validator.UnbondingIds = append(validator.UnbondingIds, id)
|
||||
|
||||
// save the now unbonded validator record and power index
|
||||
if err = k.SetValidator(ctx, validator); err != nil {
|
||||
return validator, err
|
||||
@@ -499,14 +492,6 @@ func (k Keeper) BeginUnbondingValidator(ctx context.Context, validator types.Val
|
||||
return validator, err
|
||||
}
|
||||
|
||||
if err := k.SetValidatorByUnbondingID(ctx, validator, id); err != nil {
|
||||
return validator, err
|
||||
}
|
||||
|
||||
if err := k.Hooks().AfterUnbondingInitiated(ctx, id); err != nil {
|
||||
return validator, err
|
||||
}
|
||||
|
||||
return validator, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -545,36 +545,19 @@ func (k Keeper) unbondMatureValidators(
|
||||
return errors.New("unexpected validator in unbonding queue; status was not unbonding")
|
||||
}
|
||||
|
||||
// if the ref count is not zero, early exit.
|
||||
if val.UnbondingOnHoldRefCount != 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
// otherwise do proper unbonding
|
||||
for _, id := range val.UnbondingIds {
|
||||
if err = k.DeleteUnbondingIndex(ctx, id); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
val, err = k.UnbondingToUnbonded(ctx, val)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if val.GetDelegatorShares().IsZero() {
|
||||
str, err := k.validatorAddressCodec.StringToBytes(val.GetOperator())
|
||||
addr, err := k.validatorAddressCodec.StringToBytes(val.OperatorAddress)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err = k.RemoveValidator(ctx, str); err != nil {
|
||||
if err := k.RemoveValidator(ctx, addr); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
// remove unbonding ids
|
||||
val.UnbondingIds = []uint64{}
|
||||
}
|
||||
|
||||
// remove validator from queue
|
||||
if err = k.DeleteValidatorQueue(ctx, val); err != nil {
|
||||
return err
|
||||
|
||||
@@ -3,6 +3,9 @@ package v6
|
||||
import "cosmossdk.io/collections"
|
||||
|
||||
var (
|
||||
UnbondingTypeKey = collections.NewPrefix(57) // prefix for an index containing the type of unbonding operations
|
||||
UnbondingIDKey = collections.NewPrefix(55) // key for the counter for the incrementing id for UnbondingOperations
|
||||
UnbondingIndexKey = collections.NewPrefix(56) // prefix for an index for looking up unbonding operations by their IDs
|
||||
ValidatorUpdatesKey = collections.NewPrefix(97)
|
||||
HistoricalInfoKey = collections.NewPrefix(80) // prefix for the historical info
|
||||
)
|
||||
|
||||
@@ -13,5 +13,8 @@ import (
|
||||
func MigrateStore(ctx context.Context, store storetypes.KVStore, cdc codec.BinaryCodec) error {
|
||||
store.Delete(ValidatorUpdatesKey)
|
||||
store.Delete(HistoricalInfoKey)
|
||||
store.Delete(UnbondingIDKey)
|
||||
store.Delete(UnbondingIndexKey)
|
||||
store.Delete(UnbondingTypeKey)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -259,7 +259,7 @@ message UnbondingDelegationEntry {
|
||||
(gogoproto.nullable) = false
|
||||
];
|
||||
// Incrementing id that uniquely identifies this entry
|
||||
uint64 unbonding_id = 5;
|
||||
uint64 unbonding_id = 5 [deprecated = true];
|
||||
|
||||
// Strictly positive if this entry's unbonding has been stopped by external modules
|
||||
int64 unbonding_on_hold_ref_count = 6;
|
||||
|
||||
@@ -611,20 +611,6 @@ func (mr *MockStakingHooksMockRecorder) AfterDelegationModified(ctx, delAddr, va
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AfterDelegationModified", reflect.TypeOf((*MockStakingHooks)(nil).AfterDelegationModified), ctx, delAddr, valAddr)
|
||||
}
|
||||
|
||||
// AfterUnbondingInitiated mocks base method.
|
||||
func (m *MockStakingHooks) AfterUnbondingInitiated(ctx context.Context, id uint64) error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "AfterUnbondingInitiated", ctx, id)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// AfterUnbondingInitiated indicates an expected call of AfterUnbondingInitiated.
|
||||
func (mr *MockStakingHooksMockRecorder) AfterUnbondingInitiated(ctx, id any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AfterUnbondingInitiated", reflect.TypeOf((*MockStakingHooks)(nil).AfterUnbondingInitiated), ctx, id)
|
||||
}
|
||||
|
||||
// AfterValidatorBeginUnbonding mocks base method.
|
||||
func (m *MockStakingHooks) AfterValidatorBeginUnbonding(ctx context.Context, consAddr types1.ConsAddress, valAddr types1.ValAddress) error {
|
||||
m.ctrl.T.Helper()
|
||||
|
||||
@@ -66,13 +66,12 @@ func (d Delegations) String() (out string) {
|
||||
return strings.TrimSpace(out)
|
||||
}
|
||||
|
||||
func NewUnbondingDelegationEntry(creationHeight int64, completionTime time.Time, balance math.Int, unbondingID uint64) UnbondingDelegationEntry {
|
||||
func NewUnbondingDelegationEntry(creationHeight int64, completionTime time.Time, balance math.Int) UnbondingDelegationEntry {
|
||||
return UnbondingDelegationEntry{
|
||||
CreationHeight: creationHeight,
|
||||
CompletionTime: completionTime,
|
||||
InitialBalance: balance,
|
||||
Balance: balance,
|
||||
UnbondingId: unbondingID,
|
||||
UnbondingOnHoldRefCount: 0,
|
||||
}
|
||||
}
|
||||
@@ -82,26 +81,6 @@ func (e UnbondingDelegationEntry) IsMature(currentTime time.Time) bool {
|
||||
return !e.CompletionTime.After(currentTime)
|
||||
}
|
||||
|
||||
// OnHold - is the current entry on hold due to external modules
|
||||
func (e UnbondingDelegationEntry) OnHold() bool {
|
||||
return e.UnbondingOnHoldRefCount > 0
|
||||
}
|
||||
|
||||
// return the unbonding delegation entry
|
||||
func MustMarshalUBDE(cdc codec.BinaryCodec, ubd UnbondingDelegationEntry) []byte {
|
||||
return cdc.MustMarshal(&ubd)
|
||||
}
|
||||
|
||||
// unmarshal a unbonding delegation entry from a store value
|
||||
func MustUnmarshalUBDE(cdc codec.BinaryCodec, value []byte) UnbondingDelegationEntry {
|
||||
ubd, err := UnmarshalUBDE(cdc, value)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return ubd
|
||||
}
|
||||
|
||||
// unmarshal a unbonding delegation entry from a store value
|
||||
func UnmarshalUBDE(cdc codec.BinaryCodec, value []byte) (ubd UnbondingDelegationEntry, err error) {
|
||||
err = cdc.Unmarshal(value, &ubd)
|
||||
@@ -111,7 +90,7 @@ func UnmarshalUBDE(cdc codec.BinaryCodec, value []byte) (ubd UnbondingDelegation
|
||||
// NewUnbondingDelegation - create a new unbonding delegation object
|
||||
func NewUnbondingDelegation(
|
||||
delegatorAddr sdk.AccAddress, validatorAddr sdk.ValAddress,
|
||||
creationHeight int64, minTime time.Time, balance math.Int, id uint64,
|
||||
creationHeight int64, minTime time.Time, balance math.Int,
|
||||
valAc, delAc address.Codec,
|
||||
) UnbondingDelegation {
|
||||
valAddr, err := valAc.BytesToString(validatorAddr)
|
||||
@@ -126,13 +105,13 @@ func NewUnbondingDelegation(
|
||||
DelegatorAddress: delAddr,
|
||||
ValidatorAddress: valAddr,
|
||||
Entries: []UnbondingDelegationEntry{
|
||||
NewUnbondingDelegationEntry(creationHeight, minTime, balance, id),
|
||||
NewUnbondingDelegationEntry(creationHeight, minTime, balance),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// AddEntry - append entry to the unbonding delegation
|
||||
func (ubd *UnbondingDelegation) AddEntry(creationHeight int64, minTime time.Time, balance math.Int, unbondingID uint64) bool {
|
||||
func (ubd *UnbondingDelegation) AddEntry(creationHeight int64, minTime time.Time, balance math.Int) bool {
|
||||
// Check the entries exists with creation_height and complete_time
|
||||
entryIndex := -1
|
||||
for index, ubdEntry := range ubd.Entries {
|
||||
@@ -152,7 +131,7 @@ func (ubd *UnbondingDelegation) AddEntry(creationHeight int64, minTime time.Time
|
||||
return false
|
||||
}
|
||||
// append the new unbond delegation entry
|
||||
entry := NewUnbondingDelegationEntry(creationHeight, minTime, balance, unbondingID)
|
||||
entry := NewUnbondingDelegationEntry(creationHeight, minTime, balance)
|
||||
ubd.Entries = append(ubd.Entries, entry)
|
||||
return true
|
||||
}
|
||||
@@ -194,13 +173,12 @@ func (ubds UnbondingDelegations) String() (out string) {
|
||||
return strings.TrimSpace(out)
|
||||
}
|
||||
|
||||
func NewRedelegationEntry(creationHeight int64, completionTime time.Time, balance math.Int, sharesDst math.LegacyDec, id uint64) RedelegationEntry {
|
||||
func NewRedelegationEntry(creationHeight int64, completionTime time.Time, balance math.Int, sharesDst math.LegacyDec) RedelegationEntry {
|
||||
return RedelegationEntry{
|
||||
CreationHeight: creationHeight,
|
||||
CompletionTime: completionTime,
|
||||
InitialBalance: balance,
|
||||
SharesDst: sharesDst,
|
||||
UnbondingId: id,
|
||||
UnbondingOnHoldRefCount: 0,
|
||||
}
|
||||
}
|
||||
@@ -217,7 +195,7 @@ func (e RedelegationEntry) OnHold() bool {
|
||||
|
||||
func NewRedelegation(
|
||||
delegatorAddr sdk.AccAddress, validatorSrcAddr, validatorDstAddr sdk.ValAddress,
|
||||
creationHeight int64, minTime time.Time, balance math.Int, sharesDst math.LegacyDec, id uint64,
|
||||
creationHeight int64, minTime time.Time, balance math.Int, sharesDst math.LegacyDec,
|
||||
valAc, delAc address.Codec,
|
||||
) Redelegation {
|
||||
valSrcAddr, err := valAc.BytesToString(validatorSrcAddr)
|
||||
@@ -238,14 +216,14 @@ func NewRedelegation(
|
||||
ValidatorSrcAddress: valSrcAddr,
|
||||
ValidatorDstAddress: valDstAddr,
|
||||
Entries: []RedelegationEntry{
|
||||
NewRedelegationEntry(creationHeight, minTime, balance, sharesDst, id),
|
||||
NewRedelegationEntry(creationHeight, minTime, balance, sharesDst),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// AddEntry - append entry to the unbonding delegation
|
||||
func (red *Redelegation) AddEntry(creationHeight int64, minTime time.Time, balance math.Int, sharesDst math.LegacyDec, id uint64) {
|
||||
entry := NewRedelegationEntry(creationHeight, minTime, balance, sharesDst, id)
|
||||
func (red *Redelegation) AddEntry(creationHeight int64, minTime time.Time, balance math.Int, sharesDst math.LegacyDec) {
|
||||
entry := NewRedelegationEntry(creationHeight, minTime, balance, sharesDst)
|
||||
red.Entries = append(red.Entries, entry)
|
||||
}
|
||||
|
||||
@@ -341,10 +319,10 @@ func NewRedelegationResponse(
|
||||
|
||||
// NewRedelegationEntryResponse creates a new RedelegationEntryResponse instance.
|
||||
func NewRedelegationEntryResponse(
|
||||
creationHeight int64, completionTime time.Time, sharesDst math.LegacyDec, initialBalance, balance math.Int, unbondingID uint64,
|
||||
creationHeight int64, completionTime time.Time, sharesDst math.LegacyDec, initialBalance, balance math.Int,
|
||||
) RedelegationEntryResponse {
|
||||
return RedelegationEntryResponse{
|
||||
RedelegationEntry: NewRedelegationEntry(creationHeight, completionTime, initialBalance, sharesDst, unbondingID),
|
||||
RedelegationEntry: NewRedelegationEntry(creationHeight, completionTime, initialBalance, sharesDst),
|
||||
Balance: balance,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ func TestDelegationString(t *testing.T) {
|
||||
|
||||
func TestUnbondingDelegationEqual(t *testing.T) {
|
||||
ubd1 := types.NewUnbondingDelegation(sdk.AccAddress(valAddr1), valAddr2, 0,
|
||||
time.Unix(0, 0), math.NewInt(0), 1, addresscodec.NewBech32Codec("cosmosvaloper"), addresscodec.NewBech32Codec("cosmos"))
|
||||
time.Unix(0, 0), math.NewInt(0), addresscodec.NewBech32Codec("cosmosvaloper"), addresscodec.NewBech32Codec("cosmos"))
|
||||
ubd2 := ubd1
|
||||
|
||||
ok := ubd1.String() == ubd2.String()
|
||||
@@ -67,7 +67,7 @@ func TestUnbondingDelegationEqual(t *testing.T) {
|
||||
|
||||
func TestUnbondingDelegationString(t *testing.T) {
|
||||
ubd := types.NewUnbondingDelegation(sdk.AccAddress(valAddr1), valAddr2, 0,
|
||||
time.Unix(0, 0), math.NewInt(0), 1, addresscodec.NewBech32Codec("cosmosvaloper"), addresscodec.NewBech32Codec("cosmos"))
|
||||
time.Unix(0, 0), math.NewInt(0), addresscodec.NewBech32Codec("cosmosvaloper"), addresscodec.NewBech32Codec("cosmos"))
|
||||
|
||||
require.NotEmpty(t, ubd.String())
|
||||
}
|
||||
@@ -75,10 +75,10 @@ func TestUnbondingDelegationString(t *testing.T) {
|
||||
func TestRedelegationEqual(t *testing.T) {
|
||||
r1 := types.NewRedelegation(sdk.AccAddress(valAddr1), valAddr2, valAddr3, 0,
|
||||
time.Unix(0, 0), math.NewInt(0),
|
||||
math.LegacyNewDec(0), 1, addresscodec.NewBech32Codec("cosmosvaloper"), addresscodec.NewBech32Codec("cosmos"))
|
||||
math.LegacyNewDec(0), addresscodec.NewBech32Codec("cosmosvaloper"), addresscodec.NewBech32Codec("cosmos"))
|
||||
r2 := types.NewRedelegation(sdk.AccAddress(valAddr1), valAddr2, valAddr3, 0,
|
||||
time.Unix(0, 0), math.NewInt(0),
|
||||
math.LegacyNewDec(0), 1, addresscodec.NewBech32Codec("cosmosvaloper"), addresscodec.NewBech32Codec("cosmos"))
|
||||
math.LegacyNewDec(0), addresscodec.NewBech32Codec("cosmosvaloper"), addresscodec.NewBech32Codec("cosmos"))
|
||||
require.True(t, proto.Equal(&r1, &r2))
|
||||
|
||||
r2.Entries[0].SharesDst = math.LegacyNewDec(10)
|
||||
@@ -89,7 +89,7 @@ func TestRedelegationEqual(t *testing.T) {
|
||||
func TestRedelegationString(t *testing.T) {
|
||||
r := types.NewRedelegation(sdk.AccAddress(valAddr1), valAddr2, valAddr3, 0,
|
||||
time.Unix(0, 0), math.NewInt(0),
|
||||
math.LegacyNewDec(10), 1, addresscodec.NewBech32Codec("cosmosvaloper"), addresscodec.NewBech32Codec("cosmos"))
|
||||
math.LegacyNewDec(10), addresscodec.NewBech32Codec("cosmosvaloper"), addresscodec.NewBech32Codec("cosmos"))
|
||||
|
||||
require.NotEmpty(t, r.String())
|
||||
}
|
||||
@@ -145,8 +145,8 @@ func TestRedelegationResponses(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
entries := []types.RedelegationEntryResponse{
|
||||
types.NewRedelegationEntryResponse(0, time.Unix(0, 0), math.LegacyNewDec(5), math.NewInt(5), math.NewInt(5), 0),
|
||||
types.NewRedelegationEntryResponse(0, time.Unix(0, 0), math.LegacyNewDec(5), math.NewInt(5), math.NewInt(5), 0),
|
||||
types.NewRedelegationEntryResponse(0, time.Unix(0, 0), math.LegacyNewDec(5), math.NewInt(5), math.NewInt(5)),
|
||||
types.NewRedelegationEntryResponse(0, time.Unix(0, 0), math.LegacyNewDec(5), math.NewInt(5), math.NewInt(5)),
|
||||
}
|
||||
rdr1 := types.NewRedelegationResponse(addr1, vAddr2, vAddr3, entries)
|
||||
rdr2 := types.NewRedelegationResponse(addr2, vAddr1, vAddr3, entries)
|
||||
|
||||
@@ -105,7 +105,6 @@ type StakingHooks interface {
|
||||
BeforeDelegationRemoved(ctx context.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) error // Must be called when a delegation is removed
|
||||
AfterDelegationModified(ctx context.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) error
|
||||
BeforeValidatorSlashed(ctx context.Context, valAddr sdk.ValAddress, fraction math.LegacyDec) error
|
||||
AfterUnbondingInitiated(ctx context.Context, id uint64) error
|
||||
AfterConsensusPubKeyUpdate(ctx context.Context, oldPubKey, newPubKey cryptotypes.PubKey, rotationFee sdk.Coin) error
|
||||
}
|
||||
|
||||
|
||||
@@ -109,15 +109,6 @@ func (h MultiStakingHooks) BeforeValidatorSlashed(ctx context.Context, valAddr s
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h MultiStakingHooks) AfterUnbondingInitiated(ctx context.Context, id uint64) error {
|
||||
for i := range h {
|
||||
if err := h[i].AfterUnbondingInitiated(ctx, id); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h MultiStakingHooks) AfterConsensusPubKeyUpdate(ctx context.Context, oldPubKey, newPubKey cryptotypes.PubKey, rotationFee sdk.Coin) error {
|
||||
for i := range h {
|
||||
if err := h[i].AfterConsensusPubKeyUpdate(ctx, oldPubKey, newPubKey, rotationFee); err != nil {
|
||||
|
||||
@@ -49,10 +49,6 @@ var (
|
||||
RedelegationByValSrcIndexKey = collections.NewPrefix(53) // prefix for each key for a redelegation, by source validator operator
|
||||
RedelegationByValDstIndexKey = collections.NewPrefix(54) // prefix for each key for a redelegation, by destination validator operator
|
||||
|
||||
UnbondingIDKey = collections.NewPrefix(55) // key for the counter for the incrementing id for UnbondingOperations
|
||||
UnbondingIndexKey = collections.NewPrefix(56) // prefix for an index for looking up unbonding operations by their IDs
|
||||
UnbondingTypeKey = collections.NewPrefix(57) // prefix for an index containing the type of unbonding operations
|
||||
|
||||
UnbondingQueueKey = collections.NewPrefix(65) // prefix for the timestamps in unbonding queue
|
||||
RedelegationQueueKey = collections.NewPrefix(66) // prefix for the timestamps in redelegations queue
|
||||
ValidatorQueueKey = collections.NewPrefix(67) // prefix for the timestamps in validator queue
|
||||
|
||||
+861
-860
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user