Add query for cdp deposits (#346)

* feat: query cdp deposits

* feat: test querying deposits

* fix: update comment

* fix: use single word command
This commit is contained in:
Kevin Davis 2020-01-28 14:08:17 -06:00 committed by GitHub
parent bf64a5c02c
commit 024001888c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 141 additions and 0 deletions

View File

@ -27,6 +27,7 @@ func GetQueryCmd(queryRoute string, cdc *codec.Codec) *cobra.Command {
QueryCdpCmd(queryRoute, cdc), QueryCdpCmd(queryRoute, cdc),
QueryCdpsByDenomCmd(queryRoute, cdc), QueryCdpsByDenomCmd(queryRoute, cdc),
QueryCdpsByDenomAndRatioCmd(queryRoute, cdc), QueryCdpsByDenomAndRatioCmd(queryRoute, cdc),
QueryCdpDepositsCmd(queryRoute, cdc),
QueryParamsCmd(queryRoute, cdc), QueryParamsCmd(queryRoute, cdc),
)...) )...)
@ -157,6 +158,49 @@ $ %s query %s cdps-by-ratio uatom 1.5
} }
} }
// QueryCdpDepositsCmd returns the command handler for querying the deposits of a particular cdp
func QueryCdpDepositsCmd(queryRoute string, cdc *codec.Codec) *cobra.Command {
return &cobra.Command{
Use: "deposits [owner-addr] [collateral-name]",
Short: "get deposits for a cdp",
Long: strings.TrimSpace(
fmt.Sprintf(`Get the deposits of a CDP.
Example:
$ %s query %s deposits kava15qdefkmwswysgg4qxgqpqr35k3m49pkx2jdfnw uatom
`, version.ClientName, types.ModuleName)),
Args: cobra.ExactArgs(2),
RunE: func(cmd *cobra.Command, args []string) error {
cliCtx := context.NewCLIContext().WithCodec(cdc)
// Prepare params for querier
ownerAddress, err := sdk.AccAddressFromBech32(args[0])
if err != nil {
return err
}
bz, err := cdc.MarshalJSON(types.QueryCdpParams{
CollateralDenom: args[1],
Owner: ownerAddress,
})
if err != nil {
return err
}
// Query
route := fmt.Sprintf("custom/%s/%s", queryRoute, types.QueryGetCdpDeposits)
res, _, err := cliCtx.QueryWithData(route, bz)
if err != nil {
return err
}
// Decode and print results
var deposits types.Deposits
cdc.MustUnmarshalJSON(res, &deposits)
return cliCtx.PrintOutput(deposits)
},
}
}
// QueryParamsCmd returns the command handler for cdp parameter querying // QueryParamsCmd returns the command handler for cdp parameter querying
func QueryParamsCmd(queryRoute string, cdc *codec.Codec) *cobra.Command { func QueryParamsCmd(queryRoute string, cdc *codec.Codec) *cobra.Command {
return &cobra.Command{ return &cobra.Command{

View File

@ -19,6 +19,7 @@ func registerQueryRoutes(cliCtx context.CLIContext, r *mux.Router) {
r.HandleFunc(fmt.Sprintf("/cdp/{%s}/{%s}", types.RestOwner, types.RestCollateralDenom), queryCdpHandlerFn(cliCtx)).Methods("GET") r.HandleFunc(fmt.Sprintf("/cdp/{%s}/{%s}", types.RestOwner, types.RestCollateralDenom), queryCdpHandlerFn(cliCtx)).Methods("GET")
r.HandleFunc(fmt.Sprintf("/cdp/{%s}", types.RestCollateralDenom), queryCdpsHandlerFn(cliCtx)).Methods("GET") r.HandleFunc(fmt.Sprintf("/cdp/{%s}", types.RestCollateralDenom), queryCdpsHandlerFn(cliCtx)).Methods("GET")
r.HandleFunc(fmt.Sprintf("/cdp/{%s}/ratio/{%s}", types.RestCollateralDenom, types.RestRatio), queryCdpsByRatioHandlerFn(cliCtx)).Methods("GET") r.HandleFunc(fmt.Sprintf("/cdp/{%s}/ratio/{%s}", types.RestCollateralDenom, types.RestRatio), queryCdpsByRatioHandlerFn(cliCtx)).Methods("GET")
r.HandleFunc(fmt.Sprintf("/cdp/deposits/{%s}/{%s}", types.RestOwner, types.RestCollateralDenom), queryCdpDepositsHandlerFn(cliCtx)).Methods("GET")
r.HandleFunc("/cdps/params", getParamsHandlerFn(cliCtx)).Methods("GET") r.HandleFunc("/cdps/params", getParamsHandlerFn(cliCtx)).Methods("GET")
} }
@ -110,6 +111,38 @@ func queryCdpsByRatioHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
} }
} }
func queryCdpDepositsHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
ownerBech32 := vars[types.RestOwner]
collateralDenom := vars[types.RestCollateralDenom]
owner, err := sdk.AccAddressFromBech32(ownerBech32)
if err != nil {
rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
return
}
params := types.NewQueryCdpDeposits(owner, collateralDenom)
bz, err := cliCtx.Codec.MarshalJSON(params)
if err != nil {
rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
return
}
res, height, err := cliCtx.QueryWithData(fmt.Sprintf("custom/cdp/%s", types.QueryGetCdpDeposits), bz)
if err != nil {
rest.WriteErrorResponse(w, http.StatusNotFound, err.Error())
return
}
cliCtx = cliCtx.WithHeight(height)
rest.PostProcessResponse(w, cliCtx, res)
}
}
func getParamsHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { func getParamsHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) { return func(w http.ResponseWriter, r *http.Request) {
// Get the params // Get the params

View File

@ -20,6 +20,8 @@ func NewQuerier(keeper Keeper) sdk.Querier {
return queryGetCdpsByRatio(ctx, req, keeper) return queryGetCdpsByRatio(ctx, req, keeper)
case types.QueryGetParams: case types.QueryGetParams:
return queryGetParams(ctx, req, keeper) return queryGetParams(ctx, req, keeper)
case types.QueryGetCdpDeposits:
return queryGetDeposits(ctx, req, keeper)
default: default:
return nil, sdk.ErrUnknownRequest("unknown cdp query endpoint") return nil, sdk.ErrUnknownRequest("unknown cdp query endpoint")
} }
@ -57,6 +59,34 @@ func queryGetCdp(ctx sdk.Context, req abci.RequestQuery, keeper Keeper) ([]byte,
} }
// query deposits on a particular cdp
func queryGetDeposits(ctx sdk.Context, req abci.RequestQuery, keeper Keeper) ([]byte, sdk.Error) {
var requestParams types.QueryCdpDeposits
err := keeper.cdc.UnmarshalJSON(req.Data, &requestParams)
if err != nil {
return nil, sdk.ErrUnknownRequest(sdk.AppendMsgToErr("incorrectly formatted request data", err.Error()))
}
_, valid := keeper.GetDenomPrefix(ctx, requestParams.CollateralDenom)
if !valid {
return nil, types.ErrInvalidCollateralDenom(keeper.codespace, requestParams.CollateralDenom)
}
cdp, found := keeper.GetCdpByOwnerAndDenom(ctx, requestParams.Owner, requestParams.CollateralDenom)
if !found {
return nil, types.ErrCdpNotFound(keeper.codespace, requestParams.Owner, requestParams.CollateralDenom)
}
deposits := keeper.GetDeposits(ctx, cdp.ID)
bz, err := codec.MarshalJSONIndent(keeper.cdc, deposits)
if err != nil {
return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", err.Error()))
}
return bz, nil
}
// query cdps with matching denom and ratio LESS THAN the input ratio // query cdps with matching denom and ratio LESS THAN the input ratio
func queryGetCdpsByRatio(ctx sdk.Context, req abci.RequestQuery, keeper Keeper) ([]byte, sdk.Error) { func queryGetCdpsByRatio(ctx sdk.Context, req abci.RequestQuery, keeper Keeper) ([]byte, sdk.Error) {
var requestParams types.QueryCdpsByRatioParams var requestParams types.QueryCdpsByRatioParams

View File

@ -256,6 +256,25 @@ func (suite *QuerierTestSuite) TestQueryParams() {
suite.Equal(gs.Params, p) suite.Equal(gs.Params, p)
} }
func (suite *QuerierTestSuite) TestQueryDeposits() {
ctx := suite.ctx.WithIsCheckTx(false)
query := abci.RequestQuery{
Path: strings.Join([]string{custom, types.QuerierRoute, types.QueryGetCdpDeposits}, "/"),
Data: types.ModuleCdc.MustMarshalJSON(types.NewQueryCdpDeposits(suite.cdps[0].Owner, suite.cdps[0].Collateral[0].Denom)),
}
bz, err := suite.querier(ctx, []string{types.QueryGetCdpDeposits}, query)
suite.Nil(err)
suite.NotNil(bz)
deposits := suite.keeper.GetDeposits(ctx, suite.cdps[0].ID)
var d types.Deposits
suite.Nil(types.ModuleCdc.UnmarshalJSON(bz, &d))
suite.Equal(deposits, d)
}
func TestQuerierTestSuite(t *testing.T) { func TestQuerierTestSuite(t *testing.T) {
suite.Run(t, new(QuerierTestSuite)) suite.Run(t, new(QuerierTestSuite))
} }

View File

@ -7,6 +7,7 @@ import (
// Querier routes for the cdp module // Querier routes for the cdp module
const ( const (
QueryGetCdp = "cdp" QueryGetCdp = "cdp"
QueryGetCdpDeposits = "deposits"
QueryGetCdps = "cdps" QueryGetCdps = "cdps"
QueryGetCdpsByCollateralization = "ratio" QueryGetCdpsByCollateralization = "ratio"
QueryGetParams = "params" QueryGetParams = "params"
@ -41,6 +42,20 @@ func NewQueryCdpParams(owner sdk.AccAddress, denom string) QueryCdpParams {
} }
} }
// QueryCdpDeposits params for query /cdp/deposits
type QueryCdpDeposits struct {
CollateralDenom string // get CDPs with this collateral denom
Owner sdk.AccAddress // get CDPs belonging to this owner
}
// NewQueryCdpDeposits returns QueryCdpDeposits
func NewQueryCdpDeposits(owner sdk.AccAddress, denom string) QueryCdpDeposits {
return QueryCdpDeposits{
Owner: owner,
CollateralDenom: denom,
}
}
// QueryCdpsByRatioParams params for query /cdp/cdps/ratio // QueryCdpsByRatioParams params for query /cdp/cdps/ratio
type QueryCdpsByRatioParams struct { type QueryCdpsByRatioParams struct {
CollateralDenom string // get CDPs with this collateral denom CollateralDenom string // get CDPs with this collateral denom