Skip to content

Commit

Permalink
refactor(x/staking): migrate UnbondingQueue to collections (#17481)
Browse files Browse the repository at this point in the history
  • Loading branch information
likhita-809 authored Aug 29, 2023
1 parent 0561f99 commit 6ed81a7
Show file tree
Hide file tree
Showing 6 changed files with 74 additions and 48 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ Ref: https://keepachangelog.com/en/1.0.0/

### API Breaking Changes

* (x/staking) [#17481](https://github.com/cosmos/cosmos-sdk/pull/17481) Use collections for `UnbondingQueue`:
* remove from `Keeper`: `UBDQueueIterator`
* remove from `types`: `GetUnbondingDelegationTimeKey`
* (x/staking) [#17123](https://github.com/cosmos/cosmos-sdk/pull/17123) Use collections for `Validators`
* (x/staking) [#17270](https://github.com/cosmos/cosmos-sdk/pull/17270) Use collections for `UnbondingDelegation`:
* remove from `types`: `GetUBDsKey`
Expand Down
56 changes: 20 additions & 36 deletions x/staking/keeper/delegation.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (
"time"

"cosmossdk.io/collections"
corestore "cosmossdk.io/core/store"
errorsmod "cosmossdk.io/errors"
"cosmossdk.io/math"
storetypes "cosmossdk.io/store/types"
Expand Down Expand Up @@ -347,27 +346,21 @@ func (k Keeper) SetUnbondingDelegationEntry(
// is a slice of DVPairs corresponding to unbonding delegations that expire at a
// certain time.
func (k Keeper) GetUBDQueueTimeSlice(ctx context.Context, timestamp time.Time) (dvPairs []types.DVPair, err error) {
store := k.storeService.OpenKVStore(ctx)

bz, err := store.Get(types.GetUnbondingDelegationTimeKey(timestamp))
if bz == nil || err != nil {
return []types.DVPair{}, err
pairs, err := k.UnbondingQueue.Get(ctx, timestamp)
if err != nil {
if !errors.Is(err, collections.ErrNotFound) {
return nil, err
}
return []types.DVPair{}, nil
}

pairs := types.DVPairs{}
err = k.cdc.Unmarshal(bz, &pairs)

return pairs.Pairs, err
}

// SetUBDQueueTimeSlice sets a specific unbonding queue timeslice.
func (k Keeper) SetUBDQueueTimeSlice(ctx context.Context, timestamp time.Time, keys []types.DVPair) error {
store := k.storeService.OpenKVStore(ctx)
bz, err := k.cdc.Marshal(&types.DVPairs{Pairs: keys})
if err != nil {
return err
}
return store.Set(types.GetUnbondingDelegationTimeKey(timestamp), bz)
dvPairs := types.DVPairs{Pairs: keys}
return k.UnbondingQueue.Set(ctx, timestamp, dvPairs)
}

// InsertUBDQueue inserts an unbonding delegation to the appropriate timeslice
Expand All @@ -379,9 +372,8 @@ func (k Keeper) InsertUBDQueue(ctx context.Context, ubd types.UnbondingDelegatio
if err != nil {
return err
}

if len(timeSlice) == 0 {
if err = k.SetUBDQueueTimeSlice(ctx, completionTime, []types.DVPair{dvPair}); err != nil {
if err := k.SetUBDQueueTimeSlice(ctx, completionTime, []types.DVPair{dvPair}); err != nil {
return err
}
return nil
Expand All @@ -391,38 +383,30 @@ func (k Keeper) InsertUBDQueue(ctx context.Context, ubd types.UnbondingDelegatio
return k.SetUBDQueueTimeSlice(ctx, completionTime, timeSlice)
}

// UBDQueueIterator returns all the unbonding queue timeslices from time 0 until endTime.
func (k Keeper) UBDQueueIterator(ctx context.Context, endTime time.Time) (corestore.Iterator, error) {
store := k.storeService.OpenKVStore(ctx)
return store.Iterator(types.UnbondingQueueKey,
storetypes.InclusiveEndBytes(types.GetUnbondingDelegationTimeKey(endTime)))
}

// DequeueAllMatureUBDQueue returns a concatenated list of all the timeslices inclusively previous to
// currTime, and deletes the timeslices from the queue.
func (k Keeper) DequeueAllMatureUBDQueue(ctx context.Context, currTime time.Time) (matureUnbonds []types.DVPair, err error) {
store := k.storeService.OpenKVStore(ctx)

// gets an iterator for all timeslices from time 0 until the current Blockheader time
unbondingTimesliceIterator, err := k.UBDQueueIterator(ctx, currTime)
// get an iterator for all timeslices from time 0 until the current Blockheader time
iter, err := k.UnbondingQueue.Iterate(ctx, (&collections.Range[time.Time]{}).EndInclusive(currTime))
if err != nil {
return matureUnbonds, err
}
defer unbondingTimesliceIterator.Close()
defer iter.Close()

for ; unbondingTimesliceIterator.Valid(); unbondingTimesliceIterator.Next() {
timeslice := types.DVPairs{}
value := unbondingTimesliceIterator.Value()
if err = k.cdc.Unmarshal(value, &timeslice); err != nil {
for ; iter.Valid(); iter.Next() {
timeslice, err := iter.Value()
if err != nil {
return matureUnbonds, err
}

matureUnbonds = append(matureUnbonds, timeslice.Pairs...)

if err = store.Delete(unbondingTimesliceIterator.Key()); err != nil {
key, err := iter.Key()
if err != nil {
return matureUnbonds, err
}
if err = k.UnbondingQueue.Remove(ctx, key); err != nil {
return matureUnbonds, err
}

}

return matureUnbonds, nil
Expand Down
3 changes: 3 additions & 0 deletions x/staking/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package keeper
import (
"context"
"fmt"
"time"

"cosmossdk.io/collections"
collcodec "cosmossdk.io/collections/codec"
Expand Down Expand Up @@ -44,6 +45,7 @@ type Keeper struct {
Redelegations collections.Map[collections.Triple[[]byte, []byte, []byte], types.Redelegation]
Delegations collections.Map[collections.Pair[sdk.AccAddress, sdk.ValAddress], types.Delegation]
UnbondingIndex collections.Map[uint64, []byte]
UnbondingQueue collections.Map[time.Time, types.DVPairs]
Validators collections.Map[[]byte, types.Validator]
UnbondingDelegations collections.Map[collections.Pair[[]byte, []byte], types.UnbondingDelegation]
RedelegationsByValDst collections.Map[collections.Triple[[]byte, []byte, []byte], []byte]
Expand Down Expand Up @@ -125,6 +127,7 @@ func NewKeeper(
codec.CollValue[types.Redelegation](cdc),
),
UnbondingIndex: collections.NewMap(sb, types.UnbondingIndexKey, "unbonding_index", collections.Uint64Key, collections.BytesValue),
UnbondingQueue: collections.NewMap(sb, types.UnbondingQueueKey, "unbonidng_queue", sdk.TimeKey, codec.CollValue[types.DVPairs](cdc)),
// key format is: 53 | lengthPrefixedBytes(SrcValAddr) | lengthPrefixedBytes(AccAddr) | lengthPrefixedBytes(DstValAddr)
RedelegationsByValSrc: collections.NewMap(
sb, types.RedelegationByValSrcIndexKey,
Expand Down
41 changes: 39 additions & 2 deletions x/staking/keeper/keeper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,13 @@ func getUBDKey(delAddr sdk.AccAddress, valAddr sdk.ValAddress) []byte {
return append(append(unbondingDelegationKey, addresstypes.MustLengthPrefix(delAddr)...), addresstypes.MustLengthPrefix(valAddr)...)
}

// getUnbondingDelegationTimeKey creates the prefix for all unbonding delegations from a delegator
func getUnbondingDelegationTimeKey(timestamp time.Time) []byte {
bz := sdk.FormatTimeBytes(timestamp)
unbondingQueueKey := []byte{0x41}
return append(unbondingQueueKey, bz...)
}

// getValidatorKey creates the key for the validator with address
// VALUE: staking/Validator
func getValidatorKey(operatorAddr sdk.ValAddress) []byte {
Expand Down Expand Up @@ -299,8 +306,34 @@ func (s *KeeperTestSuite) TestUnbondingDelegationsMigrationToColls() {
s.Require().NoError(err)
}

func TestKeeperTestSuite(t *testing.T) {
suite.Run(t, new(KeeperTestSuite))
func (s *KeeperTestSuite) TestUBDQueueMigrationToColls() {
s.SetupTest()

err := testutil.DiffCollectionsMigration(
s.ctx,
s.key,
100,
func(i int64) {
date := time.Date(2023, 8, 21, 14, 33, 1, 0, &time.Location{})
// legacy Set method
s.ctx.KVStore(s.key).Set(getUnbondingDelegationTimeKey(date), []byte{})
},
"7b8965aacc97646d6766a5a53bae397fe149d1c98fed027bea8774a18621ce6a",
)
s.Require().NoError(err)

err = testutil.DiffCollectionsMigration(
s.ctx,
s.key,
100,
func(i int64) {
date := time.Date(2023, 8, 21, 14, 33, 1, 0, &time.Location{})
err := s.stakingKeeper.SetUBDQueueTimeSlice(s.ctx, date, nil)
s.Require().NoError(err)
},
"7b8965aacc97646d6766a5a53bae397fe149d1c98fed027bea8774a18621ce6a",
)
s.Require().NoError(err)
}

func (s *KeeperTestSuite) TestValidatorsMigrationToColls() {
Expand Down Expand Up @@ -362,3 +395,7 @@ func (s *KeeperTestSuite) TestValidatorsMigrationToColls() {
)
s.Require().NoError(err)
}

func TestKeeperTestSuite(t *testing.T) {
suite.Run(t, new(KeeperTestSuite))
}
7 changes: 6 additions & 1 deletion x/staking/migrations/v2/store_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ func TestStoreMigration(t *testing.T) {
{
"UnbondingQueueKey",
v1.GetUnbondingDelegationTimeKey(now),
types.GetUnbondingDelegationTimeKey(now),
getUnbondingDelegationTimeKey(now),
},
{
"RedelegationQueueKey",
Expand Down Expand Up @@ -141,6 +141,11 @@ func TestStoreMigration(t *testing.T) {
}
}

func getUnbondingDelegationTimeKey(timestamp time.Time) []byte {
bz := sdk.FormatTimeBytes(timestamp)
return append(types.UnbondingQueueKey, bz...)
}

func getValidatorKey(operatorAddr sdk.ValAddress) []byte {
return append(types.ValidatorsKey, sdkaddress.MustLengthPrefix(operatorAddr)...)
}
Expand Down
12 changes: 3 additions & 9 deletions x/staking/types/keys.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,9 @@ var (
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 = []byte{0x41} // prefix for the timestamps in unbonding queue
RedelegationQueueKey = []byte{0x42} // prefix for the timestamps in redelegations queue
ValidatorQueueKey = []byte{0x43} // prefix for the timestamps in validator queue
UnbondingQueueKey = collections.NewPrefix(65) // prefix for the timestamps in unbonding queue
RedelegationQueueKey = []byte{0x42} // prefix for the timestamps in redelegations queue
ValidatorQueueKey = []byte{0x43} // prefix for the timestamps in validator queue

HistoricalInfoKey = collections.NewPrefix(80) // prefix for the historical info
ValidatorUpdatesKey = collections.NewPrefix(97) // prefix for the end block validator updates key
Expand Down Expand Up @@ -221,12 +221,6 @@ func GetUBDsByValIndexKey(valAddr sdk.ValAddress) []byte {
return append(UnbondingDelegationByValIndexKey, address.MustLengthPrefix(valAddr)...)
}

// GetUnbondingDelegationTimeKey creates the prefix for all unbonding delegations from a delegator
func GetUnbondingDelegationTimeKey(timestamp time.Time) []byte {
bz := sdk.FormatTimeBytes(timestamp)
return append(UnbondingQueueKey, bz...)
}

// GetREDKey returns a key prefix for indexing a redelegation from a delegator
// and source validator to a destination validator.
func GetREDKey(delAddr sdk.AccAddress, valSrcAddr, valDstAddr sdk.ValAddress) []byte {
Expand Down

0 comments on commit 6ed81a7

Please sign in to comment.