func GetREDsToValDstIndexKey(valDstAddr AccountID) []byte {
	return append(RedelegationByValDstIndexKey, valDstAddr.StoreKey()...)
}
gets the prefix keyspace for all redelegations redelegating towards a destination validator
package types
import (
	"encoding/binary"
	"strconv"
	"time"
	chainTypes "github.com/KuChainNetwork/kuchain/chain/types"
	stakingexport "github.com/KuChainNetwork/kuchain/x/staking/exported"
	sdk "github.com/cosmos/cosmos-sdk/types"
)
const (
	ModuleName = "kustaking"
	StoreKey = ModuleName
	TStoreKey = "transient_" + ModuleName
	QuerierRoute = ModuleName
	RouterKey = ModuleName
)
var (
	ModuleAccountName = chainTypes.MustName(ModuleName)
	ModuleAccountID   = chainTypes.NewAccountIDFromName(ModuleAccountName)
)
var (
	LastValidatorPowerKey = []byte{0x11}  
	LastTotalPowerKey     = []byte{0x12}  
	ValidatorsKey             = []byte{0x21}  
	ValidatorsByConsAddrKey   = []byte{0x22}  
	ValidatorsByPowerIndexKey = []byte{0x23}  
	DelegationKey                    = []byte{0x31}  
	UnbondingDelegationKey           = []byte{0x32}  
	UnbondingDelegationByValIndexKey = []byte{0x33}  
	RedelegationKey                  = []byte{0x34}  
	RedelegationByValSrcIndexKey     = []byte{0x35}  
	RedelegationByValDstIndexKey     = []byte{0x36}  
	UnbondingQueueKey    = []byte{0x41}  
	RedelegationQueueKey = []byte{0x42}  
	ValidatorQueueKey    = []byte{0x43}  
	HistoricalInfoKey = []byte{0x50}  
)
const (
	AccountIDlen = sdk.AddrLen + 1
)
func GetValidatorKey(operatorAddr AccountID) []byte {
	return append(ValidatorsKey, operatorAddr.StoreKey()...)
}
func GetValidatorByConsAddrKey(addr sdk.ConsAddress) []byte {
	return append(ValidatorsByConsAddrKey, addr.Bytes()...)
}
func AddressFromLastValidatorPowerKey(key []byte) []byte {
	return key[1:]  
}
func GetValidatorsByPowerIndexKey(validator Validator) []byte {
	return getValidatorPowerRank(validator)
}
func GetLastValidatorPowerKey(operator AccountID) []byte {
	return append(LastValidatorPowerKey, operator.StoreKey()...)
}
func getValidatorPowerRank(validator Validator) []byte {
	consensusPower := stakingexport.TokensToConsensusPower(validator.Tokens)
	consensusPowerBytes := make([]byte, 8)
	binary.BigEndian.PutUint64(consensusPowerBytes, uint64(consensusPower))
	powerBytes := consensusPowerBytes
	powerBytesLen := len(powerBytes)  
	key := make([]byte, 1+powerBytesLen+AccIDStoreKeyLen)
	key[0] = ValidatorsByPowerIndexKey[0]
	copy(key[1:powerBytesLen+1], powerBytes)
	operAddrInvr := sdk.CopyBytes(validator.OperatorAccount.StoreKey())
	for i, b := range operAddrInvr {
		operAddrInvr[i] = ^b
	}
	copy(key[powerBytesLen+1:], operAddrInvr)
	return key
}
func ParseValidatorPowerRankKey(key []byte) (operAddr []byte) {
	powerBytesLen := 8
	if len(key) != 1+powerBytesLen+AccIDStoreKeyLen {
		panic("Invalid validator power rank key length")
	}
	operAddr = sdk.CopyBytes(key[powerBytesLen+1:])
	for i, b := range operAddr {
		operAddr[i] = ^b
	}
	return operAddr
}
func GetValidatorQueueTimeKey(timestamp time.Time) []byte {
	bz := sdk.FormatTimeBytes(timestamp)
	return append(ValidatorQueueKey, bz...)
}
func GetDelegationKey(delAddr AccountID, valAddr AccountID) []byte {
	return append(GetDelegationsKey(delAddr), valAddr.StoreKey()...)
}
func GetDelegationsKey(delAddr AccountID) []byte {
	return append(DelegationKey, delAddr.StoreKey()...)
}
func GetUBDKey(delAddr []byte, valAddr []byte) []byte {
	return append(
		GetUBDsKey(delAddr),
		valAddr...)
}
func GetUBDByValIndexKey(delAddr AccountID, valAddr AccountID) []byte {
	return append(GetUBDsByValIndexKey(valAddr), delAddr.StoreKey()...)
}
func GetUBDKeyFromValIndexKey(indexKey []byte) []byte {
	addrs := indexKey[1:]  
	if len(addrs) != 2*AccIDStoreKeyLen {
		panic("unexpected key length")
	}
	valAddr := addrs[:AccIDStoreKeyLen]
	delAddr := addrs[AccIDStoreKeyLen:]
	return GetUBDByValIndexKey(NewAccountIDFromByte(delAddr), NewAccountIDFromByte(valAddr))
}
func GetUBDsKey(delAddr []byte) []byte {
	return append(UnbondingDelegationKey, delAddr...)
}
func GetUBDsByValIndexKey(valAddr AccountID) []byte {
	return append(UnbondingDelegationByValIndexKey, valAddr.StoreKey()...)
}
func GetUnbondingDelegationTimeKey(timestamp time.Time) []byte {
	bz := sdk.FormatTimeBytes(timestamp)
	return append(UnbondingQueueKey, bz...)
}
func GetREDKey(delAddr []byte, valSrcAddr, valDstAddr []byte) []byte {
	key := make([]byte, 1+AccIDStoreKeyLen*3)
	copy(key[0:AccIDStoreKeyLen+1], GetREDsKey(delAddr))
	copy(key[AccIDStoreKeyLen+1:2*AccIDStoreKeyLen+1], valSrcAddr)
	copy(key[2*AccIDStoreKeyLen+1:3*AccIDStoreKeyLen+1], valDstAddr)
	return key
}
func GetREDByValSrcIndexKey(delAddr []byte, valSrcAddr, valDstAddr []byte) []byte {
	REDSFromValsSrcKey := GetREDsFromValSrcIndexKey(valSrcAddr)
	offset := len(REDSFromValsSrcKey)
	key := make([]byte, len(REDSFromValsSrcKey)+2*AccIDStoreKeyLen)
	copy(key[0:offset], REDSFromValsSrcKey)
	copy(key[offset:offset+AccIDStoreKeyLen], delAddr)
	copy(key[offset+AccIDStoreKeyLen:offset+2*AccIDStoreKeyLen], valDstAddr)
	return key
}
func GetREDByValDstIndexKey(delAddr AccountID, valSrcAddr, valDstAddr AccountID) []byte {
	REDSToValsDstKey := GetREDsToValDstIndexKey(valDstAddr)
	offset := len(REDSToValsDstKey)
	key := make([]byte, len(REDSToValsDstKey)+2*AccIDStoreKeyLen)
	copy(key[0:offset], REDSToValsDstKey)
	copy(key[offset:offset+AccIDStoreKeyLen], delAddr.Value)
	copy(key[offset+AccIDStoreKeyLen:offset+2*AccIDStoreKeyLen], valSrcAddr.Value)
	return key
}
func GetREDKeyFromValSrcIndexKey(indexKey []byte) []byte {
	if len(indexKey) != 3*AccIDStoreKeyLen+1 {
		panic("unexpected key length")
	}
	valSrcAddr := indexKey[1 : AccIDStoreKeyLen+1]
	delAddr := indexKey[AccIDStoreKeyLen+1 : 2*AccIDStoreKeyLen+1]
	valDstAddr := indexKey[2*AccIDStoreKeyLen+1 : 3*AccIDStoreKeyLen+1]
	return GetREDKey(delAddr, valSrcAddr, valDstAddr)
}
func GetREDKeyFromValDstIndexKey(indexKey []byte) []byte {
	if len(indexKey) != 3*AccIDStoreKeyLen+1 {
		panic("unexpected key length")
	}
	valDstAddr := indexKey[1 : AccIDStoreKeyLen+1]
	delAddr := indexKey[AccIDStoreKeyLen+1 : 2*AccIDStoreKeyLen+1]
	valSrcAddr := indexKey[2*AccIDStoreKeyLen+1 : 3*AccIDStoreKeyLen+1]
	return GetREDKey(delAddr, valSrcAddr, valDstAddr)
}
func GetRedelegationTimeKey(timestamp time.Time) []byte {
	bz := sdk.FormatTimeBytes(timestamp)
	return append(RedelegationQueueKey, bz...)
}
func GetREDsKey(delAddr []byte) []byte {
	return append(RedelegationKey, delAddr...)
}
func GetREDsFromValSrcIndexKey(valSrcAddr []byte) []byte {
	return append(RedelegationByValSrcIndexKey, valSrcAddr...)
}