refactor(x/staking): migrate UnbondingQueue to collections (#17481)

This commit is contained in:
Likhita Polavarapu
2023-08-29 07:15:22 +00:00
committed by GitHub
parent 0561f990d8
commit 6ed81a737c
6 changed files with 74 additions and 48 deletions
+3
View File
@@ -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`
+20 -36
View File
@@ -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"
@@ -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
@@ -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
@@ -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
+3
View File
@@ -3,6 +3,7 @@ package keeper
import (
"context"
"fmt"
"time"
"cosmossdk.io/collections"
collcodec "cosmossdk.io/collections/codec"
@@ -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]
@@ -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,
+39 -2
View File
@@ -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 {
@@ -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() {
@@ -362,3 +395,7 @@ func (s *KeeperTestSuite) TestValidatorsMigrationToColls() {
)
s.Require().NoError(err)
}
func TestKeeperTestSuite(t *testing.T) {
suite.Run(t, new(KeeperTestSuite))
}
+6 -1
View File
@@ -101,7 +101,7 @@ func TestStoreMigration(t *testing.T) {
{
"UnbondingQueueKey",
v1.GetUnbondingDelegationTimeKey(now),
types.GetUnbondingDelegationTimeKey(now),
getUnbondingDelegationTimeKey(now),
},
{
"RedelegationQueueKey",
@@ -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)...)
}
+3 -9
View File
@@ -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
@@ -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 {