diff --git a/x/stake/client/rest/query.go b/x/stake/client/rest/query.go index 0398119d82..fbe48d1681 100644 --- a/x/stake/client/rest/query.go +++ b/x/stake/client/rest/query.go @@ -9,7 +9,6 @@ import ( "github.com/cosmos/cosmos-sdk/client/utils" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/x/stake" "github.com/cosmos/cosmos-sdk/x/stake/tags" "github.com/gorilla/mux" @@ -67,6 +66,12 @@ func registerQueryRoutes(cliCtx context.CLIContext, r *mux.Router, cdc *codec.Co validatorHandlerFn(cliCtx, cdc), ).Methods("GET") + // Get all outgoing redelegations from a validator + r.HandleFunc( + "/stake/validators/{validatorAddr}/redelegations", + validatorRedelegationsHandlerFn(cliCtx, cdc), + ).Methods("GET") + // Get the current state of the staking pool r.HandleFunc( "/stake/pool", @@ -191,33 +196,12 @@ func validatorsHandlerFn(cliCtx context.CLIContext, cdc *codec.Codec) http.Handl // HTTP request handler to query the validator information from a given validator address func validatorHandlerFn(cliCtx context.CLIContext, cdc *codec.Codec) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - vars := mux.Vars(r) - bech32validatorAddr := vars["validatorAddr"] + return queryValidator(cliCtx, cdc, "custom/stake/validator") +} - validatorAddr, err := sdk.ValAddressFromBech32(bech32validatorAddr) - if err != nil { - utils.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) - return - } - - params := stake.QueryValidatorParams{ - ValidatorAddr: validatorAddr, - } - - bz, err := cdc.MarshalJSON(params) - if err != nil { - utils.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) - return - } - - res, err := cliCtx.QueryWithData("custom/stake/validator", bz) - if err != nil { - utils.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) - return - } - utils.PostProcessResponse(w, cdc, res, cliCtx.Indent) - } +// HTTP request handler to query all redelegations from a source validator +func validatorRedelegationsHandlerFn(cliCtx context.CLIContext, cdc *codec.Codec) http.HandlerFunc { + return queryValidator(cliCtx, cdc, "custom/stake/validatorRedelegations") } // HTTP request handler to query the pool information diff --git a/x/stake/client/rest/utils.go b/x/stake/client/rest/utils.go index 477432032a..bb986c3147 100644 --- a/x/stake/client/rest/utils.go +++ b/x/stake/client/rest/utils.go @@ -111,3 +111,33 @@ func queryDelegator(cliCtx context.CLIContext, cdc *codec.Codec, endpoint string utils.PostProcessResponse(w, cdc, res, cliCtx.Indent) } } + +func queryValidator(cliCtx context.CLIContext, cdc *codec.Codec, endpoint string) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + bech32validatorAddr := vars["validatorAddr"] + + validatorAddr, err := sdk.ValAddressFromBech32(bech32validatorAddr) + if err != nil { + utils.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + + params := stake.QueryValidatorParams{ + ValidatorAddr: validatorAddr, + } + + bz, err := cdc.MarshalJSON(params) + if err != nil { + utils.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + + res, err := cliCtx.QueryWithData(endpoint, bz) + if err != nil { + utils.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) + return + } + utils.PostProcessResponse(w, cdc, res, cliCtx.Indent) + } +} diff --git a/x/stake/querier/queryable.go b/x/stake/querier/queryable.go index 7cf01d0d3f..2d54de976d 100644 --- a/x/stake/querier/queryable.go +++ b/x/stake/querier/queryable.go @@ -10,15 +10,16 @@ import ( // query endpoints supported by the staking Querier const ( - QueryValidators = "validators" - QueryValidator = "validator" - QueryDelegator = "delegator" - QueryDelegation = "delegation" - QueryUnbondingDelegation = "unbondingDelegation" - QueryDelegatorValidators = "delegatorValidators" - QueryDelegatorValidator = "delegatorValidator" - QueryPool = "pool" - QueryParameters = "parameters" + QueryValidators = "validators" + QueryValidator = "validator" + QueryValidatorRedelegations = "validatorRedelegations" + QueryDelegator = "delegator" + QueryDelegation = "delegation" + QueryUnbondingDelegation = "unbondingDelegation" + QueryDelegatorValidators = "delegatorValidators" + QueryDelegatorValidator = "delegatorValidator" + QueryPool = "pool" + QueryParameters = "parameters" ) // creates a querier for staking REST endpoints @@ -29,6 +30,8 @@ func NewQuerier(k keep.Keeper, cdc *codec.Codec) sdk.Querier { return queryValidators(ctx, cdc, k) case QueryValidator: return queryValidator(ctx, cdc, req, k) + case QueryValidatorRedelegations: + return queryValidatorRedelegations(ctx, cdc, req, k) case QueryDelegator: return queryDelegator(ctx, cdc, req, k) case QueryDelegation: @@ -58,6 +61,7 @@ type QueryDelegatorParams struct { // defines the params for the following queries: // - 'custom/stake/validator' +// - 'custom/stake/validatorRedelegations' type QueryValidatorParams struct { ValidatorAddr sdk.ValAddress } @@ -102,6 +106,23 @@ func queryValidator(ctx sdk.Context, cdc *codec.Codec, req abci.RequestQuery, k return res, nil } +func queryValidatorRedelegations(ctx sdk.Context, cdc *codec.Codec, req abci.RequestQuery, k keep.Keeper) (res []byte, err sdk.Error) { + var params QueryValidatorParams + + errRes := cdc.UnmarshalJSON(req.Data, ¶ms) + if errRes != nil { + return []byte{}, sdk.ErrUnknownAddress("") + } + + redelegations := k.GetRedelegationsFromValidator(ctx, params.ValidatorAddr) + + res, errRes = codec.MarshalJSONIndent(cdc, redelegations) + if errRes != nil { + return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", errRes.Error())) + } + return res, nil +} + func queryDelegator(ctx sdk.Context, cdc *codec.Codec, req abci.RequestQuery, k keep.Keeper) (res []byte, err sdk.Error) { var params QueryDelegatorParams errRes := cdc.UnmarshalJSON(req.Data, ¶ms)