Additional Hard module queries (#884)

* unsynced deposits/borrows queriers

* cli queriers

* rest querier

* implement interest factor querier

* querier cli

* querier rest

* fix typo in comment
This commit is contained in:
Denali Marsh 2021-03-22 18:57:07 +01:00 committed by GitHub
parent 99095a8fc3
commit 656c5a80b8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 582 additions and 8 deletions

View File

@ -38,11 +38,14 @@ func GetQueryCmd(queryRoute string, cdc *codec.Codec) *cobra.Command {
queryParamsCmd(queryRoute, cdc), queryParamsCmd(queryRoute, cdc),
queryModAccountsCmd(queryRoute, cdc), queryModAccountsCmd(queryRoute, cdc),
queryDepositsCmd(queryRoute, cdc), queryDepositsCmd(queryRoute, cdc),
queryUnsyncedDepositsCmd(queryRoute, cdc),
queryTotalDepositedCmd(queryRoute, cdc), queryTotalDepositedCmd(queryRoute, cdc),
queryBorrowsCmd(queryRoute, cdc), queryBorrowsCmd(queryRoute, cdc),
queryUnsyncedBorrowsCmd(queryRoute, cdc),
queryTotalBorrowedCmd(queryRoute, cdc), queryTotalBorrowedCmd(queryRoute, cdc),
queryInterestRateCmd(queryRoute, cdc), queryInterestRateCmd(queryRoute, cdc),
queryReserves(queryRoute, cdc), queryReserves(queryRoute, cdc),
queryInterestFactorsCmd(queryRoute, cdc),
)...) )...)
return hardQueryCmd return hardQueryCmd
@ -115,6 +118,66 @@ func queryModAccountsCmd(queryRoute string, cdc *codec.Codec) *cobra.Command {
} }
} }
func queryUnsyncedDepositsCmd(queryRoute string, cdc *codec.Codec) *cobra.Command {
cmd := &cobra.Command{
Use: "unsynced-deposits",
Short: "query hard module unsynced deposits with optional filters",
Long: strings.TrimSpace(`query for all hard module unsynced deposits or a specific unsynced deposit using flags:
Example:
$ kvcli q hard unsynced-deposits
$ kvcli q hard unsynced-deposits --owner kava1l0xsq2z7gqd7yly0g40y5836g0appumark77ny --denom bnb
$ kvcli q hard unsynced-deposits --denom ukava
$ kvcli q hard unsynced-deposits --denom btcb`,
),
Args: cobra.NoArgs,
RunE: func(cmd *cobra.Command, args []string) error {
cliCtx := context.NewCLIContext().WithCodec(cdc)
var owner sdk.AccAddress
ownerBech := viper.GetString(flagOwner)
denom := viper.GetString(flagDenom)
if len(ownerBech) != 0 {
depositOwner, err := sdk.AccAddressFromBech32(ownerBech)
if err != nil {
return err
}
owner = depositOwner
}
page := viper.GetInt(flags.FlagPage)
limit := viper.GetInt(flags.FlagLimit)
params := types.NewQueryUnsyncedDepositsParams(page, limit, denom, owner)
bz, err := cdc.MarshalJSON(params)
if err != nil {
return err
}
route := fmt.Sprintf("custom/%s/%s", queryRoute, types.QueryGetUnsyncedDeposits)
res, height, err := cliCtx.QueryWithData(route, bz)
if err != nil {
return err
}
cliCtx = cliCtx.WithHeight(height)
var deposits types.Deposits
if err := cdc.UnmarshalJSON(res, &deposits); err != nil {
return fmt.Errorf("failed to unmarshal deposits: %w", err)
}
return cliCtx.PrintOutput(deposits)
},
}
cmd.Flags().Int(flags.FlagPage, 1, "pagination page to query for")
cmd.Flags().Int(flags.FlagLimit, 100, "pagination limit (max 100)")
cmd.Flags().String(flagOwner, "", "(optional) filter for unsynced deposits by owner address")
cmd.Flags().String(flagDenom, "", "(optional) filter for unsynced deposits by denom")
return cmd
}
func queryDepositsCmd(queryRoute string, cdc *codec.Codec) *cobra.Command { func queryDepositsCmd(queryRoute string, cdc *codec.Codec) *cobra.Command {
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "deposits", Use: "deposits",
@ -175,6 +238,64 @@ func queryDepositsCmd(queryRoute string, cdc *codec.Codec) *cobra.Command {
return cmd return cmd
} }
func queryUnsyncedBorrowsCmd(queryRoute string, cdc *codec.Codec) *cobra.Command {
cmd := &cobra.Command{
Use: "unsynced-borrows",
Short: "query hard module unsynced borrows with optional filters",
Long: strings.TrimSpace(`query for all hard module unsynced borrows or a specific unsynced borrow using flags:
Example:
$ kvcli q hard unsynced-borrows
$ kvcli q hard unsynced-borrows --owner kava1l0xsq2z7gqd7yly0g40y5836g0appumark77ny
$ kvcli q hard unsynced-borrows --denom bnb`,
),
Args: cobra.NoArgs,
RunE: func(cmd *cobra.Command, args []string) error {
cliCtx := context.NewCLIContext().WithCodec(cdc)
var owner sdk.AccAddress
ownerBech := viper.GetString(flagOwner)
denom := viper.GetString(flagDenom)
if len(ownerBech) != 0 {
borrowOwner, err := sdk.AccAddressFromBech32(ownerBech)
if err != nil {
return err
}
owner = borrowOwner
}
page := viper.GetInt(flags.FlagPage)
limit := viper.GetInt(flags.FlagLimit)
params := types.NewQueryUnsyncedBorrowsParams(page, limit, owner, denom)
bz, err := cdc.MarshalJSON(params)
if err != nil {
return err
}
route := fmt.Sprintf("custom/%s/%s", queryRoute, types.QueryGetUnsyncedBorrows)
res, height, err := cliCtx.QueryWithData(route, bz)
if err != nil {
return err
}
cliCtx = cliCtx.WithHeight(height)
var borrows types.Borrows
if err := cdc.UnmarshalJSON(res, &borrows); err != nil {
return fmt.Errorf("failed to unmarshal borrows: %w", err)
}
return cliCtx.PrintOutput(borrows)
},
}
cmd.Flags().Int(flags.FlagPage, 1, "pagination page to query for")
cmd.Flags().Int(flags.FlagLimit, 100, "pagination limit (max 100)")
cmd.Flags().String(flagOwner, "", "(optional) filter for unsynced borrows by owner address")
cmd.Flags().String(flagDenom, "", "(optional) filter for unsynced borrows by denom")
return cmd
}
func queryBorrowsCmd(queryRoute string, cdc *codec.Codec) *cobra.Command { func queryBorrowsCmd(queryRoute string, cdc *codec.Codec) *cobra.Command {
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "borrows", Use: "borrows",
@ -404,3 +525,46 @@ func queryReserves(queryRoute string, cdc *codec.Codec) *cobra.Command {
cmd.Flags().String(flagDenom, "", "(optional) filter reserve coins by denom") cmd.Flags().String(flagDenom, "", "(optional) filter reserve coins by denom")
return cmd return cmd
} }
func queryInterestFactorsCmd(queryRoute string, cdc *codec.Codec) *cobra.Command {
cmd := &cobra.Command{
Use: "interest-factors",
Short: "get current global interest factors",
Long: strings.TrimSpace(`get current global interest factors:
Example:
$ kvcli q hard interest-factors
$ kvcli q hard interest-factors --denom bnb`,
),
Args: cobra.NoArgs,
RunE: func(cmd *cobra.Command, args []string) error {
cliCtx := context.NewCLIContext().WithCodec(cdc)
denom := viper.GetString(flagDenom)
// Construct query with params
params := types.NewQueryInterestFactorsParams(denom)
bz, err := cdc.MarshalJSON(params)
if err != nil {
return err
}
// Execute query
route := fmt.Sprintf("custom/%s/%s", queryRoute, types.QueryGetInterestFactors)
res, height, err := cliCtx.QueryWithData(route, bz)
if err != nil {
return err
}
cliCtx = cliCtx.WithHeight(height)
// Decode and print results
var interestFactors types.InterestFactors
if err := cdc.UnmarshalJSON(res, &interestFactors); err != nil {
return fmt.Errorf("failed to unmarshal interest factors: %w", err)
}
return cliCtx.PrintOutput(interestFactors)
},
}
cmd.Flags().String(flagDenom, "", "(optional) filter interest factors by denom")
return cmd
}

View File

@ -16,13 +16,16 @@ import (
func registerQueryRoutes(cliCtx context.CLIContext, r *mux.Router) { func registerQueryRoutes(cliCtx context.CLIContext, r *mux.Router) {
r.HandleFunc(fmt.Sprintf("/%s/parameters", types.ModuleName), queryParamsHandlerFn(cliCtx)).Methods("GET") r.HandleFunc(fmt.Sprintf("/%s/parameters", types.ModuleName), queryParamsHandlerFn(cliCtx)).Methods("GET")
r.HandleFunc(fmt.Sprintf("/%s/unsynced-deposits", types.ModuleName), queryUnsyncedDepositsHandlerFn(cliCtx)).Methods("GET")
r.HandleFunc(fmt.Sprintf("/%s/deposits", types.ModuleName), queryDepositsHandlerFn(cliCtx)).Methods("GET") r.HandleFunc(fmt.Sprintf("/%s/deposits", types.ModuleName), queryDepositsHandlerFn(cliCtx)).Methods("GET")
r.HandleFunc(fmt.Sprintf("/%s/total-deposited", types.ModuleName), queryTotalDepositedHandlerFn(cliCtx)).Methods("GET") r.HandleFunc(fmt.Sprintf("/%s/total-deposited", types.ModuleName), queryTotalDepositedHandlerFn(cliCtx)).Methods("GET")
r.HandleFunc(fmt.Sprintf("/%s/accounts", types.ModuleName), queryModAccountsHandlerFn(cliCtx)).Methods("GET") r.HandleFunc(fmt.Sprintf("/%s/accounts", types.ModuleName), queryModAccountsHandlerFn(cliCtx)).Methods("GET")
r.HandleFunc(fmt.Sprintf("/%s/unsynced-borrows", types.ModuleName), queryUnsyncedBorrowsHandlerFn(cliCtx)).Methods("GET")
r.HandleFunc(fmt.Sprintf("/%s/borrows", types.ModuleName), queryBorrowsHandlerFn(cliCtx)).Methods("GET") r.HandleFunc(fmt.Sprintf("/%s/borrows", types.ModuleName), queryBorrowsHandlerFn(cliCtx)).Methods("GET")
r.HandleFunc(fmt.Sprintf("/%s/total-borrowed", types.ModuleName), queryTotalBorrowedHandlerFn(cliCtx)).Methods("GET") r.HandleFunc(fmt.Sprintf("/%s/total-borrowed", types.ModuleName), queryTotalBorrowedHandlerFn(cliCtx)).Methods("GET")
r.HandleFunc(fmt.Sprintf("/%s/interest-rate", types.ModuleName), queryInterestRateHandlerFn(cliCtx)).Methods("GET") r.HandleFunc(fmt.Sprintf("/%s/interest-rate", types.ModuleName), queryInterestRateHandlerFn(cliCtx)).Methods("GET")
r.HandleFunc(fmt.Sprintf("/%s/reserves", types.ModuleName), queryReservesHandlerFn(cliCtx)).Methods("GET") r.HandleFunc(fmt.Sprintf("/%s/reserves", types.ModuleName), queryReservesHandlerFn(cliCtx)).Methods("GET")
r.HandleFunc(fmt.Sprintf("/%s/interest-factors", types.ModuleName), queryInterestFactorsHandlerFn(cliCtx)).Methods("GET")
} }
func queryParamsHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { func queryParamsHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
@ -93,6 +96,54 @@ func queryDepositsHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
} }
} }
func queryUnsyncedDepositsHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
_, page, limit, err := rest.ParseHTTPArgsWithLimit(r, 0)
if err != nil {
rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
return
}
// Parse the query height
cliCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r)
if !ok {
return
}
var denom string
var owner sdk.AccAddress
if x := r.URL.Query().Get(RestDenom); len(x) != 0 {
denom = strings.TrimSpace(x)
}
if x := r.URL.Query().Get(RestOwner); len(x) != 0 {
ownerStr := strings.ToLower(strings.TrimSpace(x))
owner, err = sdk.AccAddressFromBech32(ownerStr)
if err != nil {
rest.WriteErrorResponse(w, http.StatusBadRequest, fmt.Sprintf("cannot parse address from deposit owner %s", ownerStr))
return
}
}
params := types.NewQueryUnsyncedDepositsParams(page, limit, denom, owner)
bz, err := cliCtx.Codec.MarshalJSON(params)
if err != nil {
rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
return
}
route := fmt.Sprintf("custom/%s/%s", types.ModuleName, types.QueryGetUnsyncedDeposits)
res, height, err := cliCtx.QueryWithData(route, bz)
cliCtx = cliCtx.WithHeight(height)
if err != nil {
rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
return
}
rest.PostProcessResponse(w, cliCtx, res)
}
}
func queryTotalDepositedHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { func queryTotalDepositedHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) { return func(w http.ResponseWriter, r *http.Request) {
_, _, _, err := rest.ParseHTTPArgsWithLimit(r, 0) _, _, _, err := rest.ParseHTTPArgsWithLimit(r, 0)
@ -179,6 +230,54 @@ func queryBorrowsHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
} }
} }
func queryUnsyncedBorrowsHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
_, page, limit, err := rest.ParseHTTPArgsWithLimit(r, 0)
if err != nil {
rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
return
}
// Parse the query height
cliCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r)
if !ok {
return
}
var denom string
var owner sdk.AccAddress
if x := r.URL.Query().Get(RestDenom); len(x) != 0 {
denom = strings.TrimSpace(x)
}
if x := r.URL.Query().Get(RestOwner); len(x) != 0 {
ownerStr := strings.ToLower(strings.TrimSpace(x))
owner, err = sdk.AccAddressFromBech32(ownerStr)
if err != nil {
rest.WriteErrorResponse(w, http.StatusBadRequest, fmt.Sprintf("cannot parse address from borrow owner %s", ownerStr))
return
}
}
params := types.NewQueryUnsyncedBorrowsParams(page, limit, owner, denom)
bz, err := cliCtx.Codec.MarshalJSON(params)
if err != nil {
rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
return
}
route := fmt.Sprintf("custom/%s/%s", types.ModuleName, types.QueryGetUnsyncedBorrows)
res, height, err := cliCtx.QueryWithData(route, bz)
cliCtx = cliCtx.WithHeight(height)
if err != nil {
rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
return
}
rest.PostProcessResponse(w, cliCtx, res)
}
}
func queryTotalBorrowedHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { func queryTotalBorrowedHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) { return func(w http.ResponseWriter, r *http.Request) {
_, _, _, err := rest.ParseHTTPArgsWithLimit(r, 0) _, _, _, err := rest.ParseHTTPArgsWithLimit(r, 0)
@ -330,3 +429,41 @@ func queryReservesHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
rest.PostProcessResponse(w, cliCtx, res) rest.PostProcessResponse(w, cliCtx, res)
} }
} }
func queryInterestFactorsHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
_, _, _, err := rest.ParseHTTPArgsWithLimit(r, 0)
if err != nil {
rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
return
}
// Parse the query height
cliCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r)
if !ok {
return
}
var denom string
if x := r.URL.Query().Get(RestDenom); len(x) != 0 {
denom = strings.TrimSpace(x)
}
params := types.NewQueryInterestFactorsParams(denom)
bz, err := cliCtx.Codec.MarshalJSON(params)
if err != nil {
rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
return
}
route := fmt.Sprintf("custom/%s/%s", types.ModuleName, types.QueryGetInterestFactors)
res, height, err := cliCtx.QueryWithData(route, bz)
cliCtx = cliCtx.WithHeight(height)
if err != nil {
rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
return
}
rest.PostProcessResponse(w, cliCtx, res)
}
}

View File

@ -306,6 +306,21 @@ func (k Keeper) SetBorrowInterestFactor(ctx sdk.Context, denom string, borrowInt
store.Set([]byte(denom), bz) store.Set([]byte(denom), bz)
} }
// IterateBorrowInterestFactors iterates over all borrow interest factors in the store and returns
// both the borrow interest factor and the key (denom) it's stored under
func (k Keeper) IterateBorrowInterestFactors(ctx sdk.Context, cb func(denom string, factor sdk.Dec) (stop bool)) {
store := prefix.NewStore(ctx.KVStore(k.key), types.BorrowInterestFactorPrefix)
iterator := sdk.KVStorePrefixIterator(store, []byte{})
defer iterator.Close()
for ; iterator.Valid(); iterator.Next() {
var factor sdk.Dec
k.cdc.MustUnmarshalBinaryBare(iterator.Value(), &factor)
if cb(string(iterator.Key()), factor) {
break
}
}
}
// GetSupplyInterestFactor returns the current supply interest factor for an individual market // GetSupplyInterestFactor returns the current supply interest factor for an individual market
func (k Keeper) GetSupplyInterestFactor(ctx sdk.Context, denom string) (sdk.Dec, bool) { func (k Keeper) GetSupplyInterestFactor(ctx sdk.Context, denom string) (sdk.Dec, bool) {
store := prefix.NewStore(ctx.KVStore(k.key), types.SupplyInterestFactorPrefix) store := prefix.NewStore(ctx.KVStore(k.key), types.SupplyInterestFactorPrefix)
@ -324,3 +339,18 @@ func (k Keeper) SetSupplyInterestFactor(ctx sdk.Context, denom string, supplyInt
bz := k.cdc.MustMarshalBinaryBare(supplyInterestFactor) bz := k.cdc.MustMarshalBinaryBare(supplyInterestFactor)
store.Set([]byte(denom), bz) store.Set([]byte(denom), bz)
} }
// IterateSupplyInterestFactors iterates over all supply interest factors in the store and returns
// both the supply interest factor and the key (denom) it's stored under
func (k Keeper) IterateSupplyInterestFactors(ctx sdk.Context, cb func(denom string, factor sdk.Dec) (stop bool)) {
store := prefix.NewStore(ctx.KVStore(k.key), types.SupplyInterestFactorPrefix)
iterator := sdk.KVStorePrefixIterator(store, []byte{})
defer iterator.Close()
for ; iterator.Valid(); iterator.Next() {
var factor sdk.Dec
k.cdc.MustUnmarshalBinaryBare(iterator.Value(), &factor)
if cb(string(iterator.Key()), factor) {
break
}
}
}

View File

@ -22,16 +22,22 @@ func NewQuerier(k Keeper) sdk.Querier {
return queryGetModAccounts(ctx, req, k) return queryGetModAccounts(ctx, req, k)
case types.QueryGetDeposits: case types.QueryGetDeposits:
return queryGetDeposits(ctx, req, k) return queryGetDeposits(ctx, req, k)
case types.QueryGetUnsyncedDeposits:
return queryGetUnsyncedDeposits(ctx, req, k)
case types.QueryGetTotalDeposited: case types.QueryGetTotalDeposited:
return queryGetTotalDeposited(ctx, req, k) return queryGetTotalDeposited(ctx, req, k)
case types.QueryGetBorrows: case types.QueryGetBorrows:
return queryGetBorrows(ctx, req, k) return queryGetBorrows(ctx, req, k)
case types.QueryGetUnsyncedBorrows:
return queryGetUnsyncedBorrows(ctx, req, k)
case types.QueryGetTotalBorrowed: case types.QueryGetTotalBorrowed:
return queryGetTotalBorrowed(ctx, req, k) return queryGetTotalBorrowed(ctx, req, k)
case types.QueryGetInterestRate: case types.QueryGetInterestRate:
return queryGetInterestRate(ctx, req, k) return queryGetInterestRate(ctx, req, k)
case types.QueryGetReserves: case types.QueryGetReserves:
return queryGetReserves(ctx, req, k) return queryGetReserves(ctx, req, k)
case types.QueryGetInterestFactors:
return queryGetInterestFactors(ctx, req, k)
default: default:
return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unknown %s query endpoint", types.ModuleName) return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unknown %s query endpoint", types.ModuleName)
} }
@ -147,6 +153,62 @@ func queryGetDeposits(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte,
return bz, nil return bz, nil
} }
func queryGetUnsyncedDeposits(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) {
var params types.QueryUnsyncedDepositsParams
err := types.ModuleCdc.UnmarshalJSON(req.Data, &params)
if err != nil {
return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error())
}
denom := len(params.Denom) > 0
owner := len(params.Owner) > 0
var deposits types.Deposits
switch {
case owner && denom:
deposit, found := k.GetDeposit(ctx, params.Owner)
if found {
for _, coin := range deposit.Amount {
if coin.Denom == params.Denom {
deposits = append(deposits, deposit)
}
}
}
case owner:
deposit, found := k.GetDeposit(ctx, params.Owner)
if found {
deposits = append(deposits, deposit)
}
case denom:
k.IterateDeposits(ctx, func(deposit types.Deposit) (stop bool) {
if deposit.Amount.AmountOf(params.Denom).IsPositive() {
deposits = append(deposits, deposit)
}
return false
})
default:
k.IterateDeposits(ctx, func(deposit types.Deposit) (stop bool) {
deposits = append(deposits, deposit)
return false
})
}
var bz []byte
start, end := client.Paginate(len(deposits), params.Page, params.Limit, 100)
if start < 0 || end < 0 {
deposits = types.Deposits{}
} else {
deposits = deposits[start:end]
}
bz, err = codec.MarshalJSONIndent(types.ModuleCdc, deposits)
if err != nil {
return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error())
}
return bz, nil
}
func queryGetBorrows(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) { func queryGetBorrows(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) {
var params types.QueryBorrowsParams var params types.QueryBorrowsParams
@ -219,6 +281,62 @@ func queryGetBorrows(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte,
return bz, nil return bz, nil
} }
func queryGetUnsyncedBorrows(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) {
var params types.QueryUnsyncedBorrowsParams
err := types.ModuleCdc.UnmarshalJSON(req.Data, &params)
if err != nil {
return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error())
}
denom := len(params.Denom) > 0
owner := len(params.Owner) > 0
var borrows types.Borrows
switch {
case owner && denom:
borrow, found := k.GetBorrow(ctx, params.Owner)
if found {
for _, coin := range borrow.Amount {
if coin.Denom == params.Denom {
borrows = append(borrows, borrow)
}
}
}
case owner:
borrow, found := k.GetBorrow(ctx, params.Owner)
if found {
borrows = append(borrows, borrow)
}
case denom:
k.IterateBorrows(ctx, func(borrow types.Borrow) (stop bool) {
if borrow.Amount.AmountOf(params.Denom).IsPositive() {
borrows = append(borrows, borrow)
}
return false
})
default:
k.IterateBorrows(ctx, func(borrow types.Borrow) (stop bool) {
borrows = append(borrows, borrow)
return false
})
}
var bz []byte
start, end := client.Paginate(len(borrows), params.Page, params.Limit, 100)
if start < 0 || end < 0 {
borrows = types.Borrows{}
} else {
borrows = borrows[start:end]
}
bz, err = codec.MarshalJSONIndent(types.ModuleCdc, borrows)
if err != nil {
return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error())
}
return bz, nil
}
func queryGetTotalBorrowed(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) { func queryGetTotalBorrowed(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) {
var params types.QueryTotalBorrowedParams var params types.QueryTotalBorrowedParams
err := types.ModuleCdc.UnmarshalJSON(req.Data, &params) err := types.ModuleCdc.UnmarshalJSON(req.Data, &params)
@ -355,3 +473,58 @@ func queryGetReserves(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte,
return bz, nil return bz, nil
} }
func queryGetInterestFactors(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) {
var params types.QueryInterestFactorsParams
err := types.ModuleCdc.UnmarshalJSON(req.Data, &params)
if err != nil {
return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error())
}
var interestFactors types.InterestFactors
if len(params.Denom) > 0 {
// Fetch supply/borrow interest factors for a single denom
interestFactor := types.InterestFactor{}
interestFactor.Denom = params.Denom
supplyInterestFactor, found := k.GetSupplyInterestFactor(ctx, params.Denom)
if found {
interestFactor.SupplyInterestFactor = supplyInterestFactor
}
borrowInterestFactor, found := k.GetBorrowInterestFactor(ctx, params.Denom)
if found {
interestFactor.BorrowInterestFactor = borrowInterestFactor
}
interestFactors = append(interestFactors, interestFactor)
} else {
interestFactorMap := make(map[string]types.InterestFactor)
// Populate mapping with supply interest factors
k.IterateSupplyInterestFactors(ctx, func(denom string, factor sdk.Dec) (stop bool) {
interestFactor := types.InterestFactor{Denom: denom, SupplyInterestFactor: factor}
interestFactorMap[denom] = interestFactor
return false
})
// Populate mapping with borrow interest factors
k.IterateBorrowInterestFactors(ctx, func(denom string, factor sdk.Dec) (stop bool) {
interestFactor, ok := interestFactorMap[denom]
if !ok {
newInterestFactor := types.InterestFactor{Denom: denom, BorrowInterestFactor: factor}
interestFactorMap[denom] = newInterestFactor
} else {
interestFactor.BorrowInterestFactor = factor
interestFactorMap[denom] = interestFactor
}
return false
})
// Translate mapping to slice
for _, val := range interestFactorMap {
interestFactors = append(interestFactors, val)
}
}
bz, err := codec.MarshalJSONIndent(types.ModuleCdc, interestFactors)
if err != nil {
return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error())
}
return bz, nil
}

View File

@ -9,11 +9,14 @@ const (
QueryGetParams = "params" QueryGetParams = "params"
QueryGetModuleAccounts = "accounts" QueryGetModuleAccounts = "accounts"
QueryGetDeposits = "deposits" QueryGetDeposits = "deposits"
QueryGetUnsyncedDeposits = "unsynced-deposits"
QueryGetTotalDeposited = "total-deposited" QueryGetTotalDeposited = "total-deposited"
QueryGetBorrows = "borrows" QueryGetBorrows = "borrows"
QueryGetUnsyncedBorrows = "unsynced-borrows"
QueryGetTotalBorrowed = "total-borrowed" QueryGetTotalBorrowed = "total-borrowed"
QueryGetInterestRate = "interest-rate" QueryGetInterestRate = "interest-rate"
QueryGetReserves = "reserves" QueryGetReserves = "reserves"
QueryGetInterestFactors = "interest-factors"
) )
// QueryDepositsParams is the params for a filtered deposit query // QueryDepositsParams is the params for a filtered deposit query
@ -34,6 +37,24 @@ func NewQueryDepositsParams(page, limit int, denom string, owner sdk.AccAddress)
} }
} }
// QueryUnsyncedDepositsParams is the params for a filtered unsynced deposit query.
type QueryUnsyncedDepositsParams struct {
Page int `json:"page" yaml:"page"`
Limit int `json:"limit" yaml:"limit"`
Denom string `json:"denom" yaml:"denom"`
Owner sdk.AccAddress `json:"owner" yaml:"owner"`
}
// NewQueryUnsyncedDepositsParams creates a new QueryUnsyncedDepositsParams
func NewQueryUnsyncedDepositsParams(page, limit int, denom string, owner sdk.AccAddress) QueryUnsyncedDepositsParams {
return QueryUnsyncedDepositsParams{
Page: page,
Limit: limit,
Denom: denom,
Owner: owner,
}
}
// QueryAccountParams is the params for a filtered module account query // QueryAccountParams is the params for a filtered module account query
type QueryAccountParams struct { type QueryAccountParams struct {
Page int `json:"page" yaml:"page"` Page int `json:"page" yaml:"page"`
@ -68,6 +89,24 @@ func NewQueryBorrowsParams(page, limit int, owner sdk.AccAddress, denom string)
} }
} }
// QueryUnsyncedBorrowsParams is the params for a filtered unsynced borrows query
type QueryUnsyncedBorrowsParams struct {
Page int `json:"page" yaml:"page"`
Limit int `json:"limit" yaml:"limit"`
Owner sdk.AccAddress `json:"owner" yaml:"owner"`
Denom string `json:"denom" yaml:"denom"`
}
// NewQueryUnsyncedBorrowsParams creates a new QueryUnsyncedBorrowsParams
func NewQueryUnsyncedBorrowsParams(page, limit int, owner sdk.AccAddress, denom string) QueryUnsyncedBorrowsParams {
return QueryUnsyncedBorrowsParams{
Page: page,
Limit: limit,
Owner: owner,
Denom: denom,
}
}
// QueryTotalBorrowedParams is the params for a filtered total borrowed coins query // QueryTotalBorrowedParams is the params for a filtered total borrowed coins query
type QueryTotalBorrowedParams struct { type QueryTotalBorrowedParams struct {
Denom string `json:"denom" yaml:"denom"` Denom string `json:"denom" yaml:"denom"`
@ -134,3 +173,34 @@ func NewQueryReservesParams(denom string) QueryReservesParams {
Denom: denom, Denom: denom,
} }
} }
// QueryInterestFactorsParams is the params for a filtered interest factors query
type QueryInterestFactorsParams struct {
Denom string `json:"denom" yaml:"denom"`
}
// NewQueryInterestFactorsParams creates a new QueryInterestFactorsParams
func NewQueryInterestFactorsParams(denom string) QueryInterestFactorsParams {
return QueryInterestFactorsParams{
Denom: denom,
}
}
// InterestFactor is a unique type returned by interest factor queries
type InterestFactor struct {
Denom string `json:"denom" yaml:"denom"`
BorrowInterestFactor sdk.Dec `json:"borrow_interest_factor" yaml:"borrow_interest_factor"`
SupplyInterestFactor sdk.Dec `json:"supply_interest_factor" yaml:"supply_interest_factor"`
}
// NewInterestFactor returns a new instance of InterestFactor
func NewInterestFactor(denom string, supplyInterestFactor, borrowInterestFactor sdk.Dec) InterestFactor {
return InterestFactor{
Denom: denom,
SupplyInterestFactor: supplyInterestFactor,
BorrowInterestFactor: borrowInterestFactor,
}
}
// InterestFactors is a slice of InterestFactor
type InterestFactors = []InterestFactor