Skip to content

Commit

Permalink
Merge PR #4505: Support height queries in REST client
Browse files Browse the repository at this point in the history
  • Loading branch information
colin-axner authored and alexanderbez committed Jun 7, 2019
1 parent 3862b74 commit c777fb9
Show file tree
Hide file tree
Showing 12 changed files with 238 additions and 0 deletions.
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) {
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},
{"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

0 comments on commit c777fb9

Please sign in to comment.