From 72ada0ece5bc1cb2ccc969172bcc59384a08d0fa Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Tue, 29 Jun 2021 10:19:23 -0700 Subject: [PATCH 01/22] x/bank: create reverse prefix for denom<->address --- x/bank/keeper/send.go | 8 +++++++- x/bank/keeper/view.go | 7 ++++++- x/bank/types/key.go | 10 ++++++++++ 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/x/bank/keeper/send.go b/x/bank/keeper/send.go index 369fa631c447..5148730f32ab 100644 --- a/x/bank/keeper/send.go +++ b/x/bank/keeper/send.go @@ -4,6 +4,7 @@ import ( "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/telemetry" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/address" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/x/bank/types" paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" @@ -254,13 +255,18 @@ func (k BaseSendKeeper) setBalance(ctx sdk.Context, addr sdk.AccAddress, balance } accountStore := k.getAccountStore(ctx, addr) + denomPrefixStore := k.getDenomPrefixStore(ctx, balance.Denom) - // Bank invariants require to not store zero balances. + // x/bank invariants prohibit persistance of zero balances if balance.IsZero() { accountStore.Delete([]byte(balance.Denom)) + denomPrefixStore.Delete(address.MustLengthPrefix(addr)) } else { bz := k.cdc.MustMarshal(&balance) accountStore.Set([]byte(balance.Denom), bz) + + // store a reverse index from denomination to account address + denomPrefixStore.Set(address.MustLengthPrefix(addr), nil) } return nil diff --git a/x/bank/keeper/view.go b/x/bank/keeper/view.go index fe46ec9b6ec1..95a76caf1929 100644 --- a/x/bank/keeper/view.go +++ b/x/bank/keeper/view.go @@ -228,6 +228,11 @@ func (k BaseViewKeeper) ValidateBalance(ctx sdk.Context, addr sdk.AccAddress) er // 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)) } + +// getDenomPrefixStore returns a prefix store that acts as a reverse index +// between a denomination and account balance for that denomination. +func (k BaseViewKeeper) getDenomPrefixStore(ctx sdk.Context, denom string) prefix.Store { + return prefix.NewStore(ctx.KVStore(k.storeKey), types.CreateDenomPrefix(denom)) +} diff --git a/x/bank/types/key.go b/x/bank/types/key.go index 5d7f52baa531..3762a557fd9a 100644 --- a/x/bank/types/key.go +++ b/x/bank/types/key.go @@ -23,6 +23,7 @@ const ( var ( // BalancesPrefix is the prefix for the account balances store. We use a byte // (instead of `[]byte("balances")` to save some disk space). + DenomPrefix = []byte{0x03} BalancesPrefix = []byte{0x02} SupplyKey = []byte{0x00} DenomMetadataPrefix = []byte{0x1} @@ -43,11 +44,14 @@ func AddressFromBalancesStore(key []byte) (sdk.AccAddress, error) { if len(key) == 0 { return nil, ErrInvalidKey } + addrLen := key[0] bound := int(addrLen) + if len(key)-1 < bound { return nil, ErrInvalidKey } + return key[1 : bound+1], nil } @@ -55,3 +59,9 @@ func AddressFromBalancesStore(key []byte) (sdk.AccAddress, error) { func CreateAccountBalancesPrefix(addr []byte) []byte { return append(BalancesPrefix, address.MustLengthPrefix(addr)...) } + +// CreateDenomPrefix creates a prefix for a reverse index of denomination to +// account balance for that denomination. +func CreateDenomPrefix(denom string) []byte { + return append(DenomPrefix, []byte(denom)...) +} From 9b5f92e8a5c331675bf61fa623931ce1ff01c88e Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Tue, 29 Jun 2021 10:29:25 -0700 Subject: [PATCH 02/22] x/bank: update DenomOwners --- x/bank/keeper/grpc_query.go | 20 +++++++------------- x/bank/keeper/send.go | 2 +- 2 files changed, 8 insertions(+), 14 deletions(-) diff --git a/x/bank/keeper/grpc_query.go b/x/bank/keeper/grpc_query.go index 53c192954f6a..37933d2815f9 100644 --- a/x/bank/keeper/grpc_query.go +++ b/x/bank/keeper/grpc_query.go @@ -179,30 +179,24 @@ func (k BaseKeeper) DenomOwners( } ctx := sdk.UnwrapSDKContext(goCtx) - - store := ctx.KVStore(k.storeKey) - balancesStore := prefix.NewStore(store, types.BalancesPrefix) + denomPrefixStore := k.getDenomPrefixStore(ctx, req.Denom) var denomOwners []*types.DenomOwner pageRes, err := query.FilteredPaginate( - balancesStore, + denomPrefixStore, req.Pagination, func(key []byte, value []byte, accumulate bool) (bool, error) { - var balance sdk.Coin - if err := k.cdc.Unmarshal(value, &balance); err != nil { - return false, err - } - - if req.Denom != balance.Denom { - return false, nil - } - if accumulate { address, err := types.AddressFromBalancesStore(key) if err != nil { return false, err } + var balance sdk.Coin + if err := k.cdc.Unmarshal(value, &balance); err != nil { + return false, err + } + denomOwners = append( denomOwners, &types.DenomOwner{ diff --git a/x/bank/keeper/send.go b/x/bank/keeper/send.go index 5148730f32ab..0838538f0696 100644 --- a/x/bank/keeper/send.go +++ b/x/bank/keeper/send.go @@ -266,7 +266,7 @@ func (k BaseSendKeeper) setBalance(ctx sdk.Context, addr sdk.AccAddress, balance accountStore.Set([]byte(balance.Denom), bz) // store a reverse index from denomination to account address - denomPrefixStore.Set(address.MustLengthPrefix(addr), nil) + denomPrefixStore.Set(address.MustLengthPrefix(addr), bz) } return nil From cf595e278fbbe96eba84101684b6f1a96211cdc9 Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Tue, 29 Jun 2021 10:35:58 -0700 Subject: [PATCH 03/22] x/bank: lint++ --- x/bank/keeper/send.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/bank/keeper/send.go b/x/bank/keeper/send.go index 0838538f0696..899265385ef6 100644 --- a/x/bank/keeper/send.go +++ b/x/bank/keeper/send.go @@ -257,7 +257,7 @@ func (k BaseSendKeeper) setBalance(ctx sdk.Context, addr sdk.AccAddress, balance accountStore := k.getAccountStore(ctx, addr) denomPrefixStore := k.getDenomPrefixStore(ctx, balance.Denom) - // x/bank invariants prohibit persistance of zero balances + // x/bank invariants prohibit persistence of zero balances if balance.IsZero() { accountStore.Delete([]byte(balance.Denom)) denomPrefixStore.Delete(address.MustLengthPrefix(addr)) From 72a1ad1fdcf7b975d44c5d187dc79629b6101c2a Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Tue, 29 Jun 2021 17:48:31 -0700 Subject: [PATCH 04/22] x/bank: store 0 instead of balance --- x/bank/keeper/grpc_query.go | 7 +------ x/bank/keeper/send.go | 5 +++-- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/x/bank/keeper/grpc_query.go b/x/bank/keeper/grpc_query.go index 37933d2815f9..b7646e5b75e5 100644 --- a/x/bank/keeper/grpc_query.go +++ b/x/bank/keeper/grpc_query.go @@ -192,16 +192,11 @@ func (k BaseKeeper) DenomOwners( return false, err } - var balance sdk.Coin - if err := k.cdc.Unmarshal(value, &balance); err != nil { - return false, err - } - denomOwners = append( denomOwners, &types.DenomOwner{ Address: address.String(), - Balance: balance, + Balance: k.GetBalance(ctx, address, req.Denom), }, ) } diff --git a/x/bank/keeper/send.go b/x/bank/keeper/send.go index 899265385ef6..65c98f01125a 100644 --- a/x/bank/keeper/send.go +++ b/x/bank/keeper/send.go @@ -265,8 +265,9 @@ func (k BaseSendKeeper) setBalance(ctx sdk.Context, addr sdk.AccAddress, balance bz := k.cdc.MustMarshal(&balance) accountStore.Set([]byte(balance.Denom), bz) - // store a reverse index from denomination to account address - denomPrefixStore.Set(address.MustLengthPrefix(addr), bz) + // Store a reverse index from denomination to account address with a + // sentinel value. + denomPrefixStore.Set(address.MustLengthPrefix(addr), []byte{0}) } return nil From 01e476d718ec6379f565b1934de0fcebc4eafb2f Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Wed, 30 Jun 2021 13:51:01 -0400 Subject: [PATCH 05/22] Update x/bank/types/key.go Co-authored-by: Aaron Craelius --- x/bank/types/key.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x/bank/types/key.go b/x/bank/types/key.go index 3762a557fd9a..70d600cd1996 100644 --- a/x/bank/types/key.go +++ b/x/bank/types/key.go @@ -63,5 +63,6 @@ func CreateAccountBalancesPrefix(addr []byte) []byte { // CreateDenomPrefix creates a prefix for a reverse index of denomination to // account balance for that denomination. func CreateDenomPrefix(denom string) []byte { - return append(DenomPrefix, []byte(denom)...) + key := append(DenomPrefix, []byte(denom)...) + return append(key, 0) } From 567f2288e3443141742ec850740722395bb9de72 Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Wed, 30 Jun 2021 10:58:25 -0700 Subject: [PATCH 06/22] x/bank: update initBalances --- x/bank/keeper/genesis.go | 2 +- x/bank/keeper/send.go | 15 ++++++++++++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/x/bank/keeper/genesis.go b/x/bank/keeper/genesis.go index 24b5ef44f9fc..694fa6668e61 100644 --- a/x/bank/keeper/genesis.go +++ b/x/bank/keeper/genesis.go @@ -13,8 +13,8 @@ func (k BaseKeeper) InitGenesis(ctx sdk.Context, genState *types.GenesisState) { k.SetParams(ctx, genState.Params) totalSupply := sdk.Coins{} - genState.Balances = types.SanitizeGenesisBalances(genState.Balances) + for _, balance := range genState.Balances { addr, err := sdk.AccAddressFromBech32(balance.Address) if err != nil { diff --git a/x/bank/keeper/send.go b/x/bank/keeper/send.go index 65c98f01125a..17d2b9ce4ad5 100644 --- a/x/bank/keeper/send.go +++ b/x/bank/keeper/send.go @@ -2,6 +2,7 @@ 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" "github.com/cosmos/cosmos-sdk/types/address" @@ -232,16 +233,28 @@ func (k BaseSendKeeper) addCoins(ctx sdk.Context, addr sdk.AccAddress, amt sdk.C // An error is returned upon failure. func (k BaseSendKeeper) initBalances(ctx sdk.Context, addr sdk.AccAddress, balances sdk.Coins) error { accountStore := k.getAccountStore(ctx, addr) + denomPrefixStores := make(map[string]prefix.Store) // memoize prefix stores + for i := range balances { balance := balances[i] if !balance.IsValid() { return sdkerrors.Wrap(sdkerrors.ErrInvalidCoins, balance.String()) } - // Bank invariants require to not store zero balances. + // x/bank invariants prohibit persistence of zero balances if !balance.IsZero() { bz := k.cdc.MustMarshal(&balance) accountStore.Set([]byte(balance.Denom), bz) + + denomPrefixStore, ok := denomPrefixStores[balance.Denom] + if !ok { + denomPrefixStore = k.getDenomPrefixStore(ctx, balance.Denom) + denomPrefixStores[balance.Denom] = denomPrefixStore + } + + // Store a reverse index from denomination to account address with a + // sentinel value. + denomPrefixStore.Set(address.MustLengthPrefix(addr), []byte{0}) } } From e3cd0e7b068071687b3f4898ccf6d62f4325f8b3 Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Wed, 30 Jun 2021 11:02:31 -0700 Subject: [PATCH 07/22] x/bank: update spec --- x/bank/spec/01_state.md | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/x/bank/spec/01_state.md b/x/bank/spec/01_state.md index 5328e8b3caee..97584ca1abb6 100644 --- a/x/bank/spec/01_state.md +++ b/x/bank/spec/01_state.md @@ -4,9 +4,16 @@ order: 1 # State -The `x/bank` module keeps state of three primary objects, account balances, denom metadata and the -total supply of all balances. +The `x/bank` module keeps state of three primary objects: -- Supply: `0x0 | byte(denom) -> byte(amount)` -- Denom Metadata: `0x1 | byte(denom) -> ProtocolBuffer(Metadata)` -- Balances: `0x2 | byte(address length) | []byte(address) | []byte(balance.Denom) -> ProtocolBuffer(balance)` +1. Account balances +2. Denomination metadata +3. The total supply of all balances + +In addition, the `x/bank` module keeps the following indexes to manage the +aforementioned state: + +- Supply Index: `0x0 | byte(denom) -> byte(amount)` +- Denom Metadata Index: `0x1 | byte(denom) -> ProtocolBuffer(Metadata)` +- Balances Index: `0x2 | byte(address length) | []byte(address) | []byte(balance.Denom) -> ProtocolBuffer(balance)` +- Reverse Denomination to Address Index: `0x03 | byte(denom) | 0x00 | []byte(address) -> 0` From 7312e5b400ab6b800188b2ec3285c37a216c4029 Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Wed, 30 Jun 2021 11:25:53 -0700 Subject: [PATCH 08/22] x/bank: add v0.44 legacy migration --- x/bank/legacy/v044/store.go | 51 ++++++++++++++++++++++++++++++++ x/bank/legacy/v044/store_test.go | 1 + 2 files changed, 52 insertions(+) create mode 100644 x/bank/legacy/v044/store.go create mode 100644 x/bank/legacy/v044/store_test.go diff --git a/x/bank/legacy/v044/store.go b/x/bank/legacy/v044/store.go new file mode 100644 index 000000000000..f3b82ff624fa --- /dev/null +++ b/x/bank/legacy/v044/store.go @@ -0,0 +1,51 @@ +package v044 + +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/x/bank/types" +) + +// MigrateStore performs in-place store migrations from v0.43 to v0.44. The +// migration includes: +// +// - Add an additional reverse index from denomination to address. +func MigrateStore(ctx sdk.Context, storeKey sdk.StoreKey, cdc codec.BinaryCodec) error { + store := ctx.KVStore(storeKey) + return addDenomReverseIndex(store, cdc) +} + +func addDenomReverseIndex(store sdk.KVStore, cdc codec.BinaryCodec) error { + oldBalancesStore := prefix.NewStore(store, types.BalancesPrefix) + + oldBalancesIter := oldBalancesStore.Iterator(nil, nil) + defer oldBalancesIter.Close() + + denomPrefixStores := make(map[string]prefix.Store) // memoize prefix stores + + for ; oldBalancesIter.Valid(); oldBalancesIter.Next() { + var balance sdk.Coin + if err := cdc.Unmarshal(oldBalancesIter.Value(), &balance); err != nil { + return err + } + + addr, err := types.AddressFromBalancesStore(oldBalancesIter.Key()) + if err != nil { + return err + } + + denomPrefixStore, ok := denomPrefixStores[balance.Denom] + if !ok { + denomPrefixStore = prefix.NewStore(store, types.CreateDenomPrefix(balance.Denom)) + denomPrefixStores[balance.Denom] = denomPrefixStore + } + + // Store a reverse index from denomination to account address with a + // sentinel value. + denomPrefixStore.Set(address.MustLengthPrefix(addr), []byte{0}) + } + + return nil +} diff --git a/x/bank/legacy/v044/store_test.go b/x/bank/legacy/v044/store_test.go new file mode 100644 index 000000000000..bb8d2025b926 --- /dev/null +++ b/x/bank/legacy/v044/store_test.go @@ -0,0 +1 @@ +package v044_test From 2f00b31d2cce529d5e406d5771520b29c5f8f727 Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Wed, 30 Jun 2021 11:28:53 -0700 Subject: [PATCH 09/22] x/bank: bump ConsensusVersion to 3 --- x/bank/module.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/bank/module.go b/x/bank/module.go index c43251acc253..096036494bc8 100644 --- a/x/bank/module.go +++ b/x/bank/module.go @@ -157,7 +157,7 @@ func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.Raw } // ConsensusVersion implements AppModule/ConsensusVersion. -func (AppModule) ConsensusVersion() uint64 { return 2 } +func (AppModule) ConsensusVersion() uint64 { return 3 } // BeginBlock performs a no-op. func (AppModule) BeginBlock(_ sdk.Context, _ abci.RequestBeginBlock) {} From 67db855cb1e08a150a4ca5c81c81e15e9bcfe1c8 Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Thu, 1 Jul 2021 10:07:23 -0700 Subject: [PATCH 10/22] x/bank: update RegisterServices --- x/bank/keeper/migrations.go | 6 ++++++ x/bank/module.go | 4 ++++ 2 files changed, 10 insertions(+) diff --git a/x/bank/keeper/migrations.go b/x/bank/keeper/migrations.go index e46b386b81a9..92c17b8270f4 100644 --- a/x/bank/keeper/migrations.go +++ b/x/bank/keeper/migrations.go @@ -3,6 +3,7 @@ package keeper import ( sdk "github.com/cosmos/cosmos-sdk/types" v043 "github.com/cosmos/cosmos-sdk/x/bank/legacy/v043" + v044 "github.com/cosmos/cosmos-sdk/x/bank/legacy/v044" ) // Migrator is a struct for handling in-place store migrations. @@ -19,3 +20,8 @@ func NewMigrator(keeper BaseKeeper) Migrator { func (m Migrator) Migrate1to2(ctx sdk.Context) error { return v043.MigrateStore(ctx, m.keeper.storeKey, m.keeper.cdc) } + +// Migrate2to3 migrates x/bank storage from version 2 to 3. +func (m Migrator) Migrate2to3(ctx sdk.Context) error { + return v044.MigrateStore(ctx, m.keeper.storeKey, m.keeper.cdc) +} diff --git a/x/bank/module.go b/x/bank/module.go index 096036494bc8..1a0f72e7d74e 100644 --- a/x/bank/module.go +++ b/x/bank/module.go @@ -105,6 +105,10 @@ func (am AppModule) RegisterServices(cfg module.Configurator) { m := keeper.NewMigrator(am.keeper.(keeper.BaseKeeper)) cfg.RegisterMigration(types.ModuleName, 1, m.Migrate1to2) + + if err := cfg.RegisterMigration(types.ModuleName, 2, m.Migrate2to3); err != nil { + panic(fmt.Sprintf("failed to migrate x/bank from version 2 to 3: %v", err)) + } } // NewAppModule creates a new AppModule object From ff041bec35d8413bf86fa26e85fdeb1058edd8d3 Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Thu, 1 Jul 2021 10:17:27 -0700 Subject: [PATCH 11/22] x/bank: fix legacy types --- x/bank/legacy/v043/keys.go | 34 ++++++++++++++++++++++++++++++++++ x/bank/legacy/v043/store.go | 4 ++-- x/bank/legacy/v044/keys.go | 10 ++++++++++ x/bank/legacy/v044/store.go | 8 ++++---- 4 files changed, 50 insertions(+), 6 deletions(-) create mode 100644 x/bank/legacy/v043/keys.go create mode 100644 x/bank/legacy/v044/keys.go diff --git a/x/bank/legacy/v043/keys.go b/x/bank/legacy/v043/keys.go new file mode 100644 index 000000000000..bb73be143af1 --- /dev/null +++ b/x/bank/legacy/v043/keys.go @@ -0,0 +1,34 @@ +package v043 + +import ( + "errors" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/address" +) + +var ( + SupplyKey = []byte{0x00} + BalancesPrefix = []byte{0x02} + + ErrInvalidKey = errors.New("invalid key") +) + +func CreateAccountBalancesPrefix(addr []byte) []byte { + return append(BalancesPrefix, address.MustLengthPrefix(addr)...) +} + +func AddressFromBalancesStore(key []byte) (sdk.AccAddress, error) { + if len(key) == 0 { + return nil, ErrInvalidKey + } + + addrLen := key[0] + bound := int(addrLen) + + if len(key)-1 < bound { + return nil, ErrInvalidKey + } + + return key[1 : bound+1], nil +} diff --git a/x/bank/legacy/v043/store.go b/x/bank/legacy/v043/store.go index a57907b20560..3d53d6a0e5a4 100644 --- a/x/bank/legacy/v043/store.go +++ b/x/bank/legacy/v043/store.go @@ -28,7 +28,7 @@ func migrateSupply(store sdk.KVStore, cdc codec.BinaryCodec) error { } // We add a new key for each denom - supplyStore := prefix.NewStore(store, types.SupplyKey) + supplyStore := prefix.NewStore(store, SupplyKey) // We're sure that SupplyI is a Supply struct, there's no other // implementation. @@ -61,7 +61,7 @@ func migrateBalanceKeys(store sdk.KVStore) { for ; oldStoreIter.Valid(); oldStoreIter.Next() { addr := v040bank.AddressFromBalancesStore(oldStoreIter.Key()) denom := oldStoreIter.Key()[v040auth.AddrLen:] - newStoreKey := append(types.CreateAccountBalancesPrefix(addr), denom...) + newStoreKey := append(CreateAccountBalancesPrefix(addr), denom...) // Set new key on store. Values don't change. store.Set(newStoreKey, oldStoreIter.Value()) diff --git a/x/bank/legacy/v044/keys.go b/x/bank/legacy/v044/keys.go new file mode 100644 index 000000000000..3c3610dc505b --- /dev/null +++ b/x/bank/legacy/v044/keys.go @@ -0,0 +1,10 @@ +package v044 + +var ( + DenomPrefix = []byte{0x03} +) + +func CreateDenomPrefix(denom string) []byte { + key := append(DenomPrefix, []byte(denom)...) + return append(key, 0) +} diff --git a/x/bank/legacy/v044/store.go b/x/bank/legacy/v044/store.go index f3b82ff624fa..045d0ed23ea7 100644 --- a/x/bank/legacy/v044/store.go +++ b/x/bank/legacy/v044/store.go @@ -5,7 +5,7 @@ import ( "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/x/bank/types" + v043 "github.com/cosmos/cosmos-sdk/x/bank/legacy/v043" ) // MigrateStore performs in-place store migrations from v0.43 to v0.44. The @@ -18,7 +18,7 @@ func MigrateStore(ctx sdk.Context, storeKey sdk.StoreKey, cdc codec.BinaryCodec) } func addDenomReverseIndex(store sdk.KVStore, cdc codec.BinaryCodec) error { - oldBalancesStore := prefix.NewStore(store, types.BalancesPrefix) + oldBalancesStore := prefix.NewStore(store, v043.BalancesPrefix) oldBalancesIter := oldBalancesStore.Iterator(nil, nil) defer oldBalancesIter.Close() @@ -31,14 +31,14 @@ func addDenomReverseIndex(store sdk.KVStore, cdc codec.BinaryCodec) error { return err } - addr, err := types.AddressFromBalancesStore(oldBalancesIter.Key()) + addr, err := v043.AddressFromBalancesStore(oldBalancesIter.Key()) if err != nil { return err } denomPrefixStore, ok := denomPrefixStores[balance.Denom] if !ok { - denomPrefixStore = prefix.NewStore(store, types.CreateDenomPrefix(balance.Denom)) + denomPrefixStore = prefix.NewStore(store, CreateDenomPrefix(balance.Denom)) denomPrefixStores[balance.Denom] = denomPrefixStore } From c3ed09f7e4fc4319095b1a03c3d500dd0b159d94 Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Thu, 1 Jul 2021 10:29:14 -0700 Subject: [PATCH 12/22] x/bank: add TestMigrateStore --- x/bank/legacy/v044/store_test.go | 43 ++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/x/bank/legacy/v044/store_test.go b/x/bank/legacy/v044/store_test.go index bb8d2025b926..afbd4bb63648 100644 --- a/x/bank/legacy/v044/store_test.go +++ b/x/bank/legacy/v044/store_test.go @@ -1 +1,44 @@ package v044_test + +import ( + "testing" + + "github.com/cosmos/cosmos-sdk/simapp" + "github.com/cosmos/cosmos-sdk/store/prefix" + "github.com/cosmos/cosmos-sdk/testutil" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/address" + v043 "github.com/cosmos/cosmos-sdk/x/bank/legacy/v043" + v044 "github.com/cosmos/cosmos-sdk/x/bank/legacy/v044" + "github.com/stretchr/testify/require" +) + +func TestMigrateStore(t *testing.T) { + encCfg := simapp.MakeTestEncodingConfig() + bankKey := sdk.NewKVStoreKey("bank") + ctx := testutil.DefaultContext(bankKey, sdk.NewTransientStoreKey("transient_test")) + store := ctx.KVStore(bankKey) + + addr := sdk.AccAddress([]byte("addr________________")) + prefixAccStore := prefix.NewStore(store, v043.CreateAccountBalancesPrefix(addr)) + + balances := sdk.NewCoins( + sdk.NewCoin("foo", sdk.NewInt(10000)), + sdk.NewCoin("bar", sdk.NewInt(20000)), + ) + + for _, b := range balances { + bz, err := encCfg.Marshaler.Marshal(&b) + require.NoError(t, err) + + prefixAccStore.Set([]byte(b.Denom), bz) + } + + require.NoError(t, v044.MigrateStore(ctx, bankKey, encCfg.Marshaler)) + + for _, b := range balances { + denomPrefixStore := prefix.NewStore(store, v044.CreateDenomPrefix(b.Denom)) + bz := denomPrefixStore.Get(address.MustLengthPrefix(addr)) + require.NotNil(t, bz) + } +} From 313d902eed7e02420ff899befa2bc38e07940887 Mon Sep 17 00:00:00 2001 From: Amaury M <1293565+amaurym@users.noreply.github.com> Date: Mon, 5 Jul 2021 12:19:11 +0200 Subject: [PATCH 13/22] fix TestRunMigrations --- simapp/app_test.go | 7 ++++++- x/bank/module.go | 4 +++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/simapp/app_test.go b/simapp/app_test.go index c84c99003053..76c1a423d1f9 100644 --- a/simapp/app_test.go +++ b/simapp/app_test.go @@ -123,8 +123,13 @@ func TestRunMigrations(t *testing.T) { false, "", true, "no migrations found for module bank: not found", 0, }, { - "can register and run migration handler for x/bank", + "can register 1->2 migration handler for x/bank, cannot run migration", "bank", 1, + false, "", true, "no migration found for module bank from version 2 to version 3: not found", 0, + }, + { + "can register 2->3 migration handler for x/bank, can run migration", + "bank", 2, false, "", false, "", 1, }, { diff --git a/x/bank/module.go b/x/bank/module.go index 1a0f72e7d74e..4971e5dd5f65 100644 --- a/x/bank/module.go +++ b/x/bank/module.go @@ -104,7 +104,9 @@ func (am AppModule) RegisterServices(cfg module.Configurator) { types.RegisterQueryServer(cfg.QueryServer(), am.keeper) m := keeper.NewMigrator(am.keeper.(keeper.BaseKeeper)) - cfg.RegisterMigration(types.ModuleName, 1, m.Migrate1to2) + if err := cfg.RegisterMigration(types.ModuleName, 1, m.Migrate1to2); err != nil { + panic(fmt.Sprintf("failed to migrate x/bank from version 1 to 2: %v", err)) + } if err := cfg.RegisterMigration(types.ModuleName, 2, m.Migrate2to3); err != nil { panic(fmt.Sprintf("failed to migrate x/bank from version 2 to 3: %v", err)) From 56e11bde4038811e63a599e02275ef92a4585065 Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Mon, 5 Jul 2021 11:01:49 -0400 Subject: [PATCH 14/22] Update x/bank/types/key.go Co-authored-by: Aaron Craelius --- x/bank/types/key.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/bank/types/key.go b/x/bank/types/key.go index 70d600cd1996..7340e1141fb3 100644 --- a/x/bank/types/key.go +++ b/x/bank/types/key.go @@ -23,7 +23,7 @@ const ( var ( // BalancesPrefix is the prefix for the account balances store. We use a byte // (instead of `[]byte("balances")` to save some disk space). - DenomPrefix = []byte{0x03} + DenomAddressPrefix = []byte{0x03} BalancesPrefix = []byte{0x02} SupplyKey = []byte{0x00} DenomMetadataPrefix = []byte{0x1} From 54eac653fd4ad9d894422cf54ec5a382fe1ed96f Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Mon, 5 Jul 2021 11:07:37 -0400 Subject: [PATCH 15/22] x/bank: improve naming --- x/bank/keeper/grpc_query.go | 2 +- x/bank/keeper/send.go | 4 ++-- x/bank/keeper/view.go | 6 +++--- x/bank/legacy/v044/keys.go | 6 +++--- x/bank/legacy/v044/store.go | 2 +- x/bank/legacy/v044/store_test.go | 5 +++-- x/bank/types/key.go | 17 +++++++++-------- 7 files changed, 22 insertions(+), 20 deletions(-) diff --git a/x/bank/keeper/grpc_query.go b/x/bank/keeper/grpc_query.go index b7646e5b75e5..6f53b5abba1b 100644 --- a/x/bank/keeper/grpc_query.go +++ b/x/bank/keeper/grpc_query.go @@ -179,7 +179,7 @@ func (k BaseKeeper) DenomOwners( } ctx := sdk.UnwrapSDKContext(goCtx) - denomPrefixStore := k.getDenomPrefixStore(ctx, req.Denom) + denomPrefixStore := k.getDenomAddressPrefixStore(ctx, req.Denom) var denomOwners []*types.DenomOwner pageRes, err := query.FilteredPaginate( diff --git a/x/bank/keeper/send.go b/x/bank/keeper/send.go index 17d2b9ce4ad5..5b9aa8ff71da 100644 --- a/x/bank/keeper/send.go +++ b/x/bank/keeper/send.go @@ -248,7 +248,7 @@ func (k BaseSendKeeper) initBalances(ctx sdk.Context, addr sdk.AccAddress, balan denomPrefixStore, ok := denomPrefixStores[balance.Denom] if !ok { - denomPrefixStore = k.getDenomPrefixStore(ctx, balance.Denom) + denomPrefixStore = k.getDenomAddressPrefixStore(ctx, balance.Denom) denomPrefixStores[balance.Denom] = denomPrefixStore } @@ -268,7 +268,7 @@ func (k BaseSendKeeper) setBalance(ctx sdk.Context, addr sdk.AccAddress, balance } accountStore := k.getAccountStore(ctx, addr) - denomPrefixStore := k.getDenomPrefixStore(ctx, balance.Denom) + denomPrefixStore := k.getDenomAddressPrefixStore(ctx, balance.Denom) // x/bank invariants prohibit persistence of zero balances if balance.IsZero() { diff --git a/x/bank/keeper/view.go b/x/bank/keeper/view.go index 95a76caf1929..73334ef37035 100644 --- a/x/bank/keeper/view.go +++ b/x/bank/keeper/view.go @@ -231,8 +231,8 @@ func (k BaseViewKeeper) getAccountStore(ctx sdk.Context, addr sdk.AccAddress) pr return prefix.NewStore(store, types.CreateAccountBalancesPrefix(addr)) } -// getDenomPrefixStore returns a prefix store that acts as a reverse index +// getDenomAddressPrefixStore returns a prefix store that acts as a reverse index // between a denomination and account balance for that denomination. -func (k BaseViewKeeper) getDenomPrefixStore(ctx sdk.Context, denom string) prefix.Store { - return prefix.NewStore(ctx.KVStore(k.storeKey), types.CreateDenomPrefix(denom)) +func (k BaseViewKeeper) getDenomAddressPrefixStore(ctx sdk.Context, denom string) prefix.Store { + return prefix.NewStore(ctx.KVStore(k.storeKey), types.CreateDenomAddressPrefix(denom)) } diff --git a/x/bank/legacy/v044/keys.go b/x/bank/legacy/v044/keys.go index 3c3610dc505b..c06492658866 100644 --- a/x/bank/legacy/v044/keys.go +++ b/x/bank/legacy/v044/keys.go @@ -1,10 +1,10 @@ package v044 var ( - DenomPrefix = []byte{0x03} + DenomAddressPrefix = []byte{0x03} ) -func CreateDenomPrefix(denom string) []byte { - key := append(DenomPrefix, []byte(denom)...) +func CreateAddressDenomPrefix(denom string) []byte { + key := append(DenomAddressPrefix, []byte(denom)...) return append(key, 0) } diff --git a/x/bank/legacy/v044/store.go b/x/bank/legacy/v044/store.go index 045d0ed23ea7..e6fc49778024 100644 --- a/x/bank/legacy/v044/store.go +++ b/x/bank/legacy/v044/store.go @@ -38,7 +38,7 @@ func addDenomReverseIndex(store sdk.KVStore, cdc codec.BinaryCodec) error { denomPrefixStore, ok := denomPrefixStores[balance.Denom] if !ok { - denomPrefixStore = prefix.NewStore(store, CreateDenomPrefix(balance.Denom)) + denomPrefixStore = prefix.NewStore(store, CreateAddressDenomPrefix(balance.Denom)) denomPrefixStores[balance.Denom] = denomPrefixStore } diff --git a/x/bank/legacy/v044/store_test.go b/x/bank/legacy/v044/store_test.go index afbd4bb63648..77360a937615 100644 --- a/x/bank/legacy/v044/store_test.go +++ b/x/bank/legacy/v044/store_test.go @@ -3,6 +3,8 @@ package v044_test import ( "testing" + "github.com/stretchr/testify/require" + "github.com/cosmos/cosmos-sdk/simapp" "github.com/cosmos/cosmos-sdk/store/prefix" "github.com/cosmos/cosmos-sdk/testutil" @@ -10,7 +12,6 @@ import ( "github.com/cosmos/cosmos-sdk/types/address" v043 "github.com/cosmos/cosmos-sdk/x/bank/legacy/v043" v044 "github.com/cosmos/cosmos-sdk/x/bank/legacy/v044" - "github.com/stretchr/testify/require" ) func TestMigrateStore(t *testing.T) { @@ -37,7 +38,7 @@ func TestMigrateStore(t *testing.T) { require.NoError(t, v044.MigrateStore(ctx, bankKey, encCfg.Marshaler)) for _, b := range balances { - denomPrefixStore := prefix.NewStore(store, v044.CreateDenomPrefix(b.Denom)) + denomPrefixStore := prefix.NewStore(store, v044.CreateAddressDenomPrefix(b.Denom)) bz := denomPrefixStore.Get(address.MustLengthPrefix(addr)) require.NotNil(t, bz) } diff --git a/x/bank/types/key.go b/x/bank/types/key.go index 7340e1141fb3..ce3e363bdd06 100644 --- a/x/bank/types/key.go +++ b/x/bank/types/key.go @@ -21,12 +21,13 @@ const ( // KVStore keys var ( - // BalancesPrefix is the prefix for the account balances store. We use a byte - // (instead of `[]byte("balances")` to save some disk space). - DenomAddressPrefix = []byte{0x03} - BalancesPrefix = []byte{0x02} SupplyKey = []byte{0x00} DenomMetadataPrefix = []byte{0x1} + DenomAddressPrefix = []byte{0x03} + + // BalancesPrefix is the prefix for the account balances store. We use a byte + // (instead of `[]byte("balances")` to save some disk space). + BalancesPrefix = []byte{0x02} ) // DenomMetadataKey returns the denomination metadata key. @@ -60,9 +61,9 @@ func CreateAccountBalancesPrefix(addr []byte) []byte { return append(BalancesPrefix, address.MustLengthPrefix(addr)...) } -// CreateDenomPrefix creates a prefix for a reverse index of denomination to -// account balance for that denomination. -func CreateDenomPrefix(denom string) []byte { - key := append(DenomPrefix, []byte(denom)...) +// CreateDenomAddressPrefix creates a prefix for a reverse index of denomination +// to account balance for that denomination. +func CreateDenomAddressPrefix(denom string) []byte { + key := append(DenomAddressPrefix, []byte(denom)...) return append(key, 0) } From afeffcc8ce3e58e63b775fff13f849f0a60065aa Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Mon, 5 Jul 2021 11:09:10 -0400 Subject: [PATCH 16/22] x/bank: add Has check --- x/bank/keeper/send.go | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/x/bank/keeper/send.go b/x/bank/keeper/send.go index 5b9aa8ff71da..1d43d1a0e1d3 100644 --- a/x/bank/keeper/send.go +++ b/x/bank/keeper/send.go @@ -254,7 +254,10 @@ func (k BaseSendKeeper) initBalances(ctx sdk.Context, addr sdk.AccAddress, balan // Store a reverse index from denomination to account address with a // sentinel value. - denomPrefixStore.Set(address.MustLengthPrefix(addr), []byte{0}) + denomAddrKey := address.MustLengthPrefix(addr) + if !denomPrefixStore.Has(denomAddrKey) { + denomPrefixStore.Set(denomAddrKey, []byte{0}) + } } } @@ -280,7 +283,10 @@ func (k BaseSendKeeper) setBalance(ctx sdk.Context, addr sdk.AccAddress, balance // Store a reverse index from denomination to account address with a // sentinel value. - denomPrefixStore.Set(address.MustLengthPrefix(addr), []byte{0}) + denomAddrKey := address.MustLengthPrefix(addr) + if !denomPrefixStore.Has(denomAddrKey) { + denomPrefixStore.Set(denomAddrKey, []byte{0}) + } } return nil From 4aa6bacc4a3854c28c0727bac6b42bab3e238380 Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Sun, 11 Jul 2021 10:03:58 -0400 Subject: [PATCH 17/22] attempt fix TestSignWithMultiSignersAminoJSON --- x/auth/client/testutil/suite.go | 1 + 1 file changed, 1 insertion(+) diff --git a/x/auth/client/testutil/suite.go b/x/auth/client/testutil/suite.go index dc843db9fac6..a15154d35296 100644 --- a/x/auth/client/testutil/suite.go +++ b/x/auth/client/testutil/suite.go @@ -1095,6 +1095,7 @@ func (s *IntegrationTestSuite) TestSignWithMultiSignersAminoJSON() { val0.ClientCtx, signedTxFile.Name(), fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), + fmt.Sprintf("--%s=%d", flags.FlagGas, 200000), ) require.NoError(err) From fef3b67539c37e03a1f3595f7046f73b44298aaf Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Mon, 12 Jul 2021 07:35:32 -0400 Subject: [PATCH 18/22] attempt fix TestSignWithMultiSignersAminoJSON --- x/auth/client/testutil/suite.go | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/x/auth/client/testutil/suite.go b/x/auth/client/testutil/suite.go index a15154d35296..06e47e0164c3 100644 --- a/x/auth/client/testutil/suite.go +++ b/x/auth/client/testutil/suite.go @@ -1045,12 +1045,11 @@ func (s *IntegrationTestSuite) TestTxWithoutPublicKey() { s.Require().NotEqual(0, res.Code) } +// TestSignWithMultiSignersAminoJSON tests the case where a transaction with 2 +// messages which has to be signed with 2 different keys. Sign and append the +// signatures using the CLI with Amino signing mode. Finally, send the +// transaction to the blockchain. func (s *IntegrationTestSuite) TestSignWithMultiSignersAminoJSON() { - // test case: - // Create a transaction with 2 messages which has to be signed with 2 different keys - // Sign and append the signatures using the CLI with Amino signing mode. - // Finally send the transaction to the blockchain. It should work. - require := s.Require() val0, val1 := s.network.Validators[0], s.network.Validators[1] val0Coin := sdk.NewCoin(fmt.Sprintf("%stoken", val0.Moniker), sdk.NewInt(10)) @@ -1067,7 +1066,7 @@ func (s *IntegrationTestSuite) TestSignWithMultiSignersAminoJSON() { banktypes.NewMsgSend(val1.Address, addr1, sdk.NewCoins(val1Coin)), ) txBuilder.SetFeeAmount(sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10)))) - txBuilder.SetGasLimit(testdata.NewTestGasLimit()) // min required is 101892 + txBuilder.SetGasLimit(testdata.NewTestGasLimit() * 2) require.Equal([]sdk.AccAddress{val0.Address, val1.Address}, txBuilder.GetTx().GetSigners()) // Write the unsigned tx into a file. @@ -1083,25 +1082,29 @@ func (s *IntegrationTestSuite) TestSignWithMultiSignersAminoJSON() { // Then let val1 sign the file with signedByVal0. val1AccNum, val1Seq, err := val0.ClientCtx.AccountRetriever.GetAccountNumberSequence(val0.ClientCtx, val1.Address) require.NoError(err) + signedTx, err := TxSignExec( - val1.ClientCtx, val1.Address, signedByVal0File.Name(), - "--offline", fmt.Sprintf("--account-number=%d", val1AccNum), fmt.Sprintf("--sequence=%d", val1Seq), "--sign-mode=amino-json", + val1.ClientCtx, + val1.Address, + signedByVal0File.Name(), + "--offline", + fmt.Sprintf("--account-number=%d", val1AccNum), + fmt.Sprintf("--sequence=%d", val1Seq), + "--sign-mode=amino-json", ) require.NoError(err) signedTxFile := testutil.WriteToNewTempFile(s.T(), signedTx.String()) - // Now let's try to send this tx. res, err := TxBroadcastExec( val0.ClientCtx, signedTxFile.Name(), fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), - fmt.Sprintf("--%s=%d", flags.FlagGas, 200000), ) require.NoError(err) var txRes sdk.TxResponse require.NoError(val0.ClientCtx.Codec.UnmarshalJSON(res.Bytes(), &txRes)) - require.Equal(uint32(0), txRes.Code) + require.Equal(uint32(0), txRes.Code, txRes.RawLog) // Make sure the addr1's balance got funded. queryResJSON, err := bankcli.QueryBalancesExec(val0.ClientCtx, addr1) From 83b7019d8cc8d11cf5cfadda88d280cb5a3fcb5e Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Mon, 12 Jul 2021 07:37:20 -0400 Subject: [PATCH 19/22] attempt fix TestNewRedelegateCmd --- x/staking/client/testutil/suite.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/staking/client/testutil/suite.go b/x/staking/client/testutil/suite.go index 965c35823c57..57ac584c1c26 100644 --- a/x/staking/client/testutil/suite.go +++ b/x/staking/client/testutil/suite.go @@ -1181,7 +1181,7 @@ func (s *IntegrationTestSuite) TestNewRedelegateCmd() { val2.ValAddress.String(), // dst-validator-addr sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(150)).String(), // amount fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()), - fmt.Sprintf("--%s=%s", flags.FlagGas, "auto"), + fmt.Sprintf("--%s=%d", flags.FlagGas, 300000), fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), From f3aeb5680bab04b2fe3fc74024a00134c3ccf62f Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Sat, 17 Jul 2021 21:14:29 -0400 Subject: [PATCH 20/22] fix build --- x/bank/migrations/v043/keys.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/x/bank/migrations/v043/keys.go b/x/bank/migrations/v043/keys.go index bb73be143af1..01a4aab2ab51 100644 --- a/x/bank/migrations/v043/keys.go +++ b/x/bank/migrations/v043/keys.go @@ -7,6 +7,10 @@ import ( "github.com/cosmos/cosmos-sdk/types/address" ) +const ( + ModuleName = "bank" +) + var ( SupplyKey = []byte{0x00} BalancesPrefix = []byte{0x02} From 9a851f906d7fe1a27504179360ea4b07d05bee85 Mon Sep 17 00:00:00 2001 From: Amaury M <1293565+amaurym@users.noreply.github.com> Date: Mon, 26 Jul 2021 16:58:10 +0200 Subject: [PATCH 21/22] Fix delegation query test --- x/staking/client/testutil/suite.go | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/x/staking/client/testutil/suite.go b/x/staking/client/testutil/suite.go index 57ac584c1c26..4cbae20eba43 100644 --- a/x/staking/client/testutil/suite.go +++ b/x/staking/client/testutil/suite.go @@ -57,15 +57,18 @@ func (s *IntegrationTestSuite) SetupSuite() { val2 := s.network.Validators[1] // redelegate - _, err = MsgRedelegateExec( + out, err := MsgRedelegateExec( val.ClientCtx, val.Address, val.ValAddress, val2.ValAddress, unbond, - fmt.Sprintf("--%s=%d", flags.FlagGas, 202954), // 202954 is the required + fmt.Sprintf("--%s=%d", flags.FlagGas, 300000), ) s.Require().NoError(err) + var txRes sdk.TxResponse + s.Require().NoError(val.ClientCtx.Codec.UnmarshalJSON(out.Bytes(), &txRes)) + s.Require().Equal(uint32(0), txRes.Code) _, err = s.network.WaitForHeight(1) s.Require().NoError(err) // unbonding From 290e1d7cd5cd28a91d532cf172c8721767812ff7 Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Mon, 26 Jul 2021 11:35:49 -0400 Subject: [PATCH 22/22] ci++ --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 50af835d31d9..1849ceed13e4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -87,6 +87,11 @@ Ref: https://keepachangelog.com/en/1.0.0/ * (x/genutil) [\#9638](https://github.com/cosmos/cosmos-sdk/pull/9638) Added missing validator key save when recovering from mnemonic * (server) [#9704](https://github.com/cosmos/cosmos-sdk/pull/9704) Start GRPCWebServer in goroutine, avoid blocking other services from starting. +### State Machine Breaking + +* (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. + ## [v0.43.0-rc0](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.43.0-rc0) - 2021-06-25 ### Features