2019-02-04 16:45:18 -08:00
|
|
|
package rest
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"net/http"
|
|
|
|
|
2019-02-14 08:53:36 -08:00
|
|
|
"github.com/gorilla/mux"
|
|
|
|
|
2019-02-04 16:45:18 -08:00
|
|
|
"github.com/cosmos/cosmos-sdk/x/distribution/client/common"
|
|
|
|
"github.com/cosmos/cosmos-sdk/x/distribution/types"
|
|
|
|
|
2020-06-01 05:46:03 -07:00
|
|
|
"github.com/cosmos/cosmos-sdk/client"
|
2019-02-04 16:45:18 -08:00
|
|
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
2019-02-14 08:53:36 -08:00
|
|
|
"github.com/cosmos/cosmos-sdk/types/rest"
|
2019-02-04 16:45:18 -08:00
|
|
|
)
|
|
|
|
|
2020-06-01 05:46:03 -07:00
|
|
|
func registerQueryRoutes(clientCtx client.Context, r *mux.Router) {
|
2019-02-04 16:45:18 -08:00
|
|
|
// Get the total rewards balance from all delegations
|
|
|
|
r.HandleFunc(
|
|
|
|
"/distribution/delegators/{delegatorAddr}/rewards",
|
2020-06-01 05:46:03 -07:00
|
|
|
delegatorRewardsHandlerFn(clientCtx),
|
2019-02-04 16:45:18 -08:00
|
|
|
).Methods("GET")
|
|
|
|
|
|
|
|
// Query a delegation reward
|
|
|
|
r.HandleFunc(
|
|
|
|
"/distribution/delegators/{delegatorAddr}/rewards/{validatorAddr}",
|
2020-06-01 05:46:03 -07:00
|
|
|
delegationRewardsHandlerFn(clientCtx),
|
2019-02-04 16:45:18 -08:00
|
|
|
).Methods("GET")
|
|
|
|
|
|
|
|
// Get the rewards withdrawal address
|
|
|
|
r.HandleFunc(
|
|
|
|
"/distribution/delegators/{delegatorAddr}/withdraw_address",
|
2020-06-01 05:46:03 -07:00
|
|
|
delegatorWithdrawalAddrHandlerFn(clientCtx),
|
2019-02-04 16:45:18 -08:00
|
|
|
).Methods("GET")
|
|
|
|
|
|
|
|
// Validator distribution information
|
|
|
|
r.HandleFunc(
|
|
|
|
"/distribution/validators/{validatorAddr}",
|
2020-06-01 05:46:03 -07:00
|
|
|
validatorInfoHandlerFn(clientCtx),
|
2019-02-04 16:45:18 -08:00
|
|
|
).Methods("GET")
|
|
|
|
|
|
|
|
// Commission and self-delegation rewards of a single a validator
|
|
|
|
r.HandleFunc(
|
|
|
|
"/distribution/validators/{validatorAddr}/rewards",
|
2020-06-01 05:46:03 -07:00
|
|
|
validatorRewardsHandlerFn(clientCtx),
|
2019-02-04 16:45:18 -08:00
|
|
|
).Methods("GET")
|
|
|
|
|
2019-03-06 10:54:12 -08:00
|
|
|
// Outstanding rewards of a single validator
|
|
|
|
r.HandleFunc(
|
|
|
|
"/distribution/validators/{validatorAddr}/outstanding_rewards",
|
2020-06-01 05:46:03 -07:00
|
|
|
outstandingRewardsHandlerFn(clientCtx),
|
2019-03-06 10:54:12 -08:00
|
|
|
).Methods("GET")
|
|
|
|
|
2019-02-04 16:45:18 -08:00
|
|
|
// Get the current distribution parameter values
|
|
|
|
r.HandleFunc(
|
|
|
|
"/distribution/parameters",
|
2020-06-01 05:46:03 -07:00
|
|
|
paramsHandlerFn(clientCtx),
|
2019-02-04 16:45:18 -08:00
|
|
|
).Methods("GET")
|
|
|
|
|
2019-03-27 18:05:36 -07:00
|
|
|
// Get the amount held in the community pool
|
|
|
|
r.HandleFunc(
|
|
|
|
"/distribution/community_pool",
|
2020-06-01 05:46:03 -07:00
|
|
|
communityPoolHandler(clientCtx),
|
2019-03-27 18:05:36 -07:00
|
|
|
).Methods("GET")
|
|
|
|
|
2019-02-04 16:45:18 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
// HTTP request handler to query the total rewards balance from all delegations
|
2020-06-01 05:46:03 -07:00
|
|
|
func delegatorRewardsHandlerFn(clientCtx client.Context) http.HandlerFunc {
|
2019-02-04 16:45:18 -08:00
|
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
2020-06-01 05:46:03 -07:00
|
|
|
clientCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, clientCtx, r)
|
2019-06-07 06:02:07 -07:00
|
|
|
if !ok {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2020-01-10 13:10:37 -08:00
|
|
|
delegatorAddr, ok := checkDelegatorAddressVar(w, r)
|
2019-02-04 16:45:18 -08:00
|
|
|
if !ok {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2020-01-10 13:10:37 -08:00
|
|
|
params := types.NewQueryDelegatorParams(delegatorAddr)
|
2020-06-15 17:20:50 -07:00
|
|
|
bz, err := clientCtx.JSONMarshaler.MarshalJSON(params)
|
2020-01-10 13:10:37 -08:00
|
|
|
if err != nil {
|
|
|
|
rest.WriteErrorResponse(w, http.StatusBadRequest, fmt.Sprintf("failed to marshal params: %s", err))
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2020-04-08 08:05:14 -07:00
|
|
|
route := fmt.Sprintf("custom/%s/%s", types.QuerierRoute, types.QueryDelegatorTotalRewards)
|
2020-06-01 05:46:03 -07:00
|
|
|
res, height, err := clientCtx.QueryWithData(route, bz)
|
2020-04-01 00:50:22 -07:00
|
|
|
if rest.CheckInternalServerError(w, err) {
|
2020-01-10 13:10:37 -08:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2020-06-01 05:46:03 -07:00
|
|
|
clientCtx = clientCtx.WithHeight(height)
|
|
|
|
rest.PostProcessResponse(w, clientCtx, res)
|
2019-02-04 16:45:18 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// HTTP request handler to query a delegation rewards
|
2020-06-01 05:46:03 -07:00
|
|
|
func delegationRewardsHandlerFn(clientCtx client.Context) http.HandlerFunc {
|
2019-02-04 16:45:18 -08:00
|
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
2020-06-01 05:46:03 -07:00
|
|
|
clientCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, clientCtx, r)
|
2019-06-07 06:02:07 -07:00
|
|
|
if !ok {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2020-01-10 13:10:37 -08:00
|
|
|
delAddr := mux.Vars(r)["delegatorAddr"]
|
|
|
|
valAddr := mux.Vars(r)["validatorAddr"]
|
|
|
|
|
2019-02-04 16:45:18 -08:00
|
|
|
// query for rewards from a particular delegation
|
2020-06-01 05:46:03 -07:00
|
|
|
res, height, ok := checkResponseQueryDelegationRewards(w, clientCtx, types.QuerierRoute, delAddr, valAddr)
|
2019-02-04 16:45:18 -08:00
|
|
|
if !ok {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2020-06-01 05:46:03 -07:00
|
|
|
clientCtx = clientCtx.WithHeight(height)
|
|
|
|
rest.PostProcessResponse(w, clientCtx, res)
|
2019-02-04 16:45:18 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// HTTP request handler to query a delegation rewards
|
2020-06-01 05:46:03 -07:00
|
|
|
func delegatorWithdrawalAddrHandlerFn(clientCtx client.Context) http.HandlerFunc {
|
2019-02-04 16:45:18 -08:00
|
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
|
|
|
delegatorAddr, ok := checkDelegatorAddressVar(w, r)
|
|
|
|
if !ok {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2020-06-01 05:46:03 -07:00
|
|
|
clientCtx, ok = rest.ParseQueryHeightOrReturnBadRequest(w, clientCtx, r)
|
2019-06-07 06:02:07 -07:00
|
|
|
if !ok {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2020-06-15 17:20:50 -07:00
|
|
|
bz := clientCtx.JSONMarshaler.MustMarshalJSON(types.NewQueryDelegatorWithdrawAddrParams(delegatorAddr))
|
2020-06-01 05:46:03 -07:00
|
|
|
res, height, err := clientCtx.QueryWithData(fmt.Sprintf("custom/%s/withdraw_addr", types.QuerierRoute), bz)
|
2020-04-01 00:50:22 -07:00
|
|
|
if rest.CheckInternalServerError(w, err) {
|
2019-02-04 16:45:18 -08:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2020-06-01 05:46:03 -07:00
|
|
|
clientCtx = clientCtx.WithHeight(height)
|
|
|
|
rest.PostProcessResponse(w, clientCtx, res)
|
2019-02-04 16:45:18 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// ValidatorDistInfo defines the properties of
|
|
|
|
// validator distribution information response.
|
|
|
|
type ValidatorDistInfo struct {
|
2019-07-05 16:25:56 -07:00
|
|
|
OperatorAddress sdk.AccAddress `json:"operator_address" yaml:"operator_address"`
|
|
|
|
SelfBondRewards sdk.DecCoins `json:"self_bond_rewards" yaml:"self_bond_rewards"`
|
|
|
|
ValidatorCommission types.ValidatorAccumulatedCommission `json:"val_commission" yaml:"val_commission"`
|
2019-02-04 16:45:18 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
// NewValidatorDistInfo creates a new instance of ValidatorDistInfo.
|
|
|
|
func NewValidatorDistInfo(operatorAddr sdk.AccAddress, rewards sdk.DecCoins,
|
|
|
|
commission types.ValidatorAccumulatedCommission) ValidatorDistInfo {
|
|
|
|
return ValidatorDistInfo{
|
|
|
|
OperatorAddress: operatorAddr,
|
|
|
|
SelfBondRewards: rewards,
|
|
|
|
ValidatorCommission: commission,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// HTTP request handler to query validator's distribution information
|
2020-06-01 05:46:03 -07:00
|
|
|
func validatorInfoHandlerFn(clientCtx client.Context) http.HandlerFunc {
|
2019-02-04 16:45:18 -08:00
|
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
2020-01-10 13:10:37 -08:00
|
|
|
valAddr, ok := checkValidatorAddressVar(w, r)
|
2019-02-04 16:45:18 -08:00
|
|
|
if !ok {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2020-06-01 05:46:03 -07:00
|
|
|
clientCtx, ok = rest.ParseQueryHeightOrReturnBadRequest(w, clientCtx, r)
|
2019-06-07 06:02:07 -07:00
|
|
|
if !ok {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2019-02-04 16:45:18 -08:00
|
|
|
// query commission
|
2020-06-01 05:46:03 -07:00
|
|
|
bz, err := common.QueryValidatorCommission(clientCtx, types.QuerierRoute, valAddr)
|
2020-04-01 00:50:22 -07:00
|
|
|
if rest.CheckInternalServerError(w, err) {
|
2019-02-04 16:45:18 -08:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2020-01-10 13:10:37 -08:00
|
|
|
var commission types.ValidatorAccumulatedCommission
|
2020-06-15 17:20:50 -07:00
|
|
|
if rest.CheckInternalServerError(w, clientCtx.JSONMarshaler.UnmarshalJSON(bz, &commission)) {
|
2020-01-10 13:10:37 -08:00
|
|
|
return
|
|
|
|
}
|
2019-02-04 16:45:18 -08:00
|
|
|
|
|
|
|
// self bond rewards
|
2020-01-10 13:10:37 -08:00
|
|
|
delAddr := sdk.AccAddress(valAddr)
|
2020-06-01 05:46:03 -07:00
|
|
|
bz, height, ok := checkResponseQueryDelegationRewards(w, clientCtx, types.QuerierRoute, delAddr.String(), valAddr.String())
|
2019-02-04 16:45:18 -08:00
|
|
|
if !ok {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
var rewards sdk.DecCoins
|
2020-06-15 17:20:50 -07:00
|
|
|
if rest.CheckInternalServerError(w, clientCtx.JSONMarshaler.UnmarshalJSON(bz, &rewards)) {
|
2020-01-10 13:10:37 -08:00
|
|
|
return
|
|
|
|
}
|
2019-02-04 16:45:18 -08:00
|
|
|
|
2020-06-15 17:20:50 -07:00
|
|
|
bz, err = clientCtx.JSONMarshaler.MarshalJSON(NewValidatorDistInfo(delAddr, rewards, commission))
|
2020-04-01 00:50:22 -07:00
|
|
|
if rest.CheckInternalServerError(w, err) {
|
2020-01-10 13:10:37 -08:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2020-06-01 05:46:03 -07:00
|
|
|
clientCtx = clientCtx.WithHeight(height)
|
|
|
|
rest.PostProcessResponse(w, clientCtx, bz)
|
2019-02-04 16:45:18 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// HTTP request handler to query validator's commission and self-delegation rewards
|
2020-06-01 05:46:03 -07:00
|
|
|
func validatorRewardsHandlerFn(clientCtx client.Context) http.HandlerFunc {
|
2019-02-04 16:45:18 -08:00
|
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
|
|
|
valAddr := mux.Vars(r)["validatorAddr"]
|
|
|
|
validatorAddr, ok := checkValidatorAddressVar(w, r)
|
|
|
|
if !ok {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2020-06-01 05:46:03 -07:00
|
|
|
clientCtx, ok = rest.ParseQueryHeightOrReturnBadRequest(w, clientCtx, r)
|
2019-06-07 06:02:07 -07:00
|
|
|
if !ok {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2019-02-04 16:45:18 -08:00
|
|
|
delAddr := sdk.AccAddress(validatorAddr).String()
|
2020-06-01 05:46:03 -07:00
|
|
|
bz, height, ok := checkResponseQueryDelegationRewards(w, clientCtx, types.QuerierRoute, delAddr, valAddr)
|
2019-02-04 16:45:18 -08:00
|
|
|
if !ok {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2020-06-01 05:46:03 -07:00
|
|
|
clientCtx = clientCtx.WithHeight(height)
|
|
|
|
rest.PostProcessResponse(w, clientCtx, bz)
|
2019-02-04 16:45:18 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// HTTP request handler to query the distribution params values
|
2020-06-01 05:46:03 -07:00
|
|
|
func paramsHandlerFn(clientCtx client.Context) http.HandlerFunc {
|
2019-02-04 16:45:18 -08:00
|
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
2020-06-01 05:46:03 -07:00
|
|
|
clientCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, clientCtx, r)
|
2019-06-07 06:02:07 -07:00
|
|
|
if !ok {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2020-01-10 12:08:14 -08:00
|
|
|
route := fmt.Sprintf("custom/%s/%s", types.QuerierRoute, types.QueryParams)
|
2020-06-01 05:46:03 -07:00
|
|
|
res, height, err := clientCtx.QueryWithData(route, nil)
|
2020-04-01 00:50:22 -07:00
|
|
|
if rest.CheckInternalServerError(w, err) {
|
2019-02-04 16:45:18 -08:00
|
|
|
return
|
|
|
|
}
|
2019-06-06 08:43:15 -07:00
|
|
|
|
2020-06-01 05:46:03 -07:00
|
|
|
clientCtx = clientCtx.WithHeight(height)
|
|
|
|
rest.PostProcessResponse(w, clientCtx, res)
|
2019-02-04 16:45:18 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-01 05:46:03 -07:00
|
|
|
func communityPoolHandler(clientCtx client.Context) http.HandlerFunc {
|
2019-03-27 18:05:36 -07:00
|
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
2020-06-01 05:46:03 -07:00
|
|
|
clientCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, clientCtx, r)
|
2019-06-07 06:02:07 -07:00
|
|
|
if !ok {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2020-06-01 05:46:03 -07:00
|
|
|
res, height, err := clientCtx.QueryWithData(fmt.Sprintf("custom/%s/community_pool", types.QuerierRoute), nil)
|
2020-04-01 00:50:22 -07:00
|
|
|
if rest.CheckInternalServerError(w, err) {
|
2019-03-27 18:05:36 -07:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
var result sdk.DecCoins
|
2020-06-15 17:20:50 -07:00
|
|
|
if rest.CheckInternalServerError(w, clientCtx.JSONMarshaler.UnmarshalJSON(res, &result)) {
|
2019-03-27 18:05:36 -07:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2020-06-01 05:46:03 -07:00
|
|
|
clientCtx = clientCtx.WithHeight(height)
|
|
|
|
rest.PostProcessResponse(w, clientCtx, result)
|
2019-03-27 18:05:36 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-02-04 16:45:18 -08:00
|
|
|
// HTTP request handler to query the outstanding rewards
|
2020-06-01 05:46:03 -07:00
|
|
|
func outstandingRewardsHandlerFn(clientCtx client.Context) http.HandlerFunc {
|
2019-02-04 16:45:18 -08:00
|
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
2019-03-06 10:54:12 -08:00
|
|
|
validatorAddr, ok := checkValidatorAddressVar(w, r)
|
|
|
|
if !ok {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2020-06-01 05:46:03 -07:00
|
|
|
clientCtx, ok = rest.ParseQueryHeightOrReturnBadRequest(w, clientCtx, r)
|
2019-06-07 06:02:07 -07:00
|
|
|
if !ok {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2020-06-15 17:20:50 -07:00
|
|
|
bin := clientCtx.JSONMarshaler.MustMarshalJSON(types.NewQueryValidatorOutstandingRewardsParams(validatorAddr))
|
2020-06-01 05:46:03 -07:00
|
|
|
res, height, err := clientCtx.QueryWithData(fmt.Sprintf("custom/%s/validator_outstanding_rewards", types.QuerierRoute), bin)
|
2020-04-01 00:50:22 -07:00
|
|
|
if rest.CheckInternalServerError(w, err) {
|
2019-02-04 16:45:18 -08:00
|
|
|
return
|
|
|
|
}
|
2019-06-06 08:43:15 -07:00
|
|
|
|
2020-06-01 05:46:03 -07:00
|
|
|
clientCtx = clientCtx.WithHeight(height)
|
|
|
|
rest.PostProcessResponse(w, clientCtx, res)
|
2019-02-04 16:45:18 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-06-06 08:43:15 -07:00
|
|
|
func checkResponseQueryDelegationRewards(
|
2020-06-01 05:46:03 -07:00
|
|
|
w http.ResponseWriter, clientCtx client.Context, queryRoute, delAddr, valAddr string,
|
2020-01-10 13:10:37 -08:00
|
|
|
) (res []byte, height int64, ok bool) {
|
2019-02-04 16:45:18 -08:00
|
|
|
|
2020-06-01 05:46:03 -07:00
|
|
|
res, height, err := common.QueryDelegationRewards(clientCtx, queryRoute, delAddr, valAddr)
|
2020-04-01 00:50:22 -07:00
|
|
|
if rest.CheckInternalServerError(w, err) {
|
2020-01-10 13:10:37 -08:00
|
|
|
return nil, 0, false
|
2019-02-04 16:45:18 -08:00
|
|
|
}
|
|
|
|
|
2020-01-10 13:10:37 -08:00
|
|
|
return res, height, true
|
2019-02-04 16:45:18 -08:00
|
|
|
}
|