Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

refactor(x/staking): migrate RedelegationQueue to collections #17486

Merged
merged 35 commits into from
Sep 8, 2023
Merged
Show file tree
Hide file tree
Changes from 28 commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
95cf187
wip: migrate redelegationQueue to collections
likhita-809 Aug 21, 2023
267ed2e
Merge branch 'main' of https://github.com/cosmos/cosmos-sdk into likh…
likhita-809 Aug 21, 2023
0bf11c9
add diff test
likhita-809 Aug 21, 2023
e953dfc
Merge branch 'main' of https://github.com/cosmos/cosmos-sdk into likh…
likhita-809 Aug 23, 2023
4e9477c
Merge branch 'main' of https://github.com/cosmos/cosmos-sdk into likh…
likhita-809 Aug 23, 2023
8209bb8
use dvvTriplet instead of bytes
likhita-809 Aug 23, 2023
ff9b42c
add changelog
likhita-809 Aug 23, 2023
c24b96a
Merge branch 'main' of https://github.com/cosmos/cosmos-sdk into likh…
likhita-809 Aug 23, 2023
e00bbcb
improve changelog and nit
likhita-809 Aug 23, 2023
a6ddbe6
Merge branch 'main' of https://github.com/cosmos/cosmos-sdk into likh…
likhita-809 Aug 23, 2023
6ad6afc
Merge branch 'main' of https://github.com/cosmos/cosmos-sdk into likh…
likhita-809 Aug 28, 2023
62b9cc6
Merge branch 'main' of https://github.com/cosmos/cosmos-sdk into likh…
likhita-809 Aug 28, 2023
400e9a8
fix tests
likhita-809 Aug 28, 2023
ad632f4
Merge branch 'main' of https://github.com/cosmos/cosmos-sdk into likh…
likhita-809 Aug 29, 2023
c9a76d4
fix iterator
likhita-809 Aug 29, 2023
0bd4f7a
fix lint
likhita-809 Aug 29, 2023
4188704
Merge branch 'main' of https://github.com/cosmos/cosmos-sdk into likh…
likhita-809 Aug 29, 2023
e3cc9bc
Merge branch 'main' of https://github.com/cosmos/cosmos-sdk into likh…
likhita-809 Aug 29, 2023
f569cc3
Merge branch 'main' of https://github.com/cosmos/cosmos-sdk into likh…
likhita-809 Aug 29, 2023
4a65569
Merge branch 'main' of https://github.com/cosmos/cosmos-sdk into likh…
likhita-809 Aug 29, 2023
41f9e46
Merge branch 'main' of https://github.com/cosmos/cosmos-sdk into likh…
likhita-809 Aug 30, 2023
7ce55b1
Merge branch 'main' of https://github.com/cosmos/cosmos-sdk into likh…
likhita-809 Aug 30, 2023
41ff77b
improve keeper tests
likhita-809 Aug 30, 2023
48585c1
Merge branch 'main' of https://github.com/cosmos/cosmos-sdk into likh…
likhita-809 Aug 31, 2023
23d0261
Merge branch 'main' of https://github.com/cosmos/cosmos-sdk into likh…
likhita-809 Sep 1, 2023
3f94ce5
Merge branch 'main' of https://github.com/cosmos/cosmos-sdk into likh…
likhita-809 Sep 1, 2023
a9bce40
Merge branch 'main' of https://github.com/cosmos/cosmos-sdk into likh…
likhita-809 Sep 4, 2023
1cec61a
address review comment
likhita-809 Sep 4, 2023
3bdabd8
Merge branch 'main' into likhita/redelQueue
facundomedica Sep 5, 2023
e950a8d
fix failing test and godoc
likhita-809 Sep 5, 2023
530a34b
Merge branch 'main' of https://github.com/cosmos/cosmos-sdk into likh…
likhita-809 Sep 5, 2023
18d321b
add nit
likhita-809 Sep 8, 2023
58f8a85
Merge branch 'main' into likhita/redelQueue
mergify[bot] Sep 8, 2023
5ce87d7
Merge branch 'main' of https://github.com/cosmos/cosmos-sdk into likh…
likhita-809 Sep 8, 2023
61623ea
Merge branch 'main' of https://github.com/cosmos/cosmos-sdk into likh…
likhita-809 Sep 8, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ Ref: https://keepachangelog.com/en/1.0.0/

### API Breaking Changes

* (x/staking) [#17486](https://github.com/cosmos/cosmos-sdk/pull/17486) Use collections for `RedelegationQueueKey`:
* remove from `types`: `GetRedelegationTimeKey`
* remove from `Keeper`: `RedelegationQueueIterator`
* (x/staking) [#17498](https://github.com/cosmos/cosmos-sdk/pull/17498) Use collections for `LastValidatorPower`:
* remove from `types`: `GetLastValidatorPowerKey`
* remove from `Keeper`: `LastValidatorsIterator`, `IterateLastValidators`
Expand Down
63 changes: 20 additions & 43 deletions x/staking/keeper/delegation.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import (
"cosmossdk.io/collections"
errorsmod "cosmossdk.io/errors"
"cosmossdk.io/math"
storetypes "cosmossdk.io/store/types"

sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
Expand Down Expand Up @@ -610,33 +609,21 @@ func (k Keeper) RemoveRedelegation(ctx context.Context, red types.Redelegation)
// timeslice is a slice of DVVTriplets corresponding to redelegations that
// expire at a certain time.
func (k Keeper) GetRedelegationQueueTimeSlice(ctx context.Context, timestamp time.Time) (dvvTriplets []types.DVVTriplet, err error) {
store := k.storeService.OpenKVStore(ctx)
bz, err := store.Get(types.GetRedelegationTimeKey(timestamp))
triplets, err := k.RedelegationQueue.Get(ctx, timestamp)
if err != nil {
likhita-809 marked this conversation as resolved.
Show resolved Hide resolved
return nil, err
}

if bz == nil {
if !errors.Is(err, collections.ErrNotFound) {
return nil, err
}
return []types.DVVTriplet{}, nil
}

triplets := types.DVVTriplets{}
err = k.cdc.Unmarshal(bz, &triplets)
if err != nil {
return nil, err
}

return triplets.Triplets, nil
}

// SetRedelegationQueueTimeSlice sets a specific redelegation queue timeslice.
func (k Keeper) SetRedelegationQueueTimeSlice(ctx context.Context, timestamp time.Time, keys []types.DVVTriplet) error {
store := k.storeService.OpenKVStore(ctx)
bz, err := k.cdc.Marshal(&types.DVVTriplets{Triplets: keys})
if err != nil {
return err
}
return store.Set(types.GetRedelegationTimeKey(timestamp), bz)
triplets := types.DVVTriplets{Triplets: keys}
return k.RedelegationQueue.Set(ctx, timestamp, triplets)
}

// InsertRedelegationQueue insert an redelegation delegation to the appropriate
Expand All @@ -660,38 +647,28 @@ func (k Keeper) InsertRedelegationQueue(ctx context.Context, red types.Redelegat
return k.SetRedelegationQueueTimeSlice(ctx, completionTime, timeSlice)
}

// RedelegationQueueIterator returns all the redelegation queue timeslices from
// time 0 until endTime.
func (k Keeper) RedelegationQueueIterator(ctx context.Context, endTime time.Time) (storetypes.Iterator, error) {
store := k.storeService.OpenKVStore(ctx)
return store.Iterator(types.RedelegationQueueKey, storetypes.InclusiveEndBytes(types.GetRedelegationTimeKey(endTime)))
}

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

// gets an iterator for all timeslices from time 0 until the current Blockheader time
sdkCtx := sdk.UnwrapSDKContext(ctx)
redelegationTimesliceIterator, err := k.RedelegationQueueIterator(ctx, sdkCtx.HeaderInfo().Time)

// gets an iterator for all timeslices from time 0 until the current Blockheader time
rng := (&collections.Range[time.Time]{}).EndInclusive(sdkCtx.HeaderInfo().Time)
err = k.RedelegationQueue.Walk(ctx, rng, func(key time.Time, value types.DVVTriplets) (bool, error) {
keys = append(keys, key)
matureRedelegations = append(matureRedelegations, value.Triplets...)
return false, nil
})
if err != nil {
return nil, err
return matureRedelegations, err
}
defer redelegationTimesliceIterator.Close()

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

matureRedelegations = append(matureRedelegations, timeslice.Triplets...)

if err = store.Delete(redelegationTimesliceIterator.Key()); err != nil {
return nil, err
for _, key := range keys {
err := k.RedelegationQueue.Remove(ctx, key)
if err != nil {
return matureRedelegations, err
}
}

Expand Down
4 changes: 3 additions & 1 deletion x/staking/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ type Keeper struct {
RedelegationsByValDst collections.Map[collections.Triple[[]byte, []byte, []byte], []byte]
RedelegationsByValSrc collections.Map[collections.Triple[[]byte, []byte, []byte], []byte]
UnbondingDelegationByValIndex collections.Map[collections.Pair[[]byte, []byte], []byte]
RedelegationQueue collections.Map[time.Time, types.DVVTriplets]
LastValidatorPower collections.Map[[]byte, gogotypes.Int64Value]
}

Expand Down Expand Up @@ -162,7 +163,8 @@ func NewKeeper(
),
collections.BytesValue,
),
Validators: collections.NewMap(sb, types.ValidatorsKey, "validators", sdk.LengthPrefixedBytesKey, codec.CollValue[types.Validator](cdc)), // sdk.LengthPrefixedBytesKey is needed to retain state compatibility
RedelegationQueue: collections.NewMap(sb, types.RedelegationQueueKey, "redelegation_queue", sdk.TimeKey, codec.CollValue[types.DVVTriplets](cdc)),
Validators: collections.NewMap(sb, types.ValidatorsKey, "validators", sdk.LengthPrefixedBytesKey, codec.CollValue[types.Validator](cdc)), // sdk.LengthPrefixedBytesKey is needed to retain state compatibility
UnbondingDelegations: collections.NewMap(
sb, types.UnbondingDelegationKey,
"unbonding_delegation",
Expand Down
59 changes: 59 additions & 0 deletions x/staking/keeper/keeper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,14 @@ func getREDsFromValSrcIndexKey(valSrcAddr sdk.ValAddress) []byte {
return append(redelegationByValSrcIndexKey, addresstypes.MustLengthPrefix(valSrcAddr)...)
}

// getRedelegationTimeKey returns a key prefix for indexing an unbonding
// redelegation based on a completion time.
func getRedelegationTimeKey(timestamp time.Time) []byte {
bz := sdk.FormatTimeBytes(timestamp)
redelegationQueueKey := []byte{0x42}
return append(redelegationQueueKey, bz...)
}

// getUBDKey creates the key for an unbonding delegation by delegator and validator addr
// VALUE: staking/UnbondingDelegation
func getUBDKey(delAddr sdk.AccAddress, valAddr sdk.ValAddress) []byte {
Expand Down Expand Up @@ -445,6 +453,57 @@ func (s *KeeperTestSuite) TestValidatorsMigrationToColls() {
s.Require().NoError(err)
}

func (s *KeeperTestSuite) TestRedelegationQueueMigrationToColls() {
s.SetupTest()

addrs, valAddrs := createValAddrs(101)

err := testutil.DiffCollectionsMigration(
s.ctx,
s.key,
100,
func(i int64) {
date := time.Unix(i, i)
dvvTriplets := stakingtypes.DVVTriplets{
Triplets: []stakingtypes.DVVTriplet{
{
DelegatorAddress: addrs[i].String(),
ValidatorSrcAddress: valAddrs[i].String(),
ValidatorDstAddress: valAddrs[i+1].String(),
},
},
}
bz, err := s.cdc.Marshal(&dvvTriplets)
s.Require().NoError(err)
s.ctx.KVStore(s.key).Set(getRedelegationTimeKey(date), bz)
},
"de104dd19c7a72c6b0ad03d25c897313bb1473befc118952ad88e6a8726749c9",
)
s.Require().NoError(err)

err = testutil.DiffCollectionsMigration(
s.ctx,
s.key,
100,
func(i int64) {
date := time.Unix(i, i)
dvvTriplets := stakingtypes.DVVTriplets{
Triplets: []stakingtypes.DVVTriplet{
{
DelegatorAddress: addrs[i].String(),
ValidatorSrcAddress: valAddrs[i].String(),
ValidatorDstAddress: valAddrs[i+1].String(),
},
},
}
err := s.stakingKeeper.SetRedelegationQueueTimeSlice(s.ctx, date, dvvTriplets.Triplets)
s.Require().NoError(err)
},
"de104dd19c7a72c6b0ad03d25c897313bb1473befc118952ad88e6a8726749c9",
)
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 @@ -106,7 +106,7 @@ func TestStoreMigration(t *testing.T) {
{
"RedelegationQueueKey",
v1.GetRedelegationTimeKey(now),
types.GetRedelegationTimeKey(now),
getRedelegationTimeKey(now),
},
{
"ValidatorQueueKey",
Expand Down Expand Up @@ -141,6 +141,11 @@ func TestStoreMigration(t *testing.T) {
}
}

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

func getLastValidatorPowerKey(operator sdk.ValAddress) []byte {
return append(types.LastValidatorPowerKey, sdkaddress.MustLengthPrefix(operator)...)
}
Expand Down
9 changes: 1 addition & 8 deletions x/staking/types/keys.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ var (
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 = []byte{0x42} // prefix for the timestamps in redelegations queue
RedelegationQueueKey = collections.NewPrefix(66) // 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
Expand Down Expand Up @@ -207,13 +207,6 @@ func GetREDKey(delAddr sdk.AccAddress, valSrcAddr, valDstAddr sdk.ValAddress) []
return key
}

// GetRedelegationTimeKey returns a key prefix for indexing an unbonding
// redelegation based on a completion time.
func GetRedelegationTimeKey(timestamp time.Time) []byte {
bz := sdk.FormatTimeBytes(timestamp)
return append(RedelegationQueueKey, bz...)
}

// GetREDsKey returns a key prefix for indexing a redelegation from a delegator
// address.
func GetREDsKey(delAddr sdk.AccAddress) []byte {
Expand Down