gRPC gateway init (#7019)
* WIP: grpc server setup * add register grpc routes * updated go mod * updated grpc for all modules * added pb file for grpc gateway * udpated gw file * added a test for grpc route * fixed conflicts * added grpc server * grpc tests added * cleanup * Fix gateway forward issue * Add godoc * updated tests * fix lint * fix tests * fix tests * fix tests * fixed test * Add grpc headers * Fix error handling * Fix tests - hacky * Fix lint * remove debug logs * Fix review comments * move grpc tests into a separate file * Fix protobuf version * Update x/capability/module.go * Fix godoc * Fix review suggestions * Fix codec * Add query params test for gateway request * Fix gofmt Co-authored-by: anilCSE <anil@vitwit.com> Co-authored-by: Federico Kunze <31522760+fedekunze@users.noreply.github.com>
This commit is contained in:
parent
1f7a2787aa
commit
78194e1cdd
|
@ -27,6 +27,18 @@ func (ctx Context) Invoke(grpcCtx gocontext.Context, method string, args, reply
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// parse height header
|
||||
md, _ := metadata.FromOutgoingContext(grpcCtx)
|
||||
if heights := md.Get(grpctypes.GRPCBlockHeightHeader); len(heights) > 0 {
|
||||
height, err := strconv.ParseInt(heights[0], 10, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ctx = ctx.WithHeight(height)
|
||||
}
|
||||
|
||||
req := abci.RequestQuery{
|
||||
Path: method,
|
||||
Data: reqBz,
|
||||
|
@ -47,7 +59,7 @@ func (ctx Context) Invoke(grpcCtx gocontext.Context, method string, args, reply
|
|||
// We then parse all the call options, if the call option is a
|
||||
// HeaderCallOption, then we manually set the value of that header to the
|
||||
// metadata.
|
||||
md := metadata.Pairs(grpctypes.GRPCBlockHeightHeader, strconv.FormatInt(res.Height, 10))
|
||||
md = metadata.Pairs(grpctypes.GRPCBlockHeightHeader, strconv.FormatInt(res.Height, 10))
|
||||
for _, callOpt := range opts {
|
||||
header, ok := callOpt.(grpc.HeaderCallOption)
|
||||
if !ok {
|
||||
|
|
1
go.mod
1
go.mod
|
@ -14,6 +14,7 @@ require (
|
|||
github.com/cosmos/iavl v0.15.0-rc2
|
||||
github.com/cosmos/ledger-cosmos-go v0.11.1
|
||||
github.com/enigmampc/btcutil v1.0.3-0.20200723161021-e2fb6adb2a25
|
||||
github.com/gogo/gateway v1.1.0
|
||||
github.com/gogo/protobuf v1.3.1
|
||||
github.com/golang/mock v1.4.4
|
||||
github.com/golang/protobuf v1.4.2
|
||||
|
|
11
go.sum
11
go.sum
|
@ -178,6 +178,8 @@ github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
|
|||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 h1:ZpnhV/YsD2/4cESfV5+Hoeu/iUR3ruzNvZ+yQfO03a0=
|
||||
github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4=
|
||||
github.com/gogo/gateway v1.1.0 h1:u0SuhL9+Il+UbjM9VIE3ntfRujKbvVpFvNB4HbjeVQ0=
|
||||
github.com/gogo/gateway v1.1.0/go.mod h1:S7rR8FRQyG3QFESeSv4l2WnsyzlCLG0CzBbUUo/mbic=
|
||||
github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
|
@ -213,6 +215,7 @@ github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ
|
|||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.0 h1:/QaMHBdZ26BB3SSst0Iwl10Epc+xhTquomWX0oZEB6w=
|
||||
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
|
@ -231,14 +234,10 @@ github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5m
|
|||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||
github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
|
||||
github.com/gorilla/handlers v1.4.2 h1:0QniY0USkHQ1RGCLfKxeNHK9bkDHGRYGNDFBCS+YARg=
|
||||
github.com/gorilla/handlers v1.4.2/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ=
|
||||
github.com/gorilla/handlers v1.5.0 h1:4wjo3sf9azi99c8hTmyaxp9y5S+pFszsy3pP0rAw/lw=
|
||||
github.com/gorilla/handlers v1.5.0/go.mod h1:t8XrUpc4KVXb7HGyJ4/cEnwQiaxrX/hz1Zv/4g96P1Q=
|
||||
github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||
github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||
github.com/gorilla/mux v1.7.4 h1:VuZ8uybHlWmqV03+zRzdwKL4tUnIp1MAQtp1mIFE1bc=
|
||||
github.com/gorilla/mux v1.7.4/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
|
||||
github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
|
||||
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
|
||||
github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||
|
@ -248,7 +247,9 @@ github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/ad
|
|||
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.8.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.9.5 h1:UImYN5qQ8tuGpGE16ZmjvcTtTw24zw1QAp/SlnNrZhI=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.14.7 h1:Nk5kuHrnWUTf/0GL1a/vchH/om9Ap2/HnVna+jYZgTY=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.14.7/go.mod h1:oYZKL012gGh6LMyg/xA7Q2yq6j8bu0wa+9w14EEthWU=
|
||||
|
@ -740,6 +741,7 @@ google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 h1:+kGHl1aib/qcwaR
|
|||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
||||
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.19.1/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM=
|
||||
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
||||
google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
||||
|
@ -761,6 +763,7 @@ google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzi
|
|||
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.24.0 h1:UhZDfRO8JRQru4/+LlLE0BRKGF8L+PICnvYZmx/fEGA=
|
||||
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
|
||||
google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c=
|
||||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||
|
|
|
@ -7,8 +7,10 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/gogo/gateway"
|
||||
"github.com/gorilla/handlers"
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/grpc-ecosystem/grpc-gateway/runtime"
|
||||
"github.com/rakyll/statik/fs"
|
||||
"github.com/tendermint/tendermint/libs/log"
|
||||
tmrpcserver "github.com/tendermint/tendermint/rpc/jsonrpc/server"
|
||||
|
@ -16,6 +18,7 @@ import (
|
|||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/server/config"
|
||||
"github.com/cosmos/cosmos-sdk/telemetry"
|
||||
grpctypes "github.com/cosmos/cosmos-sdk/types/grpc"
|
||||
"github.com/cosmos/cosmos-sdk/types/rest"
|
||||
|
||||
// unnamed import of statik for swagger UI support
|
||||
|
@ -24,19 +27,54 @@ import (
|
|||
|
||||
// Server defines the server's API interface.
|
||||
type Server struct {
|
||||
Router *mux.Router
|
||||
ClientCtx client.Context
|
||||
Router *mux.Router
|
||||
GRPCRouter *runtime.ServeMux
|
||||
ClientCtx client.Context
|
||||
|
||||
logger log.Logger
|
||||
metrics *telemetry.Metrics
|
||||
listener net.Listener
|
||||
}
|
||||
|
||||
// CustomGRPCHeaderMatcher for mapping request headers to
|
||||
// GRPC metadata.
|
||||
// HTTP headers that start with 'Grpc-Metadata-' are automatically mapped to
|
||||
// gRPC metadata after removing prefix 'Grpc-Metadata-'. We can use this
|
||||
// CustomGRPCHeaderMatcher if headers don't start with `Grpc-Metadata-`
|
||||
func CustomGRPCHeaderMatcher(key string) (string, bool) {
|
||||
switch strings.ToLower(key) {
|
||||
case grpctypes.GRPCBlockHeightHeader:
|
||||
return grpctypes.GRPCBlockHeightHeader, true
|
||||
default:
|
||||
return runtime.DefaultHeaderMatcher(key)
|
||||
}
|
||||
}
|
||||
|
||||
func New(clientCtx client.Context, logger log.Logger) *Server {
|
||||
// The default JSON marshaller used by the gRPC-Gateway is unable to marshal non-nullable non-scalar fields.
|
||||
// Using the gogo/gateway package with the gRPC-Gateway WithMarshaler option fixes the scalar field marshalling issue.
|
||||
marshalerOption := &gateway.JSONPb{
|
||||
EmitDefaults: true,
|
||||
Indent: " ",
|
||||
OrigName: true,
|
||||
}
|
||||
|
||||
return &Server{
|
||||
Router: mux.NewRouter(),
|
||||
ClientCtx: clientCtx,
|
||||
logger: logger,
|
||||
GRPCRouter: runtime.NewServeMux(
|
||||
// Custom marshaler option is required for gogo proto
|
||||
runtime.WithMarshalerOption(runtime.MIMEWildcard, marshalerOption),
|
||||
|
||||
// This is necessary to get error details properly
|
||||
// marshalled in unary requests.
|
||||
runtime.WithProtoErrorHandler(runtime.DefaultHTTPProtoErrorHandler),
|
||||
|
||||
// Custom header matcher for mapping request headers to
|
||||
// GRPC metadata
|
||||
runtime.WithIncomingHeaderMatcher(CustomGRPCHeaderMatcher),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -70,6 +108,7 @@ func (s *Server) Start(cfg config.Config) error {
|
|||
return err
|
||||
}
|
||||
|
||||
s.registerGRPCRoutes()
|
||||
s.listener = listener
|
||||
var h http.Handler = s.Router
|
||||
|
||||
|
@ -93,7 +132,11 @@ func (s *Server) registerSwaggerUI() {
|
|||
}
|
||||
|
||||
staticServer := http.FileServer(statikFS)
|
||||
s.Router.PathPrefix("/").Handler(staticServer)
|
||||
s.Router.PathPrefix("/legacy").Handler(staticServer)
|
||||
}
|
||||
|
||||
func (s *Server) registerGRPCRoutes() {
|
||||
s.Router.PathPrefix("/").Handler(s.GRPCRouter)
|
||||
}
|
||||
|
||||
func (s *Server) registerMetrics() {
|
||||
|
|
|
@ -240,7 +240,6 @@ func startInProcess(ctx *Context, legacyAminoCdc *codec.LegacyAmino, appCreator
|
|||
|
||||
apiSrv = api.New(clientCtx, ctx.Logger.With("module", "api-server"))
|
||||
app.RegisterAPIRoutes(apiSrv)
|
||||
|
||||
errCh := make(chan error)
|
||||
|
||||
go func() {
|
||||
|
|
|
@ -512,6 +512,7 @@ func (app *SimApp) RegisterAPIRoutes(apiSvr *api.Server) {
|
|||
rpc.RegisterRoutes(clientCtx, apiSvr.Router)
|
||||
authrest.RegisterTxRoutes(clientCtx, apiSvr.Router)
|
||||
ModuleBasics.RegisterRESTRoutes(clientCtx, apiSvr.Router)
|
||||
ModuleBasics.RegisterGRPCRoutes(apiSvr.ClientCtx, apiSvr.GRPCRouter)
|
||||
}
|
||||
|
||||
// GetMaccPerms returns a copy of the module account permissions
|
||||
|
|
|
@ -15,6 +15,7 @@ import (
|
|||
grpc "github.com/gogo/protobuf/grpc"
|
||||
gomock "github.com/golang/mock/gomock"
|
||||
mux "github.com/gorilla/mux"
|
||||
"github.com/grpc-ecosystem/grpc-gateway/runtime"
|
||||
cobra "github.com/spf13/cobra"
|
||||
types1 "github.com/tendermint/tendermint/abci/types"
|
||||
)
|
||||
|
@ -120,6 +121,18 @@ func (mr *MockAppModuleBasicMockRecorder) RegisterRESTRoutes(arg0, arg1 interfac
|
|||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RegisterRESTRoutes", reflect.TypeOf((*MockAppModuleBasic)(nil).RegisterRESTRoutes), arg0, arg1)
|
||||
}
|
||||
|
||||
// RegisterGRPCRoutes mocks base method
|
||||
func (m *MockAppModuleBasic) RegisterGRPCRoutes(arg0 client.Context, arg1 *runtime.ServeMux) {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "RegisterGRPCRoutes", arg0, arg1)
|
||||
}
|
||||
|
||||
// RegisterGRPCRoutes indicates an expected call of RegisterGRPCRoutes
|
||||
func (mr *MockAppModuleBasicMockRecorder) RegisterGRPCRoutes(arg0, arg1 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RegisterGRPCRoutes", reflect.TypeOf((*MockAppModuleBasic)(nil).RegisterGRPCRoutes), arg0, arg1)
|
||||
}
|
||||
|
||||
// GetTxCmd mocks base method
|
||||
func (m *MockAppModuleBasic) GetTxCmd() *cobra.Command {
|
||||
m.ctrl.T.Helper()
|
||||
|
@ -249,6 +262,18 @@ func (mr *MockAppModuleGenesisMockRecorder) RegisterRESTRoutes(arg0, arg1 interf
|
|||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RegisterRESTRoutes", reflect.TypeOf((*MockAppModuleGenesis)(nil).RegisterRESTRoutes), arg0, arg1)
|
||||
}
|
||||
|
||||
// RegisterGRPCRoutes mocks base method
|
||||
func (m *MockAppModuleGenesis) RegisterGRPCRoutes(arg0 client.Context, arg1 *runtime.ServeMux) {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "RegisterRESTRoutes", arg0, arg1)
|
||||
}
|
||||
|
||||
// RegisterGRPCRoutes indicates an expected call of RegisterGRPCRoutes
|
||||
func (mr *MockAppModuleGenesisMockRecorder) RegisterGRPCRoutes(arg0, arg1 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RegisterGRPCRoutes", reflect.TypeOf((*MockAppModuleGenesis)(nil).RegisterGRPCRoutes), arg0, arg1)
|
||||
}
|
||||
|
||||
// GetTxCmd mocks base method
|
||||
func (m *MockAppModuleGenesis) GetTxCmd() *cobra.Command {
|
||||
m.ctrl.T.Helper()
|
||||
|
@ -406,6 +431,18 @@ func (mr *MockAppModuleMockRecorder) RegisterRESTRoutes(arg0, arg1 interface{})
|
|||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RegisterRESTRoutes", reflect.TypeOf((*MockAppModule)(nil).RegisterRESTRoutes), arg0, arg1)
|
||||
}
|
||||
|
||||
// RegisterGRPCRoutes mocks base method
|
||||
func (m *MockAppModule) RegisterGRPCRoutes(arg0 client.Context, arg1 *runtime.ServeMux) {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "RegisterGRPCRoutes", arg0, arg1)
|
||||
}
|
||||
|
||||
// RegisterGRPCRoutes indicates an expected call of RegisterGRPCRoutes
|
||||
func (mr *MockAppModuleMockRecorder) RegisterGRPCRoutes(arg0, arg1 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RegisterGRPCRoutes", reflect.TypeOf((*MockAppModule)(nil).RegisterGRPCRoutes), arg0, arg1)
|
||||
}
|
||||
|
||||
// GetTxCmd mocks base method
|
||||
func (m *MockAppModule) GetTxCmd() *cobra.Command {
|
||||
m.ctrl.T.Helper()
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
package testutil
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// GetRequestWithHeaders defines a wrapper around an HTTP GET request with a provided URL
|
||||
// and custom headers
|
||||
// An error is returned if the request or reading the body fails.
|
||||
func GetRequestWithHeaders(url string, headers map[string]string) ([]byte, error) {
|
||||
req, err := http.NewRequest("GET", url, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
client := &http.Client{}
|
||||
|
||||
for key, value := range headers {
|
||||
req.Header.Set(key, value)
|
||||
}
|
||||
|
||||
res, err := client.Do(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
body, err := ioutil.ReadAll(res.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err = res.Body.Close(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return body, nil
|
||||
}
|
|
@ -32,6 +32,7 @@ import (
|
|||
"encoding/json"
|
||||
|
||||
"github.com/gogo/protobuf/grpc"
|
||||
"github.com/grpc-ecosystem/grpc-gateway/runtime"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/spf13/cobra"
|
||||
|
@ -56,6 +57,7 @@ type AppModuleBasic interface {
|
|||
|
||||
// client functionality
|
||||
RegisterRESTRoutes(client.Context, *mux.Router)
|
||||
RegisterGRPCRoutes(client.Context, *runtime.ServeMux)
|
||||
GetTxCmd() *cobra.Command
|
||||
GetQueryCmd() *cobra.Command
|
||||
}
|
||||
|
@ -114,6 +116,13 @@ func (bm BasicManager) RegisterRESTRoutes(clientCtx client.Context, rtr *mux.Rou
|
|||
}
|
||||
}
|
||||
|
||||
// RegisterGRPCRoutes registers all module rest routes
|
||||
func (bm BasicManager) RegisterGRPCRoutes(clientCtx client.Context, rtr *runtime.ServeMux) {
|
||||
for _, b := range bm {
|
||||
b.RegisterGRPCRoutes(clientCtx, rtr)
|
||||
}
|
||||
}
|
||||
|
||||
// AddTxCommands adds all tx commands to the rootTxCmd.
|
||||
//
|
||||
// TODO: Remove clientCtx argument.
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
"math/rand"
|
||||
|
||||
"github.com/gogo/protobuf/grpc"
|
||||
"github.com/grpc-ecosystem/grpc-gateway/runtime"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/spf13/cobra"
|
||||
|
@ -64,6 +65,10 @@ func (AppModuleBasic) RegisterRESTRoutes(clientCtx client.Context, rtr *mux.Rout
|
|||
rest.RegisterRoutes(clientCtx, rtr, types.StoreKey)
|
||||
}
|
||||
|
||||
// RegisterGRPCRoutes registers the gRPC Gateway routes for the auth module.
|
||||
func (a AppModuleBasic) RegisterGRPCRoutes(_ client.Context, _ *runtime.ServeMux) {
|
||||
}
|
||||
|
||||
// GetTxCmd returns the root tx command for the auth module.
|
||||
func (AppModuleBasic) GetTxCmd() *cobra.Command {
|
||||
return cli.GetTxCmd()
|
||||
|
|
|
@ -0,0 +1,93 @@
|
|||
package rest_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/testutil"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
grpctypes "github.com/cosmos/cosmos-sdk/types/grpc"
|
||||
"github.com/cosmos/cosmos-sdk/x/bank/types"
|
||||
)
|
||||
|
||||
func (s *IntegrationTestSuite) TestTotalSupplyGRPCHandler() {
|
||||
val := s.network.Validators[0]
|
||||
baseURL := val.APIAddress
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
url string
|
||||
headers map[string]string
|
||||
respType fmt.Stringer
|
||||
expected fmt.Stringer
|
||||
}{
|
||||
{
|
||||
"test GRPC total supply",
|
||||
fmt.Sprintf("%s/cosmos/bank/v1beta1/supply", baseURL),
|
||||
map[string]string{
|
||||
grpctypes.GRPCBlockHeightHeader: "1",
|
||||
},
|
||||
&types.QueryTotalSupplyResponse{},
|
||||
&types.QueryTotalSupplyResponse{
|
||||
Supply: sdk.NewCoins(
|
||||
sdk.NewCoin(fmt.Sprintf("%stoken", val.Moniker), s.cfg.AccountTokens),
|
||||
sdk.NewCoin(s.cfg.BondDenom, s.cfg.StakingTokens.Add(sdk.NewInt(10))),
|
||||
),
|
||||
},
|
||||
},
|
||||
{
|
||||
"GRPC total supply of a specific denom",
|
||||
fmt.Sprintf("%s/cosmos/bank/v1beta1/supply/%s", baseURL, s.cfg.BondDenom),
|
||||
map[string]string{
|
||||
grpctypes.GRPCBlockHeightHeader: "1",
|
||||
},
|
||||
&types.QuerySupplyOfResponse{},
|
||||
&types.QuerySupplyOfResponse{
|
||||
Amount: sdk.NewCoin(s.cfg.BondDenom, s.cfg.StakingTokens.Add(sdk.NewInt(10))),
|
||||
},
|
||||
},
|
||||
{
|
||||
"Query for `height` > 1",
|
||||
fmt.Sprintf("%s/cosmos/bank/v1beta1/supply/%s", baseURL, s.cfg.BondDenom),
|
||||
map[string]string{
|
||||
grpctypes.GRPCBlockHeightHeader: "2",
|
||||
},
|
||||
&types.QuerySupplyOfResponse{},
|
||||
&types.QuerySupplyOfResponse{
|
||||
Amount: sdk.NewCoin(s.cfg.BondDenom, s.cfg.StakingTokens.Add(sdk.NewInt(20))),
|
||||
},
|
||||
},
|
||||
{
|
||||
"Query params shouldn't be considered as height",
|
||||
fmt.Sprintf("%s/cosmos/bank/v1beta1/supply/%s?height=2", baseURL, s.cfg.BondDenom),
|
||||
map[string]string{
|
||||
grpctypes.GRPCBlockHeightHeader: "1",
|
||||
},
|
||||
&types.QuerySupplyOfResponse{},
|
||||
&types.QuerySupplyOfResponse{
|
||||
Amount: sdk.NewCoin(s.cfg.BondDenom, s.cfg.StakingTokens.Add(sdk.NewInt(10))),
|
||||
},
|
||||
},
|
||||
{
|
||||
"GRPC total supply of a bogus denom",
|
||||
fmt.Sprintf("%s/cosmos/bank/v1beta1/supply/foobar", baseURL),
|
||||
map[string]string{
|
||||
grpctypes.GRPCBlockHeightHeader: "1",
|
||||
},
|
||||
&types.QuerySupplyOfResponse{},
|
||||
&types.QuerySupplyOfResponse{
|
||||
Amount: sdk.NewCoin("foobar", sdk.ZeroInt()),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
tc := tc
|
||||
s.Run(tc.name, func() {
|
||||
resp, err := testutil.GetRequestWithHeaders(tc.url, tc.headers)
|
||||
s.Require().NoError(err)
|
||||
|
||||
s.Require().NoError(val.ClientCtx.JSONMarshaler.UnmarshalJSON(resp, tc.respType))
|
||||
s.Require().Equal(tc.expected.String(), tc.respType.String())
|
||||
})
|
||||
}
|
||||
}
|
|
@ -1,12 +1,14 @@
|
|||
package bank
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
|
||||
"github.com/gogo/protobuf/grpc"
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/grpc-ecosystem/grpc-gateway/runtime"
|
||||
"github.com/spf13/cobra"
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
|
||||
|
@ -61,6 +63,11 @@ func (AppModuleBasic) RegisterRESTRoutes(clientCtx client.Context, rtr *mux.Rout
|
|||
rest.RegisterHandlers(clientCtx, rtr)
|
||||
}
|
||||
|
||||
// RegisterGRPCRoutes registers the gRPC Gateway routes for the bank module.
|
||||
func (a AppModuleBasic) RegisterGRPCRoutes(clientCtx client.Context, mux *runtime.ServeMux) {
|
||||
types.RegisterQueryHandlerClient(context.Background(), mux, types.NewQueryClient(clientCtx))
|
||||
}
|
||||
|
||||
// GetTxCmd returns the root tx command for the bank module.
|
||||
func (AppModuleBasic) GetTxCmd() *cobra.Command {
|
||||
return cli.NewTxCmd()
|
||||
|
|
|
@ -5,15 +5,16 @@ import (
|
|||
"fmt"
|
||||
"math/rand"
|
||||
|
||||
cdctypes "github.com/cosmos/cosmos-sdk/codec/types"
|
||||
|
||||
"github.com/gogo/protobuf/grpc"
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/grpc-ecosystem/grpc-gateway/runtime"
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
cdctypes "github.com/cosmos/cosmos-sdk/codec/types"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/types/module"
|
||||
simtypes "github.com/cosmos/cosmos-sdk/types/simulation"
|
||||
|
@ -71,6 +72,10 @@ func (AppModuleBasic) ValidateGenesis(cdc codec.JSONMarshaler, config client.TxE
|
|||
// RegisterRESTRoutes registers the capability module's REST service handlers.
|
||||
func (a AppModuleBasic) RegisterRESTRoutes(_ client.Context, _ *mux.Router) {}
|
||||
|
||||
// RegisterGRPCRoutes registers the gRPC Gateway routes for the capability module.
|
||||
func (a AppModuleBasic) RegisterGRPCRoutes(_ client.Context, _ *runtime.ServeMux) {
|
||||
}
|
||||
|
||||
// GetTxCmd returns the capability module's root tx command.
|
||||
func (a AppModuleBasic) GetTxCmd() *cobra.Command { return nil }
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
|
||||
"github.com/gogo/protobuf/grpc"
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/grpc-ecosystem/grpc-gateway/runtime"
|
||||
"github.com/spf13/cobra"
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
|
||||
|
@ -56,6 +57,9 @@ func (AppModuleBasic) ValidateGenesis(cdc codec.JSONMarshaler, config client.TxE
|
|||
// RegisterRESTRoutes registers no REST routes for the crisis module.
|
||||
func (AppModuleBasic) RegisterRESTRoutes(_ client.Context, _ *mux.Router) {}
|
||||
|
||||
// RegisterGRPCRoutes registers the gRPC Gateway routes for the capability module.
|
||||
func (AppModuleBasic) RegisterGRPCRoutes(_ client.Context, _ *runtime.ServeMux) {}
|
||||
|
||||
// GetTxCmd returns the root tx command for the crisis module.
|
||||
func (b AppModuleBasic) GetTxCmd() *cobra.Command {
|
||||
return cli.NewTxCmd()
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
"math/rand"
|
||||
|
||||
"github.com/gogo/protobuf/grpc"
|
||||
"github.com/grpc-ecosystem/grpc-gateway/runtime"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/spf13/cobra"
|
||||
|
@ -67,6 +68,9 @@ func (AppModuleBasic) RegisterRESTRoutes(clientCtx sdkclient.Context, rtr *mux.R
|
|||
rest.RegisterHandlers(clientCtx, rtr)
|
||||
}
|
||||
|
||||
// RegisterGRPCRoutes registers the gRPC Gateway routes for the distribution module.
|
||||
func (AppModuleBasic) RegisterGRPCRoutes(_ sdkclient.Context, _ *runtime.ServeMux) {}
|
||||
|
||||
// GetTxCmd returns the root tx command for the distribution module.
|
||||
func (AppModuleBasic) GetTxCmd() *cobra.Command {
|
||||
return cli.NewTxCmd()
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
"math/rand"
|
||||
|
||||
"github.com/gogo/protobuf/grpc"
|
||||
"github.com/grpc-ecosystem/grpc-gateway/runtime"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/spf13/cobra"
|
||||
|
@ -84,6 +85,10 @@ func (a AppModuleBasic) RegisterRESTRoutes(clientCtx client.Context, rtr *mux.Ro
|
|||
rest.RegisterRoutes(clientCtx, rtr, evidenceRESTHandlers)
|
||||
}
|
||||
|
||||
// RegisterGRPCRoutes registers the gRPC Gateway routes for the evidence module.
|
||||
func (a AppModuleBasic) RegisterGRPCRoutes(_ client.Context, _ *runtime.ServeMux) {
|
||||
}
|
||||
|
||||
// GetTxCmd returns the evidence module's root tx command.
|
||||
func (a AppModuleBasic) GetTxCmd() *cobra.Command {
|
||||
evidenceCLIHandlers := make([]*cobra.Command, len(a.evidenceHandlers))
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
"fmt"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/grpc-ecosystem/grpc-gateway/runtime"
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
|
@ -55,6 +56,10 @@ func (b AppModuleBasic) ValidateGenesis(cdc codec.JSONMarshaler, txEncodingConfi
|
|||
// RegisterRESTRoutes registers the REST routes for the genutil module.
|
||||
func (AppModuleBasic) RegisterRESTRoutes(_ client.Context, _ *mux.Router) {}
|
||||
|
||||
// RegisterGRPCRoutes registers the gRPC Gateway routes for the genutil module.
|
||||
func (AppModuleBasic) RegisterGRPCRoutes(_ client.Context, _ *runtime.ServeMux) {
|
||||
}
|
||||
|
||||
// GetTxCmd returns no root tx command for the genutil module.
|
||||
func (AppModuleBasic) GetTxCmd() *cobra.Command { return nil }
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ import (
|
|||
"math/rand"
|
||||
|
||||
"github.com/gogo/protobuf/grpc"
|
||||
"github.com/grpc-ecosystem/grpc-gateway/runtime"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/spf13/cobra"
|
||||
|
@ -83,6 +84,10 @@ func (a AppModuleBasic) RegisterRESTRoutes(clientCtx client.Context, rtr *mux.Ro
|
|||
rest.RegisterHandlers(clientCtx, rtr, proposalRESTHandlers)
|
||||
}
|
||||
|
||||
// RegisterGRPCRoutes registers the gRPC Gateway routes for the gov module.
|
||||
func (a AppModuleBasic) RegisterGRPCRoutes(_ client.Context, _ *runtime.ServeMux) {
|
||||
}
|
||||
|
||||
// GetTxCmd returns the root tx command for the gov module.
|
||||
func (a AppModuleBasic) GetTxCmd() *cobra.Command {
|
||||
proposalCLIHandlers := make([]*cobra.Command, 0, len(a.proposalHandlers))
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
"math/rand"
|
||||
|
||||
"github.com/gogo/protobuf/grpc"
|
||||
"github.com/grpc-ecosystem/grpc-gateway/runtime"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/spf13/cobra"
|
||||
|
@ -66,6 +67,10 @@ func (AppModuleBasic) ValidateGenesis(cdc codec.JSONMarshaler, config client.TxE
|
|||
func (AppModuleBasic) RegisterRESTRoutes(clientCtx client.Context, rtr *mux.Router) {
|
||||
}
|
||||
|
||||
// RegisterGRPCRoutes registers the gRPC Gateway routes for the ibc-transfer module.
|
||||
func (a AppModuleBasic) RegisterGRPCRoutes(_ client.Context, _ *runtime.ServeMux) {
|
||||
}
|
||||
|
||||
// GetTxCmd implements AppModuleBasic interface
|
||||
func (AppModuleBasic) GetTxCmd() *cobra.Command {
|
||||
return cli.NewTxCmd()
|
||||
|
|
|
@ -7,6 +7,7 @@ import (
|
|||
|
||||
"github.com/gogo/protobuf/grpc"
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/grpc-ecosystem/grpc-gateway/runtime"
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
|
@ -63,6 +64,10 @@ func (AppModuleBasic) ValidateGenesis(cdc codec.JSONMarshaler, config client.TxE
|
|||
// RegisterRESTRoutes does nothing. IBC does not support legacy REST routes.
|
||||
func (AppModuleBasic) RegisterRESTRoutes(client.Context, *mux.Router) {}
|
||||
|
||||
// RegisterGRPCRoutes registers the gRPC Gateway routes for the ibc module.
|
||||
func (a AppModuleBasic) RegisterGRPCRoutes(_ client.Context, _ *runtime.ServeMux) {
|
||||
}
|
||||
|
||||
// GetTxCmd returns the root tx command for the ibc module.
|
||||
func (AppModuleBasic) GetTxCmd() *cobra.Command {
|
||||
return cli.GetTxCmd()
|
||||
|
|
|
@ -7,6 +7,7 @@ import (
|
|||
|
||||
"github.com/gogo/protobuf/grpc"
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/grpc-ecosystem/grpc-gateway/runtime"
|
||||
"github.com/spf13/cobra"
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
|
||||
|
@ -68,6 +69,10 @@ func (AppModuleBasic) RegisterRESTRoutes(clientCtx client.Context, rtr *mux.Rout
|
|||
rest.RegisterRoutes(clientCtx, rtr)
|
||||
}
|
||||
|
||||
// RegisterGRPCRoutes registers the gRPC Gateway routes for the mint module.
|
||||
func (AppModuleBasic) RegisterGRPCRoutes(_ client.Context, _ *runtime.ServeMux) {
|
||||
}
|
||||
|
||||
// GetTxCmd returns no root tx command for the mint module.
|
||||
func (AppModuleBasic) GetTxCmd() *cobra.Command { return nil }
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
"math/rand"
|
||||
|
||||
"github.com/gogo/protobuf/grpc"
|
||||
"github.com/grpc-ecosystem/grpc-gateway/runtime"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/spf13/cobra"
|
||||
|
@ -54,6 +55,9 @@ func (AppModuleBasic) ValidateGenesis(_ codec.JSONMarshaler, config client.TxEnc
|
|||
// RegisterRESTRoutes registers the REST routes for the params module.
|
||||
func (AppModuleBasic) RegisterRESTRoutes(_ client.Context, _ *mux.Router) {}
|
||||
|
||||
// RegisterGRPCRoutes registers the gRPC Gateway routes for the params module.
|
||||
func (AppModuleBasic) RegisterGRPCRoutes(_ client.Context, _ *runtime.ServeMux) {}
|
||||
|
||||
// GetTxCmd returns no root tx command for the params module.
|
||||
func (AppModuleBasic) GetTxCmd() *cobra.Command { return nil }
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
"math/rand"
|
||||
|
||||
"github.com/gogo/protobuf/grpc"
|
||||
"github.com/grpc-ecosystem/grpc-gateway/runtime"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/spf13/cobra"
|
||||
|
@ -75,6 +76,10 @@ func (AppModuleBasic) RegisterRESTRoutes(clientCtx client.Context, rtr *mux.Rout
|
|||
rest.RegisterHandlers(clientCtx, rtr)
|
||||
}
|
||||
|
||||
// RegisterGRPCRoutes registers the gRPC Gateway routes for the slashig module.
|
||||
func (AppModuleBasic) RegisterGRPCRoutes(_ client.Context, _ *runtime.ServeMux) {
|
||||
}
|
||||
|
||||
// GetTxCmd returns the root tx command for the slashing module.
|
||||
func (AppModuleBasic) GetTxCmd() *cobra.Command {
|
||||
return cli.NewTxCmd()
|
||||
|
|
|
@ -0,0 +1,101 @@
|
|||
package rest_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/suite"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/testutil"
|
||||
"github.com/cosmos/cosmos-sdk/testutil/network"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
grpctypes "github.com/cosmos/cosmos-sdk/types/grpc"
|
||||
"github.com/cosmos/cosmos-sdk/x/staking/types"
|
||||
)
|
||||
|
||||
type IntegrationTestSuite struct {
|
||||
suite.Suite
|
||||
|
||||
cfg network.Config
|
||||
network *network.Network
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) SetupSuite() {
|
||||
s.T().Log("setting up integration test suite")
|
||||
|
||||
cfg := network.DefaultConfig()
|
||||
cfg.NumValidators = 1
|
||||
|
||||
s.cfg = cfg
|
||||
s.network = network.New(s.T(), cfg)
|
||||
|
||||
_, err := s.network.WaitForHeight(1)
|
||||
s.Require().NoError(err)
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) TearDownSuite() {
|
||||
s.T().Log("tearing down integration test suite")
|
||||
s.network.Cleanup()
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) TestQueryValidatorsGRPCHandler() {
|
||||
val := s.network.Validators[0]
|
||||
baseURL := val.APIAddress
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
url string
|
||||
headers map[string]string
|
||||
error bool
|
||||
}{
|
||||
{
|
||||
"test query validators gRPC route with invalid status",
|
||||
fmt.Sprintf("%s/cosmos/staking/v1beta1/validators?status=active", baseURL),
|
||||
map[string]string{
|
||||
grpctypes.GRPCBlockHeightHeader: "1",
|
||||
},
|
||||
true,
|
||||
},
|
||||
{
|
||||
"test query validators gRPC route without status query param",
|
||||
fmt.Sprintf("%s/cosmos/staking/v1beta1/validators", baseURL),
|
||||
map[string]string{
|
||||
grpctypes.GRPCBlockHeightHeader: "1",
|
||||
},
|
||||
true,
|
||||
},
|
||||
{
|
||||
"test query validators gRPC route with valid status",
|
||||
fmt.Sprintf("%s/cosmos/staking/v1beta1/validators?status=%s", baseURL, sdk.Bonded.String()),
|
||||
map[string]string{
|
||||
grpctypes.GRPCBlockHeightHeader: "1",
|
||||
},
|
||||
false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
tc := tc
|
||||
s.Run(tc.name, func() {
|
||||
resp, err := testutil.GetRequestWithHeaders(tc.url, tc.headers)
|
||||
s.Require().NoError(err)
|
||||
|
||||
var valRes types.QueryValidatorsResponse
|
||||
err = val.ClientCtx.JSONMarshaler.UnmarshalJSON(resp, &valRes)
|
||||
|
||||
if tc.error {
|
||||
s.Require().Error(err)
|
||||
s.Require().Nil(valRes.Validators)
|
||||
s.Require().Equal(0, len(valRes.Validators))
|
||||
} else {
|
||||
s.Require().NoError(err)
|
||||
s.Require().NotNil(valRes.Validators)
|
||||
s.Require().Equal(len(s.network.Validators), len(valRes.Validators))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestIntegrationTestSuite(t *testing.T) {
|
||||
suite.Run(t, new(IntegrationTestSuite))
|
||||
}
|
|
@ -1,11 +1,13 @@
|
|||
package staking
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
|
||||
"github.com/gogo/protobuf/grpc"
|
||||
"github.com/grpc-ecosystem/grpc-gateway/runtime"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/spf13/cobra"
|
||||
|
@ -73,6 +75,11 @@ func (AppModuleBasic) RegisterRESTRoutes(clientCtx client.Context, rtr *mux.Rout
|
|||
rest.RegisterHandlers(clientCtx, rtr)
|
||||
}
|
||||
|
||||
// RegisterGRPCRoutes registers the gRPC Gateway routes for the staking module.
|
||||
func (AppModuleBasic) RegisterGRPCRoutes(clientCtx client.Context, mux *runtime.ServeMux) {
|
||||
types.RegisterQueryHandlerClient(context.Background(), mux, types.NewQueryClient(clientCtx))
|
||||
}
|
||||
|
||||
// GetTxCmd returns the root tx command for the staking module.
|
||||
func (AppModuleBasic) GetTxCmd() *cobra.Command {
|
||||
return cli.NewTxCmd()
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"encoding/json"
|
||||
|
||||
"github.com/gogo/protobuf/grpc"
|
||||
"github.com/grpc-ecosystem/grpc-gateway/runtime"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/spf13/cobra"
|
||||
|
@ -51,6 +52,9 @@ func (AppModuleBasic) RegisterRESTRoutes(clientCtx client.Context, r *mux.Router
|
|||
rest.RegisterRoutes(clientCtx, r)
|
||||
}
|
||||
|
||||
// RegisterGRPCRoutes registers the gRPC Gateway routes for the upgrade module.
|
||||
func (AppModuleBasic) RegisterGRPCRoutes(_ client.Context, _ *runtime.ServeMux) {}
|
||||
|
||||
// GetQueryCmd returns the cli query commands for this module
|
||||
func (AppModuleBasic) GetQueryCmd() *cobra.Command {
|
||||
return cli.GetQueryCmd()
|
||||
|
|
Loading…
Reference in New Issue