Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

refactor(x/staking): migrate RedelegationByValDstIndexKey key to collections #17336

Merged
merged 38 commits into from
Aug 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
b902f71
refactor(x/staking): migrate redelegation key to use collections
atheeshp Aug 8, 2023
19fa78e
tests
atheeshp Aug 8, 2023
1e6c102
all redelegations
atheeshp Aug 8, 2023
df4cd76
Merge branch 'main' of github.com:cosmos/cosmos-sdk into ap/redelegat…
atheeshp Aug 9, 2023
ef48759
fix tests
atheeshp Aug 9, 2023
dcbba95
conflicts
atheeshp Aug 9, 2023
948e9bd
Merge branch 'main' of github.com:cosmos/cosmos-sdk into ap/redelegat…
atheeshp Aug 9, 2023
cd46d89
fix tests
atheeshp Aug 9, 2023
54b97c3
Merge branch 'main' of github.com:cosmos/cosmos-sdk into ap/redelegat…
atheeshp Aug 9, 2023
eb0ac8d
handle errors
atheeshp Aug 9, 2023
910493c
Merge branch 'main' of github.com:cosmos/cosmos-sdk into ap/redelegat…
atheeshp Aug 9, 2023
74f28cf
Merge branch 'main' into ap/redelegation-key-to-collections
atheeshp Aug 9, 2023
fa6fe54
refactor(x/staking): migrate `RedelegationByValDstIndexKey` key to co…
atheeshp Aug 9, 2023
8e37291
fix tests
atheeshp Aug 9, 2023
dea9749
Merge branch 'ap/redelegation-key-to-collections' of github.com:cosmo…
atheeshp Aug 9, 2023
3829443
Merge branch 'ap/redelegation-key-to-collections' of github.com:cosmo…
atheeshp Aug 9, 2023
235427a
lint
atheeshp Aug 9, 2023
7f3d119
Merge branch 'ap/redelegation-key-to-collections' of github.com:cosmo…
atheeshp Aug 9, 2023
67c0c40
Merge branch 'main' into ap/redelegation-key-to-collections
atheeshp Aug 9, 2023
63874f6
Merge branch 'main' into ap/redelegation-key-to-collections
atheeshp Aug 9, 2023
eb2e900
fix tests
atheeshp Aug 10, 2023
8e17907
Merge branch 'ap/redelegation-key-to-collections' of github.com:cosmo…
atheeshp Aug 10, 2023
6c61681
Merge branch 'main' of github.com:cosmos/cosmos-sdk into ap/red-from-…
atheeshp Aug 17, 2023
a3d20e6
review changes
atheeshp Aug 17, 2023
aef6358
Merge branch 'main' of github.com:cosmos/cosmos-sdk into ap/red-from-…
atheeshp Aug 17, 2023
96df42d
add tests to check diff collection
atheeshp Aug 18, 2023
817c525
Merge branch 'main' of github.com:cosmos/cosmos-sdk into ap/red-from-…
atheeshp Aug 18, 2023
fbaf112
inline docs
atheeshp Aug 19, 2023
768f623
fix lint
atheeshp Aug 19, 2023
f92e5d6
Merge branch 'main' into ap/red-from-val-dst-to-coll
atheeshp Aug 19, 2023
3032596
Merge branch 'main' into ap/red-from-val-dst-to-coll
atheeshp Aug 21, 2023
06fe202
Merge branch 'main' into ap/red-from-val-dst-to-coll
atheeshp Aug 22, 2023
1c31f42
Merge branch 'main' of github.com:cosmos/cosmos-sdk into ap/red-from-…
atheeshp Aug 22, 2023
ec066b7
fix build
atheeshp Aug 22, 2023
317a614
Merge branch 'main' of github.com:cosmos/cosmos-sdk into ap/red-from-…
atheeshp Aug 23, 2023
9741e77
Merge branch 'ap/red-from-val-dst-to-coll' of github.com:cosmos/cosmo…
atheeshp Aug 23, 2023
1291f65
fix doc
atheeshp Aug 23, 2023
f22d905
doc
atheeshp Aug 23, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 10 additions & 9 deletions x/staking/keeper/delegation.go
Original file line number Diff line number Diff line change
Expand Up @@ -522,14 +522,17 @@ func (k Keeper) GetRedelegationsFromSrcValidator(ctx context.Context, valAddr sd

// HasReceivingRedelegation checks if validator is receiving a redelegation.
func (k Keeper) HasReceivingRedelegation(ctx context.Context, delAddr sdk.AccAddress, valDstAddr sdk.ValAddress) (bool, error) {
store := k.storeService.OpenKVStore(ctx)
prefix := types.GetREDsByDelToValDstIndexKey(delAddr, valDstAddr)
iterator, err := store.Iterator(prefix, storetypes.PrefixEndBytes(prefix))
rng := collections.NewSuperPrefixedTripleRange[[]byte, []byte, []byte](valDstAddr, delAddr)
hasAtleastOneEntry := false
err := k.RedelegationsByValDst.Walk(ctx, rng, func(key collections.Triple[[]byte, []byte, []byte], value []byte) (stop bool, err error) {
hasAtleastOneEntry = true
return true, nil // returning true here to stop the iterations after 1st finding
})
if err != nil {
return false, err
}
defer iterator.Close()
return iterator.Valid(), nil

return hasAtleastOneEntry, nil
}

// HasMaxRedelegationEntries checks if the redelegation entries reached maximum limit.
Expand Down Expand Up @@ -557,7 +560,6 @@ func (k Keeper) SetRedelegation(ctx context.Context, red types.Redelegation) err
return err
}

store := k.storeService.OpenKVStore(ctx)
valSrcAddr, err := k.validatorAddressCodec.StringToBytes(red.ValidatorSrcAddress)
if err != nil {
return err
Expand All @@ -575,7 +577,7 @@ func (k Keeper) SetRedelegation(ctx context.Context, red types.Redelegation) err
return err
}

return store.Set(types.GetREDByValDstIndexKey(delegatorAddress, valSrcAddr, valDestAddr), []byte{})
return k.RedelegationsByValDst.Set(ctx, collections.Join3(valDestAddr, delegatorAddress, valSrcAddr), []byte{})
}

// SetRedelegationEntry adds an entry to the unbonding delegation at the given
Expand Down Expand Up @@ -645,7 +647,6 @@ func (k Keeper) RemoveRedelegation(ctx context.Context, red types.Redelegation)
return err
}

store := k.storeService.OpenKVStore(ctx)
valSrcAddr, err := k.validatorAddressCodec.StringToBytes(red.ValidatorSrcAddress)
if err != nil {
return err
Expand All @@ -663,7 +664,7 @@ func (k Keeper) RemoveRedelegation(ctx context.Context, red types.Redelegation)
return err
}

return store.Delete(types.GetREDByValDstIndexKey(delegatorAddress, valSrcAddr, valDestAddr))
return k.RedelegationsByValDst.Remove(ctx, collections.Join3(valDestAddr, delegatorAddress, valSrcAddr))
}

// redelegation queue timeslice operations
Expand Down
15 changes: 14 additions & 1 deletion x/staking/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +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]
RedelegationsByValDst collections.Map[collections.Triple[[]byte, []byte, []byte], []byte]
RedelegationsByValSrc collections.Map[collections.Triple[[]byte, []byte, []byte], []byte]
}

Expand Down Expand Up @@ -110,6 +111,7 @@ func NewKeeper(
collcodec.KeyToValueCodec(sdk.ValAddressKey),
),
UnbondingType: collections.NewMap(sb, types.UnbondingTypeKey, "unbonding_type", collections.Uint64Key, collections.Uint64Value),
// key format is: 52 | lengthPrefixedBytes(AccAddr) | lengthPrefixedBytes(SrcValAddr) | lengthPrefixedBytes(DstValAddr)
Redelegations: collections.NewMap(
sb, types.RedelegationKey,
"redelegations",
Expand All @@ -121,7 +123,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)
// key format is: 53 | lengthPrefixedBytes(SrcValAddr) | lengthPrefixedBytes(AccAddr) | lengthPrefixedBytes(DstValAddr)
RedelegationsByValSrc: collections.NewMap(
sb, types.RedelegationByValSrcIndexKey,
"redelegations_by_val_src",
Expand All @@ -132,6 +134,17 @@ func NewKeeper(
),
collections.BytesValue,
),
// key format is: 54 | lengthPrefixedBytes(DstValAddr) | lengthPrefixedBytes(AccAddr) | lengthPrefixedBytes(SrcValAddr)
RedelegationsByValDst: collections.NewMap(
sb, types.RedelegationByValDstIndexKey,
"redelegations_by_val_dst",
collections.TripleKeyCodec(
collections.BytesKey,
collections.BytesKey,
sdk.LengthPrefixedBytesKey, // sdk.LengthPrefixedBytesKey is needed to retain state compatibility
),
collections.BytesValue,
),
}

schema, err := sb.Build()
Expand Down
58 changes: 57 additions & 1 deletion x/staking/keeper/keeper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,23 @@ func (s *KeeperTestSuite) TestLastTotalPower() {
require.True(expTotalPower.Equal(resTotalPower))
}

// 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 {
REDSToValsDstKey := getREDsToValDstIndexKey(valDstAddr)
offset := len(REDSToValsDstKey)

// key is of the form REDSToValsDstKey || delAddrLen (1 byte) || delAddr || valSrcAddrLen (1 byte) || valSrcAddr
key := make([]byte, offset+2+len(delAddr)+len(valSrcAddr))
copy(key[0:offset], REDSToValsDstKey)
key[offset] = byte(len(delAddr))
copy(key[offset+1:offset+1+len(delAddr)], delAddr.Bytes())
key[offset+1+len(delAddr)] = byte(len(valSrcAddr))
copy(key[offset+2+len(delAddr):], valSrcAddr.Bytes())

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 {
Expand All @@ -130,14 +147,21 @@ func getREDByValSrcIndexKey(delAddr sdk.AccAddress, valSrcAddr, valDstAddr sdk.V
return key
}

// GetREDsToValDstIndexKey returns a key prefix for indexing a redelegation to a
// destination (target) validator.
func getREDsToValDstIndexKey(valDstAddr sdk.ValAddress) []byte {
redelegationByValDstIndexKey := []byte{0x36}
return append(redelegationByValDstIndexKey, addresstypes.MustLengthPrefix(valDstAddr)...)
}

// 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() {
func (s *KeeperTestSuite) TestSrcRedelegationsMigrationToColls() {
s.SetupTest()

addrs, valAddrs := createValAddrs(101)
Expand Down Expand Up @@ -169,6 +193,38 @@ func (s *KeeperTestSuite) TestRedelegationsMigrationToColls() {
s.Require().NoError(err)
}

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

addrs, valAddrs := createValAddrs(101)

err := testutil.DiffCollectionsMigration(
s.ctx,
s.key,
100,
func(i int64) {
// legacy method to set in the state
s.ctx.KVStore(s.key).Set(getREDByValDstIndexKey(addrs[i], valAddrs[i], valAddrs[i+1]), []byte{})
},
"4beb77994beff3c8ad9cecca9ee3a74fb551356250f0b8bd3936c4e4f506443b", // this hash obtained when ran this test in main branch
)
s.Require().NoError(err)

err = testutil.DiffCollectionsMigration(
s.ctx,
s.key,
100,
func(i int64) {
// using collections
err := s.stakingKeeper.RedelegationsByValDst.Set(s.ctx, collections.Join3(valAddrs[i+1].Bytes(), addrs[i].Bytes(), valAddrs[i].Bytes()), []byte{})
s.Require().NoError(err)
},
"4beb77994beff3c8ad9cecca9ee3a74fb551356250f0b8bd3936c4e4f506443b",
)

s.Require().NoError(err)
}

func TestKeeperTestSuite(t *testing.T) {
suite.Run(t, new(KeeperTestSuite))
}
30 changes: 28 additions & 2 deletions x/staking/migrations/v2/keys.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,14 @@ const (
)

var (
ValidatorsByConsAddrKey = []byte{0x22} // prefix for validators by consensus address
ValidatorsByConsAddrKey = []byte{0x22} // prefix for validators by consensus address

DelegationKey = []byte{0x31} // prefix for the delegation
RedelegationKey = []byte{0x34} // key for a redelegation
RedelegationByValDstIndexKey = []byte{0x36} // prefix for each key for an redelegation, by destination validator operator
RedelegationByValSrcIndexKey = []byte{0x35} // prefix for each key for an redelegation, by source validator operator
HistoricalInfoKey = []byte{0x50} // prefix for the historical info

HistoricalInfoKey = []byte{0x50} // prefix for the historical info
)

// GetHistoricalInfoKey returns a key prefix for indexing HistoricalInfo objects.
Expand Down Expand Up @@ -63,6 +66,23 @@ func GetREDsKey(delAddr sdk.AccAddress) []byte {
return append(RedelegationKey, address.MustLengthPrefix(delAddr)...)
}

// 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 {
REDSToValsDstKey := GetREDsToValDstIndexKey(valDstAddr)
offset := len(REDSToValsDstKey)

// key is of the form REDSToValsDstKey || delAddrLen (1 byte) || delAddr || valSrcAddrLen (1 byte) || valSrcAddr
key := make([]byte, offset+2+len(delAddr)+len(valSrcAddr))
copy(key[0:offset], REDSToValsDstKey)
key[offset] = byte(len(delAddr))
copy(key[offset+1:offset+1+len(delAddr)], delAddr.Bytes())
key[offset+1+len(delAddr)] = byte(len(valSrcAddr))
copy(key[offset+2+len(delAddr):], valSrcAddr.Bytes())

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 {
Expand All @@ -80,6 +100,12 @@ func GetREDByValSrcIndexKey(delAddr sdk.AccAddress, valSrcAddr, valDstAddr sdk.V
return key
}

// GetREDsToValDstIndexKey returns a key prefix for indexing a redelegation to a
// destination (target) validator.
func GetREDsToValDstIndexKey(valDstAddr sdk.ValAddress) []byte {
return append(RedelegationByValDstIndexKey, address.MustLengthPrefix(valDstAddr)...)
}

// GetREDsFromValSrcIndexKey returns a key prefix for indexing a redelegation to
// a source validator.
func GetREDsFromValSrcIndexKey(valSrcAddr sdk.ValAddress) []byte {
Expand Down
2 changes: 1 addition & 1 deletion x/staking/migrations/v2/store_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ func TestStoreMigration(t *testing.T) {
{
"RedelegationByValDstIndexKey",
v1.GetREDByValDstIndexKey(addr4, valAddr1, valAddr2),
types.GetREDByValDstIndexKey(addr4, valAddr1, valAddr2),
v2.GetREDByValDstIndexKey(addr4, valAddr1, valAddr2),
},
{
"UnbondingQueueKey",
Expand Down
49 changes: 1 addition & 48 deletions x/staking/types/keys.go
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changelog missing

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

missed it, will raise a PR.

Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ var (
UnbondingDelegationByValIndexKey = []byte{0x33} // prefix for each key for an unbonding-delegation, by validator operator
RedelegationKey = collections.NewPrefix(52) // key for a redelegation
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
RedelegationByValDstIndexKey = collections.NewPrefix(54) // 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 = collections.NewPrefix(56) // prefix for an index for looking up unbonding operations by their IDs
Expand Down Expand Up @@ -247,41 +247,6 @@ func GetREDKey(delAddr sdk.AccAddress, valSrcAddr, valDstAddr sdk.ValAddress) []
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 {
REDSToValsDstKey := GetREDsToValDstIndexKey(valDstAddr)
offset := len(REDSToValsDstKey)

// key is of the form REDSToValsDstKey || delAddrLen (1 byte) || delAddr || valSrcAddrLen (1 byte) || valSrcAddr
key := make([]byte, offset+2+len(delAddr)+len(valSrcAddr))
copy(key[0:offset], REDSToValsDstKey)
key[offset] = byte(len(delAddr))
copy(key[offset+1:offset+1+len(delAddr)], delAddr.Bytes())
key[offset+1+len(delAddr)] = byte(len(valSrcAddr))
copy(key[offset+2+len(delAddr):], valSrcAddr.Bytes())

return key
}

// GetREDKeyFromValDstIndexKey rearranges the ValDstIndexKey to get the REDKey
func GetREDKeyFromValDstIndexKey(indexKey []byte) []byte {
// note that first byte is prefix byte, which we remove
kv.AssertKeyAtLeastLength(indexKey, 2)
addrs := indexKey[1:]

valDstAddrLen := addrs[0]
kv.AssertKeyAtLeastLength(addrs, int(valDstAddrLen)+2)
valDstAddr := addrs[1 : valDstAddrLen+1]
delAddrLen := addrs[valDstAddrLen+1]
kv.AssertKeyAtLeastLength(addrs, int(valDstAddrLen)+int(delAddrLen)+3)
delAddr := addrs[valDstAddrLen+2 : valDstAddrLen+2+delAddrLen]
kv.AssertKeyAtLeastLength(addrs, int(valDstAddrLen)+int(delAddrLen)+4)
valSrcAddr := addrs[valDstAddrLen+delAddrLen+3:]

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 {
Expand All @@ -294,15 +259,3 @@ func GetRedelegationTimeKey(timestamp time.Time) []byte {
func GetREDsKey(delAddr sdk.AccAddress) []byte {
return append(RedelegationKey, address.MustLengthPrefix(delAddr)...)
}

// GetREDsToValDstIndexKey returns a key prefix for indexing a redelegation to a
// destination (target) validator.
func GetREDsToValDstIndexKey(valDstAddr sdk.ValAddress) []byte {
return append(RedelegationByValDstIndexKey, address.MustLengthPrefix(valDstAddr)...)
}

// GetREDsByDelToValDstIndexKey returns a key prefix for indexing a redelegation
// from an address to a source validator.
func GetREDsByDelToValDstIndexKey(delAddr sdk.AccAddress, valDstAddr sdk.ValAddress) []byte {
return append(GetREDsToValDstIndexKey(valDstAddr), address.MustLengthPrefix(delAddr)...)
}
31 changes: 0 additions & 31 deletions x/staking/types/keys_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,7 @@ import (

var (
keysPK1 = ed25519.GenPrivKeyFromSecret([]byte{1}).PubKey()
keysPK2 = ed25519.GenPrivKeyFromSecret([]byte{2}).PubKey()
keysPK3 = ed25519.GenPrivKeyFromSecret([]byte{3}).PubKey()
keysAddr1 = keysPK1.Address()
keysAddr2 = keysPK2.Address()
keysAddr3 = keysPK3.Address()
)

func TestGetValidatorPowerRank(t *testing.T) {
Expand Down Expand Up @@ -52,33 +48,6 @@ func TestGetValidatorPowerRank(t *testing.T) {
}
}

func TestGetREDByValDstIndexKey(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),
"361463d771218209d8bd03c482f69dfba57310f086091463d771218209d8bd03c482f69dfba57310f086091463d771218209d8bd03c482f69dfba57310f08609",
},
{
sdk.AccAddress(keysAddr1), sdk.ValAddress(keysAddr2), sdk.ValAddress(keysAddr3),
"36143ab62f0d93849be495e21e3e9013a517038f45bd1463d771218209d8bd03c482f69dfba57310f08609145ef3b5f25c54946d4a89fc0d09d2f126614540f2",
},
{
sdk.AccAddress(keysAddr2), sdk.ValAddress(keysAddr1), sdk.ValAddress(keysAddr3),
"36143ab62f0d93849be495e21e3e9013a517038f45bd145ef3b5f25c54946d4a89fc0d09d2f126614540f21463d771218209d8bd03c482f69dfba57310f08609",
},
}
for i, tt := range tests {
got := hex.EncodeToString(types.GetREDByValDstIndexKey(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)
Expand Down
Loading