From a2afa1db8bbcc8a2436f46d772fe1e6089e4e39f Mon Sep 17 00:00:00 2001 From: Hanjun Kim Date: Fri, 15 Jul 2022 16:21:22 +0900 Subject: [PATCH 1/3] feat: add `SpendableCoin` method to `BaseViewKeeper` --- x/bank/keeper/keeper_test.go | 2 ++ x/bank/keeper/view.go | 10 ++++++++++ 2 files changed, 12 insertions(+) diff --git a/x/bank/keeper/keeper_test.go b/x/bank/keeper/keeper_test.go index 1c4390abbcb..4480ac6daca 100644 --- a/x/bank/keeper/keeper_test.go +++ b/x/bank/keeper/keeper_test.go @@ -715,10 +715,12 @@ func (suite *IntegrationTestSuite) TestSpendableCoins() { suite.Require().NoError(testutil.FundAccount(app.BankKeeper, ctx, addr2, origCoins)) suite.Require().Equal(origCoins, app.BankKeeper.SpendableCoins(ctx, addr2)) + suite.Require().Equal(origCoins[0], app.BankKeeper.SpendableCoin(ctx, addr2, "stake")) ctx = ctx.WithBlockTime(now.Add(12 * time.Hour)) suite.Require().NoError(app.BankKeeper.DelegateCoins(ctx, addr2, addrModule, delCoins)) suite.Require().Equal(origCoins.Sub(delCoins...), app.BankKeeper.SpendableCoins(ctx, addr1)) + suite.Require().Equal(origCoins.Sub(delCoins...)[0], app.BankKeeper.SpendableCoin(ctx, addr1, "stake")) } func (suite *IntegrationTestSuite) TestVestingAccountSend() { diff --git a/x/bank/keeper/view.go b/x/bank/keeper/view.go index 5fc3446c2da..35e64082376 100644 --- a/x/bank/keeper/view.go +++ b/x/bank/keeper/view.go @@ -27,6 +27,7 @@ type ViewKeeper interface { GetBalance(ctx sdk.Context, addr sdk.AccAddress, denom string) sdk.Coin LockedCoins(ctx sdk.Context, addr sdk.AccAddress) sdk.Coins SpendableCoins(ctx sdk.Context, addr sdk.AccAddress) sdk.Coins + SpendableCoin(ctx sdk.Context, addr sdk.AccAddress, denom string) sdk.Coin IterateAccountBalances(ctx sdk.Context, addr sdk.AccAddress, cb func(coin sdk.Coin) (stop bool)) IterateAllBalances(ctx sdk.Context, cb func(address sdk.AccAddress, coin sdk.Coin) (stop bool)) @@ -187,6 +188,15 @@ func (k BaseViewKeeper) SpendableCoins(ctx sdk.Context, addr sdk.AccAddress) sdk return spendable } +// SpendableCoin returns the balance of specific denomination of spendable coins +// for an account by address. If the account has no spendable coin, a zero Coin +// is returned. +func (k BaseViewKeeper) SpendableCoin(ctx sdk.Context, addr sdk.AccAddress, denom string) sdk.Coin { + balance := k.GetBalance(ctx, addr, denom) + locked := k.LockedCoins(ctx, addr) + return balance.SubAmount(locked.AmountOf(denom)) +} + // spendableCoins returns the coins the given address can spend alongside the total amount of coins it holds. // It exists for gas efficiency, in order to avoid to have to get balance multiple times. func (k BaseViewKeeper) spendableCoins(ctx sdk.Context, addr sdk.AccAddress) (spendable, total sdk.Coins) { From 035c332a14f1d16106c5c7b1d5fb8dcb9ffcd36f Mon Sep 17 00:00:00 2001 From: Hanjun Kim Date: Mon, 18 Jul 2022 23:02:04 +0900 Subject: [PATCH 2/3] docs: add `SpendableCoin` to spec docs --- x/bank/spec/02_keepers.md | 1 + 1 file changed, 1 insertion(+) diff --git a/x/bank/spec/02_keepers.md b/x/bank/spec/02_keepers.md index 7bca8fe12b8..ef65aaebfc0 100644 --- a/x/bank/spec/02_keepers.md +++ b/x/bank/spec/02_keepers.md @@ -140,6 +140,7 @@ type ViewKeeper interface { GetBalance(ctx sdk.Context, addr sdk.AccAddress, denom string) sdk.Coin LockedCoins(ctx sdk.Context, addr sdk.AccAddress) sdk.Coins SpendableCoins(ctx sdk.Context, addr sdk.AccAddress) sdk.Coins + SpendableCoin(ctx sdk.Context, addr sdk.AccAddress, denom string) sdk.Coin IterateAccountBalances(ctx sdk.Context, addr sdk.AccAddress, cb func(coin sdk.Coin) (stop bool)) IterateAllBalances(ctx sdk.Context, cb func(address sdk.AccAddress, coin sdk.Coin) (stop bool)) From ea2b571805a3d7276301ee8659c6f6eef9d9363b Mon Sep 17 00:00:00 2001 From: Hanjun Kim Date: Tue, 19 Jul 2022 23:21:09 +0900 Subject: [PATCH 3/3] chore: update CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2e6677cd6c0..735618f91e1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -66,6 +66,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ ### API Breaking Changes +* (x/bank) [\#12593](https://github.com/cosmos/cosmos-sdk/pull/12593) Add `SpendableCoin` method to `BaseViewKeeper` * (x/slashing) [#12581](https://github.com/cosmos/cosmos-sdk/pull/12581) Remove `x/slashing` legacy querier. * (types) [\#12355](https://github.com/cosmos/cosmos-sdk/pull/12355) Remove the compile-time `types.DBbackend` variable. Removes usage of the same in server/util.go * (x/gov) [#12368](https://github.com/cosmos/cosmos-sdk/pull/12369) Gov keeper is now passed by reference instead of copy to make post-construction mutation of Hooks and Proposal Handlers possible at a framework level.