Skip to content

Commit

Permalink
keep the balance query endpoint compatible with legacy blocks
Browse files Browse the repository at this point in the history
Closes: cosmos#13296

A temporary solution before the proxy tool developed, since the balance endpoint is too important.
  • Loading branch information
yihuang committed Sep 15, 2022
1 parent ae21d8c commit fbb1877
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 16 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
* [#13178](https://github.com/cosmos/cosmos-sdk/pull/13178) Add `cosmos.msg.v1.service` protobuf annotation to allow tooling to distinguish between Msg and Query services via reflection.
* [#13233](https://github.com/cosmos/cosmos-sdk/pull/13233) Add `--append` to `add-genesis-account` sub-command to append new tokens after an account is already created.
* [#13236](https://github.com/cosmos/cosmos-sdk/pull/13236) Integrate Filter Logging
* [#]() Keep the balance query endpoint compatible with legacy blocks

### State Machine Breaking

Expand Down
7 changes: 4 additions & 3 deletions x/bank/keeper/grpc_query.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,12 @@ func (k BaseKeeper) AllBalances(ctx context.Context, req *types.QueryAllBalances
accountStore := k.getAccountStore(sdkCtx, addr)

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, sdk.NewCoin(string(key), amount))
balances = append(balances, balance)
return nil
})
if err != nil {
Expand Down
44 changes: 31 additions & 13 deletions x/bank/keeper/view.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"fmt"

"cosmossdk.io/math"

"github.com/tendermint/tendermint/libs/log"

"github.com/cosmos/cosmos-sdk/codec"
Expand Down Expand Up @@ -100,17 +101,13 @@ func (k BaseViewKeeper) GetAccountsBalances(ctx sdk.Context) []types.Balance {
// by address.
func (k BaseViewKeeper) GetBalance(ctx sdk.Context, addr sdk.AccAddress, denom string) sdk.Coin {
accountStore := k.getAccountStore(ctx, addr)
amount := math.ZeroInt()
bz := accountStore.Get([]byte(denom))
if bz == nil {
return sdk.NewCoin(denom, amount)
}

if err := amount.Unmarshal(bz); err != nil {
balance, err := UnmarshalBalanceCompat(k.cdc, bz, denom)
if err != nil {
panic(err)
}

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

// IterateAccountBalances iterates over the balances of a single account and
Expand All @@ -123,12 +120,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 @@ -153,12 +151,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 @@ -252,3 +250,23 @@ func (k BaseViewKeeper) getAccountStore(ctx sdk.Context, addr sdk.AccAddress) pr
func (k BaseViewKeeper) getDenomAddressPrefixStore(ctx sdk.Context, denom string) prefix.Store {
return prefix.NewStore(ctx.KVStore(k.storeKey), types.CreateDenomAddressPrefix(denom))
}

// UnmarshalBalanceCompat unmarshal sdk.Coin 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 fbb1877

Please sign in to comment.