From cae6b40221979ded236c0fb0bad2859434b0f086 Mon Sep 17 00:00:00 2001 From: Rigel Date: Tue, 3 Jul 2018 19:15:48 -0400 Subject: [PATCH] Merge pull request #1467: staking index keys don't hold values * docs: Explain the expected return type within the store (#1452) * bug somewhere here * ... * ... * fix appending over key * keys cleanup * changelog * remove some junk * address bucky comments - rearrange appends * hard code address length --- CHANGELOG.md | 2 + x/stake/client/cli/query.go | 12 +- x/stake/client/cli/tx.go | 2 +- x/stake/client/rest/query.go | 6 +- x/stake/keeper/delegation.go | 48 ++++---- x/stake/keeper/delegation_test.go | 40 ++++++- x/stake/keeper/key.go | 178 ++++++++++++++++++------------ x/stake/keeper/sdk_types.go | 4 +- x/stake/keeper/validator.go | 8 +- 9 files changed, 190 insertions(+), 110 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ecba0036252c..56bad46c37bf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -36,6 +36,8 @@ BREAKING CHANGES to an infraction, slash them proportional to their stake at the time * Add REST endpoint to unrevoke a validator previously revoked for downtime * Add REST endpoint to retrieve liveness signing information for a validator +* [types] renamed rational.Evaluate to rational.Round{Int64, Int} +* [stake] most index keys nolonger hold a value - inputs are rearranged to form the desired key * [lcd] Switch key creation output to return bech32 FEATURES diff --git a/x/stake/client/cli/query.go b/x/stake/client/cli/query.go index bccfd7c2bee0..5a22f2c41637 100644 --- a/x/stake/client/cli/query.go +++ b/x/stake/client/cli/query.go @@ -122,7 +122,7 @@ func GetCmdQueryDelegation(storeName string, cdc *wire.Codec) *cobra.Command { return err } - key := stake.GetDelegationKey(delAddr, valAddr, cdc) + key := stake.GetDelegationKey(delAddr, valAddr) ctx := context.NewCoreContextFromViper() res, err := ctx.QueryStore(key, storeName) if err != nil { @@ -169,7 +169,7 @@ func GetCmdQueryDelegations(storeName string, cdc *wire.Codec) *cobra.Command { if err != nil { return err } - key := stake.GetDelegationsKey(delegatorAddr, cdc) + key := stake.GetDelegationsKey(delegatorAddr) ctx := context.NewCoreContextFromViper() resKVs, err := ctx.QuerySubspace(cdc, key, storeName) if err != nil { @@ -214,7 +214,7 @@ func GetCmdQueryUnbondingDelegation(storeName string, cdc *wire.Codec) *cobra.Co return err } - key := stake.GetUBDKey(delAddr, valAddr, cdc) + key := stake.GetUBDKey(delAddr, valAddr) ctx := context.NewCoreContextFromViper() res, err := ctx.QueryStore(key, storeName) if err != nil { @@ -261,7 +261,7 @@ func GetCmdQueryUnbondingDelegations(storeName string, cdc *wire.Codec) *cobra.C if err != nil { return err } - key := stake.GetUBDsKey(delegatorAddr, cdc) + key := stake.GetUBDsKey(delegatorAddr) ctx := context.NewCoreContextFromViper() resKVs, err := ctx.QuerySubspace(cdc, key, storeName) if err != nil { @@ -309,7 +309,7 @@ func GetCmdQueryRedelegation(storeName string, cdc *wire.Codec) *cobra.Command { return err } - key := stake.GetREDKey(delAddr, valSrcAddr, valDstAddr, cdc) + key := stake.GetREDKey(delAddr, valSrcAddr, valDstAddr) ctx := context.NewCoreContextFromViper() res, err := ctx.QueryStore(key, storeName) if err != nil { @@ -356,7 +356,7 @@ func GetCmdQueryRedelegations(storeName string, cdc *wire.Codec) *cobra.Command if err != nil { return err } - key := stake.GetREDsKey(delegatorAddr, cdc) + key := stake.GetREDsKey(delegatorAddr) ctx := context.NewCoreContextFromViper() resKVs, err := ctx.QuerySubspace(cdc, key, storeName) if err != nil { diff --git a/x/stake/client/cli/tx.go b/x/stake/client/cli/tx.go index dff765fac7c1..7200caef3f21 100644 --- a/x/stake/client/cli/tx.go +++ b/x/stake/client/cli/tx.go @@ -240,7 +240,7 @@ func getShares(storeName string, cdc *wire.Codec, sharesAmountStr, sharesPercent } // make a query to get the existing delegation shares - key := stake.GetDelegationKey(delegatorAddr, validatorAddr, cdc) + key := stake.GetDelegationKey(delegatorAddr, validatorAddr) ctx := context.NewCoreContextFromViper() resQuery, err := ctx.QueryStore(key, storeName) if err != nil { diff --git a/x/stake/client/rest/query.go b/x/stake/client/rest/query.go index afa9e3bf0c12..12ef882e5e40 100644 --- a/x/stake/client/rest/query.go +++ b/x/stake/client/rest/query.go @@ -60,7 +60,7 @@ func delegationHandlerFn(ctx context.CoreContext, cdc *wire.Codec) http.HandlerF return } - key := stake.GetDelegationKey(delegatorAddr, validatorAddr, cdc) + key := stake.GetDelegationKey(delegatorAddr, validatorAddr) res, err := ctx.QueryStore(key, storeName) if err != nil { @@ -117,7 +117,7 @@ func ubdHandlerFn(ctx context.CoreContext, cdc *wire.Codec) http.HandlerFunc { return } - key := stake.GetUBDKey(delegatorAddr, validatorAddr, cdc) + key := stake.GetUBDKey(delegatorAddr, validatorAddr) res, err := ctx.QueryStore(key, storeName) if err != nil { @@ -182,7 +182,7 @@ func redHandlerFn(ctx context.CoreContext, cdc *wire.Codec) http.HandlerFunc { return } - key := stake.GetREDKey(delegatorAddr, validatorSrcAddr, validatorDstAddr, cdc) + key := stake.GetREDKey(delegatorAddr, validatorSrcAddr, validatorDstAddr) res, err := ctx.QueryStore(key, storeName) if err != nil { diff --git a/x/stake/keeper/delegation.go b/x/stake/keeper/delegation.go index 514939e17f5e..bb8170a6a3b7 100644 --- a/x/stake/keeper/delegation.go +++ b/x/stake/keeper/delegation.go @@ -12,7 +12,7 @@ func (k Keeper) GetDelegation(ctx sdk.Context, delegatorAddr, validatorAddr sdk.Address) (delegation types.Delegation, found bool) { store := ctx.KVStore(k.storeKey) - delegatorBytes := store.Get(GetDelegationKey(delegatorAddr, validatorAddr, k.cdc)) + delegatorBytes := store.Get(GetDelegationKey(delegatorAddr, validatorAddr)) if delegatorBytes == nil { return delegation, false } @@ -46,7 +46,7 @@ func (k Keeper) GetDelegations(ctx sdk.Context, delegator sdk.Address, maxRetrieve int16) (delegations []types.Delegation) { store := ctx.KVStore(k.storeKey) - delegatorPrefixKey := GetDelegationsKey(delegator, k.cdc) + delegatorPrefixKey := GetDelegationsKey(delegator) iterator := sdk.KVStorePrefixIterator(store, delegatorPrefixKey) //smallest to largest delegations = make([]types.Delegation, maxRetrieve) @@ -69,13 +69,13 @@ func (k Keeper) GetDelegations(ctx sdk.Context, delegator sdk.Address, func (k Keeper) SetDelegation(ctx sdk.Context, delegation types.Delegation) { store := ctx.KVStore(k.storeKey) b := k.cdc.MustMarshalBinary(delegation) - store.Set(GetDelegationKey(delegation.DelegatorAddr, delegation.ValidatorAddr, k.cdc), b) + store.Set(GetDelegationKey(delegation.DelegatorAddr, delegation.ValidatorAddr), b) } // remove the delegation func (k Keeper) RemoveDelegation(ctx sdk.Context, delegation types.Delegation) { store := ctx.KVStore(k.storeKey) - store.Delete(GetDelegationKey(delegation.DelegatorAddr, delegation.ValidatorAddr, k.cdc)) + store.Delete(GetDelegationKey(delegation.DelegatorAddr, delegation.ValidatorAddr)) } //_____________________________________________________________________________________ @@ -85,7 +85,7 @@ func (k Keeper) GetUnbondingDelegation(ctx sdk.Context, DelegatorAddr, ValidatorAddr sdk.Address) (ubd types.UnbondingDelegation, found bool) { store := ctx.KVStore(k.storeKey) - ubdKey := GetUBDKey(DelegatorAddr, ValidatorAddr, k.cdc) + ubdKey := GetUBDKey(DelegatorAddr, ValidatorAddr) bz := store.Get(ubdKey) if bz == nil { return ubd, false @@ -98,13 +98,12 @@ func (k Keeper) GetUnbondingDelegation(ctx sdk.Context, // load all unbonding delegations from a particular validator func (k Keeper) GetUnbondingDelegationsFromValidator(ctx sdk.Context, valAddr sdk.Address) (unbondingDelegations []types.UnbondingDelegation) { store := ctx.KVStore(k.storeKey) - iterator := sdk.KVStorePrefixIterator(store, GetUBDsByValIndexKey(valAddr, k.cdc)) - i := 0 - for ; ; i++ { + iterator := sdk.KVStorePrefixIterator(store, GetUBDsByValIndexKey(valAddr)) + for { if !iterator.Valid() { break } - unbondingKey := iterator.Value() + unbondingKey := GetUBDKeyFromValIndexKey(iterator.Key()) unbondingBytes := store.Get(unbondingKey) var unbondingDelegation types.UnbondingDelegation k.cdc.MustUnmarshalBinary(unbondingBytes, &unbondingDelegation) @@ -119,17 +118,17 @@ func (k Keeper) GetUnbondingDelegationsFromValidator(ctx sdk.Context, valAddr sd func (k Keeper) SetUnbondingDelegation(ctx sdk.Context, ubd types.UnbondingDelegation) { store := ctx.KVStore(k.storeKey) bz := k.cdc.MustMarshalBinary(ubd) - ubdKey := GetUBDKey(ubd.DelegatorAddr, ubd.ValidatorAddr, k.cdc) + ubdKey := GetUBDKey(ubd.DelegatorAddr, ubd.ValidatorAddr) store.Set(ubdKey, bz) - store.Set(GetUBDByValIndexKey(ubd.DelegatorAddr, ubd.ValidatorAddr, k.cdc), ubdKey) + store.Set(GetUBDByValIndexKey(ubd.DelegatorAddr, ubd.ValidatorAddr), []byte{}) } // remove the unbonding delegation object and associated index func (k Keeper) RemoveUnbondingDelegation(ctx sdk.Context, ubd types.UnbondingDelegation) { store := ctx.KVStore(k.storeKey) - ubdKey := GetUBDKey(ubd.DelegatorAddr, ubd.ValidatorAddr, k.cdc) + ubdKey := GetUBDKey(ubd.DelegatorAddr, ubd.ValidatorAddr) store.Delete(ubdKey) - store.Delete(GetUBDByValIndexKey(ubd.DelegatorAddr, ubd.ValidatorAddr, k.cdc)) + store.Delete(GetUBDByValIndexKey(ubd.DelegatorAddr, ubd.ValidatorAddr)) } //_____________________________________________________________________________________ @@ -139,7 +138,7 @@ func (k Keeper) GetRedelegation(ctx sdk.Context, DelegatorAddr, ValidatorSrcAddr, ValidatorDstAddr sdk.Address) (red types.Redelegation, found bool) { store := ctx.KVStore(k.storeKey) - redKey := GetREDKey(DelegatorAddr, ValidatorSrcAddr, ValidatorDstAddr, k.cdc) + redKey := GetREDKey(DelegatorAddr, ValidatorSrcAddr, ValidatorDstAddr) bz := store.Get(redKey) if bz == nil { return red, false @@ -152,13 +151,12 @@ func (k Keeper) GetRedelegation(ctx sdk.Context, // load all redelegations from a particular validator func (k Keeper) GetRedelegationsFromValidator(ctx sdk.Context, valAddr sdk.Address) (redelegations []types.Redelegation) { store := ctx.KVStore(k.storeKey) - iterator := sdk.KVStorePrefixIterator(store, GetREDsFromValSrcIndexKey(valAddr, k.cdc)) - i := 0 - for ; ; i++ { + iterator := sdk.KVStorePrefixIterator(store, GetREDsFromValSrcIndexKey(valAddr)) + for { if !iterator.Valid() { break } - redelegationKey := iterator.Value() + redelegationKey := GetREDKeyFromValSrcIndexKey(iterator.Key()) redelegationBytes := store.Get(redelegationKey) var redelegation types.Redelegation k.cdc.MustUnmarshalBinary(redelegationBytes, &redelegation) @@ -174,7 +172,7 @@ func (k Keeper) HasReceivingRedelegation(ctx sdk.Context, DelegatorAddr, ValidatorDstAddr sdk.Address) bool { store := ctx.KVStore(k.storeKey) - prefix := GetREDsByDelToValDstIndexKey(DelegatorAddr, ValidatorDstAddr, k.cdc) + prefix := GetREDsByDelToValDstIndexKey(DelegatorAddr, ValidatorDstAddr) iterator := sdk.KVStorePrefixIterator(store, prefix) //smallest to largest found := false @@ -190,19 +188,19 @@ func (k Keeper) HasReceivingRedelegation(ctx sdk.Context, func (k Keeper) SetRedelegation(ctx sdk.Context, red types.Redelegation) { store := ctx.KVStore(k.storeKey) bz := k.cdc.MustMarshalBinary(red) - redKey := GetREDKey(red.DelegatorAddr, red.ValidatorSrcAddr, red.ValidatorDstAddr, k.cdc) + redKey := GetREDKey(red.DelegatorAddr, red.ValidatorSrcAddr, red.ValidatorDstAddr) store.Set(redKey, bz) - store.Set(GetREDByValSrcIndexKey(red.DelegatorAddr, red.ValidatorSrcAddr, red.ValidatorDstAddr, k.cdc), redKey) - store.Set(GetREDByValDstIndexKey(red.DelegatorAddr, red.ValidatorSrcAddr, red.ValidatorDstAddr, k.cdc), redKey) + store.Set(GetREDByValSrcIndexKey(red.DelegatorAddr, red.ValidatorSrcAddr, red.ValidatorDstAddr), []byte{}) + store.Set(GetREDByValDstIndexKey(red.DelegatorAddr, red.ValidatorSrcAddr, red.ValidatorDstAddr), []byte{}) } // remove a redelegation object and associated index func (k Keeper) RemoveRedelegation(ctx sdk.Context, red types.Redelegation) { store := ctx.KVStore(k.storeKey) - redKey := GetREDKey(red.DelegatorAddr, red.ValidatorSrcAddr, red.ValidatorDstAddr, k.cdc) + redKey := GetREDKey(red.DelegatorAddr, red.ValidatorSrcAddr, red.ValidatorDstAddr) store.Delete(redKey) - store.Delete(GetREDByValSrcIndexKey(red.DelegatorAddr, red.ValidatorSrcAddr, red.ValidatorDstAddr, k.cdc)) - store.Delete(GetREDByValDstIndexKey(red.DelegatorAddr, red.ValidatorSrcAddr, red.ValidatorDstAddr, k.cdc)) + store.Delete(GetREDByValSrcIndexKey(red.DelegatorAddr, red.ValidatorSrcAddr, red.ValidatorDstAddr)) + store.Delete(GetREDByValDstIndexKey(red.DelegatorAddr, red.ValidatorSrcAddr, red.ValidatorDstAddr)) } //_____________________________________________________________________________________ diff --git a/x/stake/keeper/delegation_test.go b/x/stake/keeper/delegation_test.go index eb318df4d32d..c0a3ee8c5786 100644 --- a/x/stake/keeper/delegation_test.go +++ b/x/stake/keeper/delegation_test.go @@ -179,6 +179,36 @@ func TestUnbondDelegation(t *testing.T) { require.Equal(t, int64(4), pool.BondedTokens) } +// Make sure that that the retrieving the delegations doesn't affect the state +func TestGetRedelegationsFromValidator(t *testing.T) { + ctx, _, keeper := CreateTestInput(t, false, 0) + + rd := types.Redelegation{ + DelegatorAddr: addrDels[0], + ValidatorSrcAddr: addrVals[0], + ValidatorDstAddr: addrVals[1], + CreationHeight: 0, + MinTime: 0, + SharesSrc: sdk.NewRat(5), + SharesDst: sdk.NewRat(5), + } + + // set and retrieve a record + keeper.SetRedelegation(ctx, rd) + resBond, found := keeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1]) + require.True(t, found) + + // get the redelegations one time + redelegations := keeper.GetRedelegationsFromValidator(ctx, addrVals[0]) + require.Equal(t, 1, len(redelegations)) + require.True(t, redelegations[0].Equal(resBond)) + + // get the redelegations a second time, should be exactly the same + redelegations = keeper.GetRedelegationsFromValidator(ctx, addrVals[0]) + require.Equal(t, 1, len(redelegations)) + require.True(t, redelegations[0].Equal(resBond)) +} + // tests Get/Set/Remove/Has UnbondingDelegation func TestRedelegation(t *testing.T) { ctx, _, keeper := CreateTestInput(t, false, 0) @@ -201,7 +231,10 @@ func TestRedelegation(t *testing.T) { keeper.SetRedelegation(ctx, rd) resBond, found := keeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1]) require.True(t, found) - require.True(t, rd.Equal(resBond)) + + redelegations := keeper.GetRedelegationsFromValidator(ctx, addrVals[0]) + require.Equal(t, 1, len(redelegations)) + require.True(t, redelegations[0].Equal(resBond)) // check if has the redelegation has = keeper.HasReceivingRedelegation(ctx, addrDels[0], addrVals[1]) @@ -211,10 +244,15 @@ func TestRedelegation(t *testing.T) { rd.SharesSrc = sdk.NewRat(21) rd.SharesDst = sdk.NewRat(21) keeper.SetRedelegation(ctx, rd) + resBond, found = keeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1]) require.True(t, found) require.True(t, rd.Equal(resBond)) + redelegations = keeper.GetRedelegationsFromValidator(ctx, addrVals[0]) + require.Equal(t, 1, len(redelegations)) + require.True(t, redelegations[0].Equal(resBond)) + // delete a record keeper.RemoveRedelegation(ctx, rd) _, found = keeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1]) diff --git a/x/stake/keeper/key.go b/x/stake/keeper/key.go index 667f5f681ec0..cfe8ded82b04 100644 --- a/x/stake/keeper/key.go +++ b/x/stake/keeper/key.go @@ -6,7 +6,6 @@ import ( "github.com/tendermint/tendermint/crypto" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/wire" "github.com/cosmos/cosmos-sdk/x/stake/types" ) @@ -29,41 +28,49 @@ var ( UnbondingDelegationKey = []byte{0x0B} // key for an unbonding-delegation UnbondingDelegationByValIndexKey = []byte{0x0C} // prefix for each key for an unbonding-delegation, by validator owner RedelegationKey = []byte{0x0D} // key for a redelegation - RedelegationByValSrcIndexKey = []byte{0x0E} // prefix for each key for an redelegation, by validator owner - RedelegationByValDstIndexKey = []byte{0x0F} // prefix for each key for an redelegation, by validator owner + RedelegationByValSrcIndexKey = []byte{0x0E} // prefix for each key for an redelegation, by source validator owner + RedelegationByValDstIndexKey = []byte{0x0F} // prefix for each key for an redelegation, by destination validator owner ) const maxDigitsForAccount = 12 // ~220,000,000 atoms created at launch -// get the key for the validator with address +// get the key for the validator with address. +// VALUE: stake/types.Validator func GetValidatorKey(ownerAddr sdk.Address) []byte { return append(ValidatorsKey, ownerAddr.Bytes()...) } -// get the key for the validator with pubkey +// get the key for the validator with pubkey. +// VALUE: validator owner address ([]byte) func GetValidatorByPubKeyIndexKey(pubkey crypto.PubKey) []byte { return append(ValidatorsByPubKeyIndexKey, pubkey.Bytes()...) } -// get the key for the current validator group, ordered like tendermint +// get the key for the current validator group +// VALUE: none (key rearrangement with GetValKeyFromValBondedIndexKey) func GetValidatorsBondedIndexKey(ownerAddr sdk.Address) []byte { return append(ValidatorsBondedIndexKey, ownerAddr.Bytes()...) } -// get the power which is the key for the validator used in the power-store -func GetValidatorsByPowerIndexKey(validator types.Validator, pool types.Pool) []byte { +// Get the validator owner address from ValBondedIndexKey +func GetAddressFromValBondedIndexKey(IndexKey []byte) []byte { + return IndexKey[1:] // remove prefix bytes +} +// get the validator by power index. power index is the key used in the power-store, +// and represents the relative power ranking of the validator. +// VALUE: validator owner address ([]byte) +func GetValidatorsByPowerIndexKey(validator types.Validator, pool types.Pool) []byte { // NOTE the address doesn't need to be stored because counter bytes must always be different - return GetValidatorPowerRank(validator, pool) + return getValidatorPowerRank(validator, pool) } -// get the power of a validator -func GetValidatorPowerRank(validator types.Validator, pool types.Pool) []byte { +// get the power ranking of a validator +func getValidatorPowerRank(validator types.Validator, pool types.Pool) []byte { power := validator.EquivalentBondedShares(pool) powerBytes := []byte(power.ToLeftPadded(maxDigitsForAccount)) // power big-endian (more powerful validators first) - // TODO ensure that the key will be a readable string.. probably should add seperators and have revokedBytes := make([]byte, 1) if validator.Revoked { revokedBytes[0] = byte(0x01) @@ -71,127 +78,162 @@ func GetValidatorPowerRank(validator types.Validator, pool types.Pool) []byte { revokedBytes[0] = byte(0x00) } - // TODO ensure that the key will be a readable string.. probably should add seperators and have // heightBytes and counterBytes represent strings like powerBytes does heightBytes := make([]byte, binary.MaxVarintLen64) binary.BigEndian.PutUint64(heightBytes, ^uint64(validator.BondHeight)) // invert height (older validators first) counterBytes := make([]byte, 2) binary.BigEndian.PutUint16(counterBytes, ^uint16(validator.BondIntraTxCounter)) // invert counter (first txns have priority) - return append(ValidatorsByPowerIndexKey, - append(revokedBytes, - append(powerBytes, - append(heightBytes, counterBytes...)...)...)...) + return append(append(append(append( + ValidatorsByPowerIndexKey, + revokedBytes...), + powerBytes...), + heightBytes...), + counterBytes...) } -// get the key for the accumulated update validators +// get the key for the accumulated update validators. +// VALUE: abci.Validator +// note records using these keys should never persist between blocks func GetTendermintUpdatesKey(ownerAddr sdk.Address) []byte { return append(TendermintUpdatesKey, ownerAddr.Bytes()...) } //________________________________________________________________________________ -// get the key for delegator bond with validator -func GetDelegationKey(delegatorAddr, validatorAddr sdk.Address, cdc *wire.Codec) []byte { - return append(GetDelegationsKey(delegatorAddr, cdc), validatorAddr.Bytes()...) +// get the key for delegator bond with validator. +// VALUE: stake/types.Delegation +func GetDelegationKey(delegatorAddr, validatorAddr sdk.Address) []byte { + return append(GetDelegationsKey(delegatorAddr), validatorAddr.Bytes()...) } // get the prefix for a delegator for all validators -func GetDelegationsKey(delegatorAddr sdk.Address, cdc *wire.Codec) []byte { - res := cdc.MustMarshalBinary(&delegatorAddr) - return append(DelegationKey, res...) +func GetDelegationsKey(delegatorAddr sdk.Address) []byte { + return append(DelegationKey, delegatorAddr.Bytes()...) } //________________________________________________________________________________ -// get the key for an unbonding delegation -func GetUBDKey(delegatorAddr, validatorAddr sdk.Address, cdc *wire.Codec) []byte { - return append(GetUBDsKey(delegatorAddr, cdc), validatorAddr.Bytes()...) +// get the key for an unbonding delegation by delegator and validator addr. +// VALUE: stake/types.UnbondingDelegation +func GetUBDKey(delegatorAddr, validatorAddr sdk.Address) []byte { + return append( + GetUBDsKey(delegatorAddr.Bytes()), + validatorAddr.Bytes()...) } // get the index-key for an unbonding delegation, stored by validator-index -func GetUBDByValIndexKey(delegatorAddr, validatorAddr sdk.Address, cdc *wire.Codec) []byte { - return append(GetUBDsByValIndexKey(validatorAddr, cdc), delegatorAddr.Bytes()...) +// VALUE: none (key rearrangement used) +func GetUBDByValIndexKey(delegatorAddr, validatorAddr sdk.Address) []byte { + return append(GetUBDsByValIndexKey(validatorAddr), delegatorAddr.Bytes()...) +} + +// rearrange the ValIndexKey to get the UBDKey +func GetUBDKeyFromValIndexKey(IndexKey []byte) []byte { + addrs := IndexKey[1:] // remove prefix bytes + if len(addrs) != 40 { + panic("unexpected key length") + } + valAddr := addrs[:20] + delAddr := addrs[20:] + return GetUBDKey(delAddr, valAddr) } //______________ // get the prefix for all unbonding delegations from a delegator -func GetUBDsKey(delegatorAddr sdk.Address, cdc *wire.Codec) []byte { - res := cdc.MustMarshalBinary(&delegatorAddr) - return append(UnbondingDelegationKey, res...) +func GetUBDsKey(delegatorAddr sdk.Address) []byte { + return append(UnbondingDelegationKey, delegatorAddr.Bytes()...) } -// get the prefix keyspace for the indexs of unbonding delegations for a validator -func GetUBDsByValIndexKey(validatorAddr sdk.Address, cdc *wire.Codec) []byte { - res := cdc.MustMarshalBinary(&validatorAddr) - return append(UnbondingDelegationByValIndexKey, res...) +// get the prefix keyspace for the indexes of unbonding delegations for a validator +func GetUBDsByValIndexKey(validatorAddr sdk.Address) []byte { + return append(UnbondingDelegationByValIndexKey, validatorAddr.Bytes()...) } //________________________________________________________________________________ // get the key for a redelegation +// VALUE: stake/types.RedelegationKey func GetREDKey(delegatorAddr, validatorSrcAddr, - validatorDstAddr sdk.Address, cdc *wire.Codec) []byte { + validatorDstAddr sdk.Address) []byte { - return append( - GetREDsKey(delegatorAddr, cdc), - append( - validatorSrcAddr.Bytes(), - validatorDstAddr.Bytes()...)..., - ) + return append(append( + GetREDsKey(delegatorAddr.Bytes()), + validatorSrcAddr.Bytes()...), + validatorDstAddr.Bytes()...) } // get the index-key for a redelegation, stored by source-validator-index +// VALUE: none (key rearrangement used) func GetREDByValSrcIndexKey(delegatorAddr, validatorSrcAddr, - validatorDstAddr sdk.Address, cdc *wire.Codec) []byte { + validatorDstAddr sdk.Address) []byte { - return append( - GetREDsFromValSrcIndexKey(validatorSrcAddr, cdc), - append( - delegatorAddr.Bytes(), - validatorDstAddr.Bytes()...)..., - ) + return append(append( + GetREDsFromValSrcIndexKey(validatorSrcAddr), + delegatorAddr.Bytes()...), + validatorDstAddr.Bytes()...) } // get the index-key for a redelegation, stored by destination-validator-index +// VALUE: none (key rearrangement used) func GetREDByValDstIndexKey(delegatorAddr, validatorSrcAddr, - validatorDstAddr sdk.Address, cdc *wire.Codec) []byte { + validatorDstAddr sdk.Address) []byte { - return append( - GetREDsToValDstIndexKey(validatorDstAddr, cdc), - append( - delegatorAddr.Bytes(), - validatorSrcAddr.Bytes()...)..., - ) + return append(append( + GetREDsToValDstIndexKey(validatorDstAddr), + delegatorAddr.Bytes()...), + validatorSrcAddr.Bytes()...) +} + +// rearrange the ValSrcIndexKey to get the REDKey +func GetREDKeyFromValSrcIndexKey(IndexKey []byte) []byte { + addrs := IndexKey[1:] // remove prefix bytes + if len(addrs) != 60 { + panic("unexpected key length") + } + valSrcAddr := addrs[:20] + delAddr := addrs[20:40] + valDstAddr := addrs[40:] + + return GetREDKey(delAddr, valSrcAddr, valDstAddr) +} + +// rearrange the ValDstIndexKey to get the REDKey +func GetREDKeyFromValDstIndexKey(IndexKey []byte) []byte { + addrs := IndexKey[1:] // remove prefix bytes + if len(addrs) != 60 { + panic("unexpected key length") + } + valDstAddr := addrs[:20] + delAddr := addrs[20:40] + valSrcAddr := addrs[40:] + return GetREDKey(delAddr, valSrcAddr, valDstAddr) } //______________ // get the prefix keyspace for redelegations from a delegator -func GetREDsKey(delegatorAddr sdk.Address, cdc *wire.Codec) []byte { - res := cdc.MustMarshalBinary(&delegatorAddr) - return append(RedelegationKey, res...) +func GetREDsKey(delegatorAddr sdk.Address) []byte { + return append(RedelegationKey, delegatorAddr.Bytes()...) } // get the prefix keyspace for all redelegations redelegating away from a source validator -func GetREDsFromValSrcIndexKey(validatorSrcAddr sdk.Address, cdc *wire.Codec) []byte { - res := cdc.MustMarshalBinary(&validatorSrcAddr) - return append(RedelegationByValSrcIndexKey, res...) +func GetREDsFromValSrcIndexKey(validatorSrcAddr sdk.Address) []byte { + return append(RedelegationByValSrcIndexKey, validatorSrcAddr.Bytes()...) } // get the prefix keyspace for all redelegations redelegating towards a destination validator -func GetREDsToValDstIndexKey(validatorDstAddr sdk.Address, cdc *wire.Codec) []byte { - res := cdc.MustMarshalBinary(&validatorDstAddr) - return append(RedelegationByValDstIndexKey, res...) +func GetREDsToValDstIndexKey(validatorDstAddr sdk.Address) []byte { + return append(RedelegationByValDstIndexKey, validatorDstAddr.Bytes()...) } // get the prefix keyspace for all redelegations redelegating towards a destination validator // from a particular delegator func GetREDsByDelToValDstIndexKey(delegatorAddr sdk.Address, - validatorDstAddr sdk.Address, cdc *wire.Codec) []byte { + validatorDstAddr sdk.Address) []byte { return append( - GetREDsToValDstIndexKey(validatorDstAddr, cdc), + GetREDsToValDstIndexKey(validatorDstAddr), delegatorAddr.Bytes()...) } diff --git a/x/stake/keeper/sdk_types.go b/x/stake/keeper/sdk_types.go index 55ad658a2def..bedbc15591e8 100644 --- a/x/stake/keeper/sdk_types.go +++ b/x/stake/keeper/sdk_types.go @@ -34,7 +34,7 @@ func (k Keeper) IterateValidatorsBonded(ctx sdk.Context, fn func(index int64, va iterator := sdk.KVStorePrefixIterator(store, ValidatorsBondedIndexKey) i := int64(0) for ; iterator.Valid(); iterator.Next() { - address := iterator.Value() + address := GetAddressFromValBondedIndexKey(iterator.Key()) validator, found := k.GetValidator(ctx, address) if !found { panic(fmt.Sprintf("validator record not found for address: %v\n", address)) @@ -87,7 +87,7 @@ func (k Keeper) Delegation(ctx sdk.Context, addrDel sdk.Address, addrVal sdk.Add // iterate through the active validator set and perform the provided function func (k Keeper) IterateDelegations(ctx sdk.Context, delAddr sdk.Address, fn func(index int64, delegation sdk.Delegation) (stop bool)) { store := ctx.KVStore(k.storeKey) - key := GetDelegationsKey(delAddr, k.cdc) + key := GetDelegationsKey(delAddr) iterator := sdk.KVStorePrefixIterator(store, key) i := int64(0) for ; iterator.Valid(); iterator.Next() { diff --git a/x/stake/keeper/validator.go b/x/stake/keeper/validator.go index 0d556f7dc4bb..c2711788bebb 100644 --- a/x/stake/keeper/validator.go +++ b/x/stake/keeper/validator.go @@ -56,7 +56,7 @@ func (k Keeper) SetValidatorByPowerIndex(ctx sdk.Context, validator types.Valida // validator index func (k Keeper) SetValidatorBondedIndex(ctx sdk.Context, validator types.Validator) { store := ctx.KVStore(k.storeKey) - store.Set(GetValidatorsBondedIndexKey(validator.Owner), validator.Owner) + store.Set(GetValidatorsBondedIndexKey(validator.Owner), []byte{}) } // used in testing @@ -124,7 +124,7 @@ func (k Keeper) GetValidatorsBonded(ctx sdk.Context) (validators []types.Validat if i > int(maxValidators-1) { panic("maxValidators is less than the number of records in ValidatorsBonded Store, store should have been updated") } - address := iterator.Value() + address := GetAddressFromValBondedIndexKey(iterator.Key()) validator, found := k.GetValidator(ctx, address) if !found { panic(fmt.Sprintf("validator record not found for address: %v\n", address)) @@ -362,7 +362,7 @@ func (k Keeper) UpdateBondedValidatorsFull(ctx sdk.Context) { toKickOut := make(map[string]byte) iterator := sdk.KVStorePrefixIterator(store, ValidatorsBondedIndexKey) for ; iterator.Valid(); iterator.Next() { - ownerAddr := iterator.Value() + ownerAddr := GetAddressFromValBondedIndexKey(iterator.Key()) toKickOut[string(ownerAddr)] = 0 // set anything } iterator.Close() @@ -471,7 +471,7 @@ func (k Keeper) bondValidator(ctx sdk.Context, validator types.Validator) types. // save the now bonded validator record to the three referenced stores bzVal := k.cdc.MustMarshalBinary(validator) store.Set(GetValidatorKey(validator.Owner), bzVal) - store.Set(GetValidatorsBondedIndexKey(validator.Owner), validator.Owner) + store.Set(GetValidatorsBondedIndexKey(validator.Owner), []byte{}) // add to accumulated changes for tendermint bzABCI := k.cdc.MustMarshalBinary(validator.ABCIValidator())