feat!: change Coin storage model (#9832)
<!-- The default pull request template is for types feat, fix, or refactor. For other templates, add one of the following parameters to the url: - template=docs.md - template=other.md --> ## Description Closes: #9361 <!-- Add a description of the changes that this PR introduces and the files that are the most critical to review. --> --- ### Author Checklist *All items are required. Please add a note to the item if the item is not applicable and please add links to any relevant follow up issues.* I have... - [x] included the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [x] added `!` to the type prefix if API or client breaking change - [x] targeted the correct branch (see [PR Targeting](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#pr-targeting)) - [x] provided a link to the relevant issue or specification - [x] followed the guidelines for [building modules](https://github.com/cosmos/cosmos-sdk/blob/master/docs/building-modules) - [x] included the necessary unit and integration [tests](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#testing) - [x] added a changelog entry to `CHANGELOG.md` - [ ] included comments for [documenting Go code](https://blog.golang.org/godoc) - [ ] updated the relevant documentation or specification - [x] reviewed "Files changed" and left comments if necessary - [ ] confirmed all CI checks have passed ### Reviewers Checklist *All items are required. Please add a note if the item is not applicable and please add your handle next to the items reviewed if you only reviewed selected items.* I have... - [ ] confirmed the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [ ] confirmed `!` in the type prefix if API or client breaking change - [ ] confirmed all author checklist items have been addressed - [ ] reviewed state machine logic - [ ] reviewed API design and naming - [ ] reviewed documentation is accurate - [ ] reviewed tests and test coverage - [ ] manually tested (if applicable)
This commit is contained in:
parent
bdf5aee7a3
commit
eb79dd022f
|
@ -64,6 +64,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
|
||||||
* [\#9576](https://github.com/cosmos/cosmos-sdk/pull/9576) Add debug error message to `sdkerrors.QueryResult` when enabled
|
* [\#9576](https://github.com/cosmos/cosmos-sdk/pull/9576) Add debug error message to `sdkerrors.QueryResult` when enabled
|
||||||
* [\#9650](https://github.com/cosmos/cosmos-sdk/pull/9650) Removed deprecated message handler implementation from the SDK modules.
|
* [\#9650](https://github.com/cosmos/cosmos-sdk/pull/9650) Removed deprecated message handler implementation from the SDK modules.
|
||||||
* (x/capability) [\#9836](https://github.com/cosmos/cosmos-sdk/pull/9836) Removed `InitializeAndSeal(ctx sdk.Context)` and replaced with `Seal()`. App must add x/capability to begin blockers which will assure that the x/capability keeper is properly initialized. The x/capability begin blocker must be run before any other module which uses x/capability.
|
* (x/capability) [\#9836](https://github.com/cosmos/cosmos-sdk/pull/9836) Removed `InitializeAndSeal(ctx sdk.Context)` and replaced with `Seal()`. App must add x/capability to begin blockers which will assure that the x/capability keeper is properly initialized. The x/capability begin blocker must be run before any other module which uses x/capability.
|
||||||
|
* (x/bank) [\#9832] (https://github.com/cosmos/cosmos-sdk/pull/9832) `AddressFromBalancesStore` renamed to `AddressAndDenomFromBalancesStore`.
|
||||||
|
|
||||||
### Client Breaking Changes
|
### Client Breaking Changes
|
||||||
|
|
||||||
|
@ -101,6 +102,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
|
||||||
|
|
||||||
* (x/bank) [\#9611](https://github.com/cosmos/cosmos-sdk/pull/9611) Introduce a new index to act as a reverse index between a denomination and address allowing to query for
|
* (x/bank) [\#9611](https://github.com/cosmos/cosmos-sdk/pull/9611) Introduce a new index to act as a reverse index between a denomination and address allowing to query for
|
||||||
token holders of a specific denomination. `DenomOwners` is updated to use the new reverse index.
|
token holders of a specific denomination. `DenomOwners` is updated to use the new reverse index.
|
||||||
|
* (x/bank) [\#9832] (https://github.com/cosmos/cosmos-sdk/pull/9832) Account balance is stored as `sdk.Int` rather than `sdk.Coin`.
|
||||||
|
|
||||||
## [v0.43.0-rc0](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.43.0-rc0) - 2021-06-25
|
## [v0.43.0-rc0](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.43.0-rc0) - 2021-06-25
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"account_identifier": {
|
"account_identifier": {
|
||||||
"address":"cosmos1kezmr2chzy7w00nhh7qxhpqphdwum3j0mgdaw0"
|
"address":"cosmos1y3awd3vl7g29q44uvz0yrevcduf2exvkwxk3uq"
|
||||||
},
|
},
|
||||||
"currency":{
|
"currency":{
|
||||||
"symbol":"stake",
|
"symbol":"stake",
|
||||||
|
|
Binary file not shown.
|
@ -171,7 +171,7 @@ func (s *paginationTestSuite) TestReverseFilteredPaginations() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func ExampleFilteredPaginate() {
|
func ExampleFilteredPaginate() {
|
||||||
app, ctx, appCodec := setupTest()
|
app, ctx, _ := setupTest()
|
||||||
|
|
||||||
var balances sdk.Coins
|
var balances sdk.Coins
|
||||||
for i := 0; i < numBalances; i++ {
|
for i := 0; i < numBalances; i++ {
|
||||||
|
@ -200,16 +200,16 @@ func ExampleFilteredPaginate() {
|
||||||
|
|
||||||
var balResult sdk.Coins
|
var balResult sdk.Coins
|
||||||
pageRes, err := query.FilteredPaginate(accountStore, pageReq, func(key []byte, value []byte, accumulate bool) (bool, error) {
|
pageRes, err := query.FilteredPaginate(accountStore, pageReq, func(key []byte, value []byte, accumulate bool) (bool, error) {
|
||||||
var bal sdk.Coin
|
var amount sdk.Int
|
||||||
err := appCodec.Unmarshal(value, &bal)
|
err := amount.Unmarshal(value)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// filter balances with amount greater than 100
|
// filter amount greater than 100
|
||||||
if bal.Amount.Int64() > int64(100) {
|
if amount.Int64() > int64(100) {
|
||||||
if accumulate {
|
if accumulate {
|
||||||
balResult = append(balResult, bal)
|
balResult = append(balResult, sdk.NewCoin(string(key), amount))
|
||||||
}
|
}
|
||||||
|
|
||||||
return true, nil
|
return true, nil
|
||||||
|
@ -232,16 +232,16 @@ func execFilterPaginate(store sdk.KVStore, pageReq *query.PageRequest, appCodec
|
||||||
|
|
||||||
var balResult sdk.Coins
|
var balResult sdk.Coins
|
||||||
res, err = query.FilteredPaginate(accountStore, pageReq, func(key []byte, value []byte, accumulate bool) (bool, error) {
|
res, err = query.FilteredPaginate(accountStore, pageReq, func(key []byte, value []byte, accumulate bool) (bool, error) {
|
||||||
var bal sdk.Coin
|
var amount sdk.Int
|
||||||
err := appCodec.Unmarshal(value, &bal)
|
err := amount.Unmarshal(value)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// filter balances with amount greater than 100
|
// filter amount greater than 100
|
||||||
if bal.Amount.Int64() > int64(100) {
|
if amount.Int64() > int64(100) {
|
||||||
if accumulate {
|
if accumulate {
|
||||||
balResult = append(balResult, bal)
|
balResult = append(balResult, sdk.NewCoin(string(key), amount))
|
||||||
}
|
}
|
||||||
|
|
||||||
return true, nil
|
return true, nil
|
||||||
|
|
|
@ -319,12 +319,12 @@ func ExamplePaginate() {
|
||||||
balancesStore := prefix.NewStore(authStore, types.BalancesPrefix)
|
balancesStore := prefix.NewStore(authStore, types.BalancesPrefix)
|
||||||
accountStore := prefix.NewStore(balancesStore, address.MustLengthPrefix(addr1))
|
accountStore := prefix.NewStore(balancesStore, address.MustLengthPrefix(addr1))
|
||||||
pageRes, err := query.Paginate(accountStore, request.Pagination, func(key []byte, value []byte) error {
|
pageRes, err := query.Paginate(accountStore, request.Pagination, func(key []byte, value []byte) error {
|
||||||
var tempRes sdk.Coin
|
var amount sdk.Int
|
||||||
err := app.AppCodec().Unmarshal(value, &tempRes)
|
err := amount.Unmarshal(value)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
balResult = append(balResult, tempRes)
|
balResult = append(balResult, sdk.NewCoin(string(key), amount))
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
if err != nil { // should return no error
|
if err != nil { // should return no error
|
||||||
|
|
|
@ -59,13 +59,12 @@ func (k BaseKeeper) AllBalances(ctx context.Context, req *types.QueryAllBalances
|
||||||
balances := sdk.NewCoins()
|
balances := sdk.NewCoins()
|
||||||
accountStore := k.getAccountStore(sdkCtx, addr)
|
accountStore := k.getAccountStore(sdkCtx, addr)
|
||||||
|
|
||||||
pageRes, err := query.Paginate(accountStore, req.Pagination, func(_, value []byte) error {
|
pageRes, err := query.Paginate(accountStore, req.Pagination, func(key, value []byte) error {
|
||||||
var result sdk.Coin
|
var amount sdk.Int
|
||||||
err := k.cdc.Unmarshal(value, &result)
|
if err := amount.Unmarshal(value); err != nil {
|
||||||
if err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
balances = append(balances, result)
|
balances = append(balances, sdk.NewCoin(string(key), amount))
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -187,7 +186,7 @@ func (k BaseKeeper) DenomOwners(
|
||||||
req.Pagination,
|
req.Pagination,
|
||||||
func(key []byte, value []byte, accumulate bool) (bool, error) {
|
func(key []byte, value []byte, accumulate bool) (bool, error) {
|
||||||
if accumulate {
|
if accumulate {
|
||||||
address, err := types.AddressFromBalancesStore(key)
|
address, _, err := types.AddressAndDenomFromBalancesStore(key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -243,8 +243,11 @@ func (k BaseSendKeeper) initBalances(ctx sdk.Context, addr sdk.AccAddress, balan
|
||||||
|
|
||||||
// x/bank invariants prohibit persistence of zero balances
|
// x/bank invariants prohibit persistence of zero balances
|
||||||
if !balance.IsZero() {
|
if !balance.IsZero() {
|
||||||
bz := k.cdc.MustMarshal(&balance)
|
amount, err := balance.Amount.Marshal()
|
||||||
accountStore.Set([]byte(balance.Denom), bz)
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
accountStore.Set([]byte(balance.Denom), amount)
|
||||||
|
|
||||||
denomPrefixStore, ok := denomPrefixStores[balance.Denom]
|
denomPrefixStore, ok := denomPrefixStores[balance.Denom]
|
||||||
if !ok {
|
if !ok {
|
||||||
|
@ -278,8 +281,11 @@ func (k BaseSendKeeper) setBalance(ctx sdk.Context, addr sdk.AccAddress, balance
|
||||||
accountStore.Delete([]byte(balance.Denom))
|
accountStore.Delete([]byte(balance.Denom))
|
||||||
denomPrefixStore.Delete(address.MustLengthPrefix(addr))
|
denomPrefixStore.Delete(address.MustLengthPrefix(addr))
|
||||||
} else {
|
} else {
|
||||||
bz := k.cdc.MustMarshal(&balance)
|
amount, err := balance.Amount.Marshal()
|
||||||
accountStore.Set([]byte(balance.Denom), bz)
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
accountStore.Set([]byte(balance.Denom), amount)
|
||||||
|
|
||||||
// Store a reverse index from denomination to account address with a
|
// Store a reverse index from denomination to account address with a
|
||||||
// sentinel value.
|
// sentinel value.
|
||||||
|
|
|
@ -98,16 +98,17 @@ func (k BaseViewKeeper) GetAccountsBalances(ctx sdk.Context) []types.Balance {
|
||||||
// by address.
|
// by address.
|
||||||
func (k BaseViewKeeper) GetBalance(ctx sdk.Context, addr sdk.AccAddress, denom string) sdk.Coin {
|
func (k BaseViewKeeper) GetBalance(ctx sdk.Context, addr sdk.AccAddress, denom string) sdk.Coin {
|
||||||
accountStore := k.getAccountStore(ctx, addr)
|
accountStore := k.getAccountStore(ctx, addr)
|
||||||
|
amount := sdk.ZeroInt()
|
||||||
bz := accountStore.Get([]byte(denom))
|
bz := accountStore.Get([]byte(denom))
|
||||||
if bz == nil {
|
if bz == nil {
|
||||||
return sdk.NewCoin(denom, sdk.ZeroInt())
|
return sdk.NewCoin(denom, amount)
|
||||||
}
|
}
|
||||||
|
|
||||||
var balance sdk.Coin
|
if err := amount.Unmarshal(bz); err != nil {
|
||||||
k.cdc.MustUnmarshal(bz, &balance)
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
return balance
|
return sdk.NewCoin(denom, amount)
|
||||||
}
|
}
|
||||||
|
|
||||||
// IterateAccountBalances iterates over the balances of a single account and
|
// IterateAccountBalances iterates over the balances of a single account and
|
||||||
|
@ -120,10 +121,12 @@ func (k BaseViewKeeper) IterateAccountBalances(ctx sdk.Context, addr sdk.AccAddr
|
||||||
defer iterator.Close()
|
defer iterator.Close()
|
||||||
|
|
||||||
for ; iterator.Valid(); iterator.Next() {
|
for ; iterator.Valid(); iterator.Next() {
|
||||||
var balance sdk.Coin
|
var amount sdk.Int
|
||||||
k.cdc.MustUnmarshal(iterator.Value(), &balance)
|
if err := amount.Unmarshal(iterator.Value()); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
if cb(balance) {
|
if cb(sdk.NewCoin(string(iterator.Key()), amount)) {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -140,7 +143,7 @@ func (k BaseViewKeeper) IterateAllBalances(ctx sdk.Context, cb func(sdk.AccAddre
|
||||||
defer iterator.Close()
|
defer iterator.Close()
|
||||||
|
|
||||||
for ; iterator.Valid(); iterator.Next() {
|
for ; iterator.Valid(); iterator.Next() {
|
||||||
address, err := types.AddressFromBalancesStore(iterator.Key())
|
address, denom, err := types.AddressAndDenomFromBalancesStore(iterator.Key())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
k.Logger(ctx).With("key", iterator.Key(), "err", err).Error("failed to get address from balances store")
|
k.Logger(ctx).With("key", iterator.Key(), "err", err).Error("failed to get address from balances store")
|
||||||
// TODO: revisit, for now, panic here to keep same behavior as in 0.42
|
// TODO: revisit, for now, panic here to keep same behavior as in 0.42
|
||||||
|
@ -148,10 +151,12 @@ func (k BaseViewKeeper) IterateAllBalances(ctx sdk.Context, cb func(sdk.AccAddre
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var balance sdk.Coin
|
var amount sdk.Int
|
||||||
k.cdc.MustUnmarshal(iterator.Value(), &balance)
|
if err := amount.Unmarshal(iterator.Value()); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
if cb(address, balance) {
|
if cb(address, sdk.NewCoin(denom, amount)) {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,11 +6,13 @@ import (
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
"github.com/cosmos/cosmos-sdk/types/address"
|
"github.com/cosmos/cosmos-sdk/types/address"
|
||||||
v043 "github.com/cosmos/cosmos-sdk/x/bank/migrations/v043"
|
v043 "github.com/cosmos/cosmos-sdk/x/bank/migrations/v043"
|
||||||
|
"github.com/cosmos/cosmos-sdk/x/bank/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
// MigrateStore performs in-place store migrations from v0.43 to v0.44. The
|
// MigrateStore performs in-place store migrations from v0.43 to v0.44. The
|
||||||
// migration includes:
|
// migration includes:
|
||||||
//
|
//
|
||||||
|
// - Migrate coin storage to save only amount.
|
||||||
// - Add an additional reverse index from denomination to address.
|
// - Add an additional reverse index from denomination to address.
|
||||||
func MigrateStore(ctx sdk.Context, storeKey sdk.StoreKey, cdc codec.BinaryCodec) error {
|
func MigrateStore(ctx sdk.Context, storeKey sdk.StoreKey, cdc codec.BinaryCodec) error {
|
||||||
store := ctx.KVStore(storeKey)
|
store := ctx.KVStore(storeKey)
|
||||||
|
@ -36,6 +38,19 @@ func addDenomReverseIndex(store sdk.KVStore, cdc codec.BinaryCodec) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var coin sdk.DecCoin
|
||||||
|
if err := cdc.Unmarshal(oldBalancesIter.Value(), &coin); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
bz, err := coin.Amount.Marshal()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
newStore := prefix.NewStore(store, types.CreateAccountBalancesPrefix(addr))
|
||||||
|
newStore.Set([]byte(coin.Denom), bz)
|
||||||
|
|
||||||
denomPrefixStore, ok := denomPrefixStores[balance.Denom]
|
denomPrefixStore, ok := denomPrefixStores[balance.Denom]
|
||||||
if !ok {
|
if !ok {
|
||||||
denomPrefixStore = prefix.NewStore(store, CreateAddressDenomPrefix(balance.Denom))
|
denomPrefixStore = prefix.NewStore(store, CreateAddressDenomPrefix(balance.Denom))
|
||||||
|
|
|
@ -12,6 +12,7 @@ import (
|
||||||
"github.com/cosmos/cosmos-sdk/types/address"
|
"github.com/cosmos/cosmos-sdk/types/address"
|
||||||
v043 "github.com/cosmos/cosmos-sdk/x/bank/migrations/v043"
|
v043 "github.com/cosmos/cosmos-sdk/x/bank/migrations/v043"
|
||||||
v044 "github.com/cosmos/cosmos-sdk/x/bank/migrations/v044"
|
v044 "github.com/cosmos/cosmos-sdk/x/bank/migrations/v044"
|
||||||
|
"github.com/cosmos/cosmos-sdk/x/bank/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestMigrateStore(t *testing.T) {
|
func TestMigrateStore(t *testing.T) {
|
||||||
|
@ -37,6 +38,14 @@ func TestMigrateStore(t *testing.T) {
|
||||||
|
|
||||||
require.NoError(t, v044.MigrateStore(ctx, bankKey, encCfg.Codec))
|
require.NoError(t, v044.MigrateStore(ctx, bankKey, encCfg.Codec))
|
||||||
|
|
||||||
|
for _, b := range balances {
|
||||||
|
addrPrefixStore := prefix.NewStore(store, types.CreateAccountBalancesPrefix(addr))
|
||||||
|
bz := addrPrefixStore.Get([]byte(b.Denom))
|
||||||
|
var expected sdk.Int
|
||||||
|
require.NoError(t, expected.Unmarshal(bz))
|
||||||
|
require.Equal(t, expected, b.Amount)
|
||||||
|
}
|
||||||
|
|
||||||
for _, b := range balances {
|
for _, b := range balances {
|
||||||
denomPrefixStore := prefix.NewStore(store, v044.CreateAddressDenomPrefix(b.Denom))
|
denomPrefixStore := prefix.NewStore(store, v044.CreateAddressDenomPrefix(b.Denom))
|
||||||
bz := denomPrefixStore.Get(address.MustLengthPrefix(addr))
|
bz := denomPrefixStore.Get(address.MustLengthPrefix(addr))
|
||||||
|
|
|
@ -37,26 +37,25 @@ func DenomMetadataKey(denom string) []byte {
|
||||||
return append(DenomMetadataPrefix, d...)
|
return append(DenomMetadataPrefix, d...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddressFromBalancesStore returns an account address from a balances prefix
|
// AddressAndDenomFromBalancesStore returns an account address and denom from a balances prefix
|
||||||
// store. The key must not contain the prefix BalancesPrefix as the prefix store
|
// store. The key must not contain the prefix BalancesPrefix as the prefix store
|
||||||
// iterator discards the actual prefix.
|
// iterator discards the actual prefix.
|
||||||
//
|
//
|
||||||
// If invalid key is passed, AddressFromBalancesStore returns ErrInvalidKey.
|
// If invalid key is passed, AddressAndDenomFromBalancesStore returns ErrInvalidKey.
|
||||||
func AddressFromBalancesStore(key []byte) (sdk.AccAddress, error) {
|
func AddressAndDenomFromBalancesStore(key []byte) (sdk.AccAddress, string, error) {
|
||||||
if len(key) == 0 {
|
if len(key) == 0 {
|
||||||
return nil, ErrInvalidKey
|
return nil, "", ErrInvalidKey
|
||||||
}
|
}
|
||||||
|
|
||||||
kv.AssertKeyAtLeastLength(key, 1)
|
kv.AssertKeyAtLeastLength(key, 1)
|
||||||
|
|
||||||
addrLen := key[0]
|
addrBound := int(key[0])
|
||||||
bound := int(addrLen)
|
|
||||||
|
|
||||||
if len(key)-1 < bound {
|
if len(key)-1 < addrBound {
|
||||||
return nil, ErrInvalidKey
|
return nil, "", ErrInvalidKey
|
||||||
}
|
}
|
||||||
|
|
||||||
return key[1 : bound+1], nil
|
return key[1 : addrBound+1], string(key[addrBound+1:]), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateAccountBalancesPrefix creates the prefix for an account's balances.
|
// CreateAccountBalancesPrefix creates the prefix for an account's balances.
|
||||||
|
|
|
@ -42,7 +42,7 @@ func TestAddressFromBalancesStore(t *testing.T) {
|
||||||
tc := tc
|
tc := tc
|
||||||
t.Run(tc.name, func(t *testing.T) {
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
addr, err := types.AddressFromBalancesStore(tc.key)
|
addr, denom, err := types.AddressAndDenomFromBalancesStore(tc.key)
|
||||||
if tc.wantErr {
|
if tc.wantErr {
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
assert.True(t, errors.Is(types.ErrInvalidKey, err))
|
assert.True(t, errors.Is(types.ErrInvalidKey, err))
|
||||||
|
@ -51,6 +51,7 @@ func TestAddressFromBalancesStore(t *testing.T) {
|
||||||
}
|
}
|
||||||
if len(tc.expectedKey) > 0 {
|
if len(tc.expectedKey) > 0 {
|
||||||
assert.Equal(t, tc.expectedKey, addr)
|
assert.Equal(t, tc.expectedKey, addr)
|
||||||
|
assert.Equal(t, "stake", denom)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue