diff --git a/CHANGELOG.md b/CHANGELOG.md index 497bdb70dff3..69097cc68e43 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -83,6 +83,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ * (crypto/types) [\#8600](https://github.com/cosmos/cosmos-sdk/pull/8600) `CompactBitArray`: optimize the `NumTrueBitsBefore` method and add an `Equal` method. * (x/upgrade) [\#8743](https://github.com/cosmos/cosmos-sdk/pull/8743) Add tracking module versions as per ADR-041 * (types) [\#8962](https://github.com/cosmos/cosmos-sdk/issues/8962) Add `Abs()` method to `sdk.Int`. +* (x/bank) [\#8950](https://github.com/cosmos/cosmos-sdk/pull/8950) Improve efficiency on supply updates. ### Bug Fixes diff --git a/contrib/rosetta/configuration/bootstrap.json b/contrib/rosetta/configuration/bootstrap.json index f75c7ec145bb..f08dae661fa1 100644 --- a/contrib/rosetta/configuration/bootstrap.json +++ b/contrib/rosetta/configuration/bootstrap.json @@ -1,7 +1,7 @@ [ { "account_identifier": { - "address":"cosmos1ujtnemf6jmfm995j000qdry064n5lq854gfe3j" + "address":"cosmos1gykh2dsytj0lde8wr9msl9xd2nyj88duvmsnn7" }, "currency":{ "symbol":"stake", diff --git a/contrib/rosetta/node/data.tar.gz b/contrib/rosetta/node/data.tar.gz index 987bb88b33ac..342100ebccfd 100644 Binary files a/contrib/rosetta/node/data.tar.gz and b/contrib/rosetta/node/data.tar.gz differ diff --git a/x/bank/keeper/genesis.go b/x/bank/keeper/genesis.go index f0c680b24a74..375f44787dfa 100644 --- a/x/bank/keeper/genesis.go +++ b/x/bank/keeper/genesis.go @@ -31,7 +31,9 @@ func (k BaseKeeper) InitGenesis(ctx sdk.Context, genState *types.GenesisState) { panic(fmt.Errorf("genesis supply is incorrect, expected %v, got %v", genState.Supply, totalSupply)) } - k.setSupply(ctx, totalSupply) + for _, supply := range totalSupply { + k.setSupply(ctx, supply) + } for _, meta := range genState.DenomMetadata { k.SetDenomMetaData(ctx, meta) diff --git a/x/bank/keeper/keeper.go b/x/bank/keeper/keeper.go index 9daa0ba36ce2..7aa27441d118 100644 --- a/x/bank/keeper/keeper.go +++ b/x/bank/keeper/keeper.go @@ -175,39 +175,14 @@ func (k BaseKeeper) GetSupply(ctx sdk.Context, denom string) sdk.Coin { } } - var coin sdk.Coin - err := k.cdc.UnmarshalBinaryBare(bz, &coin) - if err != nil { - panic(err) + amount, ok := sdk.NewIntFromString(string(bz)) + if !ok { + panic("unexpected supply") } - return coin -} - -// SetSupply sets the Supply to store -func (k BaseKeeper) setSupply(ctx sdk.Context, supply sdk.Coins) { - store := ctx.KVStore(k.storeKey) - supplyStore := prefix.NewStore(store, types.SupplyKey) - - var newSupply []sdk.Coin - storeSupply := k.GetTotalSupply(ctx) - - // update supply for coins which have non zero amount - for _, coin := range storeSupply { - if supply.AmountOf(coin.Denom).IsZero() { - zeroCoin := &sdk.Coin{ - Denom: coin.Denom, - Amount: sdk.NewInt(0), - } - bz := k.cdc.MustMarshalBinaryBare(zeroCoin) - supplyStore.Set([]byte(coin.Denom), bz) - } - } - newSupply = append(newSupply, supply...) - - for i := range newSupply { - bz := k.cdc.MustMarshalBinaryBare(&supply[i]) - supplyStore.Set([]byte(supply[i].Denom), bz) + return sdk.Coin{ + Denom: denom, + Amount: amount, } } @@ -359,7 +334,7 @@ func (k BaseKeeper) UndelegateCoinsFromModuleToAccount( // MintCoins creates new coins from thin air and adds it to the module account. // It will panic if the module account does not exist or is unauthorized. -func (k BaseKeeper) MintCoins(ctx sdk.Context, moduleName string, amt sdk.Coins) error { +func (k BaseKeeper) MintCoins(ctx sdk.Context, moduleName string, amounts sdk.Coins) error { acc := k.ak.GetModuleAccount(ctx, moduleName) if acc == nil { panic(sdkerrors.Wrapf(sdkerrors.ErrUnknownAddress, "module account %s does not exist", moduleName)) @@ -369,23 +344,23 @@ func (k BaseKeeper) MintCoins(ctx sdk.Context, moduleName string, amt sdk.Coins) panic(sdkerrors.Wrapf(sdkerrors.ErrUnauthorized, "module account %s does not have permissions to mint tokens", moduleName)) } - err := k.addCoins(ctx, acc.GetAddress(), amt) + err := k.addCoins(ctx, acc.GetAddress(), amounts) if err != nil { return err } - // update total supply - supply := k.GetTotalSupply(ctx) - supply = supply.Add(amt...) - - k.setSupply(ctx, supply) + for _, amount := range amounts { + supply := k.GetSupply(ctx, amount.GetDenom()) + supply = supply.Add(amount) + k.setSupply(ctx, supply) + } logger := k.Logger(ctx) - logger.Info("minted coins from module account", "amount", amt.String(), "from", moduleName) + logger.Info("minted coins from module account", "amount", amounts.String(), "from", moduleName) // emit mint event ctx.EventManager().EmitEvent( - types.NewCoinMintEvent(acc.GetAddress(), amt), + types.NewCoinMintEvent(acc.GetAddress(), amounts), ) return nil @@ -393,7 +368,7 @@ func (k BaseKeeper) MintCoins(ctx sdk.Context, moduleName string, amt sdk.Coins) // BurnCoins burns coins deletes coins from the balance of the module account. // It will panic if the module account does not exist or is unauthorized. -func (k BaseKeeper) BurnCoins(ctx sdk.Context, moduleName string, amt sdk.Coins) error { +func (k BaseKeeper) BurnCoins(ctx sdk.Context, moduleName string, amounts sdk.Coins) error { acc := k.ak.GetModuleAccount(ctx, moduleName) if acc == nil { panic(sdkerrors.Wrapf(sdkerrors.ErrUnknownAddress, "module account %s does not exist", moduleName)) @@ -403,28 +378,35 @@ func (k BaseKeeper) BurnCoins(ctx sdk.Context, moduleName string, amt sdk.Coins) panic(sdkerrors.Wrapf(sdkerrors.ErrUnauthorized, "module account %s does not have permissions to burn tokens", moduleName)) } - err := k.subUnlockedCoins(ctx, acc.GetAddress(), amt) + err := k.subUnlockedCoins(ctx, acc.GetAddress(), amounts) if err != nil { return err } - // update total supply - supply := k.GetTotalSupply(ctx) - supply = supply.Sub(amt) - - k.setSupply(ctx, supply) + for _, amount := range amounts { + supply := k.GetSupply(ctx, amount.GetDenom()) + supply = supply.Sub(amount) + k.setSupply(ctx, supply) + } logger := k.Logger(ctx) - logger.Info("burned tokens from module account", "amount", amt.String(), "from", moduleName) + logger.Info("burned tokens from module account", "amount", amounts.String(), "from", moduleName) // emit burn event ctx.EventManager().EmitEvent( - types.NewCoinBurnEvent(acc.GetAddress(), amt), + types.NewCoinBurnEvent(acc.GetAddress(), amounts), ) return nil } +func (k BaseKeeper) setSupply(ctx sdk.Context, coin sdk.Coin) { + store := ctx.KVStore(k.storeKey) + supplyStore := prefix.NewStore(store, types.SupplyKey) + + supplyStore.Set([]byte(coin.GetDenom()), []byte(coin.Amount.String())) +} + func (k BaseKeeper) trackDelegation(ctx sdk.Context, addr sdk.AccAddress, balance, amt sdk.Coins) error { acc := k.ak.GetAccount(ctx, addr) if acc == nil { @@ -463,8 +445,15 @@ func (k BaseViewKeeper) IterateTotalSupply(ctx sdk.Context, cb func(sdk.Coin) bo defer iterator.Close() for ; iterator.Valid(); iterator.Next() { - var balance sdk.Coin - k.cdc.MustUnmarshalBinaryBare(iterator.Value(), &balance) + amount, ok := sdk.NewIntFromString(string(iterator.Value())) + if !ok { + panic("unexpected supply") + } + + balance := sdk.Coin{ + Denom: string(iterator.Key()), + Amount: amount, + } if cb(balance) { break