Skip to content

Commit

Permalink
Problem: subUnlockedCoins is not optimal
Browse files Browse the repository at this point in the history
  • Loading branch information
yihuang committed Oct 23, 2024
1 parent d78d66e commit 41e44fe
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 15 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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]

Expand Down
8 changes: 8 additions & 0 deletions types/coin.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,14 @@ func NewCoin(denom string, amount math.Int) Coin {
return coin
}

// UnsafeNewCoin returns a new coin without validate inputs.
func UnsafeNewCoin(denom string, amount math.Int) Coin {
return Coin{
Denom: denom,
Amount: amount,
}
}

// NewInt64Coin returns a new coin with a denomination and amount. It will panic
// if the amount is negative.
func NewInt64Coin(denom string, amount int64) Coin {
Expand Down
30 changes: 15 additions & 15 deletions x/bank/keeper/send.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -274,28 +274,28 @@ 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))
balance := k.GetBalance(ctx, addr, coin.Denom).Amount.BigIntMut()
locked := lockedCoins.AmountOf(coin.Denom).BigIntMut()
amount := coin.Amount.BigIntMut()

spendable, hasNeg := sdk.Coins{balance}.SafeSub(locked)
if hasNeg {
return errorsmod.Wrapf(sdkerrors.ErrInsufficientFunds,
"locked amount exceeds account balance funds: %s > %s", locked, balance)
if locked.Sign() == -1 {
return errorsmod.Wrapf(
sdkerrors.ErrInsufficientFunds,
"locked balance %s%s is negative",
locked, coin.Denom,
)
}

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.UnsafeNewCoin(coin.Denom, sdkmath.NewIntFromBigIntMut(balance.Sub(balance, amount)))
if err := k.setBalance(ctx, addr, newBalance); err != nil {
return err
}
Expand Down

0 comments on commit 41e44fe

Please sign in to comment.