Hard: refactor borrow/borrows and deposit/deposits query (#761)

* refactor cli borrows query

* rest api feature parity for borrows query

* refactor deposits cli query

* remove deposit/borrow query names from types

* add named deposit/borrow queries back into types

* rest api feature parity for deposits query

* load synced deposit instead of synced balance

* deposits query returns synced deposits

* borrows query returns synced borrows

* refactor querier types

* update comment for accuracy

* add deposit/borrow slice types

* refactor 'borrowed' query

* implement 'deposited' query types

* implement 'deposited' query keeper function

* implement 'deposited' query CLI

* implement 'deposited' query rest endpoint

* update naming conventions to 'total'
This commit is contained in:
Denali Marsh 2021-01-13 19:14:58 +01:00 committed by GitHub
parent d05516bbe0
commit 34a7172581
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 346 additions and 333 deletions

View File

@ -74,7 +74,6 @@ var (
NewPeriod = types.NewPeriod NewPeriod = types.NewPeriod
NewQueryAccountParams = types.NewQueryAccountParams NewQueryAccountParams = types.NewQueryAccountParams
NewQueryClaimParams = types.NewQueryClaimParams NewQueryClaimParams = types.NewQueryClaimParams
NewQueryDepositParams = types.NewQueryDepositParams
ParamKeyTable = types.ParamKeyTable ParamKeyTable = types.ParamKeyTable
RegisterCodec = types.RegisterCodec RegisterCodec = types.RegisterCodec
@ -135,7 +134,6 @@ type (
Params = types.Params Params = types.Params
QueryAccountParams = types.QueryAccountParams QueryAccountParams = types.QueryAccountParams
QueryClaimParams = types.QueryClaimParams QueryClaimParams = types.QueryClaimParams
QueryDepositParams = types.QueryDepositParams
StakingKeeper = types.StakingKeeper StakingKeeper = types.StakingKeeper
SupplyKeeper = types.SupplyKeeper SupplyKeeper = types.SupplyKeeper
) )

View File

@ -19,10 +19,10 @@ import (
// flags for cli queries // flags for cli queries
const ( const (
flagName = "name" flagName = "name"
flagDepositDenom = "deposit-denom" flagDenom = "denom"
flagOwner = "owner" flagOwner = "owner"
flagClaimType = "claim-type" flagClaimType = "claim-type"
) )
// GetQueryCmd returns the cli query commands for the module // GetQueryCmd returns the cli query commands for the module
@ -39,14 +39,13 @@ 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),
queryDepositCmd(queryRoute, cdc), queryTotalDepositedCmd(queryRoute, cdc),
queryClaimsCmd(queryRoute, cdc), queryClaimsCmd(queryRoute, cdc),
queryBorrowsCmd(queryRoute, cdc), queryBorrowsCmd(queryRoute, cdc),
queryBorrowCmd(queryRoute, cdc), queryTotalBorrowedCmd(queryRoute, cdc),
)...) )...)
return hardQueryCmd return hardQueryCmd
} }
func queryParamsCmd(queryRoute string, cdc *codec.Codec) *cobra.Command { func queryParamsCmd(queryRoute string, cdc *codec.Codec) *cobra.Command {
@ -124,9 +123,9 @@ func queryDepositsCmd(queryRoute string, cdc *codec.Codec) *cobra.Command {
Example: Example:
$ kvcli q hard deposits $ kvcli q hard deposits
$ kvcli q hard deposits --owner kava1l0xsq2z7gqd7yly0g40y5836g0appumark77ny --deposit-denom bnb $ kvcli q hard deposits --owner kava1l0xsq2z7gqd7yly0g40y5836g0appumark77ny --denom bnb
$ kvcli q hard deposits --deposit-denom ukava $ kvcli q hard deposits --denom ukava
$ kvcli q hard deposits --deposit-denom btcb`, $ kvcli q hard deposits --denom btcb`,
), ),
Args: cobra.NoArgs, Args: cobra.NoArgs,
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
@ -135,7 +134,7 @@ func queryDepositsCmd(queryRoute string, cdc *codec.Codec) *cobra.Command {
var owner sdk.AccAddress var owner sdk.AccAddress
ownerBech := viper.GetString(flagOwner) ownerBech := viper.GetString(flagOwner)
depositDenom := viper.GetString(flagDepositDenom) denom := viper.GetString(flagDenom)
if len(ownerBech) != 0 { if len(ownerBech) != 0 {
depositOwner, err := sdk.AccAddressFromBech32(ownerBech) depositOwner, err := sdk.AccAddressFromBech32(ownerBech)
@ -145,10 +144,12 @@ func queryDepositsCmd(queryRoute string, cdc *codec.Codec) *cobra.Command {
owner = depositOwner owner = depositOwner
} }
// Note: The 10 users with the lowest LTV ratio have their outstanding interest applied each block, so if
// testing with 10 or less addresses they'll all show their latest balance including outstanding interest.
page := viper.GetInt(flags.FlagPage) page := viper.GetInt(flags.FlagPage)
limit := viper.GetInt(flags.FlagLimit) limit := viper.GetInt(flags.FlagLimit)
params := types.NewQueryDepositsParams(page, limit, depositDenom, owner) params := types.NewQueryDepositsParams(page, limit, denom, owner)
bz, err := cdc.MarshalJSON(params) bz, err := cdc.MarshalJSON(params)
if err != nil { if err != nil {
return err return err
@ -161,17 +162,18 @@ func queryDepositsCmd(queryRoute string, cdc *codec.Codec) *cobra.Command {
} }
cliCtx = cliCtx.WithHeight(height) cliCtx = cliCtx.WithHeight(height)
var deposits []types.Deposit var deposits types.Deposits
if err := cdc.UnmarshalJSON(res, &deposits); err != nil { if err := cdc.UnmarshalJSON(res, &deposits); err != nil {
return fmt.Errorf("failed to unmarshal deposits: %w", err) return fmt.Errorf("failed to unmarshal deposits: %w", err)
} }
return cliCtx.PrintOutput(deposits) return cliCtx.PrintOutput(deposits)
}, },
} }
cmd.Flags().Int(flags.FlagPage, 1, "pagination page to query for") cmd.Flags().Int(flags.FlagPage, 1, "pagination page to query for")
cmd.Flags().Int(flags.FlagLimit, 100, "pagination limit (max 100)") cmd.Flags().Int(flags.FlagLimit, 100, "pagination limit (max 100)")
cmd.Flags().String(flagOwner, "", "(optional) filter for deposits by owner address") cmd.Flags().String(flagOwner, "", "(optional) filter for deposits by owner address")
cmd.Flags().String(flagDepositDenom, "", "(optional) filter for deposits by denom") cmd.Flags().String(flagDenom, "", "(optional) filter for deposits by denom")
return cmd return cmd
} }
@ -183,9 +185,9 @@ func queryClaimsCmd(queryRoute string, cdc *codec.Codec) *cobra.Command {
Example: Example:
$ kvcli q hard claims $ kvcli q hard claims
$ kvcli q hard claims --owner kava1l0xsq2z7gqd7yly0g40y5836g0appumark77ny --claim-type lp --deposit-denom bnb $ kvcli q hard claims --owner kava1l0xsq2z7gqd7yly0g40y5836g0appumark77ny --claim-type lp --denom bnb
$ kvcli q hard claims --claim-type stake --deposit-denom ukava $ kvcli q hard claims --claim-type stake --denom ukava
$ kvcli q hard claims --deposit-denom btcb`, $ kvcli q hard claims --denom btcb`,
), ),
Args: cobra.NoArgs, Args: cobra.NoArgs,
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
@ -195,7 +197,7 @@ func queryClaimsCmd(queryRoute string, cdc *codec.Codec) *cobra.Command {
var claimType types.ClaimType var claimType types.ClaimType
ownerBech := viper.GetString(flagOwner) ownerBech := viper.GetString(flagOwner)
depositDenom := viper.GetString(flagDepositDenom) denom := viper.GetString(flagDenom)
claimTypeStr := viper.GetString(flagClaimType) claimTypeStr := viper.GetString(flagClaimType)
if len(ownerBech) != 0 { if len(ownerBech) != 0 {
@ -216,7 +218,7 @@ func queryClaimsCmd(queryRoute string, cdc *codec.Codec) *cobra.Command {
page := viper.GetInt(flags.FlagPage) page := viper.GetInt(flags.FlagPage)
limit := viper.GetInt(flags.FlagLimit) limit := viper.GetInt(flags.FlagLimit)
params := types.NewQueryClaimParams(page, limit, depositDenom, owner, claimType) params := types.NewQueryClaimParams(page, limit, denom, owner, claimType)
bz, err := cdc.MarshalJSON(params) bz, err := cdc.MarshalJSON(params)
if err != nil { if err != nil {
return err return err
@ -236,10 +238,11 @@ func queryClaimsCmd(queryRoute string, cdc *codec.Codec) *cobra.Command {
return cliCtx.PrintOutput(claims) return cliCtx.PrintOutput(claims)
}, },
} }
cmd.Flags().Int(flags.FlagPage, 1, "pagination page to query for") cmd.Flags().Int(flags.FlagPage, 1, "pagination page to query for")
cmd.Flags().Int(flags.FlagLimit, 100, "pagination limit (max 100)") cmd.Flags().Int(flags.FlagLimit, 100, "pagination limit (max 100)")
cmd.Flags().String(flagOwner, "", "(optional) filter for claims by owner address") cmd.Flags().String(flagOwner, "", "(optional) filter for claims by owner address")
cmd.Flags().String(flagDepositDenom, "", "(optional) filter for claims by denom") cmd.Flags().String(flagDenom, "", "(optional) filter for claims by denom")
cmd.Flags().String(flagClaimType, "", "(optional) filter for claims by type (lp or staking)") cmd.Flags().String(flagClaimType, "", "(optional) filter for claims by type (lp or staking)")
return cmd return cmd
} }
@ -252,8 +255,8 @@ func queryBorrowsCmd(queryRoute string, cdc *codec.Codec) *cobra.Command {
Example: Example:
$ kvcli q hard borrows $ kvcli q hard borrows
$ kvcli q hard borrows --borrower kava1l0xsq2z7gqd7yly0g40y5836g0appumark77ny $ kvcli q hard borrows --owner kava1l0xsq2z7gqd7yly0g40y5836g0appumark77ny
$ kvcli q hard borrows --borrow-denom bnb`, $ kvcli q hard borrows --denom bnb`,
), ),
Args: cobra.NoArgs, Args: cobra.NoArgs,
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
@ -262,7 +265,7 @@ func queryBorrowsCmd(queryRoute string, cdc *codec.Codec) *cobra.Command {
var owner sdk.AccAddress var owner sdk.AccAddress
ownerBech := viper.GetString(flagOwner) ownerBech := viper.GetString(flagOwner)
depositDenom := viper.GetString(flagDepositDenom) denom := viper.GetString(flagDenom)
if len(ownerBech) != 0 { if len(ownerBech) != 0 {
borrowOwner, err := sdk.AccAddressFromBech32(ownerBech) borrowOwner, err := sdk.AccAddressFromBech32(ownerBech)
@ -272,10 +275,12 @@ func queryBorrowsCmd(queryRoute string, cdc *codec.Codec) *cobra.Command {
owner = borrowOwner owner = borrowOwner
} }
// Note: The 10 users with the lowest LTV ratio have their outstanding debt applied each block, so if
// testing with 10 or less addresses they'll all show their latest balance including outstanding debt.
page := viper.GetInt(flags.FlagPage) page := viper.GetInt(flags.FlagPage)
limit := viper.GetInt(flags.FlagLimit) limit := viper.GetInt(flags.FlagLimit)
params := types.NewQueryBorrowsParams(page, limit, owner, depositDenom) params := types.NewQueryBorrowsParams(page, limit, owner, denom)
bz, err := cdc.MarshalJSON(params) bz, err := cdc.MarshalJSON(params)
if err != nil { if err != nil {
return err return err
@ -288,7 +293,7 @@ func queryBorrowsCmd(queryRoute string, cdc *codec.Codec) *cobra.Command {
} }
cliCtx = cliCtx.WithHeight(height) cliCtx = cliCtx.WithHeight(height)
var borrows []types.Borrow var borrows types.Borrows
if err := cdc.UnmarshalJSON(res, &borrows); err != nil { if err := cdc.UnmarshalJSON(res, &borrows); err != nil {
return fmt.Errorf("failed to unmarshal borrows: %w", err) return fmt.Errorf("failed to unmarshal borrows: %w", err)
} }
@ -298,126 +303,92 @@ func queryBorrowsCmd(queryRoute string, cdc *codec.Codec) *cobra.Command {
cmd.Flags().Int(flags.FlagPage, 1, "pagination page to query for") cmd.Flags().Int(flags.FlagPage, 1, "pagination page to query for")
cmd.Flags().Int(flags.FlagLimit, 100, "pagination limit (max 100)") cmd.Flags().Int(flags.FlagLimit, 100, "pagination limit (max 100)")
cmd.Flags().String(flagOwner, "", "(optional) filter for borrows by owner address") cmd.Flags().String(flagOwner, "", "(optional) filter for borrows by owner address")
cmd.Flags().String(flagDenom, "", "(optional) filter for borrows by denom")
return cmd return cmd
} }
func queryBorrowedCmd(queryRoute string, cdc *codec.Codec) *cobra.Command { func queryTotalBorrowedCmd(queryRoute string, cdc *codec.Codec) *cobra.Command {
return &cobra.Command{ cmd := &cobra.Command{
Use: "borrowed", Use: "total-borrowed",
Short: "get total current borrowed amount", Short: "get total current borrowed amount",
Long: "get the total amount of coins currently borrowed for the Hard protocol", Long: strings.TrimSpace(`get the total amount of coins currently borrowed using flags:
Args: cobra.NoArgs,
Example:
$ kvcli q hard total-borrowed
$ kvcli q hard total-borrowed --denom bnb`,
),
Args: cobra.NoArgs,
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
cliCtx := context.NewCLIContext().WithCodec(cdc) cliCtx := context.NewCLIContext().WithCodec(cdc)
// Query denom := viper.GetString(flagDenom)
route := fmt.Sprintf("custom/%s/%s", queryRoute, types.QueryGetBorrowed)
res, height, err := cliCtx.QueryWithData(route, nil) // Construct query with params
params := types.NewQueryTotalBorrowedParams(denom)
bz, err := cdc.MarshalJSON(params)
if err != nil {
return err
}
// Execute query
route := fmt.Sprintf("custom/%s/%s", queryRoute, types.QueryGetTotalBorrowed)
res, height, err := cliCtx.QueryWithData(route, bz)
if err != nil { if err != nil {
return err return err
} }
cliCtx = cliCtx.WithHeight(height) cliCtx = cliCtx.WithHeight(height)
// Decode and print results // Decode and print results
var borrowedCoins sdk.Coins var totalBorrowedCoins sdk.Coins
if err := cdc.UnmarshalJSON(res, &borrowedCoins); err != nil { if err := cdc.UnmarshalJSON(res, &totalBorrowedCoins); err != nil {
return fmt.Errorf("failed to unmarshal borrowed coins: %w", err) return fmt.Errorf("failed to unmarshal total borrowed coins: %w", err)
} }
return cliCtx.PrintOutput(borrowedCoins) return cliCtx.PrintOutput(totalBorrowedCoins)
}, },
} }
cmd.Flags().String(flagDenom, "", "(optional) filter total borrowed coins by denom")
return cmd
} }
func queryBorrowCmd(queryRoute string, cdc *codec.Codec) *cobra.Command { func queryTotalDepositedCmd(queryRoute string, cdc *codec.Codec) *cobra.Command {
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "borrow", Use: "total-deposited",
Short: "query outstanding borrow balance for a user", Short: "get total current deposited amount",
Long: strings.TrimSpace(`query outstanding borrow balance for a user: Long: strings.TrimSpace(`get the total amount of coins currently deposited using flags:
Example: Example:
$ kvcli q hard borrow --owner kava1l0xsq2z7gqd7yly0g40y5836g0appumark77ny`, $ kvcli q hard total-deposited
$ kvcli q hard total-deposited --denom bnb`,
), ),
Args: cobra.NoArgs, Args: cobra.NoArgs,
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
cliCtx := context.NewCLIContext().WithCodec(cdc) cliCtx := context.NewCLIContext().WithCodec(cdc)
var owner sdk.AccAddress denom := viper.GetString(flagDenom)
ownerBech := viper.GetString(flagOwner) // Construct query with params
if len(ownerBech) != 0 { params := types.NewQueryTotalDepositedParams(denom)
borrowOwner, err := sdk.AccAddressFromBech32(ownerBech)
if err != nil {
return err
}
owner = borrowOwner
}
params := types.NewQueryBorrowParams(owner)
bz, err := cdc.MarshalJSON(params) bz, err := cdc.MarshalJSON(params)
if err != nil { if err != nil {
return err return err
} }
route := fmt.Sprintf("custom/%s/%s", queryRoute, types.QueryGetBorrow) // Execute query
route := fmt.Sprintf("custom/%s/%s", queryRoute, types.QueryGetTotalDeposited)
res, height, err := cliCtx.QueryWithData(route, bz) res, height, err := cliCtx.QueryWithData(route, bz)
if err != nil { if err != nil {
return err return err
} }
cliCtx = cliCtx.WithHeight(height) cliCtx = cliCtx.WithHeight(height)
var balance sdk.Coins // Decode and print results
if err := cdc.UnmarshalJSON(res, &balance); err != nil { var totalSuppliedCoins sdk.Coins
return fmt.Errorf("failed to unmarshal borrow balance: %w", err) if err := cdc.UnmarshalJSON(res, &totalSuppliedCoins); err != nil {
return fmt.Errorf("failed to unmarshal total deposited coins: %w", err)
} }
return cliCtx.PrintOutput(balance) return cliCtx.PrintOutput(totalSuppliedCoins)
}, },
} }
cmd.Flags().String(flagOwner, "", "filter for borrows by owner address") cmd.Flags().String(flagDenom, "", "(optional) filter total deposited coins by denom")
return cmd
}
func queryDepositCmd(queryRoute string, cdc *codec.Codec) *cobra.Command {
cmd := &cobra.Command{
Use: "deposit",
Short: "query outstanding deposit balance for a user",
Long: strings.TrimSpace(`query outstanding deposit balance for a user:
Example:
$ kvcli q hard deposit --owner kava1l0xsq2z7gqd7yly0g40y5836g0appumark77ny`,
),
Args: cobra.NoArgs,
RunE: func(cmd *cobra.Command, args []string) error {
cliCtx := context.NewCLIContext().WithCodec(cdc)
var owner sdk.AccAddress
ownerBech := viper.GetString(flagOwner)
if len(ownerBech) != 0 {
borrowOwner, err := sdk.AccAddressFromBech32(ownerBech)
if err != nil {
return err
}
owner = borrowOwner
}
params := types.NewQueryDepositParams(owner)
bz, err := cdc.MarshalJSON(params)
if err != nil {
return err
}
route := fmt.Sprintf("custom/%s/%s", queryRoute, types.QueryGetDeposit)
res, height, err := cliCtx.QueryWithData(route, bz)
if err != nil {
return err
}
cliCtx = cliCtx.WithHeight(height)
var balance sdk.Coins
if err := cdc.UnmarshalJSON(res, &balance); err != nil {
return fmt.Errorf("failed to unmarshal borrow balance: %w", err)
}
return cliCtx.PrintOutput(balance)
},
}
cmd.Flags().String(flagOwner, "", "filter for borrows by owner address")
return cmd return cmd
} }

View File

@ -17,11 +17,11 @@ 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/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/claims", types.ModuleName), queryClaimsHandlerFn(cliCtx)).Methods("GET") r.HandleFunc(fmt.Sprintf("/%s/claims", types.ModuleName), queryClaimsHandlerFn(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/borrows", types.ModuleName), queryBorrowsHandlerFn(cliCtx)).Methods("GET") r.HandleFunc(fmt.Sprintf("/%s/borrows", types.ModuleName), queryBorrowsHandlerFn(cliCtx)).Methods("GET")
r.HandleFunc(fmt.Sprintf("/%s/borrow", types.ModuleName), queryBorrowHandlerFn(cliCtx)).Methods("GET") r.HandleFunc(fmt.Sprintf("/%s/total-borrowed", types.ModuleName), queryTotalBorrowedHandlerFn(cliCtx)).Methods("GET")
r.HandleFunc(fmt.Sprintf("/%s/borrowed", types.ModuleName), queryBorrowedHandlerFn(cliCtx)).Methods("GET")
} }
func queryParamsHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { func queryParamsHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
@ -57,23 +57,23 @@ func queryDepositsHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
return return
} }
var depositDenom string var denom string
var depositOwner sdk.AccAddress var owner sdk.AccAddress
if x := r.URL.Query().Get(RestDenom); len(x) != 0 { if x := r.URL.Query().Get(RestDenom); len(x) != 0 {
depositDenom = strings.TrimSpace(x) denom = strings.TrimSpace(x)
} }
if x := r.URL.Query().Get(RestOwner); len(x) != 0 { if x := r.URL.Query().Get(RestOwner); len(x) != 0 {
depositOwnerStr := strings.ToLower(strings.TrimSpace(x)) ownerStr := strings.ToLower(strings.TrimSpace(x))
depositOwner, err = sdk.AccAddressFromBech32(depositOwnerStr) owner, err = sdk.AccAddressFromBech32(ownerStr)
if err != nil { if err != nil {
rest.WriteErrorResponse(w, http.StatusBadRequest, fmt.Sprintf("cannot parse address from deposit owner %s", depositOwnerStr)) rest.WriteErrorResponse(w, http.StatusBadRequest, fmt.Sprintf("cannot parse address from deposit owner %s", ownerStr))
return return
} }
} }
params := types.NewQueryDepositsParams(page, limit, depositDenom, depositOwner) params := types.NewQueryDepositsParams(page, limit, denom, owner)
bz, err := cliCtx.Codec.MarshalJSON(params) bz, err := cliCtx.Codec.MarshalJSON(params)
if err != nil { if err != nil {
@ -92,6 +92,44 @@ func queryDepositsHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
} }
} }
func queryTotalDepositedHandlerFn(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.NewQueryTotalDepositedParams(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.QueryGetTotalDeposited)
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 queryClaimsHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { func queryClaimsHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) { return func(w http.ResponseWriter, r *http.Request) {
_, page, limit, err := rest.ParseHTTPArgsWithLimit(r, 0) _, page, limit, err := rest.ParseHTTPArgsWithLimit(r, 0)
@ -105,12 +143,12 @@ func queryClaimsHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
return return
} }
var depositDenom string var denom string
var claimOwner sdk.AccAddress var claimOwner sdk.AccAddress
var claimType types.ClaimType var claimType types.ClaimType
if x := r.URL.Query().Get(RestDenom); len(x) != 0 { if x := r.URL.Query().Get(RestDenom); len(x) != 0 {
depositDenom = strings.TrimSpace(x) denom = strings.TrimSpace(x)
} }
if x := r.URL.Query().Get(RestOwner); len(x) != 0 { if x := r.URL.Query().Get(RestOwner); len(x) != 0 {
@ -122,7 +160,7 @@ func queryClaimsHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
} }
} }
if x := r.URL.Query().Get(RestType); len(x) != 0 { if x := r.URL.Query().Get(RestClaimType); len(x) != 0 {
claimTypeStr := strings.ToLower(strings.TrimSpace(x)) claimTypeStr := strings.ToLower(strings.TrimSpace(x))
err := types.ClaimType(claimTypeStr).IsValid() err := types.ClaimType(claimTypeStr).IsValid()
if err != nil { if err != nil {
@ -132,7 +170,7 @@ func queryClaimsHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
claimType = types.ClaimType(claimTypeStr) claimType = types.ClaimType(claimTypeStr)
} }
params := types.NewQueryClaimParams(page, limit, depositDenom, claimOwner, claimType) params := types.NewQueryClaimParams(page, limit, denom, claimOwner, claimType)
bz, err := cliCtx.Codec.MarshalJSON(params) bz, err := cliCtx.Codec.MarshalJSON(params)
if err != nil { if err != nil {
@ -164,23 +202,23 @@ func queryBorrowsHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
return return
} }
var borrowDenom string var denom string
var borrowOwner sdk.AccAddress var owner sdk.AccAddress
if x := r.URL.Query().Get(RestBorrowDenom); len(x) != 0 { if x := r.URL.Query().Get(RestDenom); len(x) != 0 {
borrowDenom = strings.TrimSpace(x) denom = strings.TrimSpace(x)
} }
if x := r.URL.Query().Get(RestOwner); len(x) != 0 { if x := r.URL.Query().Get(RestOwner); len(x) != 0 {
borrowOwnerStr := strings.ToLower(strings.TrimSpace(x)) ownerStr := strings.ToLower(strings.TrimSpace(x))
borrowOwner, err = sdk.AccAddressFromBech32(borrowOwnerStr) owner, err = sdk.AccAddressFromBech32(ownerStr)
if err != nil { if err != nil {
rest.WriteErrorResponse(w, http.StatusBadRequest, fmt.Sprintf("cannot parse address from borrow owner %s", borrowOwnerStr)) rest.WriteErrorResponse(w, http.StatusBadRequest, fmt.Sprintf("cannot parse address from borrow owner %s", ownerStr))
return return
} }
} }
params := types.NewQueryBorrowsParams(page, limit, borrowOwner, borrowDenom) params := types.NewQueryBorrowsParams(page, limit, owner, denom)
bz, err := cliCtx.Codec.MarshalJSON(params) bz, err := cliCtx.Codec.MarshalJSON(params)
if err != nil { if err != nil {
@ -199,7 +237,7 @@ func queryBorrowsHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
} }
} }
func queryBorrowHandlerFn(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)
if err != nil { if err != nil {
@ -212,18 +250,13 @@ func queryBorrowHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
return return
} }
var borrowOwner sdk.AccAddress var denom string
if x := r.URL.Query().Get(RestOwner); len(x) != 0 { if x := r.URL.Query().Get(RestDenom); len(x) != 0 {
borrowOwnerStr := strings.ToLower(strings.TrimSpace(x)) denom = strings.TrimSpace(x)
borrowOwner, err = sdk.AccAddressFromBech32(borrowOwnerStr)
if err != nil {
rest.WriteErrorResponse(w, http.StatusBadRequest, fmt.Sprintf("cannot parse address from borrow owner %s", borrowOwnerStr))
return
}
} }
params := types.NewQueryBorrowParams(borrowOwner) params := types.NewQueryTotalBorrowedParams(denom)
bz, err := cliCtx.Codec.MarshalJSON(params) bz, err := cliCtx.Codec.MarshalJSON(params)
if err != nil { if err != nil {
@ -231,45 +264,7 @@ func queryBorrowHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
return return
} }
route := fmt.Sprintf("custom/%s/%s", types.ModuleName, types.QueryGetBorrow) route := fmt.Sprintf("custom/%s/%s", types.ModuleName, types.QueryGetTotalBorrowed)
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 queryBorrowedHandlerFn(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 borrowDenom string
if x := r.URL.Query().Get(RestBorrowDenom); len(x) != 0 {
borrowDenom = strings.TrimSpace(x)
}
params := types.NewQueryBorrowedParams(borrowDenom)
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.QueryGetBorrowed)
res, height, err := cliCtx.QueryWithData(route, bz) res, height, err := cliCtx.QueryWithData(route, bz)
cliCtx = cliCtx.WithHeight(height) cliCtx = cliCtx.WithHeight(height)
if err != nil { if err != nil {

View File

@ -11,11 +11,10 @@ import (
// REST variable names // REST variable names
// nolint // nolint
const ( const (
RestOwner = "owner" RestOwner = "owner"
RestDenom = "deposit-denom" RestDenom = "denom"
RestType = "deposit-type" RestClaimType = "claim-type"
RestBorrowDenom = "borrow-denom" RestName = "name"
RestName = "name"
) )
// RegisterRoutes registers hard-related REST handlers to a router // RegisterRoutes registers hard-related REST handlers to a router

View File

@ -251,15 +251,20 @@ func (k Keeper) DecrementBorrowedCoins(ctx sdk.Context, coins sdk.Coins) error {
return nil return nil
} }
// GetBorrowBalance gets the user's total borrow balance (borrow balance + pending interest) // GetSyncedBorrow returns a borrow object containing current balances and indexes
func (k Keeper) GetBorrowBalance(ctx sdk.Context, borrower sdk.AccAddress) sdk.Coins { func (k Keeper) GetSyncedBorrow(ctx sdk.Context, borrower sdk.AccAddress) (types.Borrow, bool) {
borrowBalance := sdk.Coins{}
borrow, found := k.GetBorrow(ctx, borrower) borrow, found := k.GetBorrow(ctx, borrower)
if !found { if !found {
return borrowBalance return types.Borrow{}, false
} }
return k.loadSyncedBorrow(ctx, borrow), true
}
// loadSyncedBorrow calculates a user's synced borrow, but does not update state
func (k Keeper) loadSyncedBorrow(ctx sdk.Context, borrow types.Borrow) types.Borrow {
totalNewInterest := sdk.Coins{} totalNewInterest := sdk.Coins{}
newBorrowIndexes := types.BorrowInterestFactors{}
for _, coin := range borrow.Amount { for _, coin := range borrow.Amount {
interestFactorValue, foundInterestFactorValue := k.GetBorrowInterestFactor(ctx, coin.Denom) interestFactorValue, foundInterestFactorValue := k.GetBorrowInterestFactor(ctx, coin.Denom)
if foundInterestFactorValue { if foundInterestFactorValue {
@ -271,6 +276,7 @@ func (k Keeper) GetBorrowBalance(ctx sdk.Context, borrower sdk.AccAddress) sdk.C
break break
} }
} }
// Calculate interest owed by user for this asset // Calculate interest owed by user for this asset
if foundAtIndex != -1 { if foundAtIndex != -1 {
storedAmount := sdk.NewDecFromInt(borrow.Amount.AmountOf(coin.Denom)) storedAmount := sdk.NewDecFromInt(borrow.Amount.AmountOf(coin.Denom))
@ -279,7 +285,10 @@ func (k Keeper) GetBorrowBalance(ctx sdk.Context, borrower sdk.AccAddress) sdk.C
totalNewInterest = totalNewInterest.Add(sdk.NewCoin(coin.Denom, coinInterest.TruncateInt())) totalNewInterest = totalNewInterest.Add(sdk.NewCoin(coin.Denom, coinInterest.TruncateInt()))
} }
} }
borrowIndex := types.NewBorrowInterestFactor(coin.Denom, interestFactorValue)
newBorrowIndexes = append(newBorrowIndexes, borrowIndex)
} }
return borrow.Amount.Add(totalNewInterest...) return types.NewBorrow(borrow.Borrower, borrow.Amount.Add(totalNewInterest...), newBorrowIndexes)
} }

View File

@ -167,15 +167,20 @@ func (k Keeper) DecrementSuppliedCoins(ctx sdk.Context, coins sdk.Coins) error {
return nil return nil
} }
// GetSupplyBalance gets the user's total supply balance (supply balance + pending interest) // GetSyncedDeposit returns a deposit object containing current balances and indexes
func (k Keeper) GetSupplyBalance(ctx sdk.Context, depositor sdk.AccAddress) sdk.Coins { func (k Keeper) GetSyncedDeposit(ctx sdk.Context, depositor sdk.AccAddress) (types.Deposit, bool) {
supplyBalance := sdk.Coins{}
deposit, found := k.GetDeposit(ctx, depositor) deposit, found := k.GetDeposit(ctx, depositor)
if !found { if !found {
return supplyBalance return types.Deposit{}, false
} }
return k.loadSyncedDeposit(ctx, deposit), true
}
// loadSyncedDeposit calculates a user's synced deposit, but does not update state
func (k Keeper) loadSyncedDeposit(ctx sdk.Context, deposit types.Deposit) types.Deposit {
totalNewInterest := sdk.Coins{} totalNewInterest := sdk.Coins{}
newSupplyIndexes := types.SupplyInterestFactors{}
for _, coin := range deposit.Amount { for _, coin := range deposit.Amount {
interestFactorValue, foundInterestFactorValue := k.GetSupplyInterestFactor(ctx, coin.Denom) interestFactorValue, foundInterestFactorValue := k.GetSupplyInterestFactor(ctx, coin.Denom)
if foundInterestFactorValue { if foundInterestFactorValue {
@ -187,7 +192,8 @@ func (k Keeper) GetSupplyBalance(ctx sdk.Context, depositor sdk.AccAddress) sdk.
break break
} }
} }
// Calculate interest owed by user for this asset
// Calculate interest that will be paid to user for this asset
if foundAtIndex != -1 { if foundAtIndex != -1 {
storedAmount := sdk.NewDecFromInt(deposit.Amount.AmountOf(coin.Denom)) storedAmount := sdk.NewDecFromInt(deposit.Amount.AmountOf(coin.Denom))
userLastInterestFactor := deposit.Index[foundAtIndex].Value userLastInterestFactor := deposit.Index[foundAtIndex].Value
@ -195,7 +201,10 @@ func (k Keeper) GetSupplyBalance(ctx sdk.Context, depositor sdk.AccAddress) sdk.
totalNewInterest = totalNewInterest.Add(sdk.NewCoin(coin.Denom, coinInterest.TruncateInt())) totalNewInterest = totalNewInterest.Add(sdk.NewCoin(coin.Denom, coinInterest.TruncateInt()))
} }
} }
supplyIndex := types.NewSupplyInterestFactor(coin.Denom, interestFactorValue)
newSupplyIndexes = append(newSupplyIndexes, supplyIndex)
} }
return deposit.Amount.Add(totalNewInterest...) return types.NewDeposit(deposit.Depositor, deposit.Amount.Add(totalNewInterest...), newSupplyIndexes)
} }

View File

@ -22,16 +22,14 @@ 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.QueryGetDeposit: case types.QueryGetTotalDeposited:
return queryGetDeposit(ctx, req, k) return queryGetTotalDeposited(ctx, req, k)
case types.QueryGetClaims: case types.QueryGetClaims:
return queryGetClaims(ctx, req, k) return queryGetClaims(ctx, req, k)
case types.QueryGetBorrows: case types.QueryGetBorrows:
return queryGetBorrows(ctx, req, k) return queryGetBorrows(ctx, req, k)
case types.QueryGetBorrow: case types.QueryGetTotalBorrowed:
return queryGetBorrow(ctx, req, k) return queryGetTotalBorrowed(ctx, req, k)
case types.QueryGetBorrowed:
return queryGetBorrowed(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)
} }
@ -86,33 +84,32 @@ func queryGetDeposits(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte,
if err != nil { if err != nil {
return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error()) return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error())
} }
depositDenom := len(params.DepositDenom) > 0 denom := len(params.Denom) > 0
owner := len(params.Owner) > 0 owner := len(params.Owner) > 0
var deposits []types.Deposit var deposits types.Deposits
switch { switch {
case depositDenom && owner: case owner && denom:
deposit, found := k.GetDeposit(ctx, params.Owner) deposit, found := k.GetSyncedDeposit(ctx, params.Owner)
if found { if found {
for _, depCoin := range deposit.Amount { for _, coin := range deposit.Amount {
if depCoin.Denom == params.DepositDenom { if coin.Denom == params.Denom {
deposits = append(deposits, deposit) deposits = append(deposits, deposit)
} }
} }
} }
case depositDenom: case owner:
deposit, found := k.GetSyncedDeposit(ctx, params.Owner)
if found {
deposits = append(deposits, deposit)
}
case denom:
k.IterateDeposits(ctx, func(deposit types.Deposit) (stop bool) { k.IterateDeposits(ctx, func(deposit types.Deposit) (stop bool) {
if deposit.Amount.AmountOf(params.DepositDenom).IsPositive() { if deposit.Amount.AmountOf(params.Denom).IsPositive() {
deposits = append(deposits, deposit) deposits = append(deposits, deposit)
} }
return false return false
}) })
case owner:
deposit, found := k.GetDeposit(ctx, params.Owner)
if found {
deposits = append(deposits, deposit)
}
default: default:
k.IterateDeposits(ctx, func(deposit types.Deposit) (stop bool) { k.IterateDeposits(ctx, func(deposit types.Deposit) (stop bool) {
deposits = append(deposits, deposit) deposits = append(deposits, deposit)
@ -120,18 +117,35 @@ func queryGetDeposits(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte,
}) })
} }
start, end := client.Paginate(len(deposits), params.Page, params.Limit, 100) var bz []byte
if start < 0 || end < 0 {
deposits = []types.Deposit{} // If owner param was specified then deposits array already contains the user's synced deposit
} else { if owner {
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
} }
bz, err := codec.MarshalJSONIndent(types.ModuleCdc, deposits) // Otherwise we need to simulate syncing of each deposit
var syncedDeposits types.Deposits
for _, deposit := range deposits {
syncedDeposit, _ := k.GetSyncedDeposit(ctx, deposit.Depositor)
syncedDeposits = append(syncedDeposits, syncedDeposit)
}
start, end := client.Paginate(len(syncedDeposits), params.Page, params.Limit, 100)
if start < 0 || end < 0 {
syncedDeposits = types.Deposits{}
} else {
syncedDeposits = syncedDeposits[start:end]
}
bz, err = codec.MarshalJSONIndent(types.ModuleCdc, syncedDeposits)
if err != nil { if err != nil {
return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error())
} }
return bz, nil return bz, nil
} }
@ -142,26 +156,26 @@ func queryGetClaims(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, e
if err != nil { if err != nil {
return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error()) return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error())
} }
depositDenom := len(params.DepositDenom) > 0 depositDenom := len(params.Denom) > 0
owner := len(params.Owner) > 0 owner := len(params.Owner) > 0
claimType := len(params.ClaimType) > 0 claimType := len(params.ClaimType) > 0
var claims []types.Claim var claims []types.Claim
switch { switch {
case depositDenom && owner && claimType: case depositDenom && owner && claimType:
claim, found := k.GetClaim(ctx, params.Owner, params.DepositDenom, params.ClaimType) claim, found := k.GetClaim(ctx, params.Owner, params.Denom, params.ClaimType)
if found { if found {
claims = append(claims, claim) claims = append(claims, claim)
} }
case depositDenom && owner: case depositDenom && owner:
for _, dt := range types.ClaimTypesClaimQuery { for _, dt := range types.ClaimTypesClaimQuery {
claim, found := k.GetClaim(ctx, params.Owner, params.DepositDenom, dt) claim, found := k.GetClaim(ctx, params.Owner, params.Denom, dt)
if found { if found {
claims = append(claims, claim) claims = append(claims, claim)
} }
} }
case depositDenom && claimType: case depositDenom && claimType:
k.IterateClaimsByTypeAndDenom(ctx, params.ClaimType, params.DepositDenom, func(claim types.Claim) (stop bool) { k.IterateClaimsByTypeAndDenom(ctx, params.ClaimType, params.Denom, func(claim types.Claim) (stop bool) {
claims = append(claims, claim) claims = append(claims, claim)
return false return false
}) })
@ -185,7 +199,7 @@ func queryGetClaims(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, e
} }
case depositDenom: case depositDenom:
for _, dt := range types.ClaimTypesClaimQuery { for _, dt := range types.ClaimTypesClaimQuery {
k.IterateClaimsByTypeAndDenom(ctx, dt, params.DepositDenom, func(claim types.Claim) (stop bool) { k.IterateClaimsByTypeAndDenom(ctx, dt, params.Denom, func(claim types.Claim) (stop bool) {
claims = append(claims, claim) claims = append(claims, claim)
return false return false
}) })
@ -241,39 +255,79 @@ func queryGetClaims(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, e
} }
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
err := types.ModuleCdc.UnmarshalJSON(req.Data, &params) err := types.ModuleCdc.UnmarshalJSON(req.Data, &params)
if err != nil { if err != nil {
return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error()) return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error())
} }
denom := len(params.Denom) > 0
owner := len(params.Owner) > 0
// TODO: filter query results var borrows types.Borrows
// depositDenom := len(params.BorrowDenom) > 0 switch {
// owner := len(params.Owner) > 0 case owner && denom:
borrow, found := k.GetSyncedBorrow(ctx, params.Owner)
var borrows []types.Borrow if found {
k.IterateBorrows(ctx, func(borrow types.Borrow) (stop bool) { for _, coin := range borrow.Amount {
borrows = append(borrows, borrow) if coin.Denom == params.Denom {
return false borrows = append(borrows, borrow)
}) }
}
start, end := client.Paginate(len(borrows), params.Page, params.Limit, 100) }
if start < 0 || end < 0 { case owner:
borrows = []types.Borrow{} borrow, found := k.GetSyncedBorrow(ctx, params.Owner)
} else { if found {
borrows = borrows[start:end] 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
})
} }
bz, err := codec.MarshalJSONIndent(types.ModuleCdc, borrows) var bz []byte
// If owner param was specified then borrows array already contains the user's synced borrow
if owner {
bz, err = codec.MarshalJSONIndent(types.ModuleCdc, borrows)
if err != nil {
return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error())
}
return bz, nil
}
// Otherwise we need to simulate syncing of each borrow
var syncedBorrows types.Borrows
for _, borrow := range borrows {
syncedBorrow, _ := k.GetSyncedBorrow(ctx, borrow.Borrower)
syncedBorrows = append(syncedBorrows, syncedBorrow)
}
start, end := client.Paginate(len(syncedBorrows), params.Page, params.Limit, 100)
if start < 0 || end < 0 {
syncedBorrows = types.Borrows{}
} else {
syncedBorrows = syncedBorrows[start:end]
}
bz, err = codec.MarshalJSONIndent(types.ModuleCdc, syncedBorrows)
if err != nil { if err != nil {
return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error())
} }
return bz, nil return bz, nil
} }
func queryGetBorrowed(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.QueryBorrowedParams var params types.QueryTotalBorrowedParams
err := types.ModuleCdc.UnmarshalJSON(req.Data, &params) err := types.ModuleCdc.UnmarshalJSON(req.Data, &params)
if err != nil { if err != nil {
return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error()) return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error())
@ -297,39 +351,24 @@ func queryGetBorrowed(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte,
return bz, nil return bz, nil
} }
func queryGetBorrow(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) { func queryGetTotalDeposited(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) {
var params types.QueryBorrowsParams var params types.QueryTotalDepositedParams
err := types.ModuleCdc.UnmarshalJSON(req.Data, &params) err := types.ModuleCdc.UnmarshalJSON(req.Data, &params)
if err != nil { if err != nil {
return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error()) return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error())
} }
var borrowBalance sdk.Coins suppliedCoins, found := k.GetSuppliedCoins(ctx)
if len(params.Owner) > 0 { if !found {
borrowBalance = k.GetBorrowBalance(ctx, params.Owner) return nil, types.ErrSuppliedCoinsNotFound
} }
bz, err := codec.MarshalJSONIndent(types.ModuleCdc, borrowBalance) // If user specified a denom only return coins of that denom type
if err != nil { if len(params.Denom) > 0 {
return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) suppliedCoins = sdk.NewCoins(sdk.NewCoin(params.Denom, suppliedCoins.AmountOf(params.Denom)))
} }
return bz, nil bz, err := codec.MarshalJSONIndent(types.ModuleCdc, suppliedCoins)
}
func queryGetDeposit(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) {
var params types.QueryDepositParams
err := types.ModuleCdc.UnmarshalJSON(req.Data, &params)
if err != nil {
return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error())
}
var supplyBalance sdk.Coins
if len(params.Owner) > 0 {
supplyBalance = k.GetSupplyBalance(ctx, params.Owner)
}
bz, err := codec.MarshalJSONIndent(types.ModuleCdc, supplyBalance)
if err != nil { if err != nil {
return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error())
} }

View File

@ -20,6 +20,9 @@ func NewBorrow(borrower sdk.AccAddress, amount sdk.Coins, index BorrowInterestFa
} }
} }
// Borrows is a slice of Borrow
type Borrows []Borrow
// BorrowInterestFactor defines an individual borrow interest factor // BorrowInterestFactor defines an individual borrow interest factor
type BorrowInterestFactor struct { type BorrowInterestFactor struct {
Denom string `json:"denom" yaml:"denom"` Denom string `json:"denom" yaml:"denom"`

View File

@ -20,6 +20,9 @@ func NewDeposit(depositor sdk.AccAddress, amount sdk.Coins, indexes SupplyIntere
} }
} }
// Deposits is a slice of Deposit
type Deposits []Deposit
// SupplyInterestFactor defines an individual borrow interest factor // SupplyInterestFactor defines an individual borrow interest factor
type SupplyInterestFactor struct { type SupplyInterestFactor struct {
Denom string `json:"denom" yaml:"denom"` Denom string `json:"denom" yaml:"denom"`

View File

@ -9,60 +9,47 @@ const (
QueryGetParams = "params" QueryGetParams = "params"
QueryGetModuleAccounts = "accounts" QueryGetModuleAccounts = "accounts"
QueryGetDeposits = "deposits" QueryGetDeposits = "deposits"
QueryGetDeposit = "deposit" QueryGetTotalDeposited = "total-deposited"
QueryGetClaims = "claims" QueryGetClaims = "claims"
QueryGetBorrows = "borrows" QueryGetBorrows = "borrows"
QueryGetBorrowed = "borrowed" QueryGetTotalBorrowed = "total-borrowed"
QueryGetBorrow = "borrow"
) )
// QueryDepositParams is the params for a filtered deposit query
type QueryDepositParams struct {
Owner sdk.AccAddress `json:"owner" yaml:"owner"`
}
// NewQueryDepositParams creates a new QueryDepositParams
func NewQueryDepositParams(owner sdk.AccAddress) QueryDepositParams {
return QueryDepositParams{
Owner: owner,
}
}
// QueryDepositsParams is the params for a filtered deposit query // QueryDepositsParams is the params for a filtered deposit query
type QueryDepositsParams struct { type QueryDepositsParams struct {
Page int `json:"page" yaml:"page"` Page int `json:"page" yaml:"page"`
Limit int `json:"limit" yaml:"limit"` Limit int `json:"limit" yaml:"limit"`
DepositDenom string `json:"deposit_denom" yaml:"deposit_denom"` Denom string `json:"denom" yaml:"denom"`
Owner sdk.AccAddress `json:"owner" yaml:"owner"` Owner sdk.AccAddress `json:"owner" yaml:"owner"`
} }
// NewQueryDepositsParams creates a new QueryDepositsParams // NewQueryDepositsParams creates a new QueryDepositsParams
func NewQueryDepositsParams(page, limit int, depositDenom string, owner sdk.AccAddress) QueryDepositsParams { func NewQueryDepositsParams(page, limit int, denom string, owner sdk.AccAddress) QueryDepositsParams {
return QueryDepositsParams{ return QueryDepositsParams{
Page: page, Page: page,
Limit: limit, Limit: limit,
DepositDenom: depositDenom, Denom: denom,
Owner: owner, Owner: owner,
} }
} }
// QueryClaimParams is the params for a filtered claim query // QueryClaimParams is the params for a filtered claim query
type QueryClaimParams struct { type QueryClaimParams struct {
Page int `json:"page" yaml:"page"` Page int `json:"page" yaml:"page"`
Limit int `json:"limit" yaml:"limit"` Limit int `json:"limit" yaml:"limit"`
DepositDenom string `json:"deposit_denom" yaml:"deposit_denom"` Denom string `json:"denom" yaml:"denom"`
Owner sdk.AccAddress `json:"owner" yaml:"owner"` Owner sdk.AccAddress `json:"owner" yaml:"owner"`
ClaimType ClaimType `json:"claim_type" yaml:"claim_type"` ClaimType ClaimType `json:"claim_type" yaml:"claim_type"`
} }
// NewQueryClaimParams creates a new QueryClaimParams // NewQueryClaimParams creates a new QueryClaimParams
func NewQueryClaimParams(page, limit int, depositDenom string, owner sdk.AccAddress, claimType ClaimType) QueryClaimParams { func NewQueryClaimParams(page, limit int, denom string, owner sdk.AccAddress, claimType ClaimType) QueryClaimParams {
return QueryClaimParams{ return QueryClaimParams{
Page: page, Page: page,
Limit: limit, Limit: limit,
DepositDenom: depositDenom, Denom: denom,
Owner: owner, Owner: owner,
ClaimType: claimType, ClaimType: claimType,
} }
} }
@ -84,42 +71,42 @@ func NewQueryAccountParams(page, limit int, name string) QueryAccountParams {
// QueryBorrowsParams is the params for a filtered borrows query // QueryBorrowsParams is the params for a filtered borrows query
type QueryBorrowsParams struct { type QueryBorrowsParams struct {
Page int `json:"page" yaml:"page"` Page int `json:"page" yaml:"page"`
Limit int `json:"limit" yaml:"limit"` Limit int `json:"limit" yaml:"limit"`
Owner sdk.AccAddress `json:"owner" yaml:"owner"` Owner sdk.AccAddress `json:"owner" yaml:"owner"`
BorrowDenom string `json:"borrow_denom" yaml:"borrow_denom"` Denom string `json:"denom" yaml:"denom"`
} }
// NewQueryBorrowsParams creates a new QueryBorrowsParams // NewQueryBorrowsParams creates a new QueryBorrowsParams
func NewQueryBorrowsParams(page, limit int, owner sdk.AccAddress, borrowDenom string) QueryBorrowsParams { func NewQueryBorrowsParams(page, limit int, owner sdk.AccAddress, denom string) QueryBorrowsParams {
return QueryBorrowsParams{ return QueryBorrowsParams{
Page: page, Page: page,
Limit: limit, Limit: limit,
Owner: owner, Owner: owner,
BorrowDenom: borrowDenom,
}
}
// QueryBorrowedParams is the params for a filtered borrowed coins query
type QueryBorrowedParams struct {
Denom string `json:"denom" yaml:"denom"`
}
// NewQueryBorrowedParams creates a new QueryBorrowedParams
func NewQueryBorrowedParams(denom string) QueryBorrowedParams {
return QueryBorrowedParams{
Denom: denom, Denom: denom,
} }
} }
// QueryBorrowParams is the params for a current borrow balance query // QueryTotalBorrowedParams is the params for a filtered total borrowed coins query
type QueryBorrowParams struct { type QueryTotalBorrowedParams struct {
Owner sdk.AccAddress `json:"owner" yaml:"owner"` Denom string `json:"denom" yaml:"denom"`
} }
// NewQueryBorrowParams creates a new QueryBorrowParams // NewQueryTotalBorrowedParams creates a new QueryTotalBorrowedParams
func NewQueryBorrowParams(owner sdk.AccAddress) QueryBorrowParams { func NewQueryTotalBorrowedParams(denom string) QueryTotalBorrowedParams {
return QueryBorrowParams{ return QueryTotalBorrowedParams{
Owner: owner, Denom: denom,
}
}
// QueryTotalDepositedParams is the params for a filtered total deposited coins query
type QueryTotalDepositedParams struct {
Denom string `json:"denom" yaml:"denom"`
}
// NewQueryTotalDepositedParams creates a new QueryTotalDepositedParams
func NewQueryTotalDepositedParams(denom string) QueryTotalDepositedParams {
return QueryTotalDepositedParams{
Denom: denom,
} }
} }