Incentive queries: unsynced claims, global reward factors (#894)

* unsynced querier types

* unsynced querier keeper methods

* unsynced querier cli

* unsynced querrier rest

* reward factors querier types

* reward factors querier keeper methods

* reward factors querier cli

* reward factors querier rest

* move PostClaimReq from types to rest
This commit is contained in:
Denali Marsh 2021-04-02 23:34:42 +02:00 committed by GitHub
parent bd53bbe4b5
commit fa57876ad8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 627 additions and 50 deletions

View File

@ -140,7 +140,6 @@ type (
MultiplierName = types.MultiplierName MultiplierName = types.MultiplierName
Multipliers = types.Multipliers Multipliers = types.Multipliers
Params = types.Params Params = types.Params
PostClaimReq = types.PostClaimReq
QueryHardRewardsParams = types.QueryHardRewardsParams QueryHardRewardsParams = types.QueryHardRewardsParams
QueryRewardsParams = types.QueryRewardsParams QueryRewardsParams = types.QueryRewardsParams
QueryUSDXMintingRewardsParams = types.QueryUSDXMintingRewardsParams QueryUSDXMintingRewardsParams = types.QueryUSDXMintingRewardsParams

View File

@ -19,6 +19,8 @@ import (
const ( const (
flagOwner = "owner" flagOwner = "owner"
flagType = "type" flagType = "type"
flagUnsynced = "unsynced"
flagDenom = "denom"
) )
// GetQueryCmd returns the cli query commands for the incentive module // GetQueryCmd returns the cli query commands for the incentive module
@ -31,6 +33,7 @@ func GetQueryCmd(queryRoute string, cdc *codec.Codec) *cobra.Command {
incentiveQueryCmd.AddCommand(flags.GetCommands( incentiveQueryCmd.AddCommand(flags.GetCommands(
queryParamsCmd(queryRoute, cdc), queryParamsCmd(queryRoute, cdc),
queryRewardsCmd(queryRoute, cdc), queryRewardsCmd(queryRoute, cdc),
queryRewardFactorsCmd(queryRoute, cdc),
)...) )...)
return incentiveQueryCmd return incentiveQueryCmd
@ -49,10 +52,11 @@ func queryRewardsCmd(queryRoute string, cdc *codec.Codec) *cobra.Command {
$ %s query %s rewards --type hard $ %s query %s rewards --type hard
$ %s query %s rewards --type usdx-minting $ %s query %s rewards --type usdx-minting
$ %s query %s rewards --type hard --owner kava15qdefkmwswysgg4qxgqpqr35k3m49pkx2jdfnw $ %s query %s rewards --type hard --owner kava15qdefkmwswysgg4qxgqpqr35k3m49pkx2jdfnw
$ %s query %s rewards --type hard --unsynced true
`, `,
version.ClientName, types.ModuleName, version.ClientName, types.ModuleName, version.ClientName, types.ModuleName, version.ClientName, types.ModuleName,
version.ClientName, types.ModuleName, version.ClientName, types.ModuleName, version.ClientName, types.ModuleName, version.ClientName, types.ModuleName,
version.ClientName, types.ModuleName)), version.ClientName, types.ModuleName, version.ClientName, types.ModuleName)),
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)
@ -61,6 +65,7 @@ func queryRewardsCmd(queryRoute string, cdc *codec.Codec) *cobra.Command {
limit := viper.GetInt(flags.FlagLimit) limit := viper.GetInt(flags.FlagLimit)
strOwner := viper.GetString(flagOwner) strOwner := viper.GetString(flagOwner)
strType := viper.GetString(flagType) strType := viper.GetString(flagType)
boolUnsynced := viper.GetBool(flagUnsynced)
// Prepare params for querier // Prepare params for querier
owner, err := sdk.AccAddressFromBech32(strOwner) owner, err := sdk.AccAddressFromBech32(strOwner)
@ -70,34 +75,66 @@ func queryRewardsCmd(queryRoute string, cdc *codec.Codec) *cobra.Command {
switch strings.ToLower(strType) { switch strings.ToLower(strType) {
case "hard": case "hard":
params := types.NewQueryHardRewardsParams(page, limit, owner) var claims types.HardLiquidityProviderClaims
claims, err := executeHardRewardsQuery(queryRoute, cdc, cliCtx, params) if boolUnsynced {
params := types.NewQueryHardRewardsUnsyncedParams(page, limit, owner)
claims, err = executeHardRewardsUnsyncedQuery(queryRoute, cdc, cliCtx, params)
if err != nil { if err != nil {
return err return err
} }
} else {
params := types.NewQueryHardRewardsParams(page, limit, owner)
claims, err = executeHardRewardsQuery(queryRoute, cdc, cliCtx, params)
if err != nil {
return err
}
}
return cliCtx.PrintOutput(claims) return cliCtx.PrintOutput(claims)
case "usdx-minting": case "usdx-minting":
params := types.NewQueryUSDXMintingRewardsParams(page, limit, owner) var claims types.USDXMintingClaims
claims, err := executeUSDXMintingRewardsQuery(queryRoute, cdc, cliCtx, params) if boolUnsynced {
params := types.NewQueryUSDXMintingRewardsUnsyncedParams(page, limit, owner)
claims, err = executeUSDXMintingRewardsUnsyncedQuery(queryRoute, cdc, cliCtx, params)
if err != nil { if err != nil {
return err return err
} }
} else {
params := types.NewQueryUSDXMintingRewardsParams(page, limit, owner)
claims, err = executeUSDXMintingRewardsQuery(queryRoute, cdc, cliCtx, params)
if err != nil {
return err
}
}
return cliCtx.PrintOutput(claims) return cliCtx.PrintOutput(claims)
default: default:
paramsHard := types.NewQueryHardRewardsParams(page, limit, owner) var hardClaims types.HardLiquidityProviderClaims
hardClaims, err := executeHardRewardsQuery(queryRoute, cdc, cliCtx, paramsHard) var usdxMintingClaims types.USDXMintingClaims
if boolUnsynced {
paramsHard := types.NewQueryHardRewardsUnsyncedParams(page, limit, owner)
hardClaims, err = executeHardRewardsUnsyncedQuery(queryRoute, cdc, cliCtx, paramsHard)
if err != nil { if err != nil {
return err return err
} }
paramsUSDXMinting := types.NewQueryUSDXMintingRewardsUnsyncedParams(page, limit, owner)
usdxMintingClaims, err = executeUSDXMintingRewardsUnsyncedQuery(queryRoute, cdc, cliCtx, paramsUSDXMinting)
if err != nil {
return err
}
} else {
paramsHard := types.NewQueryHardRewardsParams(page, limit, owner)
hardClaims, err = executeHardRewardsQuery(queryRoute, cdc, cliCtx, paramsHard)
if err != nil {
return err
}
paramsUSDXMinting := types.NewQueryUSDXMintingRewardsParams(page, limit, owner)
usdxMintingClaims, err = executeUSDXMintingRewardsQuery(queryRoute, cdc, cliCtx, paramsUSDXMinting)
if err != nil {
return err
}
}
if len(hardClaims) > 0 { if len(hardClaims) > 0 {
cliCtx.PrintOutput(hardClaims) cliCtx.PrintOutput(hardClaims)
} }
paramsUSDXMinting := types.NewQueryUSDXMintingRewardsParams(page, limit, owner)
usdxMintingClaims, err := executeUSDXMintingRewardsQuery(queryRoute, cdc, cliCtx, paramsUSDXMinting)
if err != nil {
return err
}
if len(usdxMintingClaims) > 0 { if len(usdxMintingClaims) > 0 {
cliCtx.PrintOutput(usdxMintingClaims) cliCtx.PrintOutput(usdxMintingClaims)
} }
@ -107,6 +144,7 @@ func queryRewardsCmd(queryRoute string, cdc *codec.Codec) *cobra.Command {
} }
cmd.Flags().String(flagOwner, "", "(optional) filter by owner address") cmd.Flags().String(flagOwner, "", "(optional) filter by owner address")
cmd.Flags().String(flagType, "", "(optional) filter by reward type") cmd.Flags().String(flagType, "", "(optional) filter by reward type")
cmd.Flags().String(flagUnsynced, "", "(optional) get unsynced claims")
cmd.Flags().Int(flags.FlagPage, 1, "pagination page rewards of to to query for") cmd.Flags().Int(flags.FlagPage, 1, "pagination page rewards of to to query for")
cmd.Flags().Int(flags.FlagLimit, 100, "pagination limit of rewards to query for") cmd.Flags().Int(flags.FlagLimit, 100, "pagination limit of rewards to query for")
return cmd return cmd
@ -139,6 +177,49 @@ func queryParamsCmd(queryRoute string, cdc *codec.Codec) *cobra.Command {
} }
} }
func queryRewardFactorsCmd(queryRoute string, cdc *codec.Codec) *cobra.Command {
cmd := &cobra.Command{
Use: "reward-factors",
Short: "get current global reward factors",
Long: strings.TrimSpace(`get current global reward factors:
Example:
$ kvcli q hard reward-factors
$ kvcli q hard reward-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.NewQueryRewardFactorsParams(denom)
bz, err := cdc.MarshalJSON(params)
if err != nil {
return err
}
// Execute query
route := fmt.Sprintf("custom/%s/%s", queryRoute, types.QueryGetRewardFactors)
res, height, err := cliCtx.QueryWithData(route, bz)
if err != nil {
return err
}
cliCtx = cliCtx.WithHeight(height)
// Decode and print results
var rewardFactors types.RewardFactors
if err := cdc.UnmarshalJSON(res, &rewardFactors); err != nil {
return fmt.Errorf("failed to unmarshal reward factors: %w", err)
}
return cliCtx.PrintOutput(rewardFactors)
},
}
cmd.Flags().String(flagDenom, "", "(optional) filter reward factors by denom")
return cmd
}
func executeHardRewardsQuery(queryRoute string, cdc *codec.Codec, cliCtx context.CLIContext, func executeHardRewardsQuery(queryRoute string, cdc *codec.Codec, cliCtx context.CLIContext,
params types.QueryHardRewardsParams) (types.HardLiquidityProviderClaims, error) { params types.QueryHardRewardsParams) (types.HardLiquidityProviderClaims, error) {
bz, err := cdc.MarshalJSON(params) bz, err := cdc.MarshalJSON(params)
@ -162,6 +243,29 @@ func executeHardRewardsQuery(queryRoute string, cdc *codec.Codec, cliCtx context
return claims, nil return claims, nil
} }
func executeHardRewardsUnsyncedQuery(queryRoute string, cdc *codec.Codec, cliCtx context.CLIContext,
params types.QueryHardRewardsUnsyncedParams) (types.HardLiquidityProviderClaims, error) {
bz, err := cdc.MarshalJSON(params)
if err != nil {
return types.HardLiquidityProviderClaims{}, err
}
route := fmt.Sprintf("custom/%s/%s", queryRoute, types.QueryGetHardRewardsUnsynced)
res, height, err := cliCtx.QueryWithData(route, bz)
if err != nil {
return types.HardLiquidityProviderClaims{}, err
}
cliCtx = cliCtx.WithHeight(height)
var claims types.HardLiquidityProviderClaims
if err := cdc.UnmarshalJSON(res, &claims); err != nil {
return types.HardLiquidityProviderClaims{}, fmt.Errorf("failed to unmarshal claims: %w", err)
}
return claims, nil
}
func executeUSDXMintingRewardsQuery(queryRoute string, cdc *codec.Codec, cliCtx context.CLIContext, func executeUSDXMintingRewardsQuery(queryRoute string, cdc *codec.Codec, cliCtx context.CLIContext,
params types.QueryUSDXMintingRewardsParams) (types.USDXMintingClaims, error) { params types.QueryUSDXMintingRewardsParams) (types.USDXMintingClaims, error) {
bz, err := cdc.MarshalJSON(params) bz, err := cdc.MarshalJSON(params)
@ -184,3 +288,26 @@ func executeUSDXMintingRewardsQuery(queryRoute string, cdc *codec.Codec, cliCtx
return claims, nil return claims, nil
} }
func executeUSDXMintingRewardsUnsyncedQuery(queryRoute string, cdc *codec.Codec, cliCtx context.CLIContext,
params types.QueryUSDXMintingRewardsUnsyncedParams) (types.USDXMintingClaims, error) {
bz, err := cdc.MarshalJSON(params)
if err != nil {
return types.USDXMintingClaims{}, err
}
route := fmt.Sprintf("custom/%s/%s", queryRoute, types.QueryGetUSDXMintingRewardsUnsynced)
res, height, err := cliCtx.QueryWithData(route, bz)
if err != nil {
return types.USDXMintingClaims{}, err
}
cliCtx = cliCtx.WithHeight(height)
var claims types.USDXMintingClaims
if err := cdc.UnmarshalJSON(res, &claims); err != nil {
return types.USDXMintingClaims{}, fmt.Errorf("failed to unmarshal claims: %w", err)
}
return claims, nil
}

View File

@ -3,6 +3,7 @@ package rest
import ( import (
"fmt" "fmt"
"net/http" "net/http"
"strconv"
"strings" "strings"
"github.com/gorilla/mux" "github.com/gorilla/mux"
@ -17,6 +18,7 @@ import (
func registerQueryRoutes(cliCtx context.CLIContext, r *mux.Router) { func registerQueryRoutes(cliCtx context.CLIContext, r *mux.Router) {
r.HandleFunc(fmt.Sprintf("/%s/rewards", types.ModuleName), queryRewardsHandlerFn(cliCtx)).Methods("GET") r.HandleFunc(fmt.Sprintf("/%s/rewards", types.ModuleName), queryRewardsHandlerFn(cliCtx)).Methods("GET")
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/reward-factors", types.ModuleName), queryRewardFactorsHandlerFn(cliCtx)).Methods("GET")
} }
func queryRewardsHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { func queryRewardsHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
@ -46,6 +48,30 @@ func queryRewardsHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
rewardType = strings.ToLower(strings.TrimSpace(x)) rewardType = strings.ToLower(strings.TrimSpace(x))
} }
var unsynced bool
if x := r.URL.Query().Get(types.RestUnsynced); len(x) != 0 {
unsyncedStr := strings.ToLower(strings.TrimSpace(x))
unsynced, err = strconv.ParseBool(unsyncedStr)
if err != nil {
rest.WriteErrorResponse(w, http.StatusBadRequest, fmt.Sprintf("cannot parse bool from unsynced flag %s", unsyncedStr))
return
}
}
if unsynced {
switch strings.ToLower(rewardType) {
case "hard":
params := types.NewQueryHardRewardsUnsyncedParams(page, limit, owner)
executeHardRewardsUnsyncedQuery(w, cliCtx, params)
case "usdx_minting":
params := types.NewQueryUSDXMintingRewardsUnsyncedParams(page, limit, owner)
executeUSDXMintingRewardsUnsyncedQuery(w, cliCtx, params)
default:
hardParams := types.NewQueryHardRewardsUnsyncedParams(page, limit, owner)
usdxMintingParams := types.NewQueryUSDXMintingRewardsUnsyncedParams(page, limit, owner)
executeBothUnsyncedRewardQueries(w, cliCtx, hardParams, usdxMintingParams)
}
} else {
switch strings.ToLower(rewardType) { switch strings.ToLower(rewardType) {
case "hard": case "hard":
params := types.NewQueryHardRewardsParams(page, limit, owner) params := types.NewQueryHardRewardsParams(page, limit, owner)
@ -60,6 +86,7 @@ func queryRewardsHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
} }
} }
} }
}
func queryParamsHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { func queryParamsHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) { return func(w http.ResponseWriter, r *http.Request) {
@ -81,6 +108,44 @@ func queryParamsHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
} }
} }
func queryRewardFactorsHandlerFn(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.NewQueryRewardFactorsParams(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.QueryGetRewardFactors)
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 executeHardRewardsQuery(w http.ResponseWriter, cliCtx context.CLIContext, params types.QueryHardRewardsParams) { func executeHardRewardsQuery(w http.ResponseWriter, cliCtx context.CLIContext, params types.QueryHardRewardsParams) {
bz, err := cliCtx.Codec.MarshalJSON(params) bz, err := cliCtx.Codec.MarshalJSON(params)
if err != nil { if err != nil {
@ -98,6 +163,23 @@ func executeHardRewardsQuery(w http.ResponseWriter, cliCtx context.CLIContext, p
rest.PostProcessResponse(w, cliCtx, res) rest.PostProcessResponse(w, cliCtx, res)
} }
func executeHardRewardsUnsyncedQuery(w http.ResponseWriter, cliCtx context.CLIContext, params types.QueryHardRewardsUnsyncedParams) {
bz, err := cliCtx.Codec.MarshalJSON(params)
if err != nil {
rest.WriteErrorResponse(w, http.StatusBadRequest, fmt.Sprintf("failed to marshal query params: %s", err))
return
}
res, height, err := cliCtx.QueryWithData(fmt.Sprintf("custom/incentive/%s", types.QueryGetHardRewardsUnsynced), bz)
if err != nil {
rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
return
}
cliCtx = cliCtx.WithHeight(height)
rest.PostProcessResponse(w, cliCtx, res)
}
func executeUSDXMintingRewardsQuery(w http.ResponseWriter, cliCtx context.CLIContext, params types.QueryUSDXMintingRewardsParams) { func executeUSDXMintingRewardsQuery(w http.ResponseWriter, cliCtx context.CLIContext, params types.QueryUSDXMintingRewardsParams) {
bz, err := cliCtx.Codec.MarshalJSON(params) bz, err := cliCtx.Codec.MarshalJSON(params)
if err != nil { if err != nil {
@ -115,6 +197,23 @@ func executeUSDXMintingRewardsQuery(w http.ResponseWriter, cliCtx context.CLICon
rest.PostProcessResponse(w, cliCtx, res) rest.PostProcessResponse(w, cliCtx, res)
} }
func executeUSDXMintingRewardsUnsyncedQuery(w http.ResponseWriter, cliCtx context.CLIContext, params types.QueryUSDXMintingRewardsUnsyncedParams) {
bz, err := cliCtx.Codec.MarshalJSON(params)
if err != nil {
rest.WriteErrorResponse(w, http.StatusBadRequest, fmt.Sprintf("failed to marshal query params: %s", err))
return
}
res, height, err := cliCtx.QueryWithData(fmt.Sprintf("custom/incentive/%s", types.QueryGetUSDXMintingRewardsUnsynced), bz)
if err != nil {
rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
return
}
cliCtx = cliCtx.WithHeight(height)
rest.PostProcessResponse(w, cliCtx, res)
}
func executeBothRewardQueries(w http.ResponseWriter, cliCtx context.CLIContext, func executeBothRewardQueries(w http.ResponseWriter, cliCtx context.CLIContext,
hardParams types.QueryHardRewardsParams, usdxMintingParams types.QueryUSDXMintingRewardsParams) { hardParams types.QueryHardRewardsParams, usdxMintingParams types.QueryUSDXMintingRewardsParams) {
hardBz, err := cliCtx.Codec.MarshalJSON(hardParams) hardBz, err := cliCtx.Codec.MarshalJSON(hardParams)
@ -165,3 +264,54 @@ func executeBothRewardQueries(w http.ResponseWriter, cliCtx context.CLIContext,
rest.PostProcessResponse(w, cliCtx, resBz) rest.PostProcessResponse(w, cliCtx, resBz)
} }
func executeBothUnsyncedRewardQueries(w http.ResponseWriter, cliCtx context.CLIContext,
hardParams types.QueryHardRewardsUnsyncedParams, usdxMintingParams types.QueryUSDXMintingRewardsUnsyncedParams) {
hardBz, err := cliCtx.Codec.MarshalJSON(hardParams)
if err != nil {
rest.WriteErrorResponse(w, http.StatusBadRequest, fmt.Sprintf("failed to marshal query params: %s", err))
return
}
hardRes, height, err := cliCtx.QueryWithData(fmt.Sprintf("custom/incentive/%s", types.QueryGetHardRewardsUnsynced), hardBz)
if err != nil {
rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
return
}
var hardClaims types.HardLiquidityProviderClaims
cliCtx.Codec.MustUnmarshalJSON(hardRes, &hardClaims)
usdxMintingBz, err := cliCtx.Codec.MarshalJSON(usdxMintingParams)
if err != nil {
rest.WriteErrorResponse(w, http.StatusBadRequest, fmt.Sprintf("failed to marshal query params: %s", err))
return
}
usdxMintingRes, height, err := cliCtx.QueryWithData(fmt.Sprintf("custom/incentive/%s", types.QueryGetUSDXMintingRewardsUnsynced), usdxMintingBz)
if err != nil {
rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
return
}
var usdxMintingClaims types.USDXMintingClaims
cliCtx.Codec.MustUnmarshalJSON(usdxMintingRes, &usdxMintingClaims)
cliCtx = cliCtx.WithHeight(height)
type rewardResult struct {
HardClaims types.HardLiquidityProviderClaims `json:"hard_claims" yaml:"hard_claims"`
UsdxMintingClaims types.USDXMintingClaims `json:"usdx_minting_claims" yaml:"usdx_minting_claims"`
}
res := rewardResult{
HardClaims: hardClaims,
UsdxMintingClaims: usdxMintingClaims,
}
resBz, err := cliCtx.Codec.MarshalJSON(res)
if err != nil {
rest.WriteErrorResponse(w, http.StatusBadRequest, fmt.Sprintf("failed to marshal result: %s", err))
return
}
rest.PostProcessResponse(w, cliCtx, resBz)
}

View File

@ -4,6 +4,14 @@ import (
"github.com/gorilla/mux" "github.com/gorilla/mux"
"github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/client/context"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/rest"
)
// REST variable names
// nolint
const (
RestDenom = "denom"
) )
// RegisterRoutes registers incentive-related REST handlers to a router // RegisterRoutes registers incentive-related REST handlers to a router
@ -11,3 +19,10 @@ func RegisterRoutes(cliCtx context.CLIContext, r *mux.Router) {
registerQueryRoutes(cliCtx, r) registerQueryRoutes(cliCtx, r)
registerTxRoutes(cliCtx, r) registerTxRoutes(cliCtx, r)
} }
// PostClaimReq defines the properties of claim transaction's request body.
type PostClaimReq struct {
BaseReq rest.BaseReq `json:"base_req" yaml:"base_req"`
Sender sdk.AccAddress `json:"sender" yaml:"sender"`
MultiplierName string `json:"multiplier_name" yaml:"multiplier_name"`
}

View File

@ -22,7 +22,7 @@ func registerTxRoutes(cliCtx context.CLIContext, r *mux.Router) {
func postClaimCdpHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { func postClaimCdpHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) { return func(w http.ResponseWriter, r *http.Request) {
var requestBody types.PostClaimReq var requestBody PostClaimReq
if !rest.ReadRESTReq(w, r, cliCtx.Codec, &requestBody) { if !rest.ReadRESTReq(w, r, cliCtx.Codec, &requestBody) {
return return
} }
@ -55,7 +55,7 @@ func postClaimCdpHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
func postClaimHardHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { func postClaimHardHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) { return func(w http.ResponseWriter, r *http.Request) {
var requestBody types.PostClaimReq var requestBody PostClaimReq
if !rest.ReadRESTReq(w, r, cliCtx.Codec, &requestBody) { if !rest.ReadRESTReq(w, r, cliCtx.Codec, &requestBody) {
return return
} }

View File

@ -141,6 +141,20 @@ func (k Keeper) SetUSDXMintingRewardFactor(ctx sdk.Context, ctype string, factor
store.Set([]byte(ctype), k.cdc.MustMarshalBinaryBare(factor)) store.Set([]byte(ctype), k.cdc.MustMarshalBinaryBare(factor))
} }
// IterateUSDXMintingRewardFactors iterates over all USDX Minting reward factor objects in the store and preforms a callback function
func (k Keeper) IterateUSDXMintingRewardFactors(ctx sdk.Context, cb func(denom string, factor sdk.Dec) (stop bool)) {
store := prefix.NewStore(ctx.KVStore(k.key), types.USDXMintingRewardFactorKeyPrefix)
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
}
}
}
// GetHardLiquidityProviderClaim returns the claim in the store corresponding the the input address collateral type and id and a boolean for if the claim was found // GetHardLiquidityProviderClaim returns the claim in the store corresponding the the input address collateral type and id and a boolean for if the claim was found
func (k Keeper) GetHardLiquidityProviderClaim(ctx sdk.Context, addr sdk.AccAddress) (types.HardLiquidityProviderClaim, bool) { func (k Keeper) GetHardLiquidityProviderClaim(ctx sdk.Context, addr sdk.AccAddress) (types.HardLiquidityProviderClaim, bool) {
store := prefix.NewStore(ctx.KVStore(k.key), types.HardLiquidityClaimKeyPrefix) store := prefix.NewStore(ctx.KVStore(k.key), types.HardLiquidityClaimKeyPrefix)
@ -209,6 +223,20 @@ func (k Keeper) GetHardSupplyRewardIndexes(ctx sdk.Context, denom string) (types
return rewardIndexes, true return rewardIndexes, true
} }
// IterateHardSupplyRewardIndexes iterates over all Hard supply reward index objects in the store and preforms a callback function
func (k Keeper) IterateHardSupplyRewardIndexes(ctx sdk.Context, cb func(denom string, indexes types.RewardIndexes) (stop bool)) {
store := prefix.NewStore(ctx.KVStore(k.key), types.HardSupplyRewardIndexesKeyPrefix)
iterator := sdk.KVStorePrefixIterator(store, []byte{})
defer iterator.Close()
for ; iterator.Valid(); iterator.Next() {
var indexes types.RewardIndexes
k.cdc.MustUnmarshalBinaryBare(iterator.Value(), &indexes)
if cb(string(iterator.Key()), indexes) {
break
}
}
}
// SetHardBorrowRewardIndexes sets the current reward indexes for an individual denom // SetHardBorrowRewardIndexes sets the current reward indexes for an individual denom
func (k Keeper) SetHardBorrowRewardIndexes(ctx sdk.Context, denom string, indexes types.RewardIndexes) { func (k Keeper) SetHardBorrowRewardIndexes(ctx sdk.Context, denom string, indexes types.RewardIndexes) {
store := prefix.NewStore(ctx.KVStore(k.key), types.HardBorrowRewardIndexesKeyPrefix) store := prefix.NewStore(ctx.KVStore(k.key), types.HardBorrowRewardIndexesKeyPrefix)
@ -228,6 +256,20 @@ func (k Keeper) GetHardBorrowRewardIndexes(ctx sdk.Context, denom string) (types
return rewardIndexes, true return rewardIndexes, true
} }
// IterateHardBorrowRewardIndexes iterates over all Hard borrow reward index objects in the store and preforms a callback function
func (k Keeper) IterateHardBorrowRewardIndexes(ctx sdk.Context, cb func(denom string, indexes types.RewardIndexes) (stop bool)) {
store := prefix.NewStore(ctx.KVStore(k.key), types.HardBorrowRewardIndexesKeyPrefix)
iterator := sdk.KVStorePrefixIterator(store, []byte{})
defer iterator.Close()
for ; iterator.Valid(); iterator.Next() {
var indexes types.RewardIndexes
k.cdc.MustUnmarshalBinaryBare(iterator.Value(), &indexes)
if cb(string(iterator.Key()), indexes) {
break
}
}
}
// GetHardDelegatorRewardFactor returns the current reward factor for an individual collateral type // GetHardDelegatorRewardFactor returns the current reward factor for an individual collateral type
func (k Keeper) GetHardDelegatorRewardFactor(ctx sdk.Context, ctype string) (factor sdk.Dec, found bool) { func (k Keeper) GetHardDelegatorRewardFactor(ctx sdk.Context, ctype string) (factor sdk.Dec, found bool) {
store := prefix.NewStore(ctx.KVStore(k.key), types.HardDelegatorRewardFactorKeyPrefix) store := prefix.NewStore(ctx.KVStore(k.key), types.HardDelegatorRewardFactorKeyPrefix)
@ -245,6 +287,20 @@ func (k Keeper) SetHardDelegatorRewardFactor(ctx sdk.Context, ctype string, fact
store.Set([]byte(ctype), k.cdc.MustMarshalBinaryBare(factor)) store.Set([]byte(ctype), k.cdc.MustMarshalBinaryBare(factor))
} }
// IterateHardDelegatorRewardFactors iterates over all Hard delegator reward factor objects in the store and preforms a callback function
func (k Keeper) IterateHardDelegatorRewardFactors(ctx sdk.Context, cb func(denom string, factor sdk.Dec) (stop bool)) {
store := prefix.NewStore(ctx.KVStore(k.key), types.HardDelegatorRewardFactorKeyPrefix)
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
}
}
}
// GetPreviousHardSupplyRewardAccrualTime returns the last time a denom accrued Hard protocol supply-side rewards // GetPreviousHardSupplyRewardAccrualTime returns the last time a denom accrued Hard protocol supply-side rewards
func (k Keeper) GetPreviousHardSupplyRewardAccrualTime(ctx sdk.Context, denom string) (blockTime time.Time, found bool) { func (k Keeper) GetPreviousHardSupplyRewardAccrualTime(ctx sdk.Context, denom string) (blockTime time.Time, found bool) {
store := prefix.NewStore(ctx.KVStore(k.key), types.PreviousHardSupplyRewardAccrualTimeKeyPrefix) store := prefix.NewStore(ctx.KVStore(k.key), types.PreviousHardSupplyRewardAccrualTimeKeyPrefix)

View File

@ -19,8 +19,14 @@ func NewQuerier(k Keeper) sdk.Querier {
return queryGetParams(ctx, req, k) return queryGetParams(ctx, req, k)
case types.QueryGetHardRewards: case types.QueryGetHardRewards:
return queryGetHardRewards(ctx, req, k) return queryGetHardRewards(ctx, req, k)
case types.QueryGetHardRewardsUnsynced:
return queryGetHardRewardsUnsynced(ctx, req, k)
case types.QueryGetUSDXMintingRewards: case types.QueryGetUSDXMintingRewards:
return queryGetUSDXMintingRewards(ctx, req, k) return queryGetUSDXMintingRewards(ctx, req, k)
case types.QueryGetUSDXMintingRewardsUnsynced:
return queryGetUSDXMintingRewardsUnsynced(ctx, req, k)
case types.QueryGetRewardFactors:
return queryGetRewardFactors(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)
} }
@ -81,6 +87,41 @@ func queryGetHardRewards(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]by
return bz, nil return bz, nil
} }
func queryGetHardRewardsUnsynced(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) {
var params types.QueryHardRewardsUnsyncedParams
err := types.ModuleCdc.UnmarshalJSON(req.Data, &params)
if err != nil {
return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error())
}
owner := len(params.Owner) > 0
var hardClaims types.HardLiquidityProviderClaims
switch {
case owner:
hardClaim, foundHardClaim := k.GetHardLiquidityProviderClaim(ctx, params.Owner)
if foundHardClaim {
hardClaims = append(hardClaims, hardClaim)
}
default:
hardClaims = k.GetAllHardLiquidityProviderClaims(ctx)
}
var paginatedHardClaims types.HardLiquidityProviderClaims
startH, endH := client.Paginate(len(hardClaims), params.Page, params.Limit, 100)
if startH < 0 || endH < 0 {
paginatedHardClaims = types.HardLiquidityProviderClaims{}
} else {
paginatedHardClaims = hardClaims[startH:endH]
}
// Marshal Hard claims
bz, err := codec.MarshalJSONIndent(k.cdc, paginatedHardClaims)
if err != nil {
return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error())
}
return bz, nil
}
func queryGetUSDXMintingRewards(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) { func queryGetUSDXMintingRewards(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) {
var params types.QueryUSDXMintingRewardsParams var params types.QueryUSDXMintingRewardsParams
err := types.ModuleCdc.UnmarshalJSON(req.Data, &params) err := types.ModuleCdc.UnmarshalJSON(req.Data, &params)
@ -121,3 +162,128 @@ func queryGetUSDXMintingRewards(ctx sdk.Context, req abci.RequestQuery, k Keeper
} }
return bz, nil return bz, nil
} }
func queryGetUSDXMintingRewardsUnsynced(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) {
var params types.QueryUSDXMintingRewardsUnsyncedParams
err := types.ModuleCdc.UnmarshalJSON(req.Data, &params)
if err != nil {
return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error())
}
owner := len(params.Owner) > 0
var usdxMintingClaims types.USDXMintingClaims
switch {
case owner:
usdxMintingClaim, foundUsdxMintingClaim := k.GetUSDXMintingClaim(ctx, params.Owner)
if foundUsdxMintingClaim {
usdxMintingClaims = append(usdxMintingClaims, usdxMintingClaim)
}
default:
usdxMintingClaims = k.GetAllUSDXMintingClaims(ctx)
}
var paginatedUsdxMintingClaims types.USDXMintingClaims
startU, endU := client.Paginate(len(usdxMintingClaims), params.Page, params.Limit, 100)
if startU < 0 || endU < 0 {
paginatedUsdxMintingClaims = types.USDXMintingClaims{}
} else {
paginatedUsdxMintingClaims = usdxMintingClaims[startU:endU]
}
// Marshal USDX minting claims
bz, err := codec.MarshalJSONIndent(k.cdc, paginatedUsdxMintingClaims)
if err != nil {
return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error())
}
return bz, nil
}
func queryGetRewardFactors(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) {
var params types.QueryRewardFactorsParams
err := types.ModuleCdc.UnmarshalJSON(req.Data, &params)
if err != nil {
return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error())
}
var rewardFactors types.RewardFactors
if len(params.Denom) > 0 {
// Fetch reward factors for a single denom
rewardFactor := types.RewardFactor{}
rewardFactor.Denom = params.Denom
usdxMintingRewardFactor, found := k.GetUSDXMintingRewardFactor(ctx, params.Denom)
if found {
rewardFactor.USDXMintingRewardFactor = usdxMintingRewardFactor
}
hardSupplyRewardIndexes, found := k.GetHardSupplyRewardIndexes(ctx, params.Denom)
if found {
rewardFactor.HardSupplyRewardFactors = hardSupplyRewardIndexes
}
hardBorrowRewardIndexes, found := k.GetHardBorrowRewardIndexes(ctx, params.Denom)
if found {
rewardFactor.HardBorrowRewardFactors = hardBorrowRewardIndexes
}
hardDelegatorRewardFactor, found := k.GetHardDelegatorRewardFactor(ctx, params.Denom)
if found {
rewardFactor.HardDelegatorRewardFactor = hardDelegatorRewardFactor
}
rewardFactors = append(rewardFactors, rewardFactor)
} else {
rewardFactorMap := make(map[string]types.RewardFactor)
// Populate mapping with usdx minting reward factors
k.IterateUSDXMintingRewardFactors(ctx, func(denom string, factor sdk.Dec) (stop bool) {
rewardFactor := types.RewardFactor{Denom: denom, USDXMintingRewardFactor: factor}
rewardFactorMap[denom] = rewardFactor
return false
})
// Populate mapping with Hard supply reward factors
k.IterateHardSupplyRewardIndexes(ctx, func(denom string, indexes types.RewardIndexes) (stop bool) {
rewardFactor, ok := rewardFactorMap[denom]
if !ok {
rewardFactor = types.RewardFactor{Denom: denom, HardSupplyRewardFactors: indexes}
} else {
rewardFactor.HardSupplyRewardFactors = indexes
}
rewardFactorMap[denom] = rewardFactor
return false
})
// Populate mapping with Hard borrow reward factors
k.IterateHardBorrowRewardIndexes(ctx, func(denom string, indexes types.RewardIndexes) (stop bool) {
rewardFactor, ok := rewardFactorMap[denom]
if !ok {
rewardFactor = types.RewardFactor{Denom: denom, HardBorrowRewardFactors: indexes}
} else {
rewardFactor.HardBorrowRewardFactors = indexes
}
rewardFactorMap[denom] = rewardFactor
return false
})
// Populate mapping with Hard delegator reward factors
k.IterateHardDelegatorRewardFactors(ctx, func(denom string, factor sdk.Dec) (stop bool) {
rewardFactor, ok := rewardFactorMap[denom]
if !ok {
rewardFactor = types.RewardFactor{Denom: denom, HardDelegatorRewardFactor: factor}
} else {
rewardFactor.HardDelegatorRewardFactor = factor
}
rewardFactorMap[denom] = rewardFactor
return false
})
// Translate mapping to slice
for _, val := range rewardFactorMap {
rewardFactors = append(rewardFactors, val)
}
}
bz, err := codec.MarshalJSONIndent(types.ModuleCdc, rewardFactors)
if err != nil {
return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error())
}
return bz, nil
}

View File

@ -2,20 +2,23 @@ package types
import ( import (
sdk "github.com/cosmos/cosmos-sdk/types" sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/rest"
) )
// Querier routes for the incentive module // Querier routes for the incentive module
const ( const (
QueryGetRewards = "rewards" QueryGetRewards = "rewards"
QueryGetHardRewards = "hard-rewards" QueryGetHardRewards = "hard-rewards"
QueryGetHardRewardsUnsynced = "hard-rewards-unsynced"
QueryGetUSDXMintingRewards = "usdx-minting-rewards" QueryGetUSDXMintingRewards = "usdx-minting-rewards"
QueryGetUSDXMintingRewardsUnsynced = "usdx-minting-rewards-unsynced"
QueryGetRewardFactors = "reward-factors"
QueryGetParams = "parameters" QueryGetParams = "parameters"
QueryGetRewardPeriods = "reward-periods" QueryGetRewardPeriods = "reward-periods"
QueryGetClaimPeriods = "claim-periods" QueryGetClaimPeriods = "claim-periods"
RestClaimCollateralType = "collateral_type" RestClaimCollateralType = "collateral_type"
RestClaimOwner = "owner" RestClaimOwner = "owner"
RestClaimType = "type" RestClaimType = "type"
RestUnsynced = "unsynced"
) )
// QueryRewardsParams params for query /incentive/rewards // QueryRewardsParams params for query /incentive/rewards
@ -52,6 +55,22 @@ func NewQueryUSDXMintingRewardsParams(page, limit int, owner sdk.AccAddress) Que
} }
} }
// QueryUSDXMintingRewardsUnsyncedParams params for query unsynced /incentive/rewards type usdx-minting
type QueryUSDXMintingRewardsUnsyncedParams struct {
Page int `json:"page" yaml:"page"`
Limit int `json:"limit" yaml:"limit"`
Owner sdk.AccAddress
}
// NewQueryUSDXMintingRewardsUnsyncedParams returns QueryUSDXMintingRewardsUnsyncedParams
func NewQueryUSDXMintingRewardsUnsyncedParams(page, limit int, owner sdk.AccAddress) QueryUSDXMintingRewardsUnsyncedParams {
return QueryUSDXMintingRewardsUnsyncedParams{
Page: page,
Limit: limit,
Owner: owner,
}
}
// QueryHardRewardsParams params for query /incentive/rewards type hard // QueryHardRewardsParams params for query /incentive/rewards type hard
type QueryHardRewardsParams struct { type QueryHardRewardsParams struct {
Page int `json:"page" yaml:"page"` Page int `json:"page" yaml:"page"`
@ -68,9 +87,54 @@ func NewQueryHardRewardsParams(page, limit int, owner sdk.AccAddress) QueryHardR
} }
} }
// PostClaimReq defines the properties of claim transaction's request body. // QueryHardRewardsUnsyncedParams params for query unsynced /incentive/rewards type hard
type PostClaimReq struct { type QueryHardRewardsUnsyncedParams struct {
BaseReq rest.BaseReq `json:"base_req" yaml:"base_req"` Page int `json:"page" yaml:"page"`
Sender sdk.AccAddress `json:"sender" yaml:"sender"` Limit int `json:"limit" yaml:"limit"`
MultiplierName string `json:"multiplier_name" yaml:"multiplier_name"` Owner sdk.AccAddress
} }
// NewQueryHardRewardsUnsyncedParams returns QueryHardRewardsUnsyncedParams
func NewQueryHardRewardsUnsyncedParams(page, limit int, owner sdk.AccAddress) QueryHardRewardsUnsyncedParams {
return QueryHardRewardsUnsyncedParams{
Page: page,
Limit: limit,
Owner: owner,
}
}
// QueryRewardFactorsParams is the params for a filtered reward factors query
type QueryRewardFactorsParams struct {
Denom string `json:"denom" yaml:"denom"`
}
// NewQueryRewardFactorsParams creates a new QueryRewardFactorsParams
func NewQueryRewardFactorsParams(denom string) QueryRewardFactorsParams {
return QueryRewardFactorsParams{
Denom: denom,
}
}
// RewardFactor is a unique type returned by reward factor queries
type RewardFactor struct {
Denom string `json:"denom" yaml:"denom"`
USDXMintingRewardFactor sdk.Dec `json:"usdx_minting_reward_factor" yaml:"usdx_minting_reward_factor"`
HardSupplyRewardFactors RewardIndexes `json:"hard_supply_reward_factors" yaml:"hard_supply_reward_factors"`
HardBorrowRewardFactors RewardIndexes `json:"hard_borrow_reward_factors" yaml:"hard_borrow_reward_factors"`
HardDelegatorRewardFactor sdk.Dec `json:"hard_delegator_reward_factor" yaml:"hard_delegator_reward_factor"`
}
// NewRewardFactor returns a new instance of RewardFactor
func NewRewardFactor(denom string, usdxMintingRewardFactor sdk.Dec, hardSupplyRewardFactors,
hardBorrowRewardFactors RewardIndexes, hardDelegatorRewardFactor sdk.Dec) RewardFactor {
return RewardFactor{
Denom: denom,
USDXMintingRewardFactor: usdxMintingRewardFactor,
HardSupplyRewardFactors: hardSupplyRewardFactors,
HardBorrowRewardFactors: hardBorrowRewardFactors,
HardDelegatorRewardFactor: hardDelegatorRewardFactor,
}
}
// RewardFactors is a slice of RewardFactor
type RewardFactors = []RewardFactor