From b902f71fb689dba36851d6bb8b047f009b759d8d Mon Sep 17 00:00:00 2001 From: atheesh Date: Tue, 8 Aug 2023 11:03:45 +0530 Subject: [PATCH 01/19] refactor(x/staking): migrate redelegation key to use collections --- x/staking/keeper/delegation.go | 5 ++--- x/staking/keeper/keeper.go | 11 +++++++++++ x/staking/types/keys.go | 12 ++++++------ 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/x/staking/keeper/delegation.go b/x/staking/keeper/delegation.go index f7761c9f9189..768cbd0f075d 100644 --- a/x/staking/keeper/delegation.go +++ b/x/staking/keeper/delegation.go @@ -650,7 +650,6 @@ func (k Keeper) SetRedelegation(ctx context.Context, red types.Redelegation) err } store := k.storeService.OpenKVStore(ctx) - bz := types.MustMarshalRED(k.cdc, red) valSrcAddr, err := k.validatorAddressCodec.StringToBytes(red.ValidatorSrcAddress) if err != nil { return err @@ -659,8 +658,8 @@ func (k Keeper) SetRedelegation(ctx context.Context, red types.Redelegation) err if err != nil { return err } - key := types.GetREDKey(delegatorAddress, valSrcAddr, valDestAddr) - if err = store.Set(key, bz); err != nil { + + if err = k.Redelegations.Set(ctx, collections.Join3(sdk.AccAddress(delegatorAddress), sdk.ValAddress(valSrcAddr), sdk.ValAddress(valDestAddr)), red); err != nil { return err } diff --git a/x/staking/keeper/keeper.go b/x/staking/keeper/keeper.go index 351ea8cf8612..6448736f75cd 100644 --- a/x/staking/keeper/keeper.go +++ b/x/staking/keeper/keeper.go @@ -41,6 +41,7 @@ type Keeper struct { UnbondingID collections.Sequence ValidatorByConsensusAddress collections.Map[sdk.ConsAddress, sdk.ValAddress] UnbondingType collections.Map[uint64, uint64] + Redelegations collections.Map[collections.Triple[sdk.AccAddress, sdk.ValAddress, sdk.ValAddress], types.Redelegation] } // NewKeeper creates a new staking Keeper instance @@ -98,6 +99,16 @@ func NewKeeper( collcodec.KeyToValueCodec(sdk.ValAddressKey), ), UnbondingType: collections.NewMap(sb, types.UnbondingTypeKey, "unbonding_type", collections.Uint64Key, collections.Uint64Value), + Redelegations: collections.NewMap( + sb, types.RedelegationKey, + "redelegations", + collections.TripleKeyCodec( + sdk.LengthPrefixedAddressKey(sdk.AccAddressKey), // nolint: staticcheck // sdk.LengthPrefixedAddressKey is needed to retain state compatibility + sdk.LengthPrefixedAddressKey(sdk.ValAddressKey), // nolint: staticcheck // sdk.LengthPrefixedAddressKey is needed to retain state compatibility + sdk.LengthPrefixedAddressKey(sdk.ValAddressKey), // nolint: staticcheck // sdk.LengthPrefixedAddressKey is needed to retain state compatibility + ), + codec.CollValue[types.Redelegation](cdc), + ), } schema, err := sb.Build() diff --git a/x/staking/types/keys.go b/x/staking/types/keys.go index 61da6f3eda24..06c9eb4e9584 100644 --- a/x/staking/types/keys.go +++ b/x/staking/types/keys.go @@ -38,12 +38,12 @@ var ( ValidatorsByConsAddrKey = collections.NewPrefix(34) // prefix for each key to a validator index, by pubkey ValidatorsByPowerIndexKey = []byte{0x23} // prefix for each key to a validator index, sorted by power - DelegationKey = []byte{0x31} // key for a delegation - UnbondingDelegationKey = []byte{0x32} // key for an unbonding-delegation - UnbondingDelegationByValIndexKey = []byte{0x33} // prefix for each key for an unbonding-delegation, by validator operator - RedelegationKey = []byte{0x34} // key for a redelegation - RedelegationByValSrcIndexKey = []byte{0x35} // prefix for each key for an redelegation, by source validator operator - RedelegationByValDstIndexKey = []byte{0x36} // prefix for each key for an redelegation, by destination validator operator + DelegationKey = []byte{0x31} // key for a delegation + UnbondingDelegationKey = []byte{0x32} // key for an unbonding-delegation + UnbondingDelegationByValIndexKey = []byte{0x33} // prefix for each key for an unbonding-delegation, by validator operator + RedelegationKey = collections.NewPrefix(52) // key for a redelegation + RedelegationByValSrcIndexKey = []byte{0x35} // prefix for each key for an redelegation, by source validator operator + RedelegationByValDstIndexKey = []byte{0x36} // prefix for each key for an redelegation, by destination validator operator UnbondingIDKey = collections.NewPrefix(55) // key for the counter for the incrementing id for UnbondingOperations UnbondingIndexKey = []byte{0x38} // prefix for an index for looking up unbonding operations by their IDs From 19fa78e155105385e25ebd3c14b7b893129591f9 Mon Sep 17 00:00:00 2001 From: atheesh Date: Tue, 8 Aug 2023 15:48:47 +0530 Subject: [PATCH 02/19] tests --- .../staking/keeper/grpc_query_test.go | 3 +- .../integration/staking/keeper/slash_test.go | 13 ++--- x/staking/keeper/delegation.go | 53 ++++++------------- x/staking/keeper/delegation_test.go | 19 +++---- x/staking/keeper/grpc_query.go | 2 +- 5 files changed, 35 insertions(+), 55 deletions(-) diff --git a/tests/integration/staking/keeper/grpc_query_test.go b/tests/integration/staking/keeper/grpc_query_test.go index c5500f232b98..87b89e792fe9 100644 --- a/tests/integration/staking/keeper/grpc_query_test.go +++ b/tests/integration/staking/keeper/grpc_query_test.go @@ -8,6 +8,7 @@ import ( cmtproto "github.com/cometbft/cometbft/proto/tendermint/types" "gotest.tools/v3/assert" + "cosmossdk.io/collections" "cosmossdk.io/math" simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims" @@ -814,7 +815,7 @@ func TestGRPCQueryRedelegations(t *testing.T) { assert.NilError(t, err) applyValidatorSetUpdates(t, ctx, f.stakingKeeper, -1) - redel, found := f.stakingKeeper.GetRedelegation(ctx, addrAcc1, val1.GetOperator(), val2.GetOperator()) + redel, found := f.stakingKeeper.Redelegations.Get(ctx, collections.Join3(addrAcc1, val1.GetOperator(), val2.GetOperator())) assert.Assert(t, found) var req *types.QueryRedelegationsRequest diff --git a/tests/integration/staking/keeper/slash_test.go b/tests/integration/staking/keeper/slash_test.go index 7595e7034e72..e4d28f0cec8d 100644 --- a/tests/integration/staking/keeper/slash_test.go +++ b/tests/integration/staking/keeper/slash_test.go @@ -8,6 +8,7 @@ import ( "github.com/stretchr/testify/require" "gotest.tools/v3/assert" + "cosmossdk.io/collections" "cosmossdk.io/math" "github.com/cosmos/cosmos-sdk/codec/address" @@ -156,7 +157,7 @@ func TestSlashRedelegation(t *testing.T) { slashAmount, err = f.stakingKeeper.SlashRedelegation(f.sdkCtx, validator, rd, 0, fraction) assert.NilError(t, err) assert.Assert(t, slashAmount.Equal(math.NewInt(5))) - rd, found = f.stakingKeeper.GetRedelegation(f.sdkCtx, addrDels[0], addrVals[0], addrVals[1]) + rd, found = f.stakingKeeper.Redelegations.Get(f.sdkCtx, collections.Join3(addrDels[0], addrVals[0], addrVals[1])) assert.Assert(t, found) assert.Assert(t, len(rd.Entries) == 1) @@ -431,7 +432,7 @@ func TestSlashWithRedelegation(t *testing.T) { oldBonded = f.bankKeeper.GetBalance(f.sdkCtx, bondedPool.GetAddress(), bondDenom).Amount // read updating redelegation - rd, found = f.stakingKeeper.GetRedelegation(f.sdkCtx, addrDels[0], addrVals[0], addrVals[1]) + rd, found = f.stakingKeeper.Redelegations.Get(f.sdkCtx, collections.Join3(addrDels[0], addrVals[0], addrVals[1])) assert.Assert(t, found) assert.Assert(t, len(rd.Entries) == 1) // read updated validator @@ -468,7 +469,7 @@ func TestSlashWithRedelegation(t *testing.T) { oldBonded = f.bankKeeper.GetBalance(f.sdkCtx, bondedPool.GetAddress(), bondDenom).Amount // read updating redelegation - rd, found = f.stakingKeeper.GetRedelegation(f.sdkCtx, addrDels[0], addrVals[0], addrVals[1]) + rd, found = f.stakingKeeper.Redelegations.Get(f.sdkCtx, collections.Join3(addrDels[0], addrVals[0], addrVals[1])) assert.Assert(t, found) assert.Assert(t, len(rd.Entries) == 1) // read updated validator @@ -499,7 +500,7 @@ func TestSlashWithRedelegation(t *testing.T) { oldBonded = f.bankKeeper.GetBalance(f.sdkCtx, bondedPool.GetAddress(), bondDenom).Amount // read updating redelegation - rd, found = f.stakingKeeper.GetRedelegation(f.sdkCtx, addrDels[0], addrVals[0], addrVals[1]) + rd, found = f.stakingKeeper.Redelegations.Get(f.sdkCtx, collections.Join3(addrDels[0], addrVals[0], addrVals[1])) assert.Assert(t, found) assert.Assert(t, len(rd.Entries) == 1) // apply TM updates @@ -529,7 +530,7 @@ func TestSlashWithRedelegation(t *testing.T) { assert.Assert(math.IntEq(t, oldNotBonded, notBondedPoolBalance)) // read updating redelegation - rd, found = f.stakingKeeper.GetRedelegation(f.sdkCtx, addrDels[0], addrVals[0], addrVals[1]) + rd, found = f.stakingKeeper.Redelegations.Get(f.sdkCtx, collections.Join3(addrDels[0], addrVals[0], addrVals[1])) assert.Assert(t, found) assert.Assert(t, len(rd.Entries) == 1) // read updated validator @@ -600,7 +601,7 @@ func TestSlashBoth(t *testing.T) { assert.Assert(math.IntEq(t, oldNotBonded.Sub(burnedNotBondedAmount), notBondedPoolBalance)) // read updating redelegation - rdA, found = f.stakingKeeper.GetRedelegation(f.sdkCtx, addrDels[0], addrVals[0], addrVals[1]) + rdA, found = f.stakingKeeper.Redelegations.Get(f.sdkCtx, collections.Join3(addrDels[0], addrVals[0], addrVals[1])) assert.Assert(t, found) assert.Assert(t, len(rdA.Entries) == 1) // read updated validator diff --git a/x/staking/keeper/delegation.go b/x/staking/keeper/delegation.go index 768cbd0f075d..d7626b625fea 100644 --- a/x/staking/keeper/delegation.go +++ b/x/staking/keeper/delegation.go @@ -568,23 +568,6 @@ func (k Keeper) GetRedelegations(ctx context.Context, delegator sdk.AccAddress, return redelegations[:i], nil // trim if the array length < maxRetrieve } -// GetRedelegation returns a redelegation. -func (k Keeper) GetRedelegation(ctx context.Context, delAddr sdk.AccAddress, valSrcAddr, valDstAddr sdk.ValAddress) (red types.Redelegation, err error) { - store := k.storeService.OpenKVStore(ctx) - key := types.GetREDKey(delAddr, valSrcAddr, valDstAddr) - - value, err := store.Get(key) - if err != nil { - return red, err - } - - if value == nil { - return red, types.ErrNoRedelegation - } - - return types.UnmarshalRED(k.cdc, value) -} - // GetRedelegationsFromSrcValidator returns all redelegations from a particular // validator. func (k Keeper) GetRedelegationsFromSrcValidator(ctx context.Context, valAddr sdk.ValAddress) (reds []types.Redelegation, err error) { @@ -626,9 +609,9 @@ func (k Keeper) HasReceivingRedelegation(ctx context.Context, delAddr sdk.AccAdd // HasMaxRedelegationEntries checks if the redelegation entries reached maximum limit. func (k Keeper) HasMaxRedelegationEntries(ctx context.Context, delegatorAddr sdk.AccAddress, validatorSrcAddr, validatorDstAddr sdk.ValAddress) (bool, error) { - red, err := k.GetRedelegation(ctx, delegatorAddr, validatorSrcAddr, validatorDstAddr) + red, err := k.Redelegations.Get(ctx, collections.Join3(delegatorAddr, validatorSrcAddr, validatorDstAddr)) if err != nil { - if err == types.ErrNoRedelegation { + if errors.Is(err, collections.ErrNotFound) { return false, nil } @@ -683,10 +666,10 @@ func (k Keeper) SetRedelegationEntry(ctx context.Context, return types.Redelegation{}, err } - red, err := k.GetRedelegation(ctx, delegatorAddr, validatorSrcAddr, validatorDstAddr) + red, err := k.Redelegations.Get(ctx, collections.Join3(delegatorAddr, validatorSrcAddr, validatorDstAddr)) if err == nil { red.AddEntry(creationHeight, minTime, balance, sharesDst, id) - } else if errors.Is(err, types.ErrNoRedelegation) { + } else if errors.Is(err, collections.ErrNotFound) { red = types.NewRedelegation(delegatorAddr, validatorSrcAddr, validatorDstAddr, creationHeight, minTime, balance, sharesDst, id, k.validatorAddressCodec, k.authKeeper.AddressCodec()) } else { @@ -712,23 +695,17 @@ func (k Keeper) SetRedelegationEntry(ctx context.Context, // IterateRedelegations iterates through all redelegations. func (k Keeper) IterateRedelegations(ctx context.Context, fn func(index int64, red types.Redelegation) (stop bool)) error { - store := k.storeService.OpenKVStore(ctx) - iterator, err := store.Iterator(types.RedelegationKey, storetypes.PrefixEndBytes(types.RedelegationKey)) - if err != nil { - return err - } - defer iterator.Close() + var i int64 + k.Redelegations.Walk(ctx, nil, + func(key collections.Triple[sdk.AccAddress, sdk.ValAddress, sdk.ValAddress], red types.Redelegation) (bool, error) { + if stop := fn(i, red); stop { + return true, nil + } + i++ - for i := int64(0); iterator.Valid(); iterator.Next() { - red, err := types.UnmarshalRED(k.cdc, iterator.Value()) - if err != nil { - return err - } - if stop := fn(i, red); stop { - break - } - i++ - } + return false, nil + }, + ) return nil } @@ -1292,7 +1269,7 @@ func (k Keeper) BeginRedelegation( func (k Keeper) CompleteRedelegation( ctx context.Context, delAddr sdk.AccAddress, valSrcAddr, valDstAddr sdk.ValAddress, ) (sdk.Coins, error) { - red, err := k.GetRedelegation(ctx, delAddr, valSrcAddr, valDstAddr) + red, err := k.Redelegations.Get(ctx, collections.Join3(delAddr, valSrcAddr, valDstAddr)) if err != nil { return nil, err } diff --git a/x/staking/keeper/delegation_test.go b/x/staking/keeper/delegation_test.go index 26fe6fbebb6b..589a1b86fdce 100644 --- a/x/staking/keeper/delegation_test.go +++ b/x/staking/keeper/delegation_test.go @@ -5,6 +5,7 @@ import ( "github.com/golang/mock/gomock" + "cosmossdk.io/collections" "cosmossdk.io/math" "github.com/cosmos/cosmos-sdk/codec/address" @@ -681,7 +682,7 @@ func (s *KeeperTestSuite) TestGetRedelegationsFromSrcValidator() { // set and retrieve a record err := keeper.SetRedelegation(ctx, rd) require.NoError(err) - resBond, err := keeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1]) + resBond, err := keeper.Redelegations.Get(ctx, collections.Join3(addrDels[0], addrVals[0], addrVals[1])) require.NoError(err) // get the redelegations one time @@ -716,7 +717,7 @@ func (s *KeeperTestSuite) TestRedelegation() { // set and retrieve a record err = keeper.SetRedelegation(ctx, rd) require.NoError(err) - resRed, err := keeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1]) + resRed, err := keeper.Redelegations.Get(ctx, collections.Join3(addrDels[0], addrVals[0], addrVals[1])) require.NoError(err) redelegations, err := keeper.GetRedelegationsFromSrcValidator(ctx, addrVals[0]) @@ -734,7 +735,7 @@ func (s *KeeperTestSuite) TestRedelegation() { require.Equal(1, len(redelegations)) require.Equal(redelegations[0], resRed) - // check if has the redelegation + // check if it has the redelegation has, err = keeper.HasReceivingRedelegation(ctx, addrDels[0], addrVals[1]) require.NoError(err) require.True(has) @@ -744,7 +745,7 @@ func (s *KeeperTestSuite) TestRedelegation() { err = keeper.SetRedelegation(ctx, rd) require.NoError(err) - resRed, err = keeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1]) + resRed, err = keeper.Redelegations.Get(ctx, collections.Join3(addrDels[0], addrVals[0], addrVals[1])) require.NoError(err) require.Equal(rd, resRed) @@ -761,8 +762,8 @@ func (s *KeeperTestSuite) TestRedelegation() { // delete a record err = keeper.RemoveRedelegation(ctx, rd) require.NoError(err) - _, err = keeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1]) - require.ErrorIs(err, stakingtypes.ErrNoRedelegation) + _, err = keeper.Redelegations.Get(ctx, collections.Join3(addrDels[0], addrVals[0], addrVals[1])) + require.ErrorIs(err, collections.ErrNotFound) redelegations, err = keeper.GetRedelegations(ctx, addrDels[0], 5) require.NoError(err) @@ -975,7 +976,7 @@ func (s *KeeperTestSuite) TestRedelegateFromUnbondingValidator() { require.NoError(err) // retrieve the unbonding delegation - ubd, err := keeper.GetRedelegation(ctx, addrDels[1], addrVals[0], addrVals[1]) + ubd, err := keeper.Redelegations.Get(ctx, collections.Join3(addrDels[1], addrVals[0], addrVals[1])) require.NoError(err) require.Len(ubd.Entries, 1) require.Equal(blockHeight, ubd.Entries[0].CreationHeight) @@ -1049,8 +1050,8 @@ func (s *KeeperTestSuite) TestRedelegateFromUnbondedValidator() { require.NoError(err) // no red should have been found - red, err := keeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1]) - require.ErrorIs(err, stakingtypes.ErrNoRedelegation, "%v", red) + red, err := keeper.Redelegations.Get(ctx, collections.Join3(addrDels[0], addrVals[0], addrVals[1])) + require.ErrorIs(err, collections.ErrNotFound, "%v", red) } func (s *KeeperTestSuite) TestUnbondingDelegationAddEntry() { diff --git a/x/staking/keeper/grpc_query.go b/x/staking/keeper/grpc_query.go index 39f628dee83a..c55dc9439de4 100644 --- a/x/staking/keeper/grpc_query.go +++ b/x/staking/keeper/grpc_query.go @@ -517,7 +517,7 @@ func queryRedelegation(ctx context.Context, k Querier, req *types.QueryRedelegat return nil, err } - redel, err := k.GetRedelegation(ctx, delAddr, srcValAddr, dstValAddr) + redel, err := k.Keeper.Redelegations.Get(ctx, collections.Join3(sdk.AccAddress(delAddr), sdk.ValAddress(srcValAddr), sdk.ValAddress(dstValAddr))) if err != nil { return nil, status.Errorf( codes.NotFound, From 1e6c102ede0725a0f9a0438b5bb2ee7f736b4d29 Mon Sep 17 00:00:00 2001 From: atheesh Date: Tue, 8 Aug 2023 18:59:11 +0530 Subject: [PATCH 03/19] all redelegations --- x/staking/keeper/delegation.go | 40 ++++++++++------------------ x/staking/keeper/grpc_query.go | 30 +++++++++++++-------- x/staking/keeper/query_utils.go | 47 +++++++++++++-------------------- 3 files changed, 51 insertions(+), 66 deletions(-) diff --git a/x/staking/keeper/delegation.go b/x/staking/keeper/delegation.go index d7626b625fea..73abe045d253 100644 --- a/x/staking/keeper/delegation.go +++ b/x/staking/keeper/delegation.go @@ -341,22 +341,15 @@ func (k Keeper) IterateDelegatorDelegations(ctx context.Context, delegator sdk.A // IterateDelegatorRedelegations iterates through one delegator's redelegations. func (k Keeper) IterateDelegatorRedelegations(ctx context.Context, delegator sdk.AccAddress, cb func(red types.Redelegation) (stop bool)) error { - store := k.storeService.OpenKVStore(ctx) - delegatorPrefixKey := types.GetREDsKey(delegator) - iterator, err := store.Iterator(delegatorPrefixKey, storetypes.PrefixEndBytes(delegatorPrefixKey)) - if err != nil { - return err - } - - for ; iterator.Valid(); iterator.Next() { - red, err := types.UnmarshalRED(k.cdc, iterator.Value()) - if err != nil { - return err - } + rng := collections.NewPrefixedTripleRange[sdk.AccAddress, sdk.ValAddress, sdk.ValAddress](delegator) + k.Redelegations.Walk(ctx, rng, func(key collections.Triple[sdk.AccAddress, sdk.ValAddress, sdk.ValAddress], red types.Redelegation) (stop bool, err error) { if cb(red) { - break + return true, nil } - } + + return false, nil + }) + return nil } @@ -548,22 +541,17 @@ func (k Keeper) DequeueAllMatureUBDQueue(ctx context.Context, currTime time.Time func (k Keeper) GetRedelegations(ctx context.Context, delegator sdk.AccAddress, maxRetrieve uint16) (redelegations []types.Redelegation, err error) { redelegations = make([]types.Redelegation, maxRetrieve) - store := k.storeService.OpenKVStore(ctx) - delegatorPrefixKey := types.GetREDsKey(delegator) - iterator, err := store.Iterator(delegatorPrefixKey, storetypes.PrefixEndBytes(delegatorPrefixKey)) - if err != nil { - return nil, err - } - i := 0 - for ; iterator.Valid() && i < int(maxRetrieve); iterator.Next() { - redelegation, err := types.UnmarshalRED(k.cdc, iterator.Value()) - if err != nil { - return nil, err + rng := collections.NewPrefixedTripleRange[sdk.AccAddress, sdk.ValAddress, sdk.ValAddress](delegator) + k.Redelegations.Walk(ctx, rng, func(key collections.Triple[sdk.AccAddress, sdk.ValAddress, sdk.ValAddress], redelegation types.Redelegation) (stop bool, err error) { + if i >= int(maxRetrieve) { + return true, nil } + redelegations[i] = redelegation i++ - } + return false, nil + }) return redelegations[:i], nil // trim if the array length < maxRetrieve } diff --git a/x/staking/keeper/grpc_query.go b/x/staking/keeper/grpc_query.go index c55dc9439de4..66360315e784 100644 --- a/x/staking/keeper/grpc_query.go +++ b/x/staking/keeper/grpc_query.go @@ -418,7 +418,7 @@ func (k Querier) Redelegations(ctx context.Context, req *types.QueryRedelegation case req.DelegatorAddr == "" && req.SrcValidatorAddr != "" && req.DstValidatorAddr == "": redels, pageRes, err = queryRedelegationsFromSrcValidator(store, k, req) default: - redels, pageRes, err = queryAllRedelegations(store, k, req) + redels, pageRes, err = queryAllRedelegations(ctx, store, k, req) } if err != nil { return nil, status.Error(codes.Internal, err.Error()) @@ -551,21 +551,29 @@ func queryRedelegationsFromSrcValidator(store storetypes.KVStore, k Querier, req return redels, res, err } -func queryAllRedelegations(store storetypes.KVStore, k Querier, req *types.QueryRedelegationsRequest) (redels types.Redelegations, res *query.PageResponse, err error) { +func queryAllRedelegations(ctx context.Context, store storetypes.KVStore, k Querier, req *types.QueryRedelegationsRequest) (redels types.Redelegations, res *query.PageResponse, err error) { delAddr, err := k.authKeeper.AddressCodec().StringToBytes(req.DelegatorAddr) if err != nil { return nil, nil, err } - redStore := prefix.NewStore(store, types.GetREDsKey(delAddr)) - res, err = query.Paginate(redStore, req.Pagination, func(key, value []byte) error { - redelegation, err := types.UnmarshalRED(k.cdc, value) - if err != nil { - return err - } - redels = append(redels, redelegation) - return nil - }) + // redStore := prefix.NewStore(store, types.GetREDsKey(delAddr)) + + redels, res, err = query.CollectionPaginate(ctx, k.Keeper.Redelegations, req.Pagination, func(_ collections.Triple[sdk.AccAddress, sdk.ValAddress, sdk.ValAddress], red types.Redelegation) (types.Redelegation, error) { + return red, nil + }, query.WithCollectionPaginationTriplePrefix[sdk.AccAddress, sdk.ValAddress, sdk.ValAddress](delAddr)) + if err != nil { + return nil, nil, err + } + + // res, err = query.Paginate(redStore, req.Pagination, func(key, value []byte) error { + // redelegation, err := types.UnmarshalRED(k.cdc, value) + // if err != nil { + // return err + // } + // redels = append(redels, redelegation) + // return nil + // }) return redels, res, err } diff --git a/x/staking/keeper/query_utils.go b/x/staking/keeper/query_utils.go index 6bb16da3fcd0..9c071be598a8 100644 --- a/x/staking/keeper/query_utils.go +++ b/x/staking/keeper/query_utils.go @@ -3,6 +3,7 @@ package keeper import ( "context" + "cosmossdk.io/collections" storetypes "cosmossdk.io/store/types" sdk "github.com/cosmos/cosmos-sdk/types" @@ -115,40 +116,28 @@ func (k Keeper) GetAllUnbondingDelegations(ctx context.Context, delegator sdk.Ac func (k Keeper) GetAllRedelegations( ctx context.Context, delegator sdk.AccAddress, srcValAddress, dstValAddress sdk.ValAddress, ) ([]types.Redelegation, error) { - store := k.storeService.OpenKVStore(ctx) - delegatorPrefixKey := types.GetREDsKey(delegator) - - iterator, err := store.Iterator(delegatorPrefixKey, storetypes.PrefixEndBytes(delegatorPrefixKey)) // smallest to largest - if err != nil { - return nil, err - } - defer iterator.Close() srcValFilter := !(srcValAddress.Empty()) dstValFilter := !(dstValAddress.Empty()) redelegations := []types.Redelegation{} - - for ; iterator.Valid(); iterator.Next() { - redelegation := types.MustUnmarshalRED(k.cdc, iterator.Value()) - valSrcAddr, err := k.validatorAddressCodec.StringToBytes(redelegation.ValidatorSrcAddress) - if err != nil { - return nil, err - } - valDstAddr, err := k.validatorAddressCodec.StringToBytes(redelegation.ValidatorDstAddress) - if err != nil { - return nil, err - } - if srcValFilter && !(srcValAddress.Equals(sdk.ValAddress(valSrcAddr))) { - continue - } - - if dstValFilter && !(dstValAddress.Equals(sdk.ValAddress(valDstAddr))) { - continue - } - - redelegations = append(redelegations, redelegation) - } + rng := collections.NewPrefixedTripleRange[sdk.AccAddress, sdk.ValAddress, sdk.ValAddress](delegator) + k.Redelegations.Walk(ctx, rng, + func(key collections.Triple[sdk.AccAddress, sdk.ValAddress, sdk.ValAddress], redelegation types.Redelegation) (stop bool, err error) { + valSrcAddr, valDstAddr := key.K2(), key.K3() + + if srcValFilter && !(srcValAddress.Equals(sdk.ValAddress(valSrcAddr))) { + return false, nil + } + + if dstValFilter && !(dstValAddress.Equals(sdk.ValAddress(valDstAddr))) { + return false, nil + } + + redelegations = append(redelegations, redelegation) + return false, nil + }, + ) return redelegations, nil } From ef4875920bc669c91843d9a02e6e9eee8adb2768 Mon Sep 17 00:00:00 2001 From: atheesh Date: Wed, 9 Aug 2023 11:48:16 +0530 Subject: [PATCH 04/19] fix tests --- x/staking/keeper/delegation.go | 9 ++++++--- x/staking/migrations/v2/keys.go | 22 ++++++++++++++++++++++ x/staking/migrations/v2/store_test.go | 2 +- x/staking/simulation/decoder_test.go | 3 --- 4 files changed, 29 insertions(+), 7 deletions(-) diff --git a/x/staking/keeper/delegation.go b/x/staking/keeper/delegation.go index 73abe045d253..b9c894a5f345 100644 --- a/x/staking/keeper/delegation.go +++ b/x/staking/keeper/delegation.go @@ -684,7 +684,7 @@ func (k Keeper) SetRedelegationEntry(ctx context.Context, // IterateRedelegations iterates through all redelegations. func (k Keeper) IterateRedelegations(ctx context.Context, fn func(index int64, red types.Redelegation) (stop bool)) error { var i int64 - k.Redelegations.Walk(ctx, nil, + err := k.Redelegations.Walk(ctx, nil, func(key collections.Triple[sdk.AccAddress, sdk.ValAddress, sdk.ValAddress], red types.Redelegation) (bool, error) { if stop := fn(i, red); stop { return true, nil @@ -694,6 +694,9 @@ func (k Keeper) IterateRedelegations(ctx context.Context, fn func(index int64, r return false, nil }, ) + if err != nil { + return err + } return nil } @@ -714,8 +717,8 @@ func (k Keeper) RemoveRedelegation(ctx context.Context, red types.Redelegation) if err != nil { return err } - redKey := types.GetREDKey(delegatorAddress, valSrcAddr, valDestAddr) - if err = store.Delete(redKey); err != nil { + + if err = k.Redelegations.Remove(ctx, collections.Join3(sdk.AccAddress(delegatorAddress), sdk.ValAddress(valSrcAddr), sdk.ValAddress(valDestAddr))); err != nil { return err } diff --git a/x/staking/migrations/v2/keys.go b/x/staking/migrations/v2/keys.go index b115ed5492fd..81ebadd2f7f2 100644 --- a/x/staking/migrations/v2/keys.go +++ b/x/staking/migrations/v2/keys.go @@ -14,6 +14,7 @@ const ( var ( ValidatorsByConsAddrKey = []byte{0x22} // prefix for validators by consensus address + RedelegationKey = []byte{0x34} // key for a redelegation HistoricalInfoKey = []byte{0x50} // prefix for the historical info ) @@ -27,3 +28,24 @@ func GetHistoricalInfoKey(height int64) []byte { func GetValidatorByConsAddrKey(addr sdk.ConsAddress) []byte { return append(ValidatorsByConsAddrKey, address.MustLengthPrefix(addr)...) } + +// 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 { + // key is of the form GetREDsKey || valSrcAddrLen (1 byte) || valSrcAddr || valDstAddrLen (1 byte) || valDstAddr + key := make([]byte, 1+3+len(delAddr)+len(valSrcAddr)+len(valDstAddr)) + + copy(key[0:2+len(delAddr)], GetREDsKey(delAddr.Bytes())) + key[2+len(delAddr)] = byte(len(valSrcAddr)) + copy(key[3+len(delAddr):3+len(delAddr)+len(valSrcAddr)], valSrcAddr.Bytes()) + key[3+len(delAddr)+len(valSrcAddr)] = byte(len(valDstAddr)) + copy(key[4+len(delAddr)+len(valSrcAddr):], valDstAddr.Bytes()) + + return key +} + +// GetREDsKey returns a key prefix for indexing a redelegation from a delegator +// address. +func GetREDsKey(delAddr sdk.AccAddress) []byte { + return append(RedelegationKey, address.MustLengthPrefix(delAddr)...) +} diff --git a/x/staking/migrations/v2/store_test.go b/x/staking/migrations/v2/store_test.go index da808b2a3aa8..3e4b82b7206c 100644 --- a/x/staking/migrations/v2/store_test.go +++ b/x/staking/migrations/v2/store_test.go @@ -84,7 +84,7 @@ func TestStoreMigration(t *testing.T) { { "RedelegationKey", v1.GetREDKey(addr4, valAddr1, valAddr2), - types.GetREDKey(addr4, valAddr1, valAddr2), + v2.GetREDKey(addr4, valAddr1, valAddr2), }, { "RedelegationByValSrcIndexKey", diff --git a/x/staking/simulation/decoder_test.go b/x/staking/simulation/decoder_test.go index 0179794929b1..8ba0f212f9b6 100644 --- a/x/staking/simulation/decoder_test.go +++ b/x/staking/simulation/decoder_test.go @@ -33,7 +33,6 @@ func TestDecodeStore(t *testing.T) { require.NoError(t, err) del := types.NewDelegation(delAddr1.String(), valAddr1.String(), math.LegacyOneDec()) ubd := types.NewUnbondingDelegation(delAddr1, valAddr1, 15, bondTime, math.OneInt(), 1, address.NewBech32Codec("cosmosvaloper"), address.NewBech32Codec("cosmos")) - red := types.NewRedelegation(delAddr1, valAddr1, valAddr1, 12, bondTime, math.OneInt(), math.LegacyOneDec(), 0, address.NewBech32Codec("cosmosvaloper"), address.NewBech32Codec("cosmos")) oneIntBz, err := math.OneInt().Marshal() require.NoError(t, err) @@ -44,7 +43,6 @@ func TestDecodeStore(t *testing.T) { {Key: types.LastValidatorPowerKey, Value: valAddr1.Bytes()}, {Key: types.GetDelegationKey(delAddr1, valAddr1), Value: cdc.MustMarshal(&del)}, {Key: types.GetUBDKey(delAddr1, valAddr1), Value: cdc.MustMarshal(&ubd)}, - {Key: types.GetREDKey(delAddr1, valAddr1, valAddr1), Value: cdc.MustMarshal(&red)}, {Key: []byte{0x99}, Value: []byte{0x99}}, }, } @@ -58,7 +56,6 @@ func TestDecodeStore(t *testing.T) { {"LastValidatorPower/ValidatorsByConsAddr/ValidatorsByPowerIndex", fmt.Sprintf("%v\n%v", valAddr1, valAddr1)}, {"Delegation", fmt.Sprintf("%v\n%v", del, del)}, {"UnbondingDelegation", fmt.Sprintf("%v\n%v", ubd, ubd)}, - {"Redelegation", fmt.Sprintf("%v\n%v", red, red)}, {"other", ""}, } for i, tt := range tests { From dcbba95962f935a62231009861125655f48c277a Mon Sep 17 00:00:00 2001 From: atheesh Date: Wed, 9 Aug 2023 11:49:22 +0530 Subject: [PATCH 05/19] conflicts --- x/staking/keeper/keeper.go | 1 - 1 file changed, 1 deletion(-) diff --git a/x/staking/keeper/keeper.go b/x/staking/keeper/keeper.go index d8488abdc422..6cb6ac1e3be3 100644 --- a/x/staking/keeper/keeper.go +++ b/x/staking/keeper/keeper.go @@ -110,7 +110,6 @@ func NewKeeper( ), codec.CollValue[types.Redelegation](cdc), ), - UnbondingType: collections.NewMap(sb, types.UnbondingTypeKey, "unbonding_type", collections.Uint64Key, collections.Uint64Value), UnbondingIndex: collections.NewMap(sb, types.UnbondingIndexKey, "unbonding_index", collections.Uint64Key, collections.BytesValue), } From b85387af0ce78f7ab16a5b2693a6bd83deb3046b Mon Sep 17 00:00:00 2001 From: atheesh Date: Wed, 9 Aug 2023 12:38:19 +0530 Subject: [PATCH 06/19] redelegations by src validator --- x/staking/keeper/delegation.go | 4 ++-- x/staking/keeper/keeper.go | 11 +++++++++++ x/staking/types/keys.go | 2 +- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/x/staking/keeper/delegation.go b/x/staking/keeper/delegation.go index b9c894a5f345..648a26018f36 100644 --- a/x/staking/keeper/delegation.go +++ b/x/staking/keeper/delegation.go @@ -634,7 +634,7 @@ func (k Keeper) SetRedelegation(ctx context.Context, red types.Redelegation) err return err } - if err = store.Set(types.GetREDByValSrcIndexKey(delegatorAddress, valSrcAddr, valDestAddr), []byte{}); err != nil { + if err = k.RedelegationsByValSrc.Set(ctx, collections.Join3(sdk.ValAddress(valSrcAddr), sdk.AccAddress(delegatorAddress), sdk.ValAddress(valDestAddr)), []byte{}); err != nil { return err } @@ -722,7 +722,7 @@ func (k Keeper) RemoveRedelegation(ctx context.Context, red types.Redelegation) return err } - if err = store.Delete(types.GetREDByValSrcIndexKey(delegatorAddress, valSrcAddr, valDestAddr)); err != nil { + if err = k.RedelegationsByValSrc.Remove(ctx, collections.Join3(sdk.ValAddress(valSrcAddr), sdk.AccAddress(delegatorAddress), sdk.ValAddress(valDestAddr))); err != nil { return err } diff --git a/x/staking/keeper/keeper.go b/x/staking/keeper/keeper.go index 6cb6ac1e3be3..7b80a8cccf92 100644 --- a/x/staking/keeper/keeper.go +++ b/x/staking/keeper/keeper.go @@ -43,6 +43,7 @@ type Keeper struct { UnbondingType collections.Map[uint64, uint64] Redelegations collections.Map[collections.Triple[sdk.AccAddress, sdk.ValAddress, sdk.ValAddress], types.Redelegation] UnbondingIndex collections.Map[uint64, []byte] + RedelegationsByValSrc collections.Map[collections.Triple[sdk.ValAddress, sdk.AccAddress, sdk.ValAddress], []byte] } // NewKeeper creates a new staking Keeper instance @@ -111,6 +112,16 @@ func NewKeeper( codec.CollValue[types.Redelegation](cdc), ), UnbondingIndex: collections.NewMap(sb, types.UnbondingIndexKey, "unbonding_index", collections.Uint64Key, collections.BytesValue), + RedelegationsByValSrc: collections.NewMap( + sb, types.RedelegationByValSrcIndexKey, + "redelegations_by_val_src", + collections.TripleKeyCodec( + sdk.LengthPrefixedAddressKey(sdk.ValAddressKey), // nolint: staticcheck // sdk.LengthPrefixedAddressKey is needed to retain state compatibility + sdk.LengthPrefixedAddressKey(sdk.AccAddressKey), // nolint: staticcheck // sdk.LengthPrefixedAddressKey is needed to retain state compatibility + sdk.LengthPrefixedAddressKey(sdk.ValAddressKey), // nolint: staticcheck // sdk.LengthPrefixedAddressKey is needed to retain state compatibility + ), + collections.BytesValue, + ), } schema, err := sb.Build() diff --git a/x/staking/types/keys.go b/x/staking/types/keys.go index 11638c94100c..1240efaf9283 100644 --- a/x/staking/types/keys.go +++ b/x/staking/types/keys.go @@ -42,7 +42,7 @@ var ( UnbondingDelegationKey = []byte{0x32} // key for an unbonding-delegation UnbondingDelegationByValIndexKey = []byte{0x33} // prefix for each key for an unbonding-delegation, by validator operator RedelegationKey = collections.NewPrefix(52) // key for a redelegation - RedelegationByValSrcIndexKey = []byte{0x35} // prefix for each key for an redelegation, by source validator operator + RedelegationByValSrcIndexKey = collections.NewPrefix(53) // prefix for each key for an redelegation, by source validator operator RedelegationByValDstIndexKey = []byte{0x36} // prefix for each key for an redelegation, by destination validator operator UnbondingIDKey = collections.NewPrefix(55) // key for the counter for the incrementing id for UnbondingOperations From cd46d89b1831547e2d6e5c5497819d332607c321 Mon Sep 17 00:00:00 2001 From: atheesh Date: Wed, 9 Aug 2023 12:44:07 +0530 Subject: [PATCH 07/19] fix tests --- 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 b9c894a5f345..9f38c07a435a 100644 --- a/x/staking/keeper/delegation.go +++ b/x/staking/keeper/delegation.go @@ -694,7 +694,7 @@ func (k Keeper) IterateRedelegations(ctx context.Context, fn func(index int64, r return false, nil }, ) - if err != nil { + if err != nil && !errors.Is(err, collections.ErrInvalidIterator) { return err } From eb0ac8d51f3d6f8c920a48e8adc917eb22c2200d Mon Sep 17 00:00:00 2001 From: atheesh Date: Wed, 9 Aug 2023 14:36:50 +0530 Subject: [PATCH 08/19] handle errors --- x/staking/keeper/delegation.go | 11 +++++++++-- x/staking/keeper/query_utils.go | 5 ++++- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/x/staking/keeper/delegation.go b/x/staking/keeper/delegation.go index 5874eea5249f..d36f4172f298 100644 --- a/x/staking/keeper/delegation.go +++ b/x/staking/keeper/delegation.go @@ -294,13 +294,16 @@ func (k Keeper) IterateDelegatorDelegations(ctx context.Context, delegator sdk.A // IterateDelegatorRedelegations iterates through one delegator's redelegations. func (k Keeper) IterateDelegatorRedelegations(ctx context.Context, delegator sdk.AccAddress, cb func(red types.Redelegation) (stop bool)) error { rng := collections.NewPrefixedTripleRange[sdk.AccAddress, sdk.ValAddress, sdk.ValAddress](delegator) - k.Redelegations.Walk(ctx, rng, func(key collections.Triple[sdk.AccAddress, sdk.ValAddress, sdk.ValAddress], red types.Redelegation) (stop bool, err error) { + err := k.Redelegations.Walk(ctx, rng, func(key collections.Triple[sdk.AccAddress, sdk.ValAddress, sdk.ValAddress], red types.Redelegation) (stop bool, err error) { if cb(red) { return true, nil } return false, nil }) + if err != nil { + return err + } return nil } @@ -495,7 +498,7 @@ func (k Keeper) GetRedelegations(ctx context.Context, delegator sdk.AccAddress, i := 0 rng := collections.NewPrefixedTripleRange[sdk.AccAddress, sdk.ValAddress, sdk.ValAddress](delegator) - k.Redelegations.Walk(ctx, rng, func(key collections.Triple[sdk.AccAddress, sdk.ValAddress, sdk.ValAddress], redelegation types.Redelegation) (stop bool, err error) { + err = k.Redelegations.Walk(ctx, rng, func(key collections.Triple[sdk.AccAddress, sdk.ValAddress, sdk.ValAddress], redelegation types.Redelegation) (stop bool, err error) { if i >= int(maxRetrieve) { return true, nil } @@ -505,6 +508,10 @@ func (k Keeper) GetRedelegations(ctx context.Context, delegator sdk.AccAddress, return false, nil }) + if err != nil { + return nil, err + } + return redelegations[:i], nil // trim if the array length < maxRetrieve } diff --git a/x/staking/keeper/query_utils.go b/x/staking/keeper/query_utils.go index e8fbbb50227b..5a23f8350d4c 100644 --- a/x/staking/keeper/query_utils.go +++ b/x/staking/keeper/query_utils.go @@ -116,7 +116,7 @@ func (k Keeper) GetAllRedelegations( redelegations := []types.Redelegation{} rng := collections.NewPrefixedTripleRange[sdk.AccAddress, sdk.ValAddress, sdk.ValAddress](delegator) - k.Redelegations.Walk(ctx, rng, + err := k.Redelegations.Walk(ctx, rng, func(key collections.Triple[sdk.AccAddress, sdk.ValAddress, sdk.ValAddress], redelegation types.Redelegation) (stop bool, err error) { valSrcAddr, valDstAddr := key.K2(), key.K3() @@ -132,6 +132,9 @@ func (k Keeper) GetAllRedelegations( return false, nil }, ) + if err != nil { + return nil, err + } return redelegations, nil } From e64d6026c152011027f06e249d277fc4651b5a7d Mon Sep 17 00:00:00 2001 From: atheesh Date: Wed, 9 Aug 2023 16:03:55 +0530 Subject: [PATCH 09/19] src redelegations --- x/staking/keeper/delegation.go | 25 ++++++-------- x/staking/keeper/grpc_query.go | 33 +++++-------------- x/staking/migrations/v2/keys.go | 32 +++++++++++++++--- x/staking/migrations/v2/store_test.go | 2 +- x/staking/types/keys.go | 47 --------------------------- x/staking/types/keys_test.go | 27 --------------- 6 files changed, 47 insertions(+), 119 deletions(-) diff --git a/x/staking/keeper/delegation.go b/x/staking/keeper/delegation.go index 14cf8443aa99..59b983de2ab0 100644 --- a/x/staking/keeper/delegation.go +++ b/x/staking/keeper/delegation.go @@ -518,25 +518,20 @@ func (k Keeper) GetRedelegations(ctx context.Context, delegator sdk.AccAddress, // GetRedelegationsFromSrcValidator returns all redelegations from a particular // validator. func (k Keeper) GetRedelegationsFromSrcValidator(ctx context.Context, valAddr sdk.ValAddress) (reds []types.Redelegation, err error) { - store := k.storeService.OpenKVStore(ctx) - prefix := types.GetREDsFromValSrcIndexKey(valAddr) - iterator, err := store.Iterator(prefix, storetypes.PrefixEndBytes(prefix)) - if err != nil { - return nil, err - } - defer iterator.Close() + rng := collections.NewPrefixedTripleRange[sdk.ValAddress, sdk.AccAddress, sdk.ValAddress](valAddr) + err = k.RedelegationsByValSrc.Walk(ctx, rng, func(key collections.Triple[sdk.ValAddress, sdk.AccAddress, sdk.ValAddress], value []byte) (stop bool, err error) { + valSrcAddr, delAddr, valDstAddr := key.K1(), key.K2(), key.K3() - for ; iterator.Valid(); iterator.Next() { - key := types.GetREDKeyFromValSrcIndexKey(iterator.Key()) - value, err := store.Get(key) - if err != nil { - return nil, err - } - red, err := types.UnmarshalRED(k.cdc, value) + red, err := k.Redelegations.Get(ctx, collections.Join3(delAddr, valSrcAddr, valDstAddr)) if err != nil { - return nil, err + return true, err } reds = append(reds, red) + + return false, nil + }) + if err != nil { + return nil, err } return reds, nil diff --git a/x/staking/keeper/grpc_query.go b/x/staking/keeper/grpc_query.go index 81571b2d9ae0..457f0b57a257 100644 --- a/x/staking/keeper/grpc_query.go +++ b/x/staking/keeper/grpc_query.go @@ -410,7 +410,7 @@ func (k Querier) Redelegations(ctx context.Context, req *types.QueryRedelegation case req.DelegatorAddr != "" && req.SrcValidatorAddr != "" && req.DstValidatorAddr != "": redels, err = queryRedelegation(ctx, k, req) case req.DelegatorAddr == "" && req.SrcValidatorAddr != "" && req.DstValidatorAddr == "": - redels, pageRes, err = queryRedelegationsFromSrcValidator(store, k, req) + redels, pageRes, err = queryRedelegationsFromSrcValidator(ctx, store, k, req) default: redels, pageRes, err = queryAllRedelegations(ctx, store, k, req) } @@ -517,26 +517,20 @@ func queryRedelegation(ctx context.Context, k Querier, req *types.QueryRedelegat return redels, nil } -func queryRedelegationsFromSrcValidator(store storetypes.KVStore, k Querier, req *types.QueryRedelegationsRequest) (redels types.Redelegations, res *query.PageResponse, err error) { +func queryRedelegationsFromSrcValidator(ctx context.Context, store storetypes.KVStore, k Querier, req *types.QueryRedelegationsRequest) (types.Redelegations, *query.PageResponse, error) { valAddr, err := k.validatorAddressCodec.StringToBytes(req.SrcValidatorAddr) if err != nil { return nil, nil, err } - srcValPrefix := types.GetREDsFromValSrcIndexKey(valAddr) - redStore := prefix.NewStore(store, srcValPrefix) - res, err = query.Paginate(redStore, req.Pagination, func(key, value []byte) error { - storeKey := types.GetREDKeyFromValSrcIndexKey(append(srcValPrefix, key...)) - storeValue := store.Get(storeKey) - red, err := types.UnmarshalRED(k.cdc, storeValue) + return query.CollectionPaginate(ctx, k.RedelegationsByValSrc, req.Pagination, func(key collections.Triple[sdk.ValAddress, sdk.AccAddress, sdk.ValAddress], val []byte) (types.Redelegation, error) { + valSrcAddr, delAddr, valDstAddr := key.K1(), key.K2(), key.K3() + red, err := k.Keeper.Redelegations.Get(ctx, collections.Join3(delAddr, valSrcAddr, valDstAddr)) if err != nil { - return err + return types.Redelegation{}, err } - redels = append(redels, red) - return nil - }) - - return redels, res, err + return red, nil + }, query.WithCollectionPaginationTriplePrefix[sdk.ValAddress, sdk.AccAddress, sdk.ValAddress](valAddr)) } func queryAllRedelegations(ctx context.Context, store storetypes.KVStore, k Querier, req *types.QueryRedelegationsRequest) (redels types.Redelegations, res *query.PageResponse, err error) { @@ -545,8 +539,6 @@ func queryAllRedelegations(ctx context.Context, store storetypes.KVStore, k Quer return nil, nil, err } - // redStore := prefix.NewStore(store, types.GetREDsKey(delAddr)) - redels, res, err = query.CollectionPaginate(ctx, k.Keeper.Redelegations, req.Pagination, func(_ collections.Triple[sdk.AccAddress, sdk.ValAddress, sdk.ValAddress], red types.Redelegation) (types.Redelegation, error) { return red, nil }, query.WithCollectionPaginationTriplePrefix[sdk.AccAddress, sdk.ValAddress, sdk.ValAddress](delAddr)) @@ -554,15 +546,6 @@ func queryAllRedelegations(ctx context.Context, store storetypes.KVStore, k Quer return nil, nil, err } - // res, err = query.Paginate(redStore, req.Pagination, func(key, value []byte) error { - // redelegation, err := types.UnmarshalRED(k.cdc, value) - // if err != nil { - // return err - // } - // redels = append(redels, redelegation) - // return nil - // }) - return redels, res, err } diff --git a/x/staking/migrations/v2/keys.go b/x/staking/migrations/v2/keys.go index bc2d6d923c39..b3da66ccb547 100644 --- a/x/staking/migrations/v2/keys.go +++ b/x/staking/migrations/v2/keys.go @@ -13,10 +13,11 @@ const ( ) var ( - ValidatorsByConsAddrKey = []byte{0x22} // prefix for validators by consensus address - RedelegationKey = []byte{0x34} // key for a redelegation - DelegationKey = []byte{0x31} // prefix for the delegation - HistoricalInfoKey = []byte{0x50} // prefix for the historical info + ValidatorsByConsAddrKey = []byte{0x22} // prefix for validators by consensus address + DelegationKey = []byte{0x31} // prefix for the delegation + RedelegationKey = []byte{0x34} // key for a redelegation + RedelegationByValSrcIndexKey = []byte{0x35} // prefix for each key for an redelegation, by source validator operator + HistoricalInfoKey = []byte{0x50} // prefix for the historical info ) // GetHistoricalInfoKey returns a key prefix for indexing HistoricalInfo objects. @@ -61,3 +62,26 @@ func GetREDKey(delAddr sdk.AccAddress, valSrcAddr, valDstAddr sdk.ValAddress) [] func GetREDsKey(delAddr sdk.AccAddress) []byte { return append(RedelegationKey, address.MustLengthPrefix(delAddr)...) } + +// GetREDByValSrcIndexKey creates the index-key for a redelegation, stored by source-validator-index +// VALUE: none (key rearrangement used) +func GetREDByValSrcIndexKey(delAddr sdk.AccAddress, valSrcAddr, valDstAddr sdk.ValAddress) []byte { + REDSFromValsSrcKey := GetREDsFromValSrcIndexKey(valSrcAddr) + offset := len(REDSFromValsSrcKey) + + // key is of the form REDSFromValsSrcKey || delAddrLen (1 byte) || delAddr || valDstAddrLen (1 byte) || valDstAddr + key := make([]byte, offset+2+len(delAddr)+len(valDstAddr)) + copy(key[0:offset], REDSFromValsSrcKey) + key[offset] = byte(len(delAddr)) + copy(key[offset+1:offset+1+len(delAddr)], delAddr.Bytes()) + key[offset+1+len(delAddr)] = byte(len(valDstAddr)) + copy(key[offset+2+len(delAddr):], valDstAddr.Bytes()) + + return key +} + +// GetREDsFromValSrcIndexKey returns a key prefix for indexing a redelegation to +// a source validator. +func GetREDsFromValSrcIndexKey(valSrcAddr sdk.ValAddress) []byte { + return append(RedelegationByValSrcIndexKey, address.MustLengthPrefix(valSrcAddr)...) +} diff --git a/x/staking/migrations/v2/store_test.go b/x/staking/migrations/v2/store_test.go index aeafe236de43..2797c90eb08b 100644 --- a/x/staking/migrations/v2/store_test.go +++ b/x/staking/migrations/v2/store_test.go @@ -89,7 +89,7 @@ func TestStoreMigration(t *testing.T) { { "RedelegationByValSrcIndexKey", v1.GetREDByValSrcIndexKey(addr4, valAddr1, valAddr2), - types.GetREDByValSrcIndexKey(addr4, valAddr1, valAddr2), + v2.GetREDByValSrcIndexKey(addr4, valAddr1, valAddr2), }, { "RedelegationByValDstIndexKey", diff --git a/x/staking/types/keys.go b/x/staking/types/keys.go index 51f900f7310c..ef3b8f6bde81 100644 --- a/x/staking/types/keys.go +++ b/x/staking/types/keys.go @@ -77,12 +77,6 @@ func GetValidatorKey(operatorAddr sdk.ValAddress) []byte { return append(ValidatorsKey, address.MustLengthPrefix(operatorAddr)...) } -// AddressFromValidatorsKey creates the validator operator address from ValidatorsKey -func AddressFromValidatorsKey(key []byte) []byte { - kv.AssertKeyAtLeastLength(key, 3) - return key[2:] // remove prefix bytes and address length -} - // AddressFromLastValidatorPowerKey creates the validator operator address from LastValidatorPowerKey func AddressFromLastValidatorPowerKey(key []byte) []byte { kv.AssertKeyAtLeastLength(key, 3) @@ -246,23 +240,6 @@ func GetREDKey(delAddr sdk.AccAddress, valSrcAddr, valDstAddr sdk.ValAddress) [] return key } -// GetREDByValSrcIndexKey creates the index-key for a redelegation, stored by source-validator-index -// VALUE: none (key rearrangement used) -func GetREDByValSrcIndexKey(delAddr sdk.AccAddress, valSrcAddr, valDstAddr sdk.ValAddress) []byte { - REDSFromValsSrcKey := GetREDsFromValSrcIndexKey(valSrcAddr) - offset := len(REDSFromValsSrcKey) - - // key is of the form REDSFromValsSrcKey || delAddrLen (1 byte) || delAddr || valDstAddrLen (1 byte) || valDstAddr - key := make([]byte, offset+2+len(delAddr)+len(valDstAddr)) - copy(key[0:offset], REDSFromValsSrcKey) - key[offset] = byte(len(delAddr)) - copy(key[offset+1:offset+1+len(delAddr)], delAddr.Bytes()) - key[offset+1+len(delAddr)] = byte(len(valDstAddr)) - copy(key[offset+2+len(delAddr):], valDstAddr.Bytes()) - - return key -} - // GetREDByValDstIndexKey creates the index-key for a redelegation, stored by destination-validator-index // VALUE: none (key rearrangement used) func GetREDByValDstIndexKey(delAddr sdk.AccAddress, valSrcAddr, valDstAddr sdk.ValAddress) []byte { @@ -280,24 +257,6 @@ func GetREDByValDstIndexKey(delAddr sdk.AccAddress, valSrcAddr, valDstAddr sdk.V return key } -// GetREDKeyFromValSrcIndexKey rearranges the ValSrcIndexKey to get the REDKey -func GetREDKeyFromValSrcIndexKey(indexKey []byte) []byte { - // note that first byte is prefix byte, which we remove - kv.AssertKeyAtLeastLength(indexKey, 2) - addrs := indexKey[1:] - - valSrcAddrLen := addrs[0] - kv.AssertKeyAtLeastLength(addrs, int(valSrcAddrLen)+2) - valSrcAddr := addrs[1 : valSrcAddrLen+1] - delAddrLen := addrs[valSrcAddrLen+1] - kv.AssertKeyAtLeastLength(addrs, int(valSrcAddrLen)+int(delAddrLen)+2) - delAddr := addrs[valSrcAddrLen+2 : valSrcAddrLen+2+delAddrLen] - kv.AssertKeyAtLeastLength(addrs, int(valSrcAddrLen)+int(delAddrLen)+4) - valDstAddr := addrs[valSrcAddrLen+delAddrLen+3:] - - return GetREDKey(delAddr, valSrcAddr, valDstAddr) -} - // GetREDKeyFromValDstIndexKey rearranges the ValDstIndexKey to get the REDKey func GetREDKeyFromValDstIndexKey(indexKey []byte) []byte { // note that first byte is prefix byte, which we remove @@ -329,12 +288,6 @@ func GetREDsKey(delAddr sdk.AccAddress) []byte { return append(RedelegationKey, address.MustLengthPrefix(delAddr)...) } -// GetREDsFromValSrcIndexKey returns a key prefix for indexing a redelegation to -// a source validator. -func GetREDsFromValSrcIndexKey(valSrcAddr sdk.ValAddress) []byte { - return append(RedelegationByValSrcIndexKey, address.MustLengthPrefix(valSrcAddr)...) -} - // GetREDsToValDstIndexKey returns a key prefix for indexing a redelegation to a // destination (target) validator. func GetREDsToValDstIndexKey(valDstAddr sdk.ValAddress) []byte { diff --git a/x/staking/types/keys_test.go b/x/staking/types/keys_test.go index c4bd5400eafb..0ccc24833225 100644 --- a/x/staking/types/keys_test.go +++ b/x/staking/types/keys_test.go @@ -78,33 +78,6 @@ func TestGetREDByValDstIndexKey(t *testing.T) { } } -func TestGetREDByValSrcIndexKey(t *testing.T) { - tests := []struct { - delAddr sdk.AccAddress - valSrcAddr sdk.ValAddress - valDstAddr sdk.ValAddress - wantHex string - }{ - { - sdk.AccAddress(keysAddr1), sdk.ValAddress(keysAddr1), sdk.ValAddress(keysAddr1), - "351463d771218209d8bd03c482f69dfba57310f086091463d771218209d8bd03c482f69dfba57310f086091463d771218209d8bd03c482f69dfba57310f08609", - }, - { - sdk.AccAddress(keysAddr1), sdk.ValAddress(keysAddr2), sdk.ValAddress(keysAddr3), - "35145ef3b5f25c54946d4a89fc0d09d2f126614540f21463d771218209d8bd03c482f69dfba57310f08609143ab62f0d93849be495e21e3e9013a517038f45bd", - }, - { - sdk.AccAddress(keysAddr2), sdk.ValAddress(keysAddr1), sdk.ValAddress(keysAddr3), - "351463d771218209d8bd03c482f69dfba57310f08609145ef3b5f25c54946d4a89fc0d09d2f126614540f2143ab62f0d93849be495e21e3e9013a517038f45bd", - }, - } - for i, tt := range tests { - got := hex.EncodeToString(types.GetREDByValSrcIndexKey(tt.delAddr, tt.valSrcAddr, tt.valDstAddr)) - - require.Equal(t, tt.wantHex, got, "Keys did not match on test case %d", i) - } -} - func TestGetValidatorQueueKey(t *testing.T) { ts := time.Now() height := int64(1024) From 851c659694d40a813f56634d4b88b00f08c4b145 Mon Sep 17 00:00:00 2001 From: atheesh Date: Wed, 9 Aug 2023 17:04:26 +0530 Subject: [PATCH 10/19] fix tests --- x/staking/types/keys.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/x/staking/types/keys.go b/x/staking/types/keys.go index ef3b8f6bde81..60cc67107bc1 100644 --- a/x/staking/types/keys.go +++ b/x/staking/types/keys.go @@ -77,6 +77,12 @@ func GetValidatorKey(operatorAddr sdk.ValAddress) []byte { return append(ValidatorsKey, address.MustLengthPrefix(operatorAddr)...) } +// AddressFromValidatorsKey creates the validator operator address from ValidatorsKey +func AddressFromValidatorsKey(key []byte) []byte { + kv.AssertKeyAtLeastLength(key, 3) + return key[2:] // remove prefix bytes and address length +} + // AddressFromLastValidatorPowerKey creates the validator operator address from LastValidatorPowerKey func AddressFromLastValidatorPowerKey(key []byte) []byte { kv.AssertKeyAtLeastLength(key, 3) From 8e37291b70c4e4190740b1ff7125c2b0b16b8ce2 Mon Sep 17 00:00:00 2001 From: atheesh Date: Wed, 9 Aug 2023 17:07:14 +0530 Subject: [PATCH 11/19] fix tests --- x/staking/keeper/query_utils.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x/staking/keeper/query_utils.go b/x/staking/keeper/query_utils.go index 5a23f8350d4c..632f389ce681 100644 --- a/x/staking/keeper/query_utils.go +++ b/x/staking/keeper/query_utils.go @@ -120,11 +120,11 @@ func (k Keeper) GetAllRedelegations( func(key collections.Triple[sdk.AccAddress, sdk.ValAddress, sdk.ValAddress], redelegation types.Redelegation) (stop bool, err error) { valSrcAddr, valDstAddr := key.K2(), key.K3() - if srcValFilter && !(srcValAddress.Equals(sdk.ValAddress(valSrcAddr))) { + if srcValFilter && !(srcValAddress.Equals(valSrcAddr)) { return false, nil } - if dstValFilter && !(dstValAddress.Equals(sdk.ValAddress(valDstAddr))) { + if dstValFilter && !(dstValAddress.Equals(valDstAddr)) { return false, nil } From 235427a4cc186ad770b44193bbe0b46ccc7ace3f Mon Sep 17 00:00:00 2001 From: atheesh Date: Wed, 9 Aug 2023 19:58:07 +0530 Subject: [PATCH 12/19] lint --- x/staking/keeper/query_utils.go | 1 - 1 file changed, 1 deletion(-) diff --git a/x/staking/keeper/query_utils.go b/x/staking/keeper/query_utils.go index 632f389ce681..c0e118b09753 100644 --- a/x/staking/keeper/query_utils.go +++ b/x/staking/keeper/query_utils.go @@ -110,7 +110,6 @@ func (k Keeper) GetAllUnbondingDelegations(ctx context.Context, delegator sdk.Ac func (k Keeper) GetAllRedelegations( ctx context.Context, delegator sdk.AccAddress, srcValAddress, dstValAddress sdk.ValAddress, ) ([]types.Redelegation, error) { - srcValFilter := !(srcValAddress.Empty()) dstValFilter := !(dstValAddress.Empty()) From 448dd8ab9081a6891a474ca7d4af6bbf7be0943b Mon Sep 17 00:00:00 2001 From: atheesh Date: Thu, 17 Aug 2023 16:52:29 +0530 Subject: [PATCH 13/19] fix tests --- 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 e79e2a17ef58..72f97ab23e17 100644 --- a/x/staking/keeper/delegation.go +++ b/x/staking/keeper/delegation.go @@ -505,7 +505,7 @@ func (k Keeper) GetRedelegationsFromSrcValidator(ctx context.Context, valAddr sd err = k.RedelegationsByValSrc.Walk(ctx, rng, func(key collections.Triple[sdk.ValAddress, sdk.AccAddress, sdk.ValAddress], value []byte) (stop bool, err error) { valSrcAddr, delAddr, valDstAddr := key.K1(), key.K2(), key.K3() - red, err := k.Redelegations.Get(ctx, collections.Join3(delAddr, valSrcAddr, valDstAddr)) + red, err := k.Redelegations.Get(ctx, collections.Join3(delAddr.Bytes(), valSrcAddr.Bytes(), valDstAddr.Bytes())) if err != nil { return true, err } From c46d2474ab9c42ab38859bc7f3d84874164fff62 Mon Sep 17 00:00:00 2001 From: atheesh Date: Thu, 17 Aug 2023 18:05:53 +0530 Subject: [PATCH 14/19] review changes --- x/staking/keeper/delegation.go | 10 +++++----- x/staking/keeper/grpc_query.go | 6 +++--- x/staking/keeper/keeper.go | 8 ++++---- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/x/staking/keeper/delegation.go b/x/staking/keeper/delegation.go index 72f97ab23e17..2da5bae3a799 100644 --- a/x/staking/keeper/delegation.go +++ b/x/staking/keeper/delegation.go @@ -501,11 +501,11 @@ func (k Keeper) GetRedelegations(ctx context.Context, delegator sdk.AccAddress, // GetRedelegationsFromSrcValidator returns all redelegations from a particular // validator. func (k Keeper) GetRedelegationsFromSrcValidator(ctx context.Context, valAddr sdk.ValAddress) (reds []types.Redelegation, err error) { - rng := collections.NewPrefixedTripleRange[sdk.ValAddress, sdk.AccAddress, sdk.ValAddress](valAddr) - err = k.RedelegationsByValSrc.Walk(ctx, rng, func(key collections.Triple[sdk.ValAddress, sdk.AccAddress, sdk.ValAddress], value []byte) (stop bool, err error) { + rng := collections.NewPrefixedTripleRange[[]byte, []byte, []byte](valAddr) + err = k.RedelegationsByValSrc.Walk(ctx, rng, func(key collections.Triple[[]byte, []byte, []byte], value []byte) (stop bool, err error) { valSrcAddr, delAddr, valDstAddr := key.K1(), key.K2(), key.K3() - red, err := k.Redelegations.Get(ctx, collections.Join3(delAddr.Bytes(), valSrcAddr.Bytes(), valDstAddr.Bytes())) + red, err := k.Redelegations.Get(ctx, collections.Join3(delAddr, valSrcAddr, valDstAddr)) if err != nil { return true, err } @@ -571,7 +571,7 @@ func (k Keeper) SetRedelegation(ctx context.Context, red types.Redelegation) err return err } - if err = k.RedelegationsByValSrc.Set(ctx, collections.Join3(sdk.ValAddress(valSrcAddr), sdk.AccAddress(delegatorAddress), sdk.ValAddress(valDestAddr)), []byte{}); err != nil { + if err = k.RedelegationsByValSrc.Set(ctx, collections.Join3(valSrcAddr, delegatorAddress, valDestAddr), []byte{}); err != nil { return err } @@ -659,7 +659,7 @@ func (k Keeper) RemoveRedelegation(ctx context.Context, red types.Redelegation) return err } - if err = k.RedelegationsByValSrc.Remove(ctx, collections.Join3(sdk.ValAddress(valSrcAddr), sdk.AccAddress(delegatorAddress), sdk.ValAddress(valDestAddr))); err != nil { + if err = k.RedelegationsByValSrc.Remove(ctx, collections.Join3(valSrcAddr, delegatorAddress, valDestAddr)); err != nil { return err } diff --git a/x/staking/keeper/grpc_query.go b/x/staking/keeper/grpc_query.go index 1def4be05fef..961221998d6b 100644 --- a/x/staking/keeper/grpc_query.go +++ b/x/staking/keeper/grpc_query.go @@ -523,14 +523,14 @@ func queryRedelegationsFromSrcValidator(ctx context.Context, store storetypes.KV return nil, nil, err } - return query.CollectionPaginate(ctx, k.RedelegationsByValSrc, req.Pagination, func(key collections.Triple[sdk.ValAddress, sdk.AccAddress, sdk.ValAddress], val []byte) (types.Redelegation, error) { + return query.CollectionPaginate(ctx, k.RedelegationsByValSrc, req.Pagination, func(key collections.Triple[[]byte, []byte, []byte], val []byte) (types.Redelegation, error) { valSrcAddr, delAddr, valDstAddr := key.K1(), key.K2(), key.K3() - red, err := k.Keeper.Redelegations.Get(ctx, collections.Join3(delAddr.Bytes(), valSrcAddr.Bytes(), valDstAddr.Bytes())) + red, err := k.Keeper.Redelegations.Get(ctx, collections.Join3(delAddr, valSrcAddr, valDstAddr)) if err != nil { return types.Redelegation{}, err } return red, nil - }, query.WithCollectionPaginationTriplePrefix[sdk.ValAddress, sdk.AccAddress, sdk.ValAddress](valAddr)) + }, query.WithCollectionPaginationTriplePrefix[[]byte, []byte, []byte](valAddr)) } func queryAllRedelegations(ctx context.Context, store storetypes.KVStore, k Querier, req *types.QueryRedelegationsRequest) (redels types.Redelegations, res *query.PageResponse, err error) { diff --git a/x/staking/keeper/keeper.go b/x/staking/keeper/keeper.go index f771db37c5c5..dd68d240c0c3 100644 --- a/x/staking/keeper/keeper.go +++ b/x/staking/keeper/keeper.go @@ -44,7 +44,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] - RedelegationsByValSrc collections.Map[collections.Triple[sdk.ValAddress, sdk.AccAddress, sdk.ValAddress], []byte] + RedelegationsByValSrc collections.Map[collections.Triple[[]byte, []byte, []byte], []byte] } // NewKeeper creates a new staking Keeper instance @@ -125,9 +125,9 @@ func NewKeeper( sb, types.RedelegationByValSrcIndexKey, "redelegations_by_val_src", collections.TripleKeyCodec( - sdk.LengthPrefixedAddressKey(sdk.ValAddressKey), // nolint: staticcheck // sdk.LengthPrefixedAddressKey is needed to retain state compatibility - sdk.LengthPrefixedAddressKey(sdk.AccAddressKey), // nolint: staticcheck // sdk.LengthPrefixedAddressKey is needed to retain state compatibility - sdk.LengthPrefixedAddressKey(sdk.ValAddressKey), // nolint: staticcheck // sdk.LengthPrefixedAddressKey is needed to retain state compatibility + collections.BytesKey, + collections.BytesKey, + sdk.LengthPrefixedBytesKey, // sdk.LengthPrefixedBytesKey is needed to retain state compatibility ), collections.BytesValue, ), From cdcb4c84574795c37300c6f320b443fe99bab73c Mon Sep 17 00:00:00 2001 From: atheesh Date: Fri, 18 Aug 2023 11:08:52 +0530 Subject: [PATCH 15/19] add tests to test diffColls --- x/staking/keeper/keeper_test.go | 45 +++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/x/staking/keeper/keeper_test.go b/x/staking/keeper/keeper_test.go index 46aabdcabb4c..946d43969fb7 100644 --- a/x/staking/keeper/keeper_test.go +++ b/x/staking/keeper/keeper_test.go @@ -17,6 +17,7 @@ import ( "github.com/cosmos/cosmos-sdk/testutil" simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims" sdk "github.com/cosmos/cosmos-sdk/types" + addresstypes "github.com/cosmos/cosmos-sdk/types/address" moduletestutil "github.com/cosmos/cosmos-sdk/types/module/testutil" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper" @@ -39,6 +40,7 @@ type KeeperTestSuite struct { accountKeeper *stakingtestutil.MockAccountKeeper queryClient stakingtypes.QueryClient msgServer stakingtypes.MsgServer + key *storetypes.KVStoreKey } func (s *KeeperTestSuite) SetupTest() { @@ -46,6 +48,7 @@ func (s *KeeperTestSuite) SetupTest() { key := storetypes.NewKVStoreKey(stakingtypes.StoreKey) storeService := runtime.NewKVStoreService(key) testCtx := testutil.DefaultContextWithDB(s.T(), key, storetypes.NewTransientStoreKey("transient_test")) + s.key = key ctx := testCtx.Ctx.WithBlockHeader(cmtproto.Header{Time: cmttime.Now()}) encCfg := moduletestutil.MakeTestEncodingConfig() @@ -109,6 +112,48 @@ func (s *KeeperTestSuite) TestLastTotalPower() { require.True(expTotalPower.Equal(resTotalPower)) } +// GetREDByValSrcIndexKey creates the index-key for a redelegation, stored by source-validator-index +// VALUE: none (key rearrangement used) +func getREDByValSrcIndexKey(delAddr sdk.AccAddress, valSrcAddr, valDstAddr sdk.ValAddress) []byte { + REDSFromValsSrcKey := getREDsFromValSrcIndexKey(valSrcAddr) + offset := len(REDSFromValsSrcKey) + + // key is of the form REDSFromValsSrcKey || delAddrLen (1 byte) || delAddr || valDstAddrLen (1 byte) || valDstAddr + key := make([]byte, offset+2+len(delAddr)+len(valDstAddr)) + copy(key[0:offset], REDSFromValsSrcKey) + key[offset] = byte(len(delAddr)) + copy(key[offset+1:offset+1+len(delAddr)], delAddr.Bytes()) + key[offset+1+len(delAddr)] = byte(len(valDstAddr)) + copy(key[offset+2+len(delAddr):], valDstAddr.Bytes()) + + return key +} + +// GetREDsFromValSrcIndexKey returns a key prefix for indexing a redelegation to +// a source validator. +func getREDsFromValSrcIndexKey(valSrcAddr sdk.ValAddress) []byte { + redelegationByValSrcIndexKey := []byte{0x35} + return append(redelegationByValSrcIndexKey, addresstypes.MustLengthPrefix(valSrcAddr)...) +} + +func (s *KeeperTestSuite) TestRedelegationsMigrationToColls() { + s.SetupTest() + + addrs, valAddrs := createValAddrs(101) + + err := testutil.DiffCollectionsMigration( + s.ctx, + s.key, + 100, + func(i int64) { + s.ctx.KVStore(s.key).Set(getREDByValSrcIndexKey(addrs[i], valAddrs[i], valAddrs[i+1]), []byte{}) + }, + "cb7b7086b1e03add24f85f894531fb36b3b9746f2e661e1640ec528a4f23a3d9", // this hash obtained when ran this test in main branch + ) + + s.Require().NoError(err) +} + func TestKeeperTestSuite(t *testing.T) { suite.Run(t, new(KeeperTestSuite)) } From b28a7393c14af7016dc266346c82599a57e2928c Mon Sep 17 00:00:00 2001 From: atheesh Date: Sat, 19 Aug 2023 10:01:38 +0530 Subject: [PATCH 16/19] fix tests --- x/staking/keeper/keeper_test.go | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/x/staking/keeper/keeper_test.go b/x/staking/keeper/keeper_test.go index 946d43969fb7..a8bab063e2a0 100644 --- a/x/staking/keeper/keeper_test.go +++ b/x/staking/keeper/keeper_test.go @@ -8,6 +8,7 @@ import ( "github.com/golang/mock/gomock" "github.com/stretchr/testify/suite" + "cosmossdk.io/collections" "cosmossdk.io/math" storetypes "cosmossdk.io/store/types" @@ -146,9 +147,22 @@ func (s *KeeperTestSuite) TestRedelegationsMigrationToColls() { s.key, 100, func(i int64) { + // legacy method to set in the state s.ctx.KVStore(s.key).Set(getREDByValSrcIndexKey(addrs[i], valAddrs[i], valAddrs[i+1]), []byte{}) }, - "cb7b7086b1e03add24f85f894531fb36b3b9746f2e661e1640ec528a4f23a3d9", // this hash obtained when ran this test in main branch + "cb7b7086b1e03add24f85f894531fb36b3b9746f2e661e1640ec528a4f23a3d9", + ) + s.Require().NoError(err) + + err = testutil.DiffCollectionsMigration( + s.ctx, + s.key, + 100, + func(i int64) { + // using collections + s.stakingKeeper.RedelegationsByValSrc.Set(s.ctx, collections.Join3(addrs[i].Bytes(), valAddrs[i].Bytes(), valAddrs[i+1].Bytes()), []byte{}) + }, + "cb7b7086b1e03add24f85f894531fb36b3b9746f2e661e1640ec528a4f23a3d9", ) s.Require().NoError(err) From 8262eb97bfb8b814be73d8b7f19633519552af3e Mon Sep 17 00:00:00 2001 From: atheesh Date: Sat, 19 Aug 2023 10:14:41 +0530 Subject: [PATCH 17/19] refactor --- x/staking/keeper/keeper_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/staking/keeper/keeper_test.go b/x/staking/keeper/keeper_test.go index a8bab063e2a0..fefd4b5f8269 100644 --- a/x/staking/keeper/keeper_test.go +++ b/x/staking/keeper/keeper_test.go @@ -160,7 +160,7 @@ func (s *KeeperTestSuite) TestRedelegationsMigrationToColls() { 100, func(i int64) { // using collections - s.stakingKeeper.RedelegationsByValSrc.Set(s.ctx, collections.Join3(addrs[i].Bytes(), valAddrs[i].Bytes(), valAddrs[i+1].Bytes()), []byte{}) + s.stakingKeeper.RedelegationsByValSrc.Set(s.ctx, collections.Join3(valAddrs[i].Bytes(), addrs[i].Bytes(), valAddrs[i+1].Bytes()), []byte{}) }, "cb7b7086b1e03add24f85f894531fb36b3b9746f2e661e1640ec528a4f23a3d9", ) From 4fb67936dd273d1eeeafdf5ace8721375c9d33d1 Mon Sep 17 00:00:00 2001 From: atheesh Date: Sat, 19 Aug 2023 10:20:04 +0530 Subject: [PATCH 18/19] inline docs --- x/staking/keeper/keeper.go | 1 + 1 file changed, 1 insertion(+) diff --git a/x/staking/keeper/keeper.go b/x/staking/keeper/keeper.go index dd68d240c0c3..81c00360712a 100644 --- a/x/staking/keeper/keeper.go +++ b/x/staking/keeper/keeper.go @@ -121,6 +121,7 @@ func NewKeeper( codec.CollValue[types.Redelegation](cdc), ), UnbondingIndex: collections.NewMap(sb, types.UnbondingIndexKey, "unbonding_index", collections.Uint64Key, collections.BytesValue), + // key format is: 53 | lengthPrefixedBytes(DstValAddr) | lengthPrefixedBytes(AccAddr) | lengthPrefixedBytes(SrcValAddr) RedelegationsByValSrc: collections.NewMap( sb, types.RedelegationByValSrcIndexKey, "redelegations_by_val_src", From 9aa7041e3886eb51fe9176b23772d74bfbaba2ca Mon Sep 17 00:00:00 2001 From: atheesh Date: Sat, 19 Aug 2023 10:26:17 +0530 Subject: [PATCH 19/19] fix lint --- x/staking/keeper/keeper_test.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x/staking/keeper/keeper_test.go b/x/staking/keeper/keeper_test.go index fefd4b5f8269..f12a55fc04e4 100644 --- a/x/staking/keeper/keeper_test.go +++ b/x/staking/keeper/keeper_test.go @@ -160,7 +160,8 @@ func (s *KeeperTestSuite) TestRedelegationsMigrationToColls() { 100, func(i int64) { // using collections - s.stakingKeeper.RedelegationsByValSrc.Set(s.ctx, collections.Join3(valAddrs[i].Bytes(), addrs[i].Bytes(), valAddrs[i+1].Bytes()), []byte{}) + err := s.stakingKeeper.RedelegationsByValSrc.Set(s.ctx, collections.Join3(valAddrs[i].Bytes(), addrs[i].Bytes(), valAddrs[i+1].Bytes()), []byte{}) + s.Require().NoError(err) }, "cb7b7086b1e03add24f85f894531fb36b3b9746f2e661e1640ec528a4f23a3d9", )