diff --git a/CHANGELOG.md b/CHANGELOG.md index f3b3a7bd7572..89f83113ff0a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -36,6 +36,10 @@ Ref: https://keepachangelog.com/en/1.0.0/ ## Unreleased +### Improvements + +* [\#9428](https://github.com/cosmos/cosmos-sdk/pull/9428) Optimize bank InitGenesis. Added `k.initBalances`. + ### Bug Fixes * [\#9401](https://github.com/cosmos/cosmos-sdk/pull/9401) Fixes incorrect export of IBC identifier sequences. Previously, the next identifier sequence for clients/connections/channels was not set during genesis export. This resulted in the next identifiers being generated on the new chain to reuse old identifiers (the sequences began again from 0). diff --git a/x/bank/keeper/genesis.go b/x/bank/keeper/genesis.go index d30415c6a285..c70dee585c6c 100644 --- a/x/bank/keeper/genesis.go +++ b/x/bank/keeper/genesis.go @@ -20,7 +20,7 @@ func (k BaseKeeper) InitGenesis(ctx sdk.Context, genState *types.GenesisState) { panic(err) } - if err := k.SetBalances(ctx, addr, balance.Coins); err != nil { + if err := k.initBalances(ctx, addr, balance.Coins); err != nil { panic(fmt.Errorf("error on setting balances %w", err)) } diff --git a/x/bank/keeper/send.go b/x/bank/keeper/send.go index c1000b7d3025..59668463c7d1 100644 --- a/x/bank/keeper/send.go +++ b/x/bank/keeper/send.go @@ -258,6 +258,28 @@ func (k BaseSendKeeper) SetBalances(ctx sdk.Context, addr sdk.AccAddress, balanc return nil } +// initBalances sets the balance (multiple coins) for an account by address. +// An error is returned upon failure. +func (k BaseSendKeeper) initBalances(ctx sdk.Context, addr sdk.AccAddress, balances sdk.Coins) error { + store := ctx.KVStore(k.storeKey) + balancesStore := prefix.NewStore(store, types.BalancesPrefix) + accountStore := prefix.NewStore(balancesStore, addr.Bytes()) + 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. + if !balance.IsZero() { + bz := k.cdc.MustMarshalBinaryBare(&balance) + accountStore.Set([]byte(balance.Denom), bz) + } + } + + return nil +} + // SetBalance sets the coin balance for an account by address. func (k BaseSendKeeper) SetBalance(ctx sdk.Context, addr sdk.AccAddress, balance sdk.Coin) error { if !balance.IsValid() {