Add route for querying signing_info for all validators (#3952)
Also remove duplicate pagination: - move function to extract query params into types/rest - adjust pagination values locally until available in tendermint for validators Code cleanup: - helper function in test - fix pagination description in swagger.yaml - uint instead of int when possible Closes: #3226 Closes: #3991
This commit is contained in:
committed by
Alessio Treglia
parent
e5897d8d91
commit
5bb6090e38
@@ -3,9 +3,12 @@
|
||||
package rest
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/tendermint/tendermint/types"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
@@ -13,6 +16,11 @@ import (
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
|
||||
const (
|
||||
DefaultPage = 1
|
||||
DefaultLimit = 30 // should be consistent with tendermint/tendermint/rpc/core/pipe.go:19
|
||||
)
|
||||
|
||||
// GasEstimateResponse defines a response definition for tx gas estimation.
|
||||
type GasEstimateResponse struct {
|
||||
GasEstimate uint64 `json:"gas_estimate"`
|
||||
@@ -211,3 +219,53 @@ func PostProcessResponse(w http.ResponseWriter, cdc *codec.Codec, response inter
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
_, _ = w.Write(output)
|
||||
}
|
||||
|
||||
// ParseHTTPArgs parses the request's URL and returns a slice containing all arguments pairs.
|
||||
// It separates page and limit used for pagination
|
||||
func ParseHTTPArgs(r *http.Request) (tags []string, page, limit int, err error) {
|
||||
tags = make([]string, 0, len(r.Form))
|
||||
for key, values := range r.Form {
|
||||
if key == "page" || key == "limit" {
|
||||
continue
|
||||
}
|
||||
var value string
|
||||
value, err = url.QueryUnescape(values[0])
|
||||
if err != nil {
|
||||
return tags, page, limit, err
|
||||
}
|
||||
|
||||
var tag string
|
||||
if key == types.TxHeightKey {
|
||||
tag = fmt.Sprintf("%s=%s", key, value)
|
||||
} else {
|
||||
tag = fmt.Sprintf("%s='%s'", key, value)
|
||||
}
|
||||
tags = append(tags, tag)
|
||||
}
|
||||
|
||||
pageStr := r.FormValue("page")
|
||||
if pageStr == "" {
|
||||
page = DefaultPage
|
||||
} else {
|
||||
page, err = strconv.Atoi(pageStr)
|
||||
if err != nil {
|
||||
return tags, page, limit, err
|
||||
} else if page <= 0 {
|
||||
return tags, page, limit, errors.New("page must greater than 0")
|
||||
}
|
||||
}
|
||||
|
||||
limitStr := r.FormValue("limit")
|
||||
if limitStr == "" {
|
||||
limit = DefaultLimit
|
||||
} else {
|
||||
limit, err = strconv.Atoi(limitStr)
|
||||
if err != nil {
|
||||
return tags, page, limit, err
|
||||
} else if limit <= 0 {
|
||||
return tags, page, limit, errors.New("limit must greater than 0")
|
||||
}
|
||||
}
|
||||
|
||||
return tags, page, limit, nil
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
package rest
|
||||
|
||||
import (
|
||||
"io"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
@@ -55,3 +56,55 @@ func TestBaseReqValidateBasic(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseHTTPArgs(t *testing.T) {
|
||||
req0 := mustNewRequest(t, "", "/", nil)
|
||||
req1 := mustNewRequest(t, "", "/?limit=5", nil)
|
||||
req2 := mustNewRequest(t, "", "/?page=5", nil)
|
||||
req3 := mustNewRequest(t, "", "/?page=5&limit=5", nil)
|
||||
|
||||
reqE1 := mustNewRequest(t, "", "/?page=-1", nil)
|
||||
reqE2 := mustNewRequest(t, "", "/?limit=-1", nil)
|
||||
req4 := mustNewRequest(t, "", "/?foo=faa", nil)
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
req *http.Request
|
||||
w http.ResponseWriter
|
||||
tags []string
|
||||
page int
|
||||
limit int
|
||||
err bool
|
||||
}{
|
||||
{"no params", req0, httptest.NewRecorder(), []string{}, DefaultPage, DefaultLimit, false},
|
||||
{"Limit", req1, httptest.NewRecorder(), []string{}, DefaultPage, 5, false},
|
||||
{"Page", req2, httptest.NewRecorder(), []string{}, 5, DefaultLimit, false},
|
||||
{"Page and limit", req3, httptest.NewRecorder(), []string{}, 5, 5, false},
|
||||
|
||||
{"error page 0", reqE1, httptest.NewRecorder(), []string{}, DefaultPage, DefaultLimit, true},
|
||||
{"error limit 0", reqE2, httptest.NewRecorder(), []string{}, DefaultPage, DefaultLimit, true},
|
||||
|
||||
{"tags", req4, httptest.NewRecorder(), []string{"foo='faa'"}, DefaultPage, DefaultLimit, false},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
tags, page, limit, err := ParseHTTPArgs(tt.req)
|
||||
if tt.err {
|
||||
require.NotNil(t, err)
|
||||
} else {
|
||||
require.Nil(t, err)
|
||||
require.Equal(t, tt.tags, tags)
|
||||
require.Equal(t, tt.page, page)
|
||||
require.Equal(t, tt.limit, limit)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func mustNewRequest(t *testing.T, method, url string, body io.Reader) *http.Request {
|
||||
req, err := http.NewRequest(method, url, body)
|
||||
require.NoError(t, err)
|
||||
err = req.ParseForm()
|
||||
require.NoError(t, err)
|
||||
return req
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user