Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add basic x/bank gRPC query service #6343

Merged
merged 12 commits into from
Jun 5, 2020
1 change: 1 addition & 0 deletions buf.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ lint:
- UNARY_RPC
- COMMENT_FIELD
- PACKAGE_DIRECTORY_MATCH
- SERVICE_SUFFIX
ignore:
- third_party
- codec/testdata
Expand Down
9 changes: 4 additions & 5 deletions x/bank/alias.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ var (
NewBaseKeeper = keeper.NewBaseKeeper
NewBaseSendKeeper = keeper.NewBaseSendKeeper
NewBaseViewKeeper = keeper.NewBaseViewKeeper
NewQuerier = keeper.NewQuerier
RegisterCodec = types.RegisterCodec
ErrNoInputs = types.ErrNoInputs
ErrNoOutputs = types.ErrNoOutputs
Expand All @@ -44,8 +43,8 @@ var (
NewOutput = types.NewOutput
ValidateInputsOutputs = types.ValidateInputsOutputs
ParamKeyTable = types.ParamKeyTable
NewQueryBalanceParams = types.NewQueryBalanceParams
NewQueryAllBalancesParams = types.NewQueryAllBalancesParams
NewQueryBalanceRequest = types.NewQueryBalanceRequest
NewQueryAllBalancesRequest = types.NewQueryAllBalancesRequest
ModuleCdc = types.ModuleCdc
ParamStoreKeySendEnabled = types.ParamStoreKeySendEnabled
BalancesPrefix = types.BalancesPrefix
Expand All @@ -67,8 +66,8 @@ type (
MsgMultiSend = types.MsgMultiSend
Input = types.Input
Output = types.Output
QueryBalanceParams = types.QueryBalanceParams
QueryAllBalancesParams = types.QueryAllBalancesParams
QueryBalanceRequest = types.QueryBalanceRequest
QueryAllBalancesRequest = types.QueryAllBalancesRequest
GenesisBalancesIterator = types.GenesisBalancesIterator
Keeper = keeper.Keeper
GenesisState = types.GenesisState
Expand Down
4 changes: 2 additions & 2 deletions x/bank/client/cli/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,10 +72,10 @@ func GetBalancesCmd(cdc *codec.Codec) *cobra.Command {

denom := viper.GetString(flagDenom)
if denom == "" {
params = types.NewQueryAllBalancesParams(addr)
params = types.NewQueryAllBalancesRequest(addr)
route = fmt.Sprintf("custom/%s/%s", types.QuerierRoute, types.QueryAllBalances)
} else {
params = types.NewQueryBalanceParams(addr, denom)
params = types.NewQueryBalanceRequest(addr, denom)
route = fmt.Sprintf("custom/%s/%s", types.QuerierRoute, types.QueryBalance)
}

Expand Down
4 changes: 2 additions & 2 deletions x/bank/client/rest/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,10 @@ func QueryBalancesRequestHandlerFn(clientCtx client.Context) http.HandlerFunc {

denom := r.FormValue("denom")
if denom == "" {
params = types.NewQueryAllBalancesParams(addr)
params = types.NewQueryAllBalancesRequest(addr)
route = fmt.Sprintf("custom/%s/%s", types.QuerierRoute, types.QueryAllBalances)
} else {
params = types.NewQueryBalanceParams(addr, denom)
params = types.NewQueryBalanceRequest(addr, denom)
route = fmt.Sprintf("custom/%s/%s", types.QuerierRoute, types.QueryBalance)
}

Expand Down
73 changes: 73 additions & 0 deletions x/bank/keeper/grpc_query.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package keeper

import (
"context"

"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"

sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/bank/types"
)

var _ types.QueryServer = BaseKeeper{}

// Balance implements the Query/Balance gRPC method
func (q BaseKeeper) Balance(c context.Context, req *types.QueryBalanceRequest) (*types.QueryBalanceResponse, error) {
if req == nil {
return nil, status.Errorf(codes.InvalidArgument, "empty request")
}

if len(req.Address) == 0 {
return nil, status.Errorf(codes.InvalidArgument, "invalid address")
}

if req.Denom == "" {
return nil, status.Errorf(codes.InvalidArgument, "invalid denom")
}

ctx := sdk.UnwrapSDKContext(c)
balance := q.GetBalance(ctx, req.Address, req.Denom)

return &types.QueryBalanceResponse{Balance: &balance}, nil
}

// AllBalances implements the Query/AllBalances gRPC method
func (q BaseKeeper) AllBalances(c context.Context, req *types.QueryAllBalancesRequest) (*types.QueryAllBalancesResponse, error) {
if req == nil {
return nil, status.Errorf(codes.InvalidArgument, "empty request")
}

if len(req.Address) == 0 {
return nil, status.Errorf(codes.InvalidArgument, "invalid address")
}

ctx := sdk.UnwrapSDKContext(c)
balances := q.GetAllBalances(ctx, req.Address)

return &types.QueryAllBalancesResponse{Balances: balances}, nil
}

// TotalSupply implements the Query/TotalSupply gRPC method
func (q BaseKeeper) TotalSupply(c context.Context, _ *types.QueryTotalSupplyRequest) (*types.QueryTotalSupplyResponse, error) {
ctx := sdk.UnwrapSDKContext(c)
totalSupply := q.GetSupply(ctx).GetTotal()

return &types.QueryTotalSupplyResponse{Supply: totalSupply}, nil
}

// SupplyOf implements the Query/SupplyOf gRPC method
func (q BaseKeeper) SupplyOf(c context.Context, req *types.QuerySupplyOfRequest) (*types.QuerySupplyOfResponse, error) {
if req == nil {
return nil, status.Errorf(codes.InvalidArgument, "empty request")
}

if req.Denom == "" {
return nil, status.Errorf(codes.InvalidArgument, "invalid denom")
}

ctx := sdk.UnwrapSDKContext(c)
supply := q.GetSupply(ctx).GetTotal().AmountOf(req.Denom)

return &types.QuerySupplyOfResponse{Amount: supply}, nil
}
110 changes: 110 additions & 0 deletions x/bank/keeper/grpc_query_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
package keeper_test

import (
gocontext "context"

"github.com/cosmos/cosmos-sdk/baseapp"
sdk "github.com/cosmos/cosmos-sdk/types"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
"github.com/cosmos/cosmos-sdk/x/bank"
"github.com/cosmos/cosmos-sdk/x/bank/types"
)

func (suite *IntegrationTestSuite) TestQueryBalance() {
app, ctx := suite.app, suite.ctx
_, _, addr := authtypes.KeyTestPubAddr()

queryHelper := baseapp.NewQueryServerTestHelper(ctx)
types.RegisterQueryServer(queryHelper, app.BankKeeper)
queryClient := types.NewQueryClient(queryHelper)

_, err := queryClient.Balance(gocontext.Background(), &types.QueryBalanceRequest{})
suite.Require().Error(err)

_, err = queryClient.Balance(gocontext.Background(), &types.QueryBalanceRequest{Address: addr})
suite.Require().Error(err)

req := types.NewQueryBalanceRequest(addr, fooDenom)
res, err := queryClient.Balance(gocontext.Background(), req)
suite.Require().NoError(err)
suite.Require().NotNil(res)
suite.True(res.Balance.IsZero())

origCoins := sdk.NewCoins(newFooCoin(50), newBarCoin(30))
acc := app.AccountKeeper.NewAccountWithAddress(ctx, addr)

app.AccountKeeper.SetAccount(ctx, acc)
suite.Require().NoError(app.BankKeeper.SetBalances(ctx, acc.GetAddress(), origCoins))

res, err = queryClient.Balance(gocontext.Background(), req)
suite.Require().NoError(err)
suite.Require().NotNil(res)
suite.True(res.Balance.IsEqual(newFooCoin(50)))
}

func (suite *IntegrationTestSuite) TestQueryAllBalances() {
app, ctx := suite.app, suite.ctx
_, _, addr := authtypes.KeyTestPubAddr()

queryHelper := baseapp.NewQueryServerTestHelper(ctx)
types.RegisterQueryServer(queryHelper, app.BankKeeper)
queryClient := types.NewQueryClient(queryHelper)

_, err := queryClient.AllBalances(gocontext.Background(), &types.QueryAllBalancesRequest{})
suite.Require().Error(err)

req := types.NewQueryAllBalancesRequest(addr)
res, err := queryClient.AllBalances(gocontext.Background(), req)
suite.Require().NoError(err)
suite.Require().NotNil(res)
suite.True(res.Balances.IsZero())

origCoins := sdk.NewCoins(newFooCoin(50), newBarCoin(30))
acc := app.AccountKeeper.NewAccountWithAddress(ctx, addr)

app.AccountKeeper.SetAccount(ctx, acc)
suite.Require().NoError(app.BankKeeper.SetBalances(ctx, acc.GetAddress(), origCoins))

res, err = queryClient.AllBalances(gocontext.Background(), req)
suite.Require().NoError(err)
suite.Require().NotNil(res)
suite.True(res.Balances.IsEqual(origCoins))
}

func (suite *IntegrationTestSuite) TestQueryTotalSupply() {
app, ctx := suite.app, suite.ctx
expectedTotalSupply := bank.NewSupply(sdk.NewCoins(sdk.NewInt64Coin("test", 400000000)))
app.BankKeeper.SetSupply(ctx, expectedTotalSupply)

queryHelper := baseapp.NewQueryServerTestHelper(ctx)
types.RegisterQueryServer(queryHelper, app.BankKeeper)
queryClient := types.NewQueryClient(queryHelper)

res, err := queryClient.TotalSupply(gocontext.Background(), &types.QueryTotalSupplyRequest{})
suite.Require().NoError(err)
suite.Require().NotNil(res)

suite.Require().Equal(expectedTotalSupply.Total, res.Supply)
}

func (suite *IntegrationTestSuite) TestQueryTotalSupplyOf() {
app, ctx := suite.app, suite.ctx

test1Supply := sdk.NewInt64Coin("test1", 4000000)
test2Supply := sdk.NewInt64Coin("test2", 700000000)
expectedTotalSupply := bank.NewSupply(sdk.NewCoins(test1Supply, test2Supply))
app.BankKeeper.SetSupply(ctx, expectedTotalSupply)

queryHelper := baseapp.NewQueryServerTestHelper(ctx)
types.RegisterQueryServer(queryHelper, app.BankKeeper)
queryClient := types.NewQueryClient(queryHelper)

_, err := queryClient.SupplyOf(gocontext.Background(), &types.QuerySupplyOfRequest{})
suite.Require().Error(err)

res, err := queryClient.SupplyOf(gocontext.Background(), &types.QuerySupplyOfRequest{Denom: test1Supply.Denom})
suite.Require().NoError(err)
suite.Require().NotNil(res)

suite.Require().Equal(test1Supply.Amount, res.Amount)
}
2 changes: 2 additions & 0 deletions x/bank/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ type Keeper interface {
UnmarshalSupply(bz []byte) (exported.SupplyI, error)
MarshalSupplyJSON(supply exported.SupplyI) ([]byte, error)
UnmarshalSupplyJSON(bz []byte) (exported.SupplyI, error)

types.QueryServer
}

// BaseKeeper manages transfers between accounts. It implements the Keeper interface.
Expand Down
4 changes: 2 additions & 2 deletions x/bank/keeper/querier.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ func NewQuerier(k Keeper) sdk.Querier {
}

func queryBalance(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) {
var params types.QueryBalanceParams
var params types.QueryBalanceRequest

if err := types.ModuleCdc.UnmarshalJSON(req.Data, &params); err != nil {
return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error())
Expand All @@ -50,7 +50,7 @@ func queryBalance(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, err
}

func queryAllBalance(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) {
var params types.QueryAllBalancesParams
var params types.QueryAllBalancesRequest

if err := types.ModuleCdc.UnmarshalJSON(req.Data, &params); err != nil {
return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error())
Expand Down
4 changes: 2 additions & 2 deletions x/bank/keeper/querier_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ func (suite *IntegrationTestSuite) TestQuerier_QueryBalance() {
suite.Require().NotNil(err)
suite.Require().Nil(res)

req.Data = app.Codec().MustMarshalJSON(types.NewQueryBalanceParams(addr, fooDenom))
req.Data = app.Codec().MustMarshalJSON(types.NewQueryBalanceRequest(addr, fooDenom))
res, err = querier(ctx, []string{types.QueryBalance}, req)
suite.Require().NoError(err)
suite.Require().NotNil(res)
Expand Down Expand Up @@ -62,7 +62,7 @@ func (suite *IntegrationTestSuite) TestQuerier_QueryAllBalances() {
suite.Require().NotNil(err)
suite.Require().Nil(res)

req.Data = app.Codec().MustMarshalJSON(types.NewQueryAllBalancesParams(addr))
req.Data = app.Codec().MustMarshalJSON(types.NewQueryAllBalancesRequest(addr))
res, err = querier(ctx, []string{types.QueryAllBalances}, req)
suite.Require().NoError(err)
suite.Require().NotNil(res)
Expand Down
23 changes: 6 additions & 17 deletions x/bank/types/querier.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,25 +12,14 @@ const (
QuerySupplyOf = "supply_of"
)

// QueryBalanceParams defines the params for querying an account balance.
type QueryBalanceParams struct {
Address sdk.AccAddress
Denom string
// NewQueryBalanceRequest creates a new instance of QueryBalanceRequest.
func NewQueryBalanceRequest(addr sdk.AccAddress, denom string) *QueryBalanceRequest {
return &QueryBalanceRequest{Address: addr, Denom: denom}
}

// NewQueryBalanceParams creates a new instance of QueryBalanceParams.
func NewQueryBalanceParams(addr sdk.AccAddress, denom string) QueryBalanceParams {
return QueryBalanceParams{Address: addr, Denom: denom}
}

// QueryAllBalancesParams defines the params for querying all account balances
type QueryAllBalancesParams struct {
Address sdk.AccAddress
}

// NewQueryAllBalancesParams creates a new instance of QueryAllBalancesParams.
func NewQueryAllBalancesParams(addr sdk.AccAddress) QueryAllBalancesParams {
return QueryAllBalancesParams{Address: addr}
// NewQueryAllBalancesRequest creates a new instance of QueryAllBalancesRequest.
func NewQueryAllBalancesRequest(addr sdk.AccAddress) *QueryAllBalancesRequest {
return &QueryAllBalancesRequest{Address: addr}
}

// QueryTotalSupply defines the params for the following queries:
Expand Down
Loading