Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

R4R: support height queries in rest client #4505

Merged
merged 6 commits into from
Jun 7, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .pending/improvements/sdk/4501-Support-height-
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#4501 Support height queriers in rest client
6 changes: 6 additions & 0 deletions client/context/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,12 @@ func (ctx CLIContext) WithNodeURI(nodeURI string) CLIContext {
return ctx
}

// WithHeight returns a copy of the context with an updated height.
func (ctx CLIContext) WithHeight(height int64) CLIContext {
ctx.Height = height
return ctx
}

// WithClient returns a copy of the context with an updated RPC client
// instance.
func (ctx CLIContext) WithClient(client rpcclient.Client) CLIContext {
Expand Down
10 changes: 10 additions & 0 deletions client/tx/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,11 @@ func QueryTxsByTagsRequestHandlerFn(cliCtx context.CLIContext) http.HandlerFunc
return
}

cliCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r)
if !ok {
return
}

if len(r.Form) == 0 {
rest.PostProcessResponse(w, cliCtx, txs)
return
Expand Down Expand Up @@ -184,6 +189,11 @@ func QueryTxRequestHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
vars := mux.Vars(r)
hashHexStr := vars["hash"]

cliCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r)
if !ok {
return
}

output, err := queryTx(cliCtx, hashHexStr)
if err != nil {
if strings.Contains(err.Error(), hashHexStr) {
Expand Down
19 changes: 19 additions & 0 deletions types/rest/rest.go
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,25 @@ func ParseFloat64OrReturnBadRequest(w http.ResponseWriter, s string, defaultIfEm
return n, true
}

// ParseQueryHeightOrReturnBadRequest sets the height to execute a query if set by the http request.
// It returns false if there was an error parsing the height.
func ParseQueryHeightOrReturnBadRequest(w http.ResponseWriter, cliCtx context.CLIContext, r *http.Request) (context.CLIContext, bool) {
alexanderbez marked this conversation as resolved.
Show resolved Hide resolved
heightStr := r.FormValue("height")
if heightStr != "" {
height, err := strconv.ParseInt(heightStr, 10, 64)
if err != nil {
WriteErrorResponse(w, http.StatusBadRequest, err.Error())
return cliCtx, false
}

if height > 0 {
cliCtx = cliCtx.WithHeight(height)
}
}

return cliCtx, true
}

// PostProcessResponse performs post processing for a REST response.
func PostProcessResponse(w http.ResponseWriter, cliCtx context.CLIContext, response interface{}) {
var output []byte
Expand Down
37 changes: 37 additions & 0 deletions types/rest/rest_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"net/http/httptest"
"testing"

"github.com/cosmos/cosmos-sdk/client/context"
"github.com/stretchr/testify/require"

"github.com/cosmos/cosmos-sdk/types"
Expand Down Expand Up @@ -101,6 +102,42 @@ func TestParseHTTPArgs(t *testing.T) {
}
}

func TestParseQueryHeight(t *testing.T) {
var emptyHeight int64
height := int64(1256756)

req0 := mustNewRequest(t, "", "/", nil)
req1 := mustNewRequest(t, "", "/?height=1256756", nil)
req2 := mustNewRequest(t, "", "/?height=456yui4567", nil)
req3 := mustNewRequest(t, "", "/?height=-1", nil)

tests := []struct {
name string
req *http.Request
w http.ResponseWriter
cliCtx context.CLIContext
expectedHeight int64
expectedOk bool
}{
{"no height", req0, httptest.NewRecorder(), context.CLIContext{}, emptyHeight, true},
{"height", req1, httptest.NewRecorder(), context.CLIContext{}, height, true},
{"invalid height", req2, httptest.NewRecorder(), context.CLIContext{}, emptyHeight, false},
alexanderbez marked this conversation as resolved.
Show resolved Hide resolved
{"negative height", req3, httptest.NewRecorder(), context.CLIContext{}, emptyHeight, true},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
cliCtx, ok := ParseQueryHeightOrReturnBadRequest(tt.w, tt.cliCtx, tt.req)
if tt.expectedOk {
require.True(t, ok)
require.Equal(t, tt.expectedHeight, cliCtx.Height)
} else {
require.False(t, ok)
require.Empty(t, tt.expectedHeight, cliCtx.Height)
}
})
}
}

func mustNewRequest(t *testing.T, method, url string, body io.Reader) *http.Request {
req, err := http.NewRequest(method, url, body)
require.NoError(t, err)
Expand Down
10 changes: 10 additions & 0 deletions x/auth/client/rest/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@ func QueryAccountRequestHandlerFn(
return
}

cliCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r)
if !ok {
return
}

res, err := cliCtx.QueryStore(types.AddressStoreKey(addr), storeName)
if err != nil {
rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
Expand Down Expand Up @@ -79,6 +84,11 @@ func QueryBalancesRequestHandlerFn(
return
}

cliCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r)
if !ok {
return
}

res, err := cliCtx.QueryStore(types.AddressStoreKey(addr), storeName)
if err != nil {
rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
Expand Down
40 changes: 40 additions & 0 deletions x/distribution/client/rest/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,11 @@ func registerQueryRoutes(cliCtx context.CLIContext, r *mux.Router, queryRoute st
// HTTP request handler to query the total rewards balance from all delegations
func delegatorRewardsHandlerFn(cliCtx context.CLIContext, queryRoute string) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
cliCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r)
if !ok {
return
}

// query for rewards from a particular delegator
res, ok := checkResponseQueryDelegatorTotalRewards(w, cliCtx, queryRoute, mux.Vars(r)["delegatorAddr"])
if !ok {
Expand All @@ -81,6 +86,11 @@ func delegatorRewardsHandlerFn(cliCtx context.CLIContext, queryRoute string) htt
// HTTP request handler to query a delegation rewards
func delegationRewardsHandlerFn(cliCtx context.CLIContext, queryRoute string) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
cliCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r)
if !ok {
return
}

// query for rewards from a particular delegation
res, ok := checkResponseQueryDelegationRewards(w, cliCtx, queryRoute, mux.Vars(r)["delegatorAddr"], mux.Vars(r)["validatorAddr"])
if !ok {
Expand All @@ -99,6 +109,11 @@ func delegatorWithdrawalAddrHandlerFn(cliCtx context.CLIContext, queryRoute stri
return
}

cliCtx, ok = rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r)
if !ok {
return
}

bz := cliCtx.Codec.MustMarshalJSON(types.NewQueryDelegatorWithdrawAddrParams(delegatorAddr))
res, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/withdraw_addr", queryRoute), bz)
if err != nil {
Expand Down Expand Up @@ -137,6 +152,11 @@ func validatorInfoHandlerFn(cliCtx context.CLIContext, queryRoute string) http.H
return
}

cliCtx, ok = rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r)
if !ok {
return
}

// query commission
commissionRes, err := common.QueryValidatorCommission(cliCtx, queryRoute, validatorAddr)
if err != nil {
Expand Down Expand Up @@ -172,6 +192,11 @@ func validatorRewardsHandlerFn(cliCtx context.CLIContext, queryRoute string) htt
return
}

cliCtx, ok = rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r)
if !ok {
return
}

delAddr := sdk.AccAddress(validatorAddr).String()
res, ok := checkResponseQueryDelegationRewards(w, cliCtx, queryRoute, delAddr, valAddr)
if !ok {
Expand All @@ -185,6 +210,11 @@ func validatorRewardsHandlerFn(cliCtx context.CLIContext, queryRoute string) htt
// HTTP request handler to query the distribution params values
func paramsHandlerFn(cliCtx context.CLIContext, queryRoute string) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
cliCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r)
if !ok {
return
}

params, err := common.QueryParams(cliCtx, queryRoute)
if err != nil {
rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
Expand All @@ -197,6 +227,11 @@ func paramsHandlerFn(cliCtx context.CLIContext, queryRoute string) http.HandlerF

func communityPoolHandler(cliCtx context.CLIContext, queryRoute string) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
cliCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r)
if !ok {
return
}

res, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/community_pool", queryRoute), nil)
if err != nil {
rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
Expand All @@ -221,6 +256,11 @@ func outstandingRewardsHandlerFn(cliCtx context.CLIContext, queryRoute string) h
return
}

cliCtx, ok = rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r)
if !ok {
return
}

bin := cliCtx.Codec.MustMarshalJSON(types.NewQueryValidatorOutstandingRewardsParams(validatorAddr))
res, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/validator_outstanding_rewards", queryRoute), bin)
if err != nil {
Expand Down
45 changes: 45 additions & 0 deletions x/gov/client/rest/rest.go
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,11 @@ func queryParamsHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
vars := mux.Vars(r)
paramType := vars[RestParamsType]

cliCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r)
if !ok {
return
}

res, err := cliCtx.QueryWithData(fmt.Sprintf("custom/gov/%s/%s", types.QueryParams, paramType), nil)
if err != nil {
rest.WriteErrorResponse(w, http.StatusNotFound, err.Error())
Expand All @@ -222,6 +227,11 @@ func queryProposalHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
return
}

cliCtx, ok = rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r)
if !ok {
return
}

params := types.NewQueryProposalParams(proposalID)

bz, err := cliCtx.Codec.MarshalJSON(params)
Expand Down Expand Up @@ -250,6 +260,11 @@ func queryDepositsHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
return
}

cliCtx, ok = rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r)
if !ok {
return
}

params := types.NewQueryProposalParams(proposalID)

bz, err := cliCtx.Codec.MarshalJSON(params)
Expand Down Expand Up @@ -298,6 +313,11 @@ func queryProposerHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
return
}

cliCtx, ok = rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r)
if !ok {
return
}

res, err := gcutils.QueryProposerByTxQuery(cliCtx, proposalID)
if err != nil {
rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
Expand Down Expand Up @@ -337,6 +357,11 @@ func queryDepositHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
return
}

cliCtx, ok = rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r)
if !ok {
return
}

params := types.NewQueryDepositParams(proposalID, depositorAddr)

bz, err := cliCtx.Codec.MarshalJSON(params)
Expand Down Expand Up @@ -414,6 +439,11 @@ func queryVoteHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
return
}

cliCtx, ok = rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r)
if !ok {
return
}

params := types.NewQueryVoteParams(proposalID, voterAddr)

bz, err := cliCtx.Codec.MarshalJSON(params)
Expand Down Expand Up @@ -479,6 +509,11 @@ func queryVotesOnProposalHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
return
}

cliCtx, ok = rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r)
if !ok {
return
}

params := types.NewQueryProposalParams(proposalID)

bz, err := cliCtx.Codec.MarshalJSON(params)
Expand Down Expand Up @@ -561,6 +596,11 @@ func queryProposalsWithParameterFn(cliCtx context.CLIContext) http.HandlerFunc {
params.Limit = numLimit
}

cliCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r)
if !ok {
return
}

bz, err := cliCtx.Codec.MarshalJSON(params)
if err != nil {
rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
Expand Down Expand Up @@ -594,6 +634,11 @@ func queryTallyOnProposalHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
return
}

cliCtx, ok = rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r)
if !ok {
return
}

params := types.NewQueryProposalParams(proposalID)

bz, err := cliCtx.Codec.MarshalJSON(params)
Expand Down
15 changes: 15 additions & 0 deletions x/mint/client/rest/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@ func queryParamsHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
route := fmt.Sprintf("custom/%s/%s", types.QuerierRoute, types.QueryParameters)

cliCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r)
if !ok {
return
}

res, err := cliCtx.QueryWithData(route, nil)
if err != nil {
rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
Expand All @@ -46,6 +51,11 @@ func queryInflationHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
route := fmt.Sprintf("custom/%s/%s", types.QuerierRoute, types.QueryInflation)

cliCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r)
if !ok {
return
}

res, err := cliCtx.QueryWithData(route, nil)
if err != nil {
rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
Expand All @@ -60,6 +70,11 @@ func queryAnnualProvisionsHandlerFn(cliCtx context.CLIContext) http.HandlerFunc
return func(w http.ResponseWriter, r *http.Request) {
route := fmt.Sprintf("custom/%s/%s", types.QuerierRoute, types.QueryAnnualProvisions)

cliCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r)
if !ok {
return
}

res, err := cliCtx.QueryWithData(route, nil)
if err != nil {
rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
Expand Down
Loading