diff --git a/CHANGELOG.md b/CHANGELOG.md index 2ba20e167f9e5..2c94d226505d0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -54,6 +54,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ * [#261](https://github.com/crypto-org-chain/cosmos-sdk/pull/261) `ctx.BlockHeader` don't do protobuf deep copy, shallow copy seems enough, reduce scope of mutex in `PriorityNonceMempool.Remove`. * [#507](https://github.com/crypto-org-chain/cosmos-sdk/pull/507) mempool respect gas wanted returned by ante handler * [#744](https://github.com/crypto-org-chain/cosmos-sdk/pull/744) Pass raw transactions to tx executor so it can do pre-estimations. +* [#]() Optimize subUnlockedCoins implementation. ## [Unreleased] diff --git a/x/bank/keeper/send.go b/x/bank/keeper/send.go index 9ab40e8a6bbc7..04051d47e1119 100644 --- a/x/bank/keeper/send.go +++ b/x/bank/keeper/send.go @@ -8,7 +8,7 @@ import ( "cosmossdk.io/core/store" errorsmod "cosmossdk.io/errors" "cosmossdk.io/log" - "cosmossdk.io/math" + sdkmath "cosmossdk.io/math" storetypes "cosmossdk.io/store/types" "github.com/cosmos/cosmos-sdk/codec" @@ -274,28 +274,20 @@ func (k BaseSendKeeper) subUnlockedCoins(ctx context.Context, addr sdk.AccAddres lockedCoins := k.LockedCoins(ctx, addr) for _, coin := range amt { - balance := k.GetBalance(ctx, addr, coin.Denom) - locked := sdk.NewCoin(coin.Denom, lockedCoins.AmountOf(coin.Denom)) - - spendable, hasNeg := sdk.Coins{balance}.SafeSub(locked) - if hasNeg { - return errorsmod.Wrapf(sdkerrors.ErrInsufficientFunds, - "locked amount exceeds account balance funds: %s > %s", locked, balance) - } + balance := k.GetBalance(ctx, addr, coin.Denom).Amount.BigIntMut() + locked := lockedCoins.AmountOf(coin.Denom).BigIntMut() + amount := coin.Amount.BigIntMut() - if _, hasNeg := spendable.SafeSub(coin); hasNeg { - if len(spendable) == 0 { - spendable = sdk.Coins{sdk.NewCoin(coin.Denom, math.ZeroInt())} - } + if balance.Cmp(locked.Add(locked, amount)) == -1 { + spendable := balance.Sub(balance, locked) return errorsmod.Wrapf( sdkerrors.ErrInsufficientFunds, - "spendable balance %s is smaller than %s", - spendable, coin, + "spendable balance %s%s is smaller than %s%s", + spendable, coin.Denom, amount, coin.Denom, ) } - newBalance := balance.Sub(coin) - + newBalance := sdk.NewCoin(coin.Denom, sdkmath.NewIntFromBigIntMut(balance.Sub(balance, amount))) if err := k.setBalance(ctx, addr, newBalance); err != nil { return err }