From 95cf18761ba799afe328d86cb1863112a4e721f0 Mon Sep 17 00:00:00 2001 From: likhita-809 Date: Mon, 21 Aug 2023 15:08:10 +0530 Subject: [PATCH 01/12] wip: migrate redelegationQueue to collections --- x/staking/keeper/delegation.go | 44 ++++++++++----------------- x/staking/keeper/keeper.go | 5 ++- x/staking/migrations/v2/store_test.go | 7 ++++- x/staking/types/keys.go | 13 ++------ 4 files changed, 29 insertions(+), 40 deletions(-) diff --git a/x/staking/keeper/delegation.go b/x/staking/keeper/delegation.go index e6eae66f4866..0da791ab2d80 100644 --- a/x/staking/keeper/delegation.go +++ b/x/staking/keeper/delegation.go @@ -677,8 +677,7 @@ 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)) + bz, err := k.RedelegationQueue.Get(ctx, timestamp) if err != nil { return nil, err } @@ -698,21 +697,17 @@ func (k Keeper) GetRedelegationQueueTimeSlice(ctx context.Context, timestamp tim // 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) + return k.RedelegationQueue.Set(ctx, timestamp, bz) } // InsertRedelegationQueue insert an redelegation delegation to the appropriate // timeslice in the redelegation queue. func (k Keeper) InsertRedelegationQueue(ctx context.Context, red types.Redelegation, completionTime time.Time) error { - timeSlice, err := k.GetRedelegationQueueTimeSlice(ctx, completionTime) - if err != nil { - return err - } + timeSlice, _ := k.GetRedelegationQueueTimeSlice(ctx, completionTime) dvvTriplet := types.DVVTriplet{ DelegatorAddress: red.DelegatorAddress, ValidatorSrcAddress: red.ValidatorSrcAddress, @@ -727,39 +722,32 @@ 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) - // 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) - if err != nil { - return nil, err - } - defer redelegationTimesliceIterator.Close() - - for ; redelegationTimesliceIterator.Valid(); redelegationTimesliceIterator.Next() { + err = k.RedelegationQueue.Walk(ctx, nil, func(key time.Time, _ []byte) (bool, error) { timeslice := types.DVVTriplets{} - value := redelegationTimesliceIterator.Value() + value, err := k.RedelegationQueue.Get(ctx, sdkCtx.HeaderInfo().Time) + if err != nil { + return true, err + } if err = k.cdc.Unmarshal(value, ×lice); err != nil { - return nil, err + return true, err } matureRedelegations = append(matureRedelegations, timeslice.Triplets...) - if err = store.Delete(redelegationTimesliceIterator.Key()); err != nil { - return nil, err + if err = k.RedelegationQueue.Remove(ctx, key); err != nil { + return true, err } + return false, nil + }) + + if err != nil { + return matureRedelegations, err } return matureRedelegations, nil diff --git a/x/staking/keeper/keeper.go b/x/staking/keeper/keeper.go index a2d8f6ff3985..e8c58743d638 100644 --- a/x/staking/keeper/keeper.go +++ b/x/staking/keeper/keeper.go @@ -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] + RedelegationQueue collections.Map[time.Time, []byte] } // NewKeeper creates a new staking Keeper instance @@ -119,7 +121,8 @@ func NewKeeper( ), codec.CollValue[types.Redelegation](cdc), ), - UnbondingIndex: collections.NewMap(sb, types.UnbondingIndexKey, "unbonding_index", collections.Uint64Key, collections.BytesValue), + UnbondingIndex: collections.NewMap(sb, types.UnbondingIndexKey, "unbonding_index", collections.Uint64Key, collections.BytesValue), + RedelegationQueue: collections.NewMap(sb, types.RedelegationQueueKey, "redelegation_queue", sdk.TimeKey, collections.BytesValue), } schema, err := sb.Build() diff --git a/x/staking/migrations/v2/store_test.go b/x/staking/migrations/v2/store_test.go index 7e8750877d0d..04a2fc0fd5a1 100644 --- a/x/staking/migrations/v2/store_test.go +++ b/x/staking/migrations/v2/store_test.go @@ -105,7 +105,7 @@ func TestStoreMigration(t *testing.T) { { "RedelegationQueueKey", v1.GetRedelegationTimeKey(now), - types.GetRedelegationTimeKey(now), + getRedelegationTimeKey(now), }, { "ValidatorQueueKey", @@ -139,3 +139,8 @@ func TestStoreMigration(t *testing.T) { }) } } + +func getRedelegationTimeKey(timestamp time.Time) []byte { + bz := sdk.FormatTimeBytes(timestamp) + return append(types.RedelegationQueueKey, bz...) +} diff --git a/x/staking/types/keys.go b/x/staking/types/keys.go index 961f9b33f3da..9dbbe1b058cc 100644 --- a/x/staking/types/keys.go +++ b/x/staking/types/keys.go @@ -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 = []byte{0x41} // prefix for the timestamps in unbonding 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 ValidatorUpdatesKey = collections.NewPrefix(97) // prefix for the end block validator updates key @@ -317,13 +317,6 @@ func GetREDKeyFromValDstIndexKey(indexKey []byte) []byte { return GetREDKey(delAddr, valSrcAddr, valDstAddr) } -// 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 { From 0bf11c94387dbe569538f3a065da0ce55b7cce16 Mon Sep 17 00:00:00 2001 From: likhita-809 Date: Mon, 21 Aug 2023 16:19:54 +0530 Subject: [PATCH 02/12] add diff test --- x/staking/keeper/keeper_test.go | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/x/staking/keeper/keeper_test.go b/x/staking/keeper/keeper_test.go index 46aabdcabb4c..6e50569adc30 100644 --- a/x/staking/keeper/keeper_test.go +++ b/x/staking/keeper/keeper_test.go @@ -2,6 +2,7 @@ package keeper_test import ( "testing" + "time" cmtproto "github.com/cometbft/cometbft/proto/tendermint/types" cmttime "github.com/cometbft/cometbft/types/time" @@ -39,11 +40,13 @@ type KeeperTestSuite struct { accountKeeper *stakingtestutil.MockAccountKeeper queryClient stakingtypes.QueryClient msgServer stakingtypes.MsgServer + key *storetypes.KVStoreKey } func (s *KeeperTestSuite) SetupTest() { require := s.Require() key := storetypes.NewKVStoreKey(stakingtypes.StoreKey) + s.key = key storeService := runtime.NewKVStoreService(key) testCtx := testutil.DefaultContextWithDB(s.T(), key, storetypes.NewTransientStoreKey("transient_test")) ctx := testCtx.Ctx.WithBlockHeader(cmtproto.Header{Time: cmttime.Now()}) @@ -112,3 +115,20 @@ func (s *KeeperTestSuite) TestLastTotalPower() { func TestKeeperTestSuite(t *testing.T) { suite.Run(t, new(KeeperTestSuite)) } + +func (s *KeeperTestSuite) TestDiffCollsMigration() { + 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{}) + err := s.stakingKeeper.SetRedelegationQueueTimeSlice(s.ctx, date, nil) + s.Require().NoError(err) + }, + "035e246f9d0bf0aa3dfeb88acf1665684168256d8afb742ae065872d6334f6d6", + ) + s.Require().NoError(err) +} From 8209bb88947c244ce6adcb7b9aaf839cbae23ed2 Mon Sep 17 00:00:00 2001 From: likhita-809 Date: Wed, 23 Aug 2023 16:03:13 +0530 Subject: [PATCH 03/12] use dvvTriplet instead of bytes --- x/staking/keeper/delegation.go | 28 ++++++++-------------------- x/staking/keeper/keeper.go | 4 ++-- x/staking/keeper/keeper_test.go | 30 +++++++++++++++++++++++++----- x/staking/types/keys.go | 7 ------- 4 files changed, 35 insertions(+), 34 deletions(-) diff --git a/x/staking/keeper/delegation.go b/x/staking/keeper/delegation.go index d19e61628785..c71cc610a709 100644 --- a/x/staking/keeper/delegation.go +++ b/x/staking/keeper/delegation.go @@ -673,31 +673,23 @@ 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) { - bz, err := k.RedelegationQueue.Get(ctx, timestamp) + dvvTriplet, err := k.RedelegationQueue.Get(ctx, timestamp) if err != nil { return nil, err } - if bz == nil { - return []types.DVVTriplet{}, nil - } - triplets := types.DVVTriplets{} - err = k.cdc.Unmarshal(bz, &triplets) - if err != nil { - return nil, err - } + triplets.Triplets = append(triplets.Triplets, dvvTriplet) 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 { - bz, err := k.cdc.Marshal(&types.DVVTriplets{Triplets: keys}) - if err != nil { - return err + if len(keys) == 0 { + return k.RedelegationQueue.Set(ctx, timestamp, types.DVVTriplet{}) } - return k.RedelegationQueue.Set(ctx, timestamp, bz) + return k.RedelegationQueue.Set(ctx, timestamp, keys[0]) } // InsertRedelegationQueue insert an redelegation delegation to the appropriate @@ -724,17 +716,13 @@ func (k Keeper) InsertRedelegationQueue(ctx context.Context, red types.Redelegat func (k Keeper) DequeueAllMatureRedelegationQueue(ctx context.Context, currTime time.Time) (matureRedelegations []types.DVVTriplet, err error) { // gets an iterator for all timeslices from time 0 until the current Blockheader time sdkCtx := sdk.UnwrapSDKContext(ctx) - err = k.RedelegationQueue.Walk(ctx, nil, func(key time.Time, _ []byte) (bool, error) { - timeslice := types.DVVTriplets{} - value, err := k.RedelegationQueue.Get(ctx, sdkCtx.HeaderInfo().Time) + err = k.RedelegationQueue.Walk(ctx, nil, func(key time.Time, _ types.DVVTriplet) (bool, error) { + timeslice, err := k.RedelegationQueue.Get(ctx, sdkCtx.HeaderInfo().Time) if err != nil { return true, err } - if err = k.cdc.Unmarshal(value, ×lice); err != nil { - return true, err - } - matureRedelegations = append(matureRedelegations, timeslice.Triplets...) + matureRedelegations = append(matureRedelegations, timeslice) if err = k.RedelegationQueue.Remove(ctx, key); err != nil { return true, err diff --git a/x/staking/keeper/keeper.go b/x/staking/keeper/keeper.go index 05d8f2f53635..3f52ab7d3359 100644 --- a/x/staking/keeper/keeper.go +++ b/x/staking/keeper/keeper.go @@ -45,7 +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] - RedelegationQueue collections.Map[time.Time, []byte] + RedelegationQueue collections.Map[time.Time, types.DVVTriplet] RedelegationsByValDst collections.Map[collections.Triple[[]byte, []byte, []byte], []byte] RedelegationsByValSrc collections.Map[collections.Triple[[]byte, []byte, []byte], []byte] } @@ -147,7 +147,7 @@ func NewKeeper( ), collections.BytesValue, ), - RedelegationQueue: collections.NewMap(sb, types.RedelegationQueueKey, "redelegation_queue", sdk.TimeKey, collections.BytesValue), + RedelegationQueue: collections.NewMap(sb, types.RedelegationQueueKey, "redelegation_queue", sdk.TimeKey, codec.CollValue[types.DVVTriplet](cdc)), } schema, err := sb.Build() diff --git a/x/staking/keeper/keeper_test.go b/x/staking/keeper/keeper_test.go index ced38469573e..8619690912b6 100644 --- a/x/staking/keeper/keeper_test.go +++ b/x/staking/keeper/keeper_test.go @@ -163,6 +163,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...) +} + func (s *KeeperTestSuite) TestSrcRedelegationsMigrationToColls() { s.SetupTest() @@ -227,14 +235,22 @@ func (s *KeeperTestSuite) TestDstRedelegationsMigrationToColls() { s.Require().NoError(err) } -func TestKeeperTestSuite(t *testing.T) { - suite.Run(t, new(KeeperTestSuite)) -} - -func (s *KeeperTestSuite) TestDiffCollsMigration() { +func (s *KeeperTestSuite) TestRedelegationQueueMigrationToColls() { 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{}) + s.ctx.KVStore(s.key).Set(getRedelegationTimeKey(date), []byte{}) + }, + "035e246f9d0bf0aa3dfeb88acf1665684168256d8afb742ae065872d6334f6d6", + ) + s.Require().NoError(err) + + err = testutil.DiffCollectionsMigration( s.ctx, s.key, 100, @@ -247,3 +263,7 @@ func (s *KeeperTestSuite) TestDiffCollsMigration() { ) s.Require().NoError(err) } + +func TestKeeperTestSuite(t *testing.T) { + suite.Run(t, new(KeeperTestSuite)) +} diff --git a/x/staking/types/keys.go b/x/staking/types/keys.go index d717b7fe4972..e31a6ae2579d 100644 --- a/x/staking/types/keys.go +++ b/x/staking/types/keys.go @@ -247,13 +247,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 { From ff9b42ce5e32cf3fcd16fcf17622e819f4ffedd0 Mon Sep 17 00:00:00 2001 From: likhita-809 Date: Wed, 23 Aug 2023 16:07:36 +0530 Subject: [PATCH 04/12] add changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3738c96aa539..90482cf3687b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -52,6 +52,8 @@ 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` * (x/staking) [#17336](https://github.com/cosmos/cosmos-sdk/pull/17336) Use collections for `RedelegationByValDstIndexKey`: * remove from `types`: `GetREDByValDstIndexKey`, `GetREDsToValDstIndexKey` * (x/staking) [#17332](https://github.com/cosmos/cosmos-sdk/pull/17332) Use collections for `RedelegationByValSrcIndexKey`: From e00bbcb0a76db2905764b6348307a4b3a1d6121e Mon Sep 17 00:00:00 2001 From: likhita-809 Date: Wed, 23 Aug 2023 18:15:31 +0530 Subject: [PATCH 05/12] improve changelog and nit --- CHANGELOG.md | 1 + x/staking/keeper/delegation.go | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a09a216b02c0..6d97849e20a5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -56,6 +56,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ * (x/staking) [#17486](https://github.com/cosmos/cosmos-sdk/pull/17486) Use collections for `RedelegationQueueKey`: * remove from `types`: `GetRedelegationTimeKey` + * remove from `Keeper`: `RedelegationQueueIterator` * (client/keys) [#17503](https://github.com/cosmos/cosmos-sdk/pull/17503) `clientkeys.NewKeyOutput`, `MkConsKeyOutput`, `MkValKeyOutput`, `MkAccKeyOutput`, `MkAccKeysOutput` now take their corresponding address codec instead of using the global SDK config. * (x/staking) [#17336](https://github.com/cosmos/cosmos-sdk/pull/17336) Use collections for `RedelegationByValDstIndexKey`: * remove from `types`: `GetREDByValDstIndexKey`, `GetREDsToValDstIndexKey` diff --git a/x/staking/keeper/delegation.go b/x/staking/keeper/delegation.go index c71cc610a709..ac4d5bd8a3a8 100644 --- a/x/staking/keeper/delegation.go +++ b/x/staking/keeper/delegation.go @@ -695,7 +695,10 @@ func (k Keeper) SetRedelegationQueueTimeSlice(ctx context.Context, timestamp tim // InsertRedelegationQueue insert an redelegation delegation to the appropriate // timeslice in the redelegation queue. func (k Keeper) InsertRedelegationQueue(ctx context.Context, red types.Redelegation, completionTime time.Time) error { - timeSlice, _ := k.GetRedelegationQueueTimeSlice(ctx, completionTime) + timeSlice, err := k.GetRedelegationQueueTimeSlice(ctx, completionTime) + if err != nil { + return err + } dvvTriplet := types.DVVTriplet{ DelegatorAddress: red.DelegatorAddress, ValidatorSrcAddress: red.ValidatorSrcAddress, From 400e9a8cc182c279b37b9a1691676465a2861b15 Mon Sep 17 00:00:00 2001 From: likhita-809 Date: Mon, 28 Aug 2023 17:43:33 +0530 Subject: [PATCH 06/12] fix tests --- x/staking/keeper/delegation.go | 20 ++++----- x/staking/keeper/keeper.go | 4 +- x/staking/keeper/keeper_test.go | 80 ++++++++++++++++----------------- 3 files changed, 51 insertions(+), 53 deletions(-) diff --git a/x/staking/keeper/delegation.go b/x/staking/keeper/delegation.go index f44b07f854c6..56974570ddd0 100644 --- a/x/staking/keeper/delegation.go +++ b/x/staking/keeper/delegation.go @@ -626,23 +626,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) { - dvvTriplet, err := k.RedelegationQueue.Get(ctx, timestamp) + triplets, err := k.RedelegationQueue.Get(ctx, timestamp) if err != nil { - return nil, err + if !errors.Is(err, collections.ErrNotFound) { + return nil, err + } + return []types.DVVTriplet{}, nil } - triplets := types.DVVTriplets{} - triplets.Triplets = append(triplets.Triplets, dvvTriplet) - 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 { - if len(keys) == 0 { - return k.RedelegationQueue.Set(ctx, timestamp, types.DVVTriplet{}) - } - return k.RedelegationQueue.Set(ctx, timestamp, keys[0]) + triplets := types.DVVTriplets{Triplets: keys} + return k.RedelegationQueue.Set(ctx, timestamp, triplets) } // InsertRedelegationQueue insert an redelegation delegation to the appropriate @@ -672,13 +670,13 @@ func (k Keeper) InsertRedelegationQueue(ctx context.Context, red types.Redelegat func (k Keeper) DequeueAllMatureRedelegationQueue(ctx context.Context, currTime time.Time) (matureRedelegations []types.DVVTriplet, err error) { // gets an iterator for all timeslices from time 0 until the current Blockheader time sdkCtx := sdk.UnwrapSDKContext(ctx) - err = k.RedelegationQueue.Walk(ctx, nil, func(key time.Time, _ types.DVVTriplet) (bool, error) { + err = k.RedelegationQueue.Walk(ctx, nil, func(key time.Time, _ types.DVVTriplets) (bool, error) { timeslice, err := k.RedelegationQueue.Get(ctx, sdkCtx.HeaderInfo().Time) if err != nil { return true, err } - matureRedelegations = append(matureRedelegations, timeslice) + matureRedelegations = append(matureRedelegations, timeslice.Triplets...) if err = k.RedelegationQueue.Remove(ctx, key); err != nil { return true, err diff --git a/x/staking/keeper/keeper.go b/x/staking/keeper/keeper.go index 2e6789e1e45b..efcd74773c12 100644 --- a/x/staking/keeper/keeper.go +++ b/x/staking/keeper/keeper.go @@ -45,7 +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] - RedelegationQueue collections.Map[time.Time, types.DVVTriplet] + RedelegationQueue collections.Map[time.Time, types.DVVTriplets] UnbondingDelegations collections.Map[collections.Pair[[]byte, []byte], types.UnbondingDelegation] RedelegationsByValDst collections.Map[collections.Triple[[]byte, []byte, []byte], []byte] RedelegationsByValSrc collections.Map[collections.Triple[[]byte, []byte, []byte], []byte] @@ -148,7 +148,7 @@ func NewKeeper( ), collections.BytesValue, ), - RedelegationQueue: collections.NewMap(sb, types.RedelegationQueueKey, "redelegation_queue", sdk.TimeKey, codec.CollValue[types.DVVTriplet](cdc)), + RedelegationQueue: collections.NewMap(sb, types.RedelegationQueueKey, "redelegation_queue", sdk.TimeKey, codec.CollValue[types.DVVTriplets](cdc)), UnbondingDelegations: collections.NewMap( sb, types.UnbondingDelegationKey, "unbonding_delegation", diff --git a/x/staking/keeper/keeper_test.go b/x/staking/keeper/keeper_test.go index 2a0532668038..870f4c3f4398 100644 --- a/x/staking/keeper/keeper_test.go +++ b/x/staking/keeper/keeper_test.go @@ -174,6 +174,13 @@ func getRedelegationTimeKey(timestamp time.Time) []byte { 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 { + unbondingDelegationKey := []byte{0x32} + return append(append(unbondingDelegationKey, addresstypes.MustLengthPrefix(delAddr)...), addresstypes.MustLengthPrefix(valAddr)...) +} + func (s *KeeperTestSuite) TestSrcRedelegationsMigrationToColls() { s.SetupTest() @@ -238,46 +245,6 @@ func (s *KeeperTestSuite) TestDstRedelegationsMigrationToColls() { s.Require().NoError(err) } -func (s *KeeperTestSuite) TestRedelegationQueueMigrationToColls() { - 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{}) - s.ctx.KVStore(s.key).Set(getRedelegationTimeKey(date), []byte{}) - }, - "035e246f9d0bf0aa3dfeb88acf1665684168256d8afb742ae065872d6334f6d6", - ) - 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.SetRedelegationQueueTimeSlice(s.ctx, date, nil) - s.Require().NoError(err) - }, - "035e246f9d0bf0aa3dfeb88acf1665684168256d8afb742ae065872d6334f6d6", - ) - s.Require().NoError(err) -} - -func TestKeeperTestSuite(t *testing.T) { - suite.Run(t, new(KeeperTestSuite)) -} - -// 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 { - unbondingDelegationKey := []byte{0x32} - return append(append(unbondingDelegationKey, addresstypes.MustLengthPrefix(delAddr)...), addresstypes.MustLengthPrefix(valAddr)...) -} - func (s *KeeperTestSuite) TestUnbondingDelegationsMigrationToColls() { s.SetupTest() @@ -332,3 +299,36 @@ func (s *KeeperTestSuite) TestUnbondingDelegationsMigrationToColls() { s.Require().NoError(err) } + +func (s *KeeperTestSuite) TestRedelegationQueueMigrationToColls() { + 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{}) + s.ctx.KVStore(s.key).Set(getRedelegationTimeKey(date), []byte{}) + }, + "035e246f9d0bf0aa3dfeb88acf1665684168256d8afb742ae065872d6334f6d6", + ) + 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.SetRedelegationQueueTimeSlice(s.ctx, date, nil) + s.Require().NoError(err) + }, + "035e246f9d0bf0aa3dfeb88acf1665684168256d8afb742ae065872d6334f6d6", + ) + s.Require().NoError(err) +} + +func TestKeeperTestSuite(t *testing.T) { + suite.Run(t, new(KeeperTestSuite)) +} From c9a76d4864d7b4d726f037a87bc6427dd2e30280 Mon Sep 17 00:00:00 2001 From: likhita-809 Date: Tue, 29 Aug 2023 12:03:00 +0530 Subject: [PATCH 07/12] fix iterator --- x/staking/keeper/delegation.go | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/x/staking/keeper/delegation.go b/x/staking/keeper/delegation.go index 56974570ddd0..49a562436093 100644 --- a/x/staking/keeper/delegation.go +++ b/x/staking/keeper/delegation.go @@ -670,22 +670,27 @@ func (k Keeper) InsertRedelegationQueue(ctx context.Context, red types.Redelegat func (k Keeper) DequeueAllMatureRedelegationQueue(ctx context.Context, currTime time.Time) (matureRedelegations []types.DVVTriplet, err error) { // gets an iterator for all timeslices from time 0 until the current Blockheader time sdkCtx := sdk.UnwrapSDKContext(ctx) - err = k.RedelegationQueue.Walk(ctx, nil, func(key time.Time, _ types.DVVTriplets) (bool, error) { - timeslice, err := k.RedelegationQueue.Get(ctx, sdkCtx.HeaderInfo().Time) + redelegationTimesliceIterator, err := k.RedelegationQueue.Iterate(ctx, (&collections.Range[time.Time]{}).EndInclusive(sdkCtx.HeaderInfo().Time)) + if err != nil { + return nil, err + } + defer redelegationTimesliceIterator.Close() + + for ; redelegationTimesliceIterator.Valid(); redelegationTimesliceIterator.Next() { + timeslice, err := redelegationTimesliceIterator.Value() if err != nil { - return true, err + return matureRedelegations, err } matureRedelegations = append(matureRedelegations, timeslice.Triplets...) + key, err := redelegationTimesliceIterator.Key() + if err != nil { + return matureRedelegations, err + } if err = k.RedelegationQueue.Remove(ctx, key); err != nil { - return true, err + return matureRedelegations, err } - return false, nil - }) - - if err != nil { - return matureRedelegations, err } return matureRedelegations, nil From 0bd4f7aa8a7187caf9494b075f6e32c4eb4b271f Mon Sep 17 00:00:00 2001 From: likhita-809 Date: Tue, 29 Aug 2023 12:09:27 +0530 Subject: [PATCH 08/12] fix lint --- x/staking/keeper/delegation.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/staking/keeper/delegation.go b/x/staking/keeper/delegation.go index 49a562436093..baf4246104ef 100644 --- a/x/staking/keeper/delegation.go +++ b/x/staking/keeper/delegation.go @@ -675,7 +675,7 @@ func (k Keeper) DequeueAllMatureRedelegationQueue(ctx context.Context, currTime return nil, err } defer redelegationTimesliceIterator.Close() - + for ; redelegationTimesliceIterator.Valid(); redelegationTimesliceIterator.Next() { timeslice, err := redelegationTimesliceIterator.Value() if err != nil { From 41ff77bd5fb40bb9e47270099c527c6ce93cac04 Mon Sep 17 00:00:00 2001 From: likhita-809 Date: Wed, 30 Aug 2023 15:30:09 +0530 Subject: [PATCH 09/12] improve keeper tests --- x/staking/keeper/keeper_test.go | 34 +++++++++++++++++++++++++++------ 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/x/staking/keeper/keeper_test.go b/x/staking/keeper/keeper_test.go index ff51c14410b3..00aaf83846d8 100644 --- a/x/staking/keeper/keeper_test.go +++ b/x/staking/keeper/keeper_test.go @@ -414,15 +414,28 @@ func (s *KeeperTestSuite) TestValidatorsMigrationToColls() { func (s *KeeperTestSuite) TestRedelegationQueueMigrationToColls() { s.SetupTest() + addrs, valAddrs := createValAddrs(101) + err := testutil.DiffCollectionsMigration( s.ctx, s.key, 100, func(i int64) { - date := time.Date(2023, 8, 21, 14, 33, 1, 0, &time.Location{}) - s.ctx.KVStore(s.key).Set(getRedelegationTimeKey(date), []byte{}) + 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) }, - "035e246f9d0bf0aa3dfeb88acf1665684168256d8afb742ae065872d6334f6d6", + "de104dd19c7a72c6b0ad03d25c897313bb1473befc118952ad88e6a8726749c9", ) s.Require().NoError(err) @@ -431,11 +444,20 @@ func (s *KeeperTestSuite) TestRedelegationQueueMigrationToColls() { s.key, 100, func(i int64) { - date := time.Date(2023, 8, 21, 14, 33, 1, 0, &time.Location{}) - err := s.stakingKeeper.SetRedelegationQueueTimeSlice(s.ctx, date, nil) + 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) }, - "035e246f9d0bf0aa3dfeb88acf1665684168256d8afb742ae065872d6334f6d6", + "de104dd19c7a72c6b0ad03d25c897313bb1473befc118952ad88e6a8726749c9", ) s.Require().NoError(err) } From 1cec61a400dba0768e79cd576fd77ac88b6e3a40 Mon Sep 17 00:00:00 2001 From: likhita-809 Date: Mon, 4 Sep 2023 22:00:12 +0530 Subject: [PATCH 10/12] address review comment --- x/staking/keeper/delegation.go | 30 +++++++++++++----------------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/x/staking/keeper/delegation.go b/x/staking/keeper/delegation.go index 3b59843f1ab4..daae6876af6e 100644 --- a/x/staking/keeper/delegation.go +++ b/x/staking/keeper/delegation.go @@ -651,29 +651,25 @@ func (k Keeper) InsertRedelegationQueue(ctx context.Context, red types.Redelegat // 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) { - // gets an iterator for all timeslices from time 0 until the current Blockheader time + var keys []time.Time + sdkCtx := sdk.UnwrapSDKContext(ctx) - redelegationTimesliceIterator, err := k.RedelegationQueue.Iterate(ctx, (&collections.Range[time.Time]{}).EndInclusive(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, err := redelegationTimesliceIterator.Value() + for _, key := range keys { + err := k.RedelegationQueue.Remove(ctx, key) if err != nil { return matureRedelegations, err } - - matureRedelegations = append(matureRedelegations, timeslice.Triplets...) - - key, err := redelegationTimesliceIterator.Key() - if err != nil { - return matureRedelegations, err - } - if err = k.RedelegationQueue.Remove(ctx, key); err != nil { - return matureRedelegations, err - } } return matureRedelegations, nil From e950a8d843afed8e268d61220ec473917e522030 Mon Sep 17 00:00:00 2001 From: likhita-809 Date: Tue, 5 Sep 2023 10:06:05 +0530 Subject: [PATCH 11/12] fix failing test and godoc --- x/staking/keeper/keeper.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x/staking/keeper/keeper.go b/x/staking/keeper/keeper.go index 5d470ae17f74..1a3c46afd553 100644 --- a/x/staking/keeper/keeper.go +++ b/x/staking/keeper/keeper.go @@ -68,8 +68,8 @@ type Keeper struct { RedelegationsByValSrc collections.Map[collections.Triple[[]byte, []byte, []byte], []byte] // UnbondingDelegationByValIndex key: valAddr+delAddr | value: none used (index key for UnbondingDelegations stored by validator index) UnbondingDelegationByValIndex collections.Map[collections.Pair[[]byte, []byte], []byte] - RedelegationQueue collections.Map[time.Time, types.DVVTriplets] - LastValidatorPower collections.Map[[]byte, gogotypes.Int64Value] + // RedelegationQueue key: Timestamp | value: DVVTriplets [delAddr+valSrcAddr+valDstAddr] + RedelegationQueue collections.Map[time.Time, types.DVVTriplets] // LastValidatorPower key: valAddr | value: power(gogotypes.Int64Value()) LastValidatorPower collections.Map[[]byte, gogotypes.Int64Value] } From 18d321b42b5bba48814f1cd3592317790d601a99 Mon Sep 17 00:00:00 2001 From: likhita-809 Date: Fri, 8 Sep 2023 16:07:34 +0530 Subject: [PATCH 12/12] add nit --- x/staking/keeper/delegation.go | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/x/staking/keeper/delegation.go b/x/staking/keeper/delegation.go index daae6876af6e..22fe53ec75ef 100644 --- a/x/staking/keeper/delegation.go +++ b/x/staking/keeper/delegation.go @@ -610,11 +610,8 @@ func (k Keeper) RemoveRedelegation(ctx context.Context, red types.Redelegation) // expire at a certain time. func (k Keeper) GetRedelegationQueueTimeSlice(ctx context.Context, timestamp time.Time) (dvvTriplets []types.DVVTriplet, err error) { triplets, err := k.RedelegationQueue.Get(ctx, timestamp) - if err != nil { - if !errors.Is(err, collections.ErrNotFound) { - return nil, err - } - return []types.DVVTriplet{}, nil + if err != nil && !errors.Is(err, collections.ErrNotFound) { + return []types.DVVTriplet{}, err } return triplets.Triplets, nil