Skip to content

Commit

Permalink
fix: keep the balance query endpoint compatible with legacy blocks (b…
Browse files Browse the repository at this point in the history
…ackport cosmos#13301) (cosmos#13318)

* fix: keep the balance query endpoint compatible with legacy blocks (cosmos#13301)

* keep the balance query endpoint compatible with legacy blocks

Closes: cosmos#13296

A temporary solution before the proxy tool developed, since the balance endpoint is too important.

* Update CHANGELOG.md

* Apply suggestions from code review

Co-authored-by: Julien Robert <julien@rbrt.fr>
Co-authored-by: Marko <marbar3778@yahoo.com>
(cherry picked from commit 6c4f94b)

# Conflicts:
#	CHANGELOG.md
#	x/bank/keeper/view.go

* Apply suggestions from code review

* fix lint

Co-authored-by: yihuang <huang@crypto.com>
Co-authored-by: Julien Robert <julien@rbrt.fr>
  • Loading branch information
3 people authored and JeancarloBarrios committed Sep 28, 2024
1 parent 56d6f06 commit 2b1215e
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 14 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
* (x/group) [#13214](https://github.com/cosmos/cosmos-sdk/pull/13214) Add `withdraw-proposal` command to group module's CLI transaction commands.
* (x/auth) [#13048](https://github.com/cosmos/cosmos-sdk/pull/13048) Add handling of AccountNumberStoreKeyPrefix to the simulation decoder.
* (simapp) [#13108](https://github.com/cosmos/cosmos-sdk/pull/13108) Call `SetIAVLCacheSize` with the configured value in simapp.
* [#13318](https://github.com/cosmos/cosmos-sdk/pull/13318) Keep the balance query endpoint compatible with legacy blocks

### Bug Fixes

Expand Down
8 changes: 4 additions & 4 deletions x/bank/keeper/grpc_query.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package keeper
import (
"context"

"cosmossdk.io/math"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"

Expand Down Expand Up @@ -88,11 +87,12 @@ func (k BaseKeeper) SpendableBalances(ctx context.Context, req *types.QuerySpend
}

pageRes, err := query.Paginate(accountStore, req.Pagination, func(key, value []byte) error {
var amount math.Int
if err := amount.Unmarshal(value); err != nil {
denom := string(key)
balance, err := UnmarshalBalanceCompat(k.cdc, value, denom)
if err != nil {
return err
}
balances = append(balances, result)
balances = append(balances, balance)
return nil
})
if err != nil {
Expand Down
56 changes: 46 additions & 10 deletions x/bank/keeper/view.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,12 +134,15 @@ func (k BaseViewKeeper) GetAccountsBalances(ctx context.Context) []types.Balance

// GetBalance returns the balance of a specific denomination for a given account
// by address.
func (k BaseViewKeeper) GetBalance(ctx context.Context, addr sdk.AccAddress, denom string) sdk.Coin {
amt, err := k.Balances.Get(ctx, collections.Join(addr, denom))
func (k BaseViewKeeper) GetBalance(ctx sdk.Context, addr sdk.AccAddress, denom string) sdk.Coin {
accountStore := k.getAccountStore(ctx, addr)
bz := accountStore.Get([]byte(denom))
balance, err := UnmarshalBalanceCompat(k.cdc, bz, denom)
if err != nil {
return sdk.NewCoin(denom, math.ZeroInt())
panic(err)
}
return sdk.NewCoin(denom, amt)

return balance
}

// IterateAccountBalances iterates over the balances of a single account and
Expand All @@ -152,12 +155,13 @@ func (k BaseViewKeeper) IterateAccountBalances(ctx sdk.Context, addr sdk.AccAddr
defer iterator.Close()

for ; iterator.Valid(); iterator.Next() {
var amount math.Int
if err := amount.Unmarshal(iterator.Value()); err != nil {
denom := string(iterator.Key())
balance, err := UnmarshalBalanceCompat(k.cdc, iterator.Value(), denom)
if err != nil {
panic(err)
}

if cb(sdk.NewCoin(string(iterator.Key()), amount)) {
if cb(balance) {
break
}
}
Expand All @@ -182,12 +186,12 @@ func (k BaseViewKeeper) IterateAllBalances(ctx sdk.Context, cb func(sdk.AccAddre
panic(err)
}

var amount math.Int
if err := amount.Unmarshal(iterator.Value()); err != nil {
balance, err := UnmarshalBalanceCompat(k.cdc, iterator.Value(), denom)
if err != nil {
panic(err)
}

if cb(address, sdk.NewCoin(denom, amount)) {
if cb(address, balance) {
break
}
}
Expand Down Expand Up @@ -276,3 +280,35 @@ func (k BaseViewKeeper) ValidateBalance(ctx context.Context, addr sdk.AccAddress

return nil
}

// getAccountStore gets the account store of the given address.
func (k BaseViewKeeper) getAccountStore(ctx sdk.Context, addr sdk.AccAddress) prefix.Store {
store := ctx.KVStore(k.storeKey)
return prefix.NewStore(store, types.CreateAccountBalancesPrefix(addr))
}

// getDenomAddressPrefixStore returns a prefix store that acts as a reverse index
// between a denomination and account balance for that denomination.
func (k BaseViewKeeper) getDenomAddressPrefixStore(ctx sdk.Context, denom string) prefix.Store {
return prefix.NewStore(ctx.KVStore(k.storeKey), types.CreateDenomAddressPrefix(denom))
}

// UnmarshalBalanceCompat unmarshal balance amount from storage, it's backward-compatible with the legacy format.
func UnmarshalBalanceCompat(cdc codec.BinaryCodec, bz []byte, denom string) (sdk.Coin, error) {
amount := math.ZeroInt()
if bz == nil {
return sdk.NewCoin(denom, amount), nil
}

if err := amount.Unmarshal(bz); err != nil {
// try to unmarshal with the legacy format.
var balance sdk.Coin
if cdc.Unmarshal(bz, &balance) != nil {
// return with the original error
return sdk.Coin{}, err
}
return balance, nil
}

return sdk.NewCoin(denom, amount), nil
}

0 comments on commit 2b1215e

Please sign in to comment.