Refactor store keys for variable-length addresses (#8363)
* Change account store key in x/bank * Fix pagination test * Fix merge master * Fix staking keys.go * Use bech32 in val state change map * Fix sortNoLongerBonded * Use length-prefix function * Use length prefix function * Fix test accountStore * Fix ExamplePaginate * Fix staking keys * Use shorter balances prefix * Do slashing keys * Fix gov keys * Fix x/gov tests * Fix x/distrib * Address reviews * add change log entry * Add changelog * Fix failing tests * Fix sim tests * fix after-export sim * Fix lint * Address review * Fix x/authz * Fix global config in test * Update x/staking/keeper/val_state_change.go Co-authored-by: Robert Zaremba <robert@zaremba.ch> * Address comments * Fix comments * Address review * Fix authz test * Update comment * Rename to LengthPrefixedAddressStoreKey * Use variable * Rename function * Fix test build * chore: update rosetta CI (#8453) * Rename again * Rename yet again * Update feegrant keys * Add function to create prefix Co-authored-by: Robert Zaremba <robert@zaremba.ch> Co-authored-by: Frojdi Dymylja <33157909+fdymylja@users.noreply.github.com> Co-authored-by: Aaron Craelius <aaron@regen.network> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
This commit is contained in:
co-authored by
Robert Zaremba
Frojdi Dymylja
Aaron Craelius
mergify[bot]
parent
17d7e9a8d5
commit
c1b567f44c
@@ -36,8 +36,13 @@ Ref: https://keepachangelog.com/en/1.0.0/
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### Client Breaking Changes
|
||||
|
||||
* [\#8363](https://github.com/cosmos/cosmos-sdk/issues/8363) Addresses no longer have a fixed 20-byte length. From the SDK modules' point of view, any 1-255 bytes-long byte array is a valid address.
|
||||
|
||||
### State Machine Breaking
|
||||
|
||||
* (x/{bank,distrib,gov,slashing,staking}) [\#8363](https://github.com/cosmos/cosmos-sdk/issues/8363) Store keys have been modified to allow for variable-length addresses.
|
||||
* (x/ibc) [\#8266](https://github.com/cosmos/cosmos-sdk/issues/8266) Add amino JSON for IBC messages in order to support Ledger text signing.
|
||||
|
||||
### Improvements
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
[
|
||||
{
|
||||
"account_identifier": {
|
||||
"address":"cosmos1hdmjfmqmf8ck4pv4evu0s3up0ucm0yjjqfl87e"
|
||||
"address":"cosmos158nkd0l9tyemv2crp579rmj8dg37qty8lzff88"
|
||||
},
|
||||
"currency":{
|
||||
"symbol":"stake",
|
||||
"decimals":0
|
||||
},
|
||||
"value": "999900000000"
|
||||
"value": "999990000000"
|
||||
}
|
||||
]
|
||||
@@ -16,12 +16,13 @@ simd init simd --chain-id testing
|
||||
simd keys add fd --keyring-backend=test
|
||||
|
||||
addr=$(simd keys show fd -a --keyring-backend=test)
|
||||
val_addr=$(simd keys show fd --keyring-backend=test --bech val -a)
|
||||
|
||||
# give the accounts some money
|
||||
simd add-genesis-account "$addr" 1000000000000stake --keyring-backend=test
|
||||
|
||||
# save configs for the daemon
|
||||
simd gentx fd --chain-id testing --keyring-backend=test
|
||||
simd gentx fd 10000000stake --chain-id testing --keyring-backend=test
|
||||
|
||||
# input genTx to the genesis file
|
||||
simd collect-gentxs
|
||||
@@ -55,4 +56,4 @@ echo zipping data dir and saving to /tmp/data.tar.gz
|
||||
|
||||
tar -czvf /tmp/data.tar.gz /root/.simapp
|
||||
|
||||
echo new address for bootstrap.json "$addr"
|
||||
echo new address for bootstrap.json "$addr" "$val_addr"
|
||||
|
||||
@@ -94,7 +94,7 @@ staking(1){
|
||||
"account": {
|
||||
"address": "staking_account",
|
||||
"sub_account": {
|
||||
"address" : "cosmosvaloper1hdmjfmqmf8ck4pv4evu0s3up0ucm0yjj9atjj2"
|
||||
"address" : "cosmosvaloper158nkd0l9tyemv2crp579rmj8dg37qty86kaut5"
|
||||
}
|
||||
},
|
||||
"amount":{
|
||||
@@ -134,7 +134,7 @@ staking(1){
|
||||
"account": {
|
||||
"address": "staking_account",
|
||||
"sub_account": {
|
||||
"address" : "cosmosvaloper1hdmjfmqmf8ck4pv4evu0s3up0ucm0yjj9atjj2"
|
||||
"address" : "cosmosvaloper158nkd0l9tyemv2crp579rmj8dg37qty86kaut5"
|
||||
}
|
||||
},
|
||||
"amount":{
|
||||
|
||||
Binary file not shown.
+1
-1
@@ -157,7 +157,7 @@ func (app *SimApp) prepForZeroHeightGenesis(ctx sdk.Context, jailAllowedAddrs []
|
||||
counter := int16(0)
|
||||
|
||||
for ; iter.Valid(); iter.Next() {
|
||||
addr := sdk.ValAddress(iter.Key()[1:])
|
||||
addr := sdk.ValAddress(stakingtypes.AddressFromValidatorsKey(iter.Key()))
|
||||
validator, found := app.StakingKeeper.GetValidator(ctx, addr)
|
||||
if !found {
|
||||
panic("expected validator, not found")
|
||||
|
||||
+10
-4
@@ -12,7 +12,9 @@ import (
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/codec/legacy"
|
||||
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
|
||||
"github.com/cosmos/cosmos-sdk/types/address"
|
||||
"github.com/cosmos/cosmos-sdk/types/bech32"
|
||||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -28,8 +30,6 @@ const (
|
||||
// config.SetFullFundraiserPath(yourFullFundraiserPath)
|
||||
// config.Seal()
|
||||
|
||||
// AddrLen defines a valid address length
|
||||
AddrLen = 20
|
||||
// Bech32MainPrefix defines the main SDK Bech32 prefix of an account's address
|
||||
Bech32MainPrefix = "cosmos"
|
||||
|
||||
@@ -110,9 +110,15 @@ func VerifyAddressFormat(bz []byte) error {
|
||||
if verifier != nil {
|
||||
return verifier(bz)
|
||||
}
|
||||
if len(bz) != AddrLen {
|
||||
return fmt.Errorf("incorrect address length (expected: %d, actual: %d)", AddrLen, len(bz))
|
||||
|
||||
if len(bz) == 0 {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrUnknownAddress, "addresses cannot be empty")
|
||||
}
|
||||
|
||||
if len(bz) > address.MaxAddrLen {
|
||||
return sdkerrors.Wrapf(sdkerrors.ErrUnknownAddress, "address max length is %d, got %d", address.MaxAddrLen, len(bz))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
package address
|
||||
|
||||
import (
|
||||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||
)
|
||||
|
||||
// MaxAddrLen is the maximum allowed length (in bytes) for an address.
|
||||
const MaxAddrLen = 255
|
||||
|
||||
// LengthPrefix prefixes the address bytes with its length, this is used
|
||||
// for example for variable-length components in store keys.
|
||||
func LengthPrefix(bz []byte) ([]byte, error) {
|
||||
bzLen := len(bz)
|
||||
if bzLen == 0 {
|
||||
return bz, nil
|
||||
}
|
||||
|
||||
if bzLen > MaxAddrLen {
|
||||
return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownAddress, "address length should be max %d bytes, got %d", MaxAddrLen, bzLen)
|
||||
}
|
||||
|
||||
return append([]byte{byte(bzLen)}, bz...), nil
|
||||
}
|
||||
|
||||
// MustLengthPrefix is LengthPrefix with panic on error.
|
||||
func MustLengthPrefix(bz []byte) []byte {
|
||||
res, err := LengthPrefix(bz)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package address_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/types/address"
|
||||
)
|
||||
|
||||
func TestLengthPrefixedAddressStoreKey(t *testing.T) {
|
||||
addr10byte := []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
|
||||
addr20byte := []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19}
|
||||
addr256byte := make([]byte, 256)
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
addr []byte
|
||||
expStoreKey []byte
|
||||
expErr bool
|
||||
}{
|
||||
{"10-byte address", addr10byte, append([]byte{byte(10)}, addr10byte...), false},
|
||||
{"20-byte address", addr20byte, append([]byte{byte(20)}, addr20byte...), false},
|
||||
{"256-byte address (too long)", addr256byte, nil, true},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
tt := tt
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
storeKey, err := address.LengthPrefix(tt.addr)
|
||||
if tt.expErr {
|
||||
require.Error(t, err)
|
||||
} else {
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, tt.expStoreKey, storeKey)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
+24
-16
@@ -347,15 +347,18 @@ func (s *addressTestSuite) TestVerifyAddressFormat() {
|
||||
addr5 := make([]byte, 5)
|
||||
addr20 := make([]byte, 20)
|
||||
addr32 := make([]byte, 32)
|
||||
addr256 := make([]byte, 256)
|
||||
|
||||
err := types.VerifyAddressFormat(addr0)
|
||||
s.Require().EqualError(err, "incorrect address length 0")
|
||||
s.Require().EqualError(err, "addresses cannot be empty: unknown address")
|
||||
err = types.VerifyAddressFormat(addr5)
|
||||
s.Require().EqualError(err, "incorrect address length 5")
|
||||
s.Require().NoError(err)
|
||||
err = types.VerifyAddressFormat(addr20)
|
||||
s.Require().Nil(err)
|
||||
s.Require().NoError(err)
|
||||
err = types.VerifyAddressFormat(addr32)
|
||||
s.Require().EqualError(err, "incorrect address length 32")
|
||||
s.Require().NoError(err)
|
||||
err = types.VerifyAddressFormat(addr256)
|
||||
s.Require().EqualError(err, "address max length is 255, got 256: unknown address")
|
||||
}
|
||||
|
||||
func (s *addressTestSuite) TestCustomAddressVerifier() {
|
||||
@@ -364,34 +367,39 @@ func (s *addressTestSuite) TestCustomAddressVerifier() {
|
||||
accBech := types.AccAddress(addr).String()
|
||||
valBech := types.ValAddress(addr).String()
|
||||
consBech := types.ConsAddress(addr).String()
|
||||
// Verifiy that the default logic rejects this 10 byte address
|
||||
// Verify that the default logic doesn't reject this 10 byte address
|
||||
// The default verifier is nil, we're only checking address length is
|
||||
// between 1-255 bytes.
|
||||
err := types.VerifyAddressFormat(addr)
|
||||
s.Require().NotNil(err)
|
||||
s.Require().Nil(err)
|
||||
_, err = types.AccAddressFromBech32(accBech)
|
||||
s.Require().NotNil(err)
|
||||
s.Require().Nil(err)
|
||||
_, err = types.ValAddressFromBech32(valBech)
|
||||
s.Require().NotNil(err)
|
||||
s.Require().Nil(err)
|
||||
_, err = types.ConsAddressFromBech32(consBech)
|
||||
s.Require().NotNil(err)
|
||||
s.Require().Nil(err)
|
||||
|
||||
// Set a custom address verifier that accepts 10 or 20 byte addresses
|
||||
// Set a custom address verifier only accepts 20 byte addresses
|
||||
types.GetConfig().SetAddressVerifier(func(bz []byte) error {
|
||||
n := len(bz)
|
||||
if n == 10 || n == types.AddrLen {
|
||||
if n == 20 {
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("incorrect address length %d", n)
|
||||
})
|
||||
|
||||
// Verifiy that the custom logic accepts this 10 byte address
|
||||
// Verifiy that the custom logic rejects this 10 byte address
|
||||
err = types.VerifyAddressFormat(addr)
|
||||
s.Require().Nil(err)
|
||||
s.Require().NotNil(err)
|
||||
_, err = types.AccAddressFromBech32(accBech)
|
||||
s.Require().Nil(err)
|
||||
s.Require().NotNil(err)
|
||||
_, err = types.ValAddressFromBech32(valBech)
|
||||
s.Require().Nil(err)
|
||||
s.Require().NotNil(err)
|
||||
_, err = types.ConsAddressFromBech32(consBech)
|
||||
s.Require().Nil(err)
|
||||
s.Require().NotNil(err)
|
||||
|
||||
// Reinitialize the global config to default address verifier (nil)
|
||||
types.GetConfig().SetAddressVerifier(nil)
|
||||
}
|
||||
|
||||
func (s *addressTestSuite) TestBech32ifyAddressBytes() {
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
"github.com/cosmos/cosmos-sdk/store/prefix"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/types/address"
|
||||
"github.com/cosmos/cosmos-sdk/types/query"
|
||||
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/bank/types"
|
||||
@@ -111,7 +112,7 @@ func ExampleFilteredPaginate() {
|
||||
pageReq := &query.PageRequest{Key: nil, Limit: 1, CountTotal: true}
|
||||
store := ctx.KVStore(app.GetKey(authtypes.StoreKey))
|
||||
balancesStore := prefix.NewStore(store, types.BalancesPrefix)
|
||||
accountStore := prefix.NewStore(balancesStore, addr1.Bytes())
|
||||
accountStore := prefix.NewStore(balancesStore, address.MustLengthPrefix(addr1))
|
||||
|
||||
var balResult sdk.Coins
|
||||
pageRes, err := query.FilteredPaginate(accountStore, pageReq, func(key []byte, value []byte, accumulate bool) (bool, error) {
|
||||
@@ -143,7 +144,7 @@ func ExampleFilteredPaginate() {
|
||||
|
||||
func execFilterPaginate(store sdk.KVStore, pageReq *query.PageRequest, appCodec codec.Marshaler) (balances sdk.Coins, res *query.PageResponse, err error) {
|
||||
balancesStore := prefix.NewStore(store, types.BalancesPrefix)
|
||||
accountStore := prefix.NewStore(balancesStore, addr1.Bytes())
|
||||
accountStore := prefix.NewStore(balancesStore, address.MustLengthPrefix(addr1))
|
||||
|
||||
var balResult sdk.Coins
|
||||
res, err = query.FilteredPaginate(accountStore, pageReq, func(key []byte, value []byte, accumulate bool) (bool, error) {
|
||||
|
||||
@@ -17,6 +17,7 @@ import (
|
||||
"github.com/cosmos/cosmos-sdk/store"
|
||||
"github.com/cosmos/cosmos-sdk/store/prefix"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/types/address"
|
||||
"github.com/cosmos/cosmos-sdk/types/query"
|
||||
authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper"
|
||||
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
|
||||
@@ -193,7 +194,7 @@ func ExamplePaginate() {
|
||||
balResult := sdk.NewCoins()
|
||||
authStore := ctx.KVStore(app.GetKey(authtypes.StoreKey))
|
||||
balancesStore := prefix.NewStore(authStore, types.BalancesPrefix)
|
||||
accountStore := prefix.NewStore(balancesStore, addr1.Bytes())
|
||||
accountStore := prefix.NewStore(balancesStore, address.MustLengthPrefix(addr1))
|
||||
pageRes, err := query.Paginate(accountStore, request.Pagination, func(key []byte, value []byte) error {
|
||||
var tempRes sdk.Coin
|
||||
err := app.AppCodec().UnmarshalBinaryBare(value, &tempRes)
|
||||
|
||||
+15
-4
@@ -2,6 +2,7 @@ package types
|
||||
|
||||
import (
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/types/address"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -21,7 +22,7 @@ const (
|
||||
// Keys for authz store
|
||||
// Items are stored with the following key: values
|
||||
//
|
||||
// - 0x01<granterAddress_Bytes><granteeAddress_Bytes><msgType_Bytes>: Grant
|
||||
// - 0x01<granterAddressLen (1 Byte)><granterAddress_Bytes><granteeAddressLen (1 Byte)><granteeAddress_Bytes><msgType_Bytes>: Grant
|
||||
|
||||
var (
|
||||
// Keys for store prefixes
|
||||
@@ -30,12 +31,22 @@ var (
|
||||
|
||||
// GetAuthorizationStoreKey - return authorization store key
|
||||
func GetAuthorizationStoreKey(grantee sdk.AccAddress, granter sdk.AccAddress, msgType string) []byte {
|
||||
return append(append(append(GrantKey, granter.Bytes()...), grantee.Bytes()...), []byte(msgType)...)
|
||||
return append(append(append(
|
||||
GrantKey,
|
||||
address.MustLengthPrefix(granter)...),
|
||||
address.MustLengthPrefix(grantee)...),
|
||||
[]byte(msgType)...,
|
||||
)
|
||||
}
|
||||
|
||||
// ExtractAddressesFromGrantKey - split granter & grantee address from the authorization key
|
||||
func ExtractAddressesFromGrantKey(key []byte) (granterAddr, granteeAddr sdk.AccAddress) {
|
||||
granterAddr = sdk.AccAddress(key[1 : sdk.AddrLen+1])
|
||||
granteeAddr = sdk.AccAddress(key[sdk.AddrLen+1 : sdk.AddrLen*2+1])
|
||||
// key if of format:
|
||||
// 0x01<granterAddressLen (1 Byte)><granterAddress_Bytes><granteeAddressLen (1 Byte)><granteeAddress_Bytes><msgType_Bytes>
|
||||
granterAddrLen := key[1] // remove prefix key
|
||||
granterAddr = sdk.AccAddress(key[2 : 2+granterAddrLen])
|
||||
granteeAddrLen := int(key[2+granterAddrLen])
|
||||
granteeAddr = sdk.AccAddress(key[3+granterAddrLen : 3+granterAddrLen+byte(granteeAddrLen)])
|
||||
|
||||
return granterAddr, granteeAddr
|
||||
}
|
||||
|
||||
@@ -57,9 +57,7 @@ func (k BaseKeeper) AllBalances(ctx context.Context, req *types.QueryAllBalances
|
||||
sdkCtx := sdk.UnwrapSDKContext(ctx)
|
||||
|
||||
balances := sdk.NewCoins()
|
||||
store := sdkCtx.KVStore(k.storeKey)
|
||||
balancesStore := prefix.NewStore(store, types.BalancesPrefix)
|
||||
accountStore := prefix.NewStore(balancesStore, addr.Bytes())
|
||||
accountStore := k.getAccountStore(sdkCtx, addr)
|
||||
|
||||
pageRes, err := query.Paginate(accountStore, req.Pagination, func(_, value []byte) error {
|
||||
var result sdk.Coin
|
||||
|
||||
@@ -2,7 +2,6 @@ package keeper
|
||||
|
||||
import (
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
"github.com/cosmos/cosmos-sdk/store/prefix"
|
||||
"github.com/cosmos/cosmos-sdk/telemetry"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||
@@ -233,9 +232,7 @@ func (k BaseSendKeeper) ClearBalances(ctx sdk.Context, addr sdk.AccAddress) {
|
||||
return false
|
||||
})
|
||||
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
balancesStore := prefix.NewStore(store, types.BalancesPrefix)
|
||||
accountStore := prefix.NewStore(balancesStore, addr.Bytes())
|
||||
accountStore := k.getAccountStore(ctx, addr)
|
||||
|
||||
for _, key := range keys {
|
||||
accountStore.Delete(key)
|
||||
@@ -264,9 +261,7 @@ func (k BaseSendKeeper) SetBalance(ctx sdk.Context, addr sdk.AccAddress, balance
|
||||
return sdkerrors.Wrap(sdkerrors.ErrInvalidCoins, balance.String())
|
||||
}
|
||||
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
balancesStore := prefix.NewStore(store, types.BalancesPrefix)
|
||||
accountStore := prefix.NewStore(balancesStore, addr.Bytes())
|
||||
accountStore := k.getAccountStore(ctx, addr)
|
||||
|
||||
bz := k.cdc.MustMarshalBinaryBare(&balance)
|
||||
accountStore.Set([]byte(balance.Denom), bz)
|
||||
|
||||
@@ -97,9 +97,7 @@ func (k BaseViewKeeper) GetAccountsBalances(ctx sdk.Context) []types.Balance {
|
||||
// GetBalance returns the balance of a specific denomination for a given account
|
||||
// by address.
|
||||
func (k BaseViewKeeper) GetBalance(ctx sdk.Context, addr sdk.AccAddress, denom string) sdk.Coin {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
balancesStore := prefix.NewStore(store, types.BalancesPrefix)
|
||||
accountStore := prefix.NewStore(balancesStore, addr.Bytes())
|
||||
accountStore := k.getAccountStore(ctx, addr)
|
||||
|
||||
bz := accountStore.Get([]byte(denom))
|
||||
if bz == nil {
|
||||
@@ -116,9 +114,7 @@ func (k BaseViewKeeper) GetBalance(ctx sdk.Context, addr sdk.AccAddress, denom s
|
||||
// provides the token balance to a callback. If true is returned from the
|
||||
// callback, iteration is halted.
|
||||
func (k BaseViewKeeper) IterateAccountBalances(ctx sdk.Context, addr sdk.AccAddress, cb func(sdk.Coin) bool) {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
balancesStore := prefix.NewStore(store, types.BalancesPrefix)
|
||||
accountStore := prefix.NewStore(balancesStore, addr.Bytes())
|
||||
accountStore := k.getAccountStore(ctx, addr)
|
||||
|
||||
iterator := accountStore.Iterator(nil, nil)
|
||||
defer iterator.Close()
|
||||
@@ -214,3 +210,10 @@ func (k BaseViewKeeper) ValidateBalance(ctx sdk.Context, addr sdk.AccAddress) er
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// getAccountStore gets the account store of the given address.
|
||||
func (k BaseViewKeeper) getAccountStore(ctx sdk.Context, addr sdk.AccAddress) prefix.Store {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
|
||||
return prefix.NewStore(store, types.CreateAccountBalancesPrefix(addr))
|
||||
}
|
||||
|
||||
+11
-7
@@ -1,9 +1,8 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/types/address"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -22,7 +21,9 @@ const (
|
||||
|
||||
// KVStore keys
|
||||
var (
|
||||
BalancesPrefix = []byte("balances")
|
||||
// BalancesPrefix is the for the account balances store. We use a byte
|
||||
// (instead of say `[]]byte("balances")` to save some disk space).
|
||||
BalancesPrefix = []byte{0x02}
|
||||
SupplyKey = []byte{0x00}
|
||||
DenomMetadataPrefix = []byte{0x1}
|
||||
)
|
||||
@@ -37,10 +38,13 @@ func DenomMetadataKey(denom string) []byte {
|
||||
// store. The key must not contain the perfix BalancesPrefix as the prefix store
|
||||
// iterator discards the actual prefix.
|
||||
func AddressFromBalancesStore(key []byte) sdk.AccAddress {
|
||||
addr := key[:sdk.AddrLen]
|
||||
if len(addr) != sdk.AddrLen {
|
||||
panic(fmt.Sprintf("unexpected account address key length; got: %d, expected: %d", len(addr), sdk.AddrLen))
|
||||
}
|
||||
addrLen := key[0]
|
||||
addr := key[1 : addrLen+1]
|
||||
|
||||
return sdk.AccAddress(addr)
|
||||
}
|
||||
|
||||
// CreateAccountBalancesPrefix creates the prefix for an account's balances.
|
||||
func CreateAccountBalancesPrefix(addr []byte) []byte {
|
||||
return append(BalancesPrefix, address.MustLengthPrefix(addr)...)
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/types/address"
|
||||
"github.com/cosmos/cosmos-sdk/x/bank/types"
|
||||
)
|
||||
|
||||
@@ -19,8 +20,10 @@ func cloneAppend(bz []byte, tail []byte) (res []byte) {
|
||||
func TestAddressFromBalancesStore(t *testing.T) {
|
||||
addr, err := sdk.AccAddressFromBech32("cosmos1n88uc38xhjgxzw9nwre4ep2c8ga4fjxcar6mn7")
|
||||
require.NoError(t, err)
|
||||
addrLen := len(addr)
|
||||
require.Equal(t, 20, addrLen)
|
||||
|
||||
key := cloneAppend(addr.Bytes(), []byte("stake"))
|
||||
key := cloneAppend(address.MustLengthPrefix(addr), []byte("stake"))
|
||||
res := types.AddressFromBalancesStore(key)
|
||||
require.Equal(t, res, addr)
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ func TestMsgSendValidation(t *testing.T) {
|
||||
addr1 := sdk.AccAddress([]byte("from________________"))
|
||||
addr2 := sdk.AccAddress([]byte("to__________________"))
|
||||
addrEmpty := sdk.AccAddress([]byte(""))
|
||||
addrTooLong := sdk.AccAddress([]byte("Accidentally used 33 bytes pubkey"))
|
||||
addrLong := sdk.AccAddress([]byte("Purposefully long address"))
|
||||
|
||||
atom123 := sdk.NewCoins(sdk.NewInt64Coin("atom", 123))
|
||||
atom0 := sdk.NewCoins(sdk.NewInt64Coin("atom", 0))
|
||||
@@ -36,12 +36,12 @@ func TestMsgSendValidation(t *testing.T) {
|
||||
}{
|
||||
{"", NewMsgSend(addr1, addr2, atom123)}, // valid send
|
||||
{"", NewMsgSend(addr1, addr2, atom123eth123)}, // valid send with multiple coins
|
||||
{"", NewMsgSend(addrLong, addr2, atom123)}, // valid send with long addr sender
|
||||
{"", NewMsgSend(addr1, addrLong, atom123)}, // valid send with long addr recipient
|
||||
{": invalid coins", NewMsgSend(addr1, addr2, atom0)}, // non positive coin
|
||||
{"123atom,0eth: invalid coins", NewMsgSend(addr1, addr2, atom123eth0)}, // non positive coin in multicoins
|
||||
{"Invalid sender address (empty address string is not allowed): invalid address", NewMsgSend(addrEmpty, addr2, atom123)},
|
||||
{"Invalid sender address (incorrect address length (expected: 20, actual: 33)): invalid address", NewMsgSend(addrTooLong, addr2, atom123)},
|
||||
{"Invalid recipient address (empty address string is not allowed): invalid address", NewMsgSend(addr1, addrEmpty, atom123)},
|
||||
{"Invalid recipient address (incorrect address length (expected: 20, actual: 33)): invalid address", NewMsgSend(addr1, addrTooLong, atom123)},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
@@ -91,7 +91,7 @@ func TestInputValidation(t *testing.T) {
|
||||
addr1 := sdk.AccAddress([]byte("_______alice________"))
|
||||
addr2 := sdk.AccAddress([]byte("________bob_________"))
|
||||
addrEmpty := sdk.AccAddress([]byte(""))
|
||||
addrTooLong := sdk.AccAddress([]byte("Accidentally used 33 bytes pubkey"))
|
||||
addrLong := sdk.AccAddress([]byte("Purposefully long address"))
|
||||
|
||||
someCoins := sdk.NewCoins(sdk.NewInt64Coin("atom", 123))
|
||||
multiCoins := sdk.NewCoins(sdk.NewInt64Coin("atom", 123), sdk.NewInt64Coin("eth", 20))
|
||||
@@ -109,9 +109,9 @@ func TestInputValidation(t *testing.T) {
|
||||
{"", NewInput(addr1, someCoins)},
|
||||
{"", NewInput(addr2, someCoins)},
|
||||
{"", NewInput(addr2, multiCoins)},
|
||||
{"", NewInput(addrLong, someCoins)},
|
||||
|
||||
{"empty address string is not allowed", NewInput(addrEmpty, someCoins)},
|
||||
{"incorrect address length (expected: 20, actual: 33)", NewInput(addrTooLong, someCoins)},
|
||||
{": invalid coins", NewInput(addr1, emptyCoins)}, // invalid coins
|
||||
{": invalid coins", NewInput(addr1, emptyCoins2)}, // invalid coins
|
||||
{"10eth,0atom: invalid coins", NewInput(addr1, someEmptyCoins)}, // invalid coins
|
||||
@@ -132,7 +132,7 @@ func TestOutputValidation(t *testing.T) {
|
||||
addr1 := sdk.AccAddress([]byte("_______alice________"))
|
||||
addr2 := sdk.AccAddress([]byte("________bob_________"))
|
||||
addrEmpty := sdk.AccAddress([]byte(""))
|
||||
addrTooLong := sdk.AccAddress([]byte("Accidentally used 33 bytes pubkey"))
|
||||
addrLong := sdk.AccAddress([]byte("Purposefully long address"))
|
||||
|
||||
someCoins := sdk.NewCoins(sdk.NewInt64Coin("atom", 123))
|
||||
multiCoins := sdk.NewCoins(sdk.NewInt64Coin("atom", 123), sdk.NewInt64Coin("eth", 20))
|
||||
@@ -150,9 +150,9 @@ func TestOutputValidation(t *testing.T) {
|
||||
{"", NewOutput(addr1, someCoins)},
|
||||
{"", NewOutput(addr2, someCoins)},
|
||||
{"", NewOutput(addr2, multiCoins)},
|
||||
{"", NewOutput(addrLong, someCoins)},
|
||||
|
||||
{"Invalid output address (empty address string is not allowed): invalid address", NewOutput(addrEmpty, someCoins)},
|
||||
{"Invalid output address (incorrect address length (expected: 20, actual: 33)): invalid address", NewOutput(addrTooLong, someCoins)},
|
||||
{": invalid coins", NewOutput(addr1, emptyCoins)}, // invalid coins
|
||||
{": invalid coins", NewOutput(addr1, emptyCoins2)}, // invalid coins
|
||||
{"10eth,0atom: invalid coins", NewOutput(addr1, someEmptyCoins)}, // invalid coins
|
||||
@@ -251,8 +251,6 @@ func TestMsgMultiSendGetSigners(t *testing.T) {
|
||||
require.Equal(t, "[696E707574313131313131313131313131313131 696E707574323232323232323232323232323232 696E707574333333333333333333333333333333]", fmt.Sprintf("%v", res))
|
||||
}
|
||||
|
||||
/*
|
||||
// what to do w/ this test?
|
||||
func TestMsgSendSigners(t *testing.T) {
|
||||
signers := []sdk.AccAddress{
|
||||
{1, 2, 3},
|
||||
@@ -265,8 +263,7 @@ func TestMsgSendSigners(t *testing.T) {
|
||||
for i, signer := range signers {
|
||||
inputs[i] = NewInput(signer, someCoins)
|
||||
}
|
||||
tx := NewMsgSend(inputs, nil)
|
||||
tx := NewMsgMultiSend(inputs, nil)
|
||||
|
||||
require.Equal(t, signers, tx.Signers())
|
||||
require.Equal(t, signers, tx.GetSigners())
|
||||
}
|
||||
*/
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"encoding/binary"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/types/address"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -27,19 +28,19 @@ const (
|
||||
//
|
||||
// - 0x01: sdk.ConsAddress
|
||||
//
|
||||
// - 0x02<valAddr_Bytes>: ValidatorOutstandingRewards
|
||||
// - 0x02<valAddrLen (1 Byte)><valAddr_Bytes>: ValidatorOutstandingRewards
|
||||
//
|
||||
// - 0x03<accAddr_Bytes>: sdk.AccAddress
|
||||
// - 0x03<accAddrLen (1 Byte)><accAddr_Bytes>: sdk.AccAddress
|
||||
//
|
||||
// - 0x04<valAddr_Bytes><accAddr_Bytes>: DelegatorStartingInfo
|
||||
// - 0x04<valAddrLen (1 Byte)><valAddr_Bytes><accAddrLen (1 Byte)><accAddr_Bytes>: DelegatorStartingInfo
|
||||
//
|
||||
// - 0x05<valAddr_Bytes><period_Bytes>: ValidatorHistoricalRewards
|
||||
// - 0x05<valAddrLen (1 Byte)><valAddr_Bytes><period_Bytes>: ValidatorHistoricalRewards
|
||||
//
|
||||
// - 0x06<valAddr_Bytes>: ValidatorCurrentRewards
|
||||
// - 0x06<valAddrLen (1 Byte)><valAddr_Bytes>: ValidatorCurrentRewards
|
||||
//
|
||||
// - 0x07<valAddr_Bytes>: ValidatorCurrentRewards
|
||||
// - 0x07<valAddrLen (1 Byte)><valAddr_Bytes>: ValidatorCurrentRewards
|
||||
//
|
||||
// - 0x08<valAddr_Bytes><height>: ValidatorSlashEvent
|
||||
// - 0x08<valAddrLen (1 Byte)><valAddr_Bytes><height>: ValidatorSlashEvent
|
||||
var (
|
||||
FeePoolKey = []byte{0x00} // key for global distribution state
|
||||
ProposerKey = []byte{0x01} // key for the proposer operator address
|
||||
@@ -53,47 +54,56 @@ var (
|
||||
ValidatorSlashEventPrefix = []byte{0x08} // key for validator slash fraction
|
||||
)
|
||||
|
||||
// gets an address from a validator's outstanding rewards key
|
||||
// GetValidatorOutstandingRewardsAddress creates an address from a validator's outstanding rewards key.
|
||||
func GetValidatorOutstandingRewardsAddress(key []byte) (valAddr sdk.ValAddress) {
|
||||
addr := key[1:]
|
||||
if len(addr) != sdk.AddrLen {
|
||||
// key is in the format:
|
||||
// 0x02<valAddrLen (1 Byte)><valAddr_Bytes>
|
||||
|
||||
// Remove prefix and address length.
|
||||
addr := key[2:]
|
||||
if len(addr) != int(key[1]) {
|
||||
panic("unexpected key length")
|
||||
}
|
||||
|
||||
return sdk.ValAddress(addr)
|
||||
}
|
||||
|
||||
// gets an address from a delegator's withdraw info key
|
||||
// GetDelegatorWithdrawInfoAddress creates an address from a delegator's withdraw info key.
|
||||
func GetDelegatorWithdrawInfoAddress(key []byte) (delAddr sdk.AccAddress) {
|
||||
addr := key[1:]
|
||||
if len(addr) != sdk.AddrLen {
|
||||
// key is in the format:
|
||||
// 0x03<accAddrLen (1 Byte)><accAddr_Bytes>
|
||||
|
||||
// Remove prefix and address length.
|
||||
addr := key[2:]
|
||||
if len(addr) != int(key[1]) {
|
||||
panic("unexpected key length")
|
||||
}
|
||||
|
||||
return sdk.AccAddress(addr)
|
||||
}
|
||||
|
||||
// gets the addresses from a delegator starting info key
|
||||
// GetDelegatorStartingInfoAddresses creates the addresses from a delegator starting info key.
|
||||
func GetDelegatorStartingInfoAddresses(key []byte) (valAddr sdk.ValAddress, delAddr sdk.AccAddress) {
|
||||
addr := key[1 : 1+sdk.AddrLen]
|
||||
if len(addr) != sdk.AddrLen {
|
||||
// key is in the format:
|
||||
// 0x04<valAddrLen (1 Byte)><valAddr_Bytes><accAddrLen (1 Byte)><accAddr_Bytes>
|
||||
valAddrLen := int(key[1])
|
||||
valAddr = sdk.ValAddress(key[2 : 2+valAddrLen])
|
||||
delAddrLen := int(key[2+valAddrLen])
|
||||
delAddr = sdk.AccAddress(key[3+valAddrLen:])
|
||||
if len(delAddr.Bytes()) != delAddrLen {
|
||||
panic("unexpected key length")
|
||||
}
|
||||
valAddr = sdk.ValAddress(addr)
|
||||
addr = key[1+sdk.AddrLen:]
|
||||
if len(addr) != sdk.AddrLen {
|
||||
panic("unexpected key length")
|
||||
}
|
||||
delAddr = sdk.AccAddress(addr)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// gets the address & period from a validator's historical rewards key
|
||||
// GetValidatorHistoricalRewardsAddressPeriod creates the address & period from a validator's historical rewards key.
|
||||
func GetValidatorHistoricalRewardsAddressPeriod(key []byte) (valAddr sdk.ValAddress, period uint64) {
|
||||
addr := key[1 : 1+sdk.AddrLen]
|
||||
if len(addr) != sdk.AddrLen {
|
||||
panic("unexpected key length")
|
||||
}
|
||||
valAddr = sdk.ValAddress(addr)
|
||||
b := key[1+sdk.AddrLen:]
|
||||
// key is in the format:
|
||||
// 0x05<valAddrLen (1 Byte)><valAddr_Bytes><period_Bytes>
|
||||
valAddrLen := int(key[1])
|
||||
valAddr = sdk.ValAddress(key[2 : 2+valAddrLen])
|
||||
b := key[2+valAddrLen:]
|
||||
if len(b) != 8 {
|
||||
panic("unexpected key length")
|
||||
}
|
||||
@@ -101,93 +111,104 @@ func GetValidatorHistoricalRewardsAddressPeriod(key []byte) (valAddr sdk.ValAddr
|
||||
return
|
||||
}
|
||||
|
||||
// gets the address from a validator's current rewards key
|
||||
// GetValidatorCurrentRewardsAddress creates the address from a validator's current rewards key.
|
||||
func GetValidatorCurrentRewardsAddress(key []byte) (valAddr sdk.ValAddress) {
|
||||
addr := key[1:]
|
||||
if len(addr) != sdk.AddrLen {
|
||||
// key is in the format:
|
||||
// 0x06<valAddrLen (1 Byte)><valAddr_Bytes>: ValidatorCurrentRewards
|
||||
|
||||
// Remove prefix and address length.
|
||||
addr := key[2:]
|
||||
if len(addr) != int(key[1]) {
|
||||
panic("unexpected key length")
|
||||
}
|
||||
|
||||
return sdk.ValAddress(addr)
|
||||
}
|
||||
|
||||
// gets the address from a validator's accumulated commission key
|
||||
// GetValidatorAccumulatedCommissionAddress creates the address from a validator's accumulated commission key.
|
||||
func GetValidatorAccumulatedCommissionAddress(key []byte) (valAddr sdk.ValAddress) {
|
||||
addr := key[1:]
|
||||
if len(addr) != sdk.AddrLen {
|
||||
// key is in the format:
|
||||
// 0x07<valAddrLen (1 Byte)><valAddr_Bytes>: ValidatorCurrentRewards
|
||||
|
||||
// Remove prefix and address length.
|
||||
addr := key[2:]
|
||||
if len(addr) != int(key[1]) {
|
||||
panic("unexpected key length")
|
||||
}
|
||||
|
||||
return sdk.ValAddress(addr)
|
||||
}
|
||||
|
||||
// gets the height from a validator's slash event key
|
||||
// GetValidatorSlashEventAddressHeight creates the height from a validator's slash event key.
|
||||
func GetValidatorSlashEventAddressHeight(key []byte) (valAddr sdk.ValAddress, height uint64) {
|
||||
addr := key[1 : 1+sdk.AddrLen]
|
||||
if len(addr) != sdk.AddrLen {
|
||||
panic("unexpected key length")
|
||||
}
|
||||
valAddr = sdk.ValAddress(addr)
|
||||
startB := 1 + sdk.AddrLen
|
||||
// key is in the format:
|
||||
// 0x08<valAddrLen (1 Byte)><valAddr_Bytes><height>: ValidatorSlashEvent
|
||||
valAddrLen := int(key[1])
|
||||
valAddr = key[2 : 2+valAddrLen]
|
||||
startB := 2 + valAddrLen
|
||||
b := key[startB : startB+8] // the next 8 bytes represent the height
|
||||
height = binary.BigEndian.Uint64(b)
|
||||
return
|
||||
}
|
||||
|
||||
// gets the outstanding rewards key for a validator
|
||||
// GetValidatorOutstandingRewardsKey creates the outstanding rewards key for a validator.
|
||||
func GetValidatorOutstandingRewardsKey(valAddr sdk.ValAddress) []byte {
|
||||
return append(ValidatorOutstandingRewardsPrefix, valAddr.Bytes()...)
|
||||
return append(ValidatorOutstandingRewardsPrefix, address.MustLengthPrefix(valAddr.Bytes())...)
|
||||
}
|
||||
|
||||
// gets the key for a delegator's withdraw addr
|
||||
// GetDelegatorWithdrawAddrKey creates the key for a delegator's withdraw addr.
|
||||
func GetDelegatorWithdrawAddrKey(delAddr sdk.AccAddress) []byte {
|
||||
return append(DelegatorWithdrawAddrPrefix, delAddr.Bytes()...)
|
||||
return append(DelegatorWithdrawAddrPrefix, address.MustLengthPrefix(delAddr.Bytes())...)
|
||||
}
|
||||
|
||||
// gets the key for a delegator's starting info
|
||||
// GetDelegatorStartingInfoKey creates the key for a delegator's starting info.
|
||||
func GetDelegatorStartingInfoKey(v sdk.ValAddress, d sdk.AccAddress) []byte {
|
||||
return append(append(DelegatorStartingInfoPrefix, v.Bytes()...), d.Bytes()...)
|
||||
return append(append(DelegatorStartingInfoPrefix, address.MustLengthPrefix(v.Bytes())...), address.MustLengthPrefix(d.Bytes())...)
|
||||
}
|
||||
|
||||
// gets the prefix key for a validator's historical rewards
|
||||
// GetValidatorHistoricalRewardsPrefix creates the prefix key for a validator's historical rewards.
|
||||
func GetValidatorHistoricalRewardsPrefix(v sdk.ValAddress) []byte {
|
||||
return append(ValidatorHistoricalRewardsPrefix, v.Bytes()...)
|
||||
return append(ValidatorHistoricalRewardsPrefix, address.MustLengthPrefix(v.Bytes())...)
|
||||
}
|
||||
|
||||
// gets the key for a validator's historical rewards
|
||||
// GetValidatorHistoricalRewardsKey creates the key for a validator's historical rewards.
|
||||
func GetValidatorHistoricalRewardsKey(v sdk.ValAddress, k uint64) []byte {
|
||||
b := make([]byte, 8)
|
||||
binary.LittleEndian.PutUint64(b, k)
|
||||
return append(append(ValidatorHistoricalRewardsPrefix, v.Bytes()...), b...)
|
||||
return append(append(ValidatorHistoricalRewardsPrefix, address.MustLengthPrefix(v.Bytes())...), b...)
|
||||
}
|
||||
|
||||
// gets the key for a validator's current rewards
|
||||
// GetValidatorCurrentRewardsKey creates the key for a validator's current rewards.
|
||||
func GetValidatorCurrentRewardsKey(v sdk.ValAddress) []byte {
|
||||
return append(ValidatorCurrentRewardsPrefix, v.Bytes()...)
|
||||
return append(ValidatorCurrentRewardsPrefix, address.MustLengthPrefix(v.Bytes())...)
|
||||
}
|
||||
|
||||
// gets the key for a validator's current commission
|
||||
// GetValidatorAccumulatedCommissionKey creates the key for a validator's current commission.
|
||||
func GetValidatorAccumulatedCommissionKey(v sdk.ValAddress) []byte {
|
||||
return append(ValidatorAccumulatedCommissionPrefix, v.Bytes()...)
|
||||
return append(ValidatorAccumulatedCommissionPrefix, address.MustLengthPrefix(v.Bytes())...)
|
||||
}
|
||||
|
||||
// gets the prefix key for a validator's slash fractions
|
||||
// GetValidatorSlashEventPrefix creates the prefix key for a validator's slash fractions.
|
||||
func GetValidatorSlashEventPrefix(v sdk.ValAddress) []byte {
|
||||
return append(ValidatorSlashEventPrefix, v.Bytes()...)
|
||||
return append(ValidatorSlashEventPrefix, address.MustLengthPrefix(v.Bytes())...)
|
||||
}
|
||||
|
||||
// gets the prefix key for a validator's slash fraction (ValidatorSlashEventPrefix + height)
|
||||
// GetValidatorSlashEventKeyPrefix creates the prefix key for a validator's slash fraction (ValidatorSlashEventPrefix + height).
|
||||
func GetValidatorSlashEventKeyPrefix(v sdk.ValAddress, height uint64) []byte {
|
||||
heightBz := make([]byte, 8)
|
||||
binary.BigEndian.PutUint64(heightBz, height)
|
||||
|
||||
return append(
|
||||
ValidatorSlashEventPrefix,
|
||||
append(v.Bytes(), heightBz...)...,
|
||||
append(address.MustLengthPrefix(v.Bytes()), heightBz...)...,
|
||||
)
|
||||
}
|
||||
|
||||
// gets the key for a validator's slash fraction
|
||||
// GetValidatorSlashEventKey creates the key for a validator's slash fraction.
|
||||
func GetValidatorSlashEventKey(v sdk.ValAddress, height, period uint64) []byte {
|
||||
periodBz := make([]byte, 8)
|
||||
binary.BigEndian.PutUint64(periodBz, period)
|
||||
prefix := GetValidatorSlashEventKeyPrefix(v, height)
|
||||
|
||||
return append(prefix, periodBz...)
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package types
|
||||
|
||||
import (
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/types/address"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -26,10 +27,10 @@ var (
|
||||
// FeeAllowanceKey is the canonical key to store a grant from granter to grantee
|
||||
// We store by grantee first to allow searching by everyone who granted to you
|
||||
func FeeAllowanceKey(granter sdk.AccAddress, grantee sdk.AccAddress) []byte {
|
||||
return append(append(FeeAllowanceKeyPrefix, grantee.Bytes()...), granter.Bytes()...)
|
||||
return append(FeeAllowancePrefixByGrantee(grantee), address.MustLengthPrefix(granter.Bytes())...)
|
||||
}
|
||||
|
||||
// FeeAllowancePrefixByGrantee returns a prefix to scan for all grants to this given address.
|
||||
func FeeAllowancePrefixByGrantee(grantee sdk.AccAddress) []byte {
|
||||
return append(FeeAllowanceKeyPrefix, grantee.Bytes()...)
|
||||
return append(FeeAllowanceKeyPrefix, address.MustLengthPrefix(grantee.Bytes())...)
|
||||
}
|
||||
|
||||
+8
-9
@@ -6,6 +6,7 @@ import (
|
||||
"time"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/types/address"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -33,9 +34,9 @@ const (
|
||||
//
|
||||
// - 0x03: nextProposalID
|
||||
//
|
||||
// - 0x10<proposalID_Bytes><depositorAddr_Bytes>: Deposit
|
||||
// - 0x10<proposalID_Bytes><depositorAddrLen (1 Byte)><depositorAddr_Bytes>: Deposit
|
||||
//
|
||||
// - 0x20<proposalID_Bytes><voterAddr_Bytes>: Voter
|
||||
// - 0x20<proposalID_Bytes><voterAddrLen (1 Byte)><voterAddr_Bytes>: Voter
|
||||
var (
|
||||
ProposalsKeyPrefix = []byte{0x00}
|
||||
ActiveProposalQueuePrefix = []byte{0x01}
|
||||
@@ -93,7 +94,7 @@ func DepositsKey(proposalID uint64) []byte {
|
||||
|
||||
// DepositKey key of a specific deposit from the store
|
||||
func DepositKey(proposalID uint64, depositorAddr sdk.AccAddress) []byte {
|
||||
return append(DepositsKey(proposalID), depositorAddr.Bytes()...)
|
||||
return append(DepositsKey(proposalID), address.MustLengthPrefix(depositorAddr.Bytes())...)
|
||||
}
|
||||
|
||||
// VotesKey gets the first part of the votes key based on the proposalID
|
||||
@@ -103,7 +104,7 @@ func VotesKey(proposalID uint64) []byte {
|
||||
|
||||
// VoteKey key of a specific vote from the store
|
||||
func VoteKey(proposalID uint64, voterAddr sdk.AccAddress) []byte {
|
||||
return append(VotesKey(proposalID), voterAddr.Bytes()...)
|
||||
return append(VotesKey(proposalID), address.MustLengthPrefix(voterAddr.Bytes())...)
|
||||
}
|
||||
|
||||
// Split keys function; used for iterators
|
||||
@@ -154,11 +155,9 @@ func splitKeyWithTime(key []byte) (proposalID uint64, endTime time.Time) {
|
||||
}
|
||||
|
||||
func splitKeyWithAddress(key []byte) (proposalID uint64, addr sdk.AccAddress) {
|
||||
if len(key[1:]) != 8+sdk.AddrLen {
|
||||
panic(fmt.Sprintf("unexpected key length (%d ≠ %d)", len(key), 8+sdk.AddrLen))
|
||||
}
|
||||
|
||||
// Both Vote and Deposit store keys are of format:
|
||||
// <prefix (1 Byte)><proposalID (8 bytes)><addrLen (1 Byte)><addr_Bytes>
|
||||
proposalID = GetProposalIDFromBytes(key[1:9])
|
||||
addr = sdk.AccAddress(key[9:])
|
||||
addr = sdk.AccAddress(key[10:])
|
||||
return
|
||||
}
|
||||
|
||||
@@ -46,11 +46,6 @@ func TestDepositKeys(t *testing.T) {
|
||||
proposalID, depositorAddr := SplitKeyDeposit(key)
|
||||
require.Equal(t, int(proposalID), 2)
|
||||
require.Equal(t, addr, depositorAddr)
|
||||
|
||||
// invalid key
|
||||
addr2 := sdk.AccAddress("test1")
|
||||
key = DepositKey(5, addr2)
|
||||
require.Panics(t, func() { SplitKeyDeposit(key) })
|
||||
}
|
||||
|
||||
func TestVoteKeys(t *testing.T) {
|
||||
@@ -63,9 +58,4 @@ func TestVoteKeys(t *testing.T) {
|
||||
proposalID, voterAddr := SplitKeyDeposit(key)
|
||||
require.Equal(t, int(proposalID), 2)
|
||||
require.Equal(t, addr, voterAddr)
|
||||
|
||||
// invalid key
|
||||
addr2 := sdk.AccAddress("test1")
|
||||
key = VoteKey(5, addr2)
|
||||
require.Panics(t, func() { SplitKeyVote(key) })
|
||||
}
|
||||
|
||||
+12
-11
@@ -4,6 +4,7 @@ import (
|
||||
"encoding/binary"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/types/address"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -23,11 +24,11 @@ const (
|
||||
// Keys for slashing store
|
||||
// Items are stored with the following key: values
|
||||
//
|
||||
// - 0x01<consAddress_Bytes>: ValidatorSigningInfo
|
||||
// - 0x01<consAddrLen (1 Byte)><consAddress_Bytes>: ValidatorSigningInfo
|
||||
//
|
||||
// - 0x02<consAddress_Bytes><period_Bytes>: bool
|
||||
// - 0x02<consAddrLen (1 Byte)><consAddress_Bytes><period_Bytes>: bool
|
||||
//
|
||||
// - 0x03<accAddr_Bytes>: crypto.PubKey
|
||||
// - 0x03<accAddrLen (1 Byte)><accAddr_Bytes>: cryptotypes.PubKey
|
||||
var (
|
||||
ValidatorSigningInfoKeyPrefix = []byte{0x01} // Prefix for signing info
|
||||
ValidatorMissedBlockBitArrayKeyPrefix = []byte{0x02} // Prefix for missed block bit array
|
||||
@@ -36,31 +37,31 @@ var (
|
||||
|
||||
// ValidatorSigningInfoKey - stored by *Consensus* address (not operator address)
|
||||
func ValidatorSigningInfoKey(v sdk.ConsAddress) []byte {
|
||||
return append(ValidatorSigningInfoKeyPrefix, v.Bytes()...)
|
||||
return append(ValidatorSigningInfoKeyPrefix, address.MustLengthPrefix(v.Bytes())...)
|
||||
}
|
||||
|
||||
// ValidatorSigningInfoAddress - extract the address from a validator signing info key
|
||||
func ValidatorSigningInfoAddress(key []byte) (v sdk.ConsAddress) {
|
||||
addr := key[1:]
|
||||
if len(addr) != sdk.AddrLen {
|
||||
panic("unexpected key length")
|
||||
}
|
||||
// Remove prefix and address length.
|
||||
addr := key[2:]
|
||||
|
||||
return sdk.ConsAddress(addr)
|
||||
}
|
||||
|
||||
// ValidatorMissedBlockBitArrayPrefixKey - stored by *Consensus* address (not operator address)
|
||||
func ValidatorMissedBlockBitArrayPrefixKey(v sdk.ConsAddress) []byte {
|
||||
return append(ValidatorMissedBlockBitArrayKeyPrefix, v.Bytes()...)
|
||||
return append(ValidatorMissedBlockBitArrayKeyPrefix, address.MustLengthPrefix(v.Bytes())...)
|
||||
}
|
||||
|
||||
// ValidatorMissedBlockBitArrayKey - stored by *Consensus* address (not operator address)
|
||||
func ValidatorMissedBlockBitArrayKey(v sdk.ConsAddress, i int64) []byte {
|
||||
b := make([]byte, 8)
|
||||
binary.LittleEndian.PutUint64(b, uint64(i))
|
||||
|
||||
return append(ValidatorMissedBlockBitArrayPrefixKey(v), b...)
|
||||
}
|
||||
|
||||
// AddrPubkeyRelationKey gets pubkey relation key used to get the pubkey from the address
|
||||
func AddrPubkeyRelationKey(address []byte) []byte {
|
||||
return append(AddrPubkeyRelationKeyPrefix, address...)
|
||||
func AddrPubkeyRelationKey(addr []byte) []byte {
|
||||
return append(AddrPubkeyRelationKeyPrefix, address.MustLengthPrefix(addr)...)
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ import (
|
||||
"github.com/cosmos/cosmos-sdk/x/staking/types"
|
||||
)
|
||||
|
||||
// Calculate the ValidatorUpdates for the current block
|
||||
// BlockValidatorUpdates calculates the ValidatorUpdates for the current block
|
||||
// Called in each EndBlock
|
||||
func (k Keeper) BlockValidatorUpdates(ctx sdk.Context) []abci.ValidatorUpdate {
|
||||
// Calculate validator set changes.
|
||||
@@ -97,7 +97,7 @@ func (k Keeper) BlockValidatorUpdates(ctx sdk.Context) []abci.ValidatorUpdate {
|
||||
return validatorUpdates
|
||||
}
|
||||
|
||||
// Apply and return accumulated updates to the bonded validator set. Also,
|
||||
// ApplyAndReturnValidatorSetUpdates applies and return accumulated updates to the bonded validator set. Also,
|
||||
// * Updates the active valset as keyed by LastValidatorPowerKey.
|
||||
// * Updates the total power as keyed by LastTotalPowerKey.
|
||||
// * Updates validator status' according to updated powers.
|
||||
@@ -117,7 +117,10 @@ func (k Keeper) ApplyAndReturnValidatorSetUpdates(ctx sdk.Context) (updates []ab
|
||||
// Retrieve the last validator set.
|
||||
// The persistent set is updated later in this function.
|
||||
// (see LastValidatorPowerKey).
|
||||
last := k.getLastValidatorsByAddr(ctx)
|
||||
last, err := k.getLastValidatorsByAddr(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Iterate over validators, highest power to lowest.
|
||||
iterator := k.ValidatorsPowerStoreIterator(ctx)
|
||||
@@ -160,10 +163,11 @@ func (k Keeper) ApplyAndReturnValidatorSetUpdates(ctx sdk.Context) (updates []ab
|
||||
}
|
||||
|
||||
// fetch the old power bytes
|
||||
var valAddrBytes [sdk.AddrLen]byte
|
||||
|
||||
copy(valAddrBytes[:], valAddr[:])
|
||||
oldPowerBytes, found := last[valAddrBytes]
|
||||
valAddrStr, err := sdk.Bech32ifyAddressBytes(sdk.Bech32PrefixValAddr, valAddr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
oldPowerBytes, found := last[valAddrStr]
|
||||
newPower := validator.ConsensusPower()
|
||||
newPowerBytes := k.cdc.MustMarshalBinaryBare(&gogotypes.Int64Value{Value: newPower})
|
||||
|
||||
@@ -174,13 +178,17 @@ func (k Keeper) ApplyAndReturnValidatorSetUpdates(ctx sdk.Context) (updates []ab
|
||||
k.SetLastValidatorPower(ctx, valAddr, newPower)
|
||||
}
|
||||
|
||||
delete(last, valAddrBytes)
|
||||
delete(last, valAddrStr)
|
||||
count++
|
||||
|
||||
totalPower = totalPower.Add(sdk.NewInt(newPower))
|
||||
}
|
||||
|
||||
noLongerBonded := sortNoLongerBonded(last)
|
||||
noLongerBonded, err := sortNoLongerBonded(last)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, valAddrBytes := range noLongerBonded {
|
||||
validator := k.mustGetValidator(ctx, sdk.ValAddress(valAddrBytes))
|
||||
validator, err = k.bondedToUnbonding(ctx, validator)
|
||||
@@ -339,39 +347,46 @@ func (k Keeper) completeUnbondingValidator(ctx sdk.Context, validator types.Vali
|
||||
return validator
|
||||
}
|
||||
|
||||
// map of operator addresses to serialized power
|
||||
type validatorsByAddr map[[sdk.AddrLen]byte][]byte
|
||||
// map of operator bech32-addresses to serialized power
|
||||
// We use bech32 strings here, because we can't have slices as keys: map[[]byte][]byte
|
||||
type validatorsByAddr map[string][]byte
|
||||
|
||||
// get the last validator set
|
||||
func (k Keeper) getLastValidatorsByAddr(ctx sdk.Context) validatorsByAddr {
|
||||
func (k Keeper) getLastValidatorsByAddr(ctx sdk.Context) (validatorsByAddr, error) {
|
||||
last := make(validatorsByAddr)
|
||||
|
||||
iterator := k.LastValidatorsIterator(ctx)
|
||||
defer iterator.Close()
|
||||
|
||||
for ; iterator.Valid(); iterator.Next() {
|
||||
var valAddr [sdk.AddrLen]byte
|
||||
// extract the validator address from the key (prefix is 1-byte)
|
||||
copy(valAddr[:], iterator.Key()[1:])
|
||||
// extract the validator address from the key (prefix is 1-byte, addrLen is 1-byte)
|
||||
valAddr := types.AddressFromLastValidatorPowerKey(iterator.Key())
|
||||
valAddrStr, err := sdk.Bech32ifyAddressBytes(sdk.Bech32PrefixValAddr, valAddr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
powerBytes := iterator.Value()
|
||||
last[valAddr] = make([]byte, len(powerBytes))
|
||||
copy(last[valAddr], powerBytes)
|
||||
last[valAddrStr] = make([]byte, len(powerBytes))
|
||||
copy(last[valAddrStr], powerBytes)
|
||||
}
|
||||
|
||||
return last
|
||||
return last, nil
|
||||
}
|
||||
|
||||
// given a map of remaining validators to previous bonded power
|
||||
// returns the list of validators to be unbonded, sorted by operator address
|
||||
func sortNoLongerBonded(last validatorsByAddr) [][]byte {
|
||||
func sortNoLongerBonded(last validatorsByAddr) ([][]byte, error) {
|
||||
// sort the map keys for determinism
|
||||
noLongerBonded := make([][]byte, len(last))
|
||||
index := 0
|
||||
|
||||
for valAddrBytes := range last {
|
||||
valAddr := make([]byte, sdk.AddrLen)
|
||||
copy(valAddr, valAddrBytes[:])
|
||||
noLongerBonded[index] = valAddr
|
||||
for valAddrStr := range last {
|
||||
valAddrBytes, err := sdk.ValAddressFromBech32(valAddrStr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
noLongerBonded[index] = valAddrBytes
|
||||
index++
|
||||
}
|
||||
// sorted by address - order doesn't matter
|
||||
@@ -380,5 +395,5 @@ func sortNoLongerBonded(last validatorsByAddr) [][]byte {
|
||||
return bytes.Compare(noLongerBonded[i], noLongerBonded[j]) == -1
|
||||
})
|
||||
|
||||
return noLongerBonded
|
||||
return noLongerBonded, nil
|
||||
}
|
||||
|
||||
@@ -327,7 +327,7 @@ func (k Keeper) IterateLastValidatorPowers(ctx sdk.Context, handler func(operato
|
||||
defer iter.Close()
|
||||
|
||||
for ; iter.Valid(); iter.Next() {
|
||||
addr := sdk.ValAddress(iter.Key()[len(types.LastValidatorPowerKey):])
|
||||
addr := sdk.ValAddress(types.AddressFromLastValidatorPowerKey(iter.Key()))
|
||||
intV := &gogotypes.Int64Value{}
|
||||
|
||||
k.cdc.MustUnmarshalBinaryBare(iter.Value(), intV)
|
||||
|
||||
+82
-73
@@ -8,6 +8,7 @@ import (
|
||||
"time"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/types/address"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -48,24 +49,29 @@ var (
|
||||
HistoricalInfoKey = []byte{0x50} // prefix for the historical info
|
||||
)
|
||||
|
||||
// gets the key for the validator with address
|
||||
// GetValidatorKey creates the key for the validator with address
|
||||
// VALUE: staking/Validator
|
||||
func GetValidatorKey(operatorAddr sdk.ValAddress) []byte {
|
||||
return append(ValidatorsKey, operatorAddr.Bytes()...)
|
||||
return append(ValidatorsKey, address.MustLengthPrefix(operatorAddr)...)
|
||||
}
|
||||
|
||||
// gets the key for the validator with pubkey
|
||||
// GetValidatorByConsAddrKey creates the key for the validator with pubkey
|
||||
// VALUE: validator operator address ([]byte)
|
||||
func GetValidatorByConsAddrKey(addr sdk.ConsAddress) []byte {
|
||||
return append(ValidatorsByConsAddrKey, addr.Bytes()...)
|
||||
return append(ValidatorsByConsAddrKey, address.MustLengthPrefix(addr)...)
|
||||
}
|
||||
|
||||
// Get the validator operator address from LastValidatorPowerKey
|
||||
// AddressFromValidatorsKey creates the validator operator address from ValidatorsKey
|
||||
func AddressFromValidatorsKey(key []byte) []byte {
|
||||
return key[2:] // remove prefix bytes and address length
|
||||
}
|
||||
|
||||
// AddressFromLastValidatorPowerKey creates the validator operator address from LastValidatorPowerKey
|
||||
func AddressFromLastValidatorPowerKey(key []byte) []byte {
|
||||
return key[1:] // remove prefix bytes
|
||||
return key[2:] // remove prefix bytes and address length
|
||||
}
|
||||
|
||||
// get the validator by power index.
|
||||
// GetValidatorsByPowerIndexKey creates 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 operator address ([]byte)
|
||||
@@ -80,39 +86,39 @@ func GetValidatorsByPowerIndexKey(validator Validator) []byte {
|
||||
powerBytes := consensusPowerBytes
|
||||
powerBytesLen := len(powerBytes) // 8
|
||||
|
||||
// key is of format prefix || powerbytes || addrBytes
|
||||
key := make([]byte, 1+powerBytesLen+sdk.AddrLen)
|
||||
|
||||
key[0] = ValidatorsByPowerIndexKey[0]
|
||||
copy(key[1:powerBytesLen+1], powerBytes)
|
||||
addr, err := sdk.ValAddressFromBech32(validator.OperatorAddress)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
operAddrInvr := sdk.CopyBytes(addr)
|
||||
addrLen := len(operAddrInvr)
|
||||
|
||||
for i, b := range operAddrInvr {
|
||||
operAddrInvr[i] = ^b
|
||||
}
|
||||
|
||||
copy(key[powerBytesLen+1:], operAddrInvr)
|
||||
// key is of format prefix || powerbytes || addrLen (1byte) || addrBytes
|
||||
key := make([]byte, 1+powerBytesLen+1+addrLen)
|
||||
|
||||
key[0] = ValidatorsByPowerIndexKey[0]
|
||||
copy(key[1:powerBytesLen+1], powerBytes)
|
||||
key[powerBytesLen+1] = byte(addrLen)
|
||||
copy(key[powerBytesLen+2:], operAddrInvr)
|
||||
|
||||
return key
|
||||
}
|
||||
|
||||
// get the bonded validator index key for an operator address
|
||||
// GetLastValidatorPowerKey creates the bonded validator index key for an operator address
|
||||
func GetLastValidatorPowerKey(operator sdk.ValAddress) []byte {
|
||||
return append(LastValidatorPowerKey, operator...)
|
||||
return append(LastValidatorPowerKey, address.MustLengthPrefix(operator)...)
|
||||
}
|
||||
|
||||
// parse the validators operator address from power rank key
|
||||
// ParseValidatorPowerRankKey parses the validators operator address from power rank key
|
||||
func ParseValidatorPowerRankKey(key []byte) (operAddr []byte) {
|
||||
powerBytesLen := 8
|
||||
if len(key) != 1+powerBytesLen+sdk.AddrLen {
|
||||
panic("Invalid validator power rank key length")
|
||||
}
|
||||
|
||||
operAddr = sdk.CopyBytes(key[powerBytesLen+1:])
|
||||
// key is of format prefix (1 byte) || powerbytes || addrLen (1byte) || addrBytes
|
||||
operAddr = sdk.CopyBytes(key[powerBytesLen+2:])
|
||||
|
||||
for i, b := range operAddr {
|
||||
operAddr[i] = ^b
|
||||
@@ -165,55 +171,51 @@ func ParseValidatorQueueKey(bz []byte) (time.Time, int64, error) {
|
||||
return ts, int64(height), nil
|
||||
}
|
||||
|
||||
// gets the key for delegator bond with validator
|
||||
// GetDelegationKey creates the key for delegator bond with validator
|
||||
// VALUE: staking/Delegation
|
||||
func GetDelegationKey(delAddr sdk.AccAddress, valAddr sdk.ValAddress) []byte {
|
||||
return append(GetDelegationsKey(delAddr), valAddr.Bytes()...)
|
||||
return append(GetDelegationsKey(delAddr), address.MustLengthPrefix(valAddr)...)
|
||||
}
|
||||
|
||||
// gets the prefix for a delegator for all validators
|
||||
// GetDelegationsKey creates the prefix for a delegator for all validators
|
||||
func GetDelegationsKey(delAddr sdk.AccAddress) []byte {
|
||||
return append(DelegationKey, delAddr.Bytes()...)
|
||||
return append(DelegationKey, address.MustLengthPrefix(delAddr)...)
|
||||
}
|
||||
|
||||
// gets the key for an unbonding delegation by delegator and validator addr
|
||||
// GetUBDKey creates the key for an unbonding delegation by delegator and validator addr
|
||||
// VALUE: staking/UnbondingDelegation
|
||||
func GetUBDKey(delAddr sdk.AccAddress, valAddr sdk.ValAddress) []byte {
|
||||
return append(
|
||||
GetUBDsKey(delAddr.Bytes()),
|
||||
valAddr.Bytes()...)
|
||||
return append(GetUBDsKey(delAddr.Bytes()), address.MustLengthPrefix(valAddr)...)
|
||||
}
|
||||
|
||||
// gets the index-key for an unbonding delegation, stored by validator-index
|
||||
// GetUBDByValIndexKey creates the index-key for an unbonding delegation, stored by validator-index
|
||||
// VALUE: none (key rearrangement used)
|
||||
func GetUBDByValIndexKey(delAddr sdk.AccAddress, valAddr sdk.ValAddress) []byte {
|
||||
return append(GetUBDsByValIndexKey(valAddr), delAddr.Bytes()...)
|
||||
return append(GetUBDsByValIndexKey(valAddr), address.MustLengthPrefix(delAddr)...)
|
||||
}
|
||||
|
||||
// rearranges the ValIndexKey to get the UBDKey
|
||||
// GetUBDKeyFromValIndexKey rearranges the ValIndexKey to get the UBDKey
|
||||
func GetUBDKeyFromValIndexKey(indexKey []byte) []byte {
|
||||
addrs := indexKey[1:] // remove prefix bytes
|
||||
if len(addrs) != 2*sdk.AddrLen {
|
||||
panic("unexpected key length")
|
||||
}
|
||||
|
||||
valAddr := addrs[:sdk.AddrLen]
|
||||
delAddr := addrs[sdk.AddrLen:]
|
||||
valAddrLen := addrs[0]
|
||||
valAddr := addrs[1 : 1+valAddrLen]
|
||||
delAddr := addrs[valAddrLen+2:]
|
||||
|
||||
return GetUBDKey(delAddr, valAddr)
|
||||
}
|
||||
|
||||
// gets the prefix for all unbonding delegations from a delegator
|
||||
// GetUBDsKey creates the prefix for all unbonding delegations from a delegator
|
||||
func GetUBDsKey(delAddr sdk.AccAddress) []byte {
|
||||
return append(UnbondingDelegationKey, delAddr.Bytes()...)
|
||||
return append(UnbondingDelegationKey, address.MustLengthPrefix(delAddr)...)
|
||||
}
|
||||
|
||||
// gets the prefix keyspace for the indexes of unbonding delegations for a validator
|
||||
// GetUBDsByValIndexKey creates the prefix keyspace for the indexes of unbonding delegations for a validator
|
||||
func GetUBDsByValIndexKey(valAddr sdk.ValAddress) []byte {
|
||||
return append(UnbondingDelegationByValIndexKey, valAddr.Bytes()...)
|
||||
return append(UnbondingDelegationByValIndexKey, address.MustLengthPrefix(valAddr)...)
|
||||
}
|
||||
|
||||
// gets the prefix for all unbonding delegations from a delegator
|
||||
// GetUnbondingDelegationTimeKey creates the prefix for all unbonding delegations from a delegator
|
||||
func GetUnbondingDelegationTimeKey(timestamp time.Time) []byte {
|
||||
bz := sdk.FormatTimeBytes(timestamp)
|
||||
return append(UnbondingQueueKey, bz...)
|
||||
@@ -222,69 +224,76 @@ func GetUnbondingDelegationTimeKey(timestamp time.Time) []byte {
|
||||
// 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 := make([]byte, 1+sdk.AddrLen*3)
|
||||
// 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:sdk.AddrLen+1], GetREDsKey(delAddr.Bytes()))
|
||||
copy(key[sdk.AddrLen+1:2*sdk.AddrLen+1], valSrcAddr.Bytes())
|
||||
copy(key[2*sdk.AddrLen+1:3*sdk.AddrLen+1], valDstAddr.Bytes())
|
||||
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
|
||||
}
|
||||
|
||||
// gets the index-key for a redelegation, stored by source-validator-index
|
||||
// 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 || delAddr || valDstAddr
|
||||
key := make([]byte, len(REDSFromValsSrcKey)+2*sdk.AddrLen)
|
||||
// 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)
|
||||
copy(key[offset:offset+sdk.AddrLen], delAddr.Bytes())
|
||||
copy(key[offset+sdk.AddrLen:offset+2*sdk.AddrLen], valDstAddr.Bytes())
|
||||
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
|
||||
}
|
||||
|
||||
// gets the index-key for a redelegation, stored by destination-validator-index
|
||||
// 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 || delAddr || valSrcAddr
|
||||
key := make([]byte, len(REDSToValsDstKey)+2*sdk.AddrLen)
|
||||
// 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)
|
||||
copy(key[offset:offset+sdk.AddrLen], delAddr.Bytes())
|
||||
copy(key[offset+sdk.AddrLen:offset+2*sdk.AddrLen], valSrcAddr.Bytes())
|
||||
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
|
||||
}
|
||||
|
||||
// GetREDKeyFromValSrcIndexKey rearranges the ValSrcIndexKey to get the REDKey
|
||||
func GetREDKeyFromValSrcIndexKey(indexKey []byte) []byte {
|
||||
// note that first byte is prefix byte
|
||||
if len(indexKey) != 3*sdk.AddrLen+1 {
|
||||
panic("unexpected key length")
|
||||
}
|
||||
// note that first byte is prefix byte, which we remove
|
||||
addrs := indexKey[1:]
|
||||
|
||||
valSrcAddr := indexKey[1 : sdk.AddrLen+1]
|
||||
delAddr := indexKey[sdk.AddrLen+1 : 2*sdk.AddrLen+1]
|
||||
valDstAddr := indexKey[2*sdk.AddrLen+1 : 3*sdk.AddrLen+1]
|
||||
valSrcAddrLen := addrs[0]
|
||||
valSrcAddr := addrs[1 : valSrcAddrLen+1]
|
||||
delAddrLen := addrs[valSrcAddrLen+1]
|
||||
delAddr := addrs[valSrcAddrLen+2 : valSrcAddrLen+2+delAddrLen]
|
||||
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
|
||||
if len(indexKey) != 3*sdk.AddrLen+1 {
|
||||
panic("unexpected key length")
|
||||
}
|
||||
// note that first byte is prefix byte, which we remove
|
||||
addrs := indexKey[1:]
|
||||
|
||||
valDstAddr := indexKey[1 : sdk.AddrLen+1]
|
||||
delAddr := indexKey[sdk.AddrLen+1 : 2*sdk.AddrLen+1]
|
||||
valSrcAddr := indexKey[2*sdk.AddrLen+1 : 3*sdk.AddrLen+1]
|
||||
valDstAddrLen := addrs[0]
|
||||
valDstAddr := addrs[1 : valDstAddrLen+1]
|
||||
delAddrLen := addrs[valDstAddrLen+1]
|
||||
delAddr := addrs[valDstAddrLen+2 : valDstAddrLen+2+delAddrLen]
|
||||
valSrcAddr := addrs[valDstAddrLen+delAddrLen+3:]
|
||||
|
||||
return GetREDKey(delAddr, valSrcAddr, valDstAddr)
|
||||
}
|
||||
@@ -299,25 +308,25 @@ func GetRedelegationTimeKey(timestamp time.Time) []byte {
|
||||
// GetREDsKey returns a key prefix for indexing a redelegation from a delegator
|
||||
// address.
|
||||
func GetREDsKey(delAddr sdk.AccAddress) []byte {
|
||||
return append(RedelegationKey, delAddr.Bytes()...)
|
||||
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, valSrcAddr.Bytes()...)
|
||||
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 {
|
||||
return append(RedelegationByValDstIndexKey, valDstAddr.Bytes()...)
|
||||
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), delAddr.Bytes()...)
|
||||
return append(GetREDsToValDstIndexKey(valDstAddr), address.MustLengthPrefix(delAddr)...)
|
||||
}
|
||||
|
||||
// GetHistoricalInfoKey returns a key prefix for indexing HistoricalInfo objects.
|
||||
|
||||
@@ -37,10 +37,10 @@ func TestGetValidatorPowerRank(t *testing.T) {
|
||||
validator types.Validator
|
||||
wantHex string
|
||||
}{
|
||||
{val1, "2300000000000000009c288ede7df62742fc3b7d0962045a8cef0f79f6"},
|
||||
{val2, "2300000000000000019c288ede7df62742fc3b7d0962045a8cef0f79f6"},
|
||||
{val3, "23000000000000000a9c288ede7df62742fc3b7d0962045a8cef0f79f6"},
|
||||
{val4, "2300000100000000009c288ede7df62742fc3b7d0962045a8cef0f79f6"},
|
||||
{val1, "230000000000000000149c288ede7df62742fc3b7d0962045a8cef0f79f6"},
|
||||
{val2, "230000000000000001149c288ede7df62742fc3b7d0962045a8cef0f79f6"},
|
||||
{val3, "23000000000000000a149c288ede7df62742fc3b7d0962045a8cef0f79f6"},
|
||||
{val4, "230000010000000000149c288ede7df62742fc3b7d0962045a8cef0f79f6"},
|
||||
}
|
||||
for i, tt := range tests {
|
||||
got := hex.EncodeToString(types.GetValidatorsByPowerIndexKey(tt.validator))
|
||||
@@ -57,11 +57,11 @@ func TestGetREDByValDstIndexKey(t *testing.T) {
|
||||
wantHex string
|
||||
}{
|
||||
{sdk.AccAddress(keysAddr1), sdk.ValAddress(keysAddr1), sdk.ValAddress(keysAddr1),
|
||||
"3663d771218209d8bd03c482f69dfba57310f0860963d771218209d8bd03c482f69dfba57310f0860963d771218209d8bd03c482f69dfba57310f08609"},
|
||||
"361463d771218209d8bd03c482f69dfba57310f086091463d771218209d8bd03c482f69dfba57310f086091463d771218209d8bd03c482f69dfba57310f08609"},
|
||||
{sdk.AccAddress(keysAddr1), sdk.ValAddress(keysAddr2), sdk.ValAddress(keysAddr3),
|
||||
"363ab62f0d93849be495e21e3e9013a517038f45bd63d771218209d8bd03c482f69dfba57310f086095ef3b5f25c54946d4a89fc0d09d2f126614540f2"},
|
||||
"36143ab62f0d93849be495e21e3e9013a517038f45bd1463d771218209d8bd03c482f69dfba57310f08609145ef3b5f25c54946d4a89fc0d09d2f126614540f2"},
|
||||
{sdk.AccAddress(keysAddr2), sdk.ValAddress(keysAddr1), sdk.ValAddress(keysAddr3),
|
||||
"363ab62f0d93849be495e21e3e9013a517038f45bd5ef3b5f25c54946d4a89fc0d09d2f126614540f263d771218209d8bd03c482f69dfba57310f08609"},
|
||||
"36143ab62f0d93849be495e21e3e9013a517038f45bd145ef3b5f25c54946d4a89fc0d09d2f126614540f21463d771218209d8bd03c482f69dfba57310f08609"},
|
||||
}
|
||||
for i, tt := range tests {
|
||||
got := hex.EncodeToString(types.GetREDByValDstIndexKey(tt.delAddr, tt.valSrcAddr, tt.valDstAddr))
|
||||
@@ -78,11 +78,11 @@ func TestGetREDByValSrcIndexKey(t *testing.T) {
|
||||
wantHex string
|
||||
}{
|
||||
{sdk.AccAddress(keysAddr1), sdk.ValAddress(keysAddr1), sdk.ValAddress(keysAddr1),
|
||||
"3563d771218209d8bd03c482f69dfba57310f0860963d771218209d8bd03c482f69dfba57310f0860963d771218209d8bd03c482f69dfba57310f08609"},
|
||||
"351463d771218209d8bd03c482f69dfba57310f086091463d771218209d8bd03c482f69dfba57310f086091463d771218209d8bd03c482f69dfba57310f08609"},
|
||||
{sdk.AccAddress(keysAddr1), sdk.ValAddress(keysAddr2), sdk.ValAddress(keysAddr3),
|
||||
"355ef3b5f25c54946d4a89fc0d09d2f126614540f263d771218209d8bd03c482f69dfba57310f086093ab62f0d93849be495e21e3e9013a517038f45bd"},
|
||||
"35145ef3b5f25c54946d4a89fc0d09d2f126614540f21463d771218209d8bd03c482f69dfba57310f08609143ab62f0d93849be495e21e3e9013a517038f45bd"},
|
||||
{sdk.AccAddress(keysAddr2), sdk.ValAddress(keysAddr1), sdk.ValAddress(keysAddr3),
|
||||
"3563d771218209d8bd03c482f69dfba57310f086095ef3b5f25c54946d4a89fc0d09d2f126614540f23ab62f0d93849be495e21e3e9013a517038f45bd"},
|
||||
"351463d771218209d8bd03c482f69dfba57310f08609145ef3b5f25c54946d4a89fc0d09d2f126614540f2143ab62f0d93849be495e21e3e9013a517038f45bd"},
|
||||
}
|
||||
for i, tt := range tests {
|
||||
got := hex.EncodeToString(types.GetREDByValSrcIndexKey(tt.delAddr, tt.valSrcAddr, tt.valDstAddr))
|
||||
|
||||
Reference in New Issue
Block a user