From e94b6736ed437a8011ecf9cf93a48f7d0967292e Mon Sep 17 00:00:00 2001 From: Aaron Craelius Date: Wed, 3 Jun 2020 09:33:51 -0400 Subject: [PATCH] Merge PR #6325: Add GRPCRouter --- baseapp/grpcrouter.go | 76 +++ baseapp/grpcrouter_helpers.go | 53 +++ baseapp/grpcrouter_test.go | 49 ++ codec/testdata/proto.pb.go | 861 +++++++++++++++++++++++++++++++++- codec/testdata/proto.proto | 21 + go.mod | 3 +- go.sum | 12 +- scripts/protocgen.sh | 2 +- types/context.go | 19 + types/context_test.go | 12 + 10 files changed, 1079 insertions(+), 29 deletions(-) create mode 100644 baseapp/grpcrouter.go create mode 100644 baseapp/grpcrouter_helpers.go create mode 100644 baseapp/grpcrouter_test.go diff --git a/baseapp/grpcrouter.go b/baseapp/grpcrouter.go new file mode 100644 index 0000000000..8036942ad0 --- /dev/null +++ b/baseapp/grpcrouter.go @@ -0,0 +1,76 @@ +package baseapp + +import ( + "fmt" + + gogogrpc "github.com/gogo/protobuf/grpc" + abci "github.com/tendermint/tendermint/abci/types" + "google.golang.org/grpc" + "google.golang.org/grpc/encoding" + "google.golang.org/grpc/encoding/proto" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +var protoCodec = encoding.GetCodec(proto.Name) + +// GRPCRouter routes ABCI Query requests to GRPC handlers +type GRPCRouter struct { + routes map[string]GRPCQueryHandler +} + +var _ gogogrpc.Server + +// NewGRPCRouter creates a new GRPCRouter +func NewGRPCRouter() *GRPCRouter { + return &GRPCRouter{ + routes: map[string]GRPCQueryHandler{}, + } +} + +// GRPCQueryHandler defines a function type which handles ABCI Query requests +// using gRPC +type GRPCQueryHandler = func(ctx sdk.Context, req abci.RequestQuery) (abci.ResponseQuery, error) + +// Route returns the GRPCQueryHandler for a given query route path or nil +// if not found +func (qrt *GRPCRouter) Route(path string) GRPCQueryHandler { + handler, found := qrt.routes[path] + if !found { + return nil + } + return handler +} + +// RegisterService implements the gRPC Server.RegisterService method. sd is a gRPC +// service description, handler is an object which implements that gRPC service +func (qrt *GRPCRouter) RegisterService(sd *grpc.ServiceDesc, handler interface{}) { + // adds a top-level query handler based on the gRPC service name + for _, method := range sd.Methods { + fqName := fmt.Sprintf("/%s/%s", sd.ServiceName, method.MethodName) + methodHandler := method.Handler + + qrt.routes[fqName] = func(ctx sdk.Context, req abci.RequestQuery) (abci.ResponseQuery, error) { + // call the method handler from the service description with the handler object, + // a wrapped sdk.Context with proto-unmarshaled data from the ABCI request data + res, err := methodHandler(handler, sdk.WrapSDKContext(ctx), func(i interface{}) error { + return protoCodec.Unmarshal(req.Data, i) + }, nil) + if err != nil { + return abci.ResponseQuery{}, err + } + + // proto marshal the result bytes + resBytes, err := protoCodec.Marshal(res) + if err != nil { + return abci.ResponseQuery{}, err + } + + // return the result bytes as the response value + return abci.ResponseQuery{ + Height: req.Height, + Value: resBytes, + }, nil + } + } +} diff --git a/baseapp/grpcrouter_helpers.go b/baseapp/grpcrouter_helpers.go new file mode 100644 index 0000000000..efe88bb87a --- /dev/null +++ b/baseapp/grpcrouter_helpers.go @@ -0,0 +1,53 @@ +package baseapp + +import ( + gocontext "context" + "fmt" + + gogogrpc "github.com/gogo/protobuf/grpc" + abci "github.com/tendermint/tendermint/abci/types" + "google.golang.org/grpc" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// QueryServiceTestHelper provides a helper for making grpc query service +// rpc calls in unit tests. It implements both the grpc Server and ClientConn +// interfaces needed to register a query service server and create a query +// service client. +type QueryServiceTestHelper struct { + *GRPCRouter + ctx sdk.Context +} + +// NewQueryServerTestHelper creates a new QueryServiceTestHelper that wraps +// the provided sdk.Context +func NewQueryServerTestHelper(ctx sdk.Context) *QueryServiceTestHelper { + return &QueryServiceTestHelper{GRPCRouter: NewGRPCRouter(), ctx: ctx} +} + +// Invoke implements the grpc ClientConn.Invoke method +func (q *QueryServiceTestHelper) Invoke(_ gocontext.Context, method string, args, reply interface{}, _ ...grpc.CallOption) error { + querier := q.Route(method) + if querier == nil { + return fmt.Errorf("handler not found for %s", method) + } + reqBz, err := protoCodec.Marshal(args) + if err != nil { + return err + } + res, err := querier(q.ctx, abci.RequestQuery{Data: reqBz}) + + if err != nil { + return err + } + return protoCodec.Unmarshal(res.Value, reply) +} + +// NewStream implements the grpc ClientConn.NewStream method +func (q *QueryServiceTestHelper) NewStream(gocontext.Context, *grpc.StreamDesc, string, ...grpc.CallOption) (grpc.ClientStream, error) { + return nil, fmt.Errorf("not supported") +} + +var _ gogogrpc.Server = &QueryServiceTestHelper{} +var _ gogogrpc.ClientConn = &QueryServiceTestHelper{} diff --git a/baseapp/grpcrouter_test.go b/baseapp/grpcrouter_test.go new file mode 100644 index 0000000000..0db3e9c51d --- /dev/null +++ b/baseapp/grpcrouter_test.go @@ -0,0 +1,49 @@ +package baseapp + +import ( + "context" + "fmt" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/cosmos/cosmos-sdk/codec/testdata" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +type testServer struct{} + +func (e testServer) Echo(_ context.Context, req *testdata.EchoRequest) (*testdata.EchoResponse, error) { + return &testdata.EchoResponse{Message: req.Message}, nil +} + +func (e testServer) SayHello(_ context.Context, request *testdata.SayHelloRequest) (*testdata.SayHelloResponse, error) { + greeting := fmt.Sprintf("Hello %s!", request.Name) + return &testdata.SayHelloResponse{Greeting: greeting}, nil +} + +var _ testdata.TestServiceServer = testServer{} + +func TestGRPCRouter(t *testing.T) { + qr := NewGRPCRouter() + testdata.RegisterTestServiceServer(qr, testServer{}) + helper := &QueryServiceTestHelper{ + GRPCRouter: qr, + ctx: sdk.Context{}, + } + client := testdata.NewTestServiceClient(helper) + + res, err := client.Echo(context.Background(), &testdata.EchoRequest{Message: "hello"}) + require.Nil(t, err) + require.NotNil(t, res) + require.Equal(t, "hello", res.Message) + + require.Panics(t, func() { + _, _ = client.Echo(context.Background(), nil) + }) + + res2, err := client.SayHello(context.Background(), &testdata.SayHelloRequest{Name: "Foo"}) + require.Nil(t, err) + require.NotNil(t, res) + require.Equal(t, "Hello Foo!", res2.Greeting) +} diff --git a/codec/testdata/proto.pb.go b/codec/testdata/proto.pb.go index 8250f11e40..458fc7987b 100644 --- a/codec/testdata/proto.pb.go +++ b/codec/testdata/proto.pb.go @@ -4,9 +4,14 @@ package testdata import ( + context "context" fmt "fmt" types "github.com/cosmos/cosmos-sdk/codec/types" + grpc1 "github.com/gogo/protobuf/grpc" proto "github.com/gogo/protobuf/proto" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" io "io" math "math" math_bits "math/bits" @@ -267,37 +272,341 @@ func (m *HasHasHasAnimal) GetHasHasAnimal() *types.Any { return nil } +type EchoRequest struct { + Message string `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"` +} + +func (m *EchoRequest) Reset() { *m = EchoRequest{} } +func (m *EchoRequest) String() string { return proto.CompactTextString(m) } +func (*EchoRequest) ProtoMessage() {} +func (*EchoRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_ae1353846770e6e2, []int{5} +} +func (m *EchoRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *EchoRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_EchoRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *EchoRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_EchoRequest.Merge(m, src) +} +func (m *EchoRequest) XXX_Size() int { + return m.Size() +} +func (m *EchoRequest) XXX_DiscardUnknown() { + xxx_messageInfo_EchoRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_EchoRequest proto.InternalMessageInfo + +func (m *EchoRequest) GetMessage() string { + if m != nil { + return m.Message + } + return "" +} + +type EchoResponse struct { + Message string `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"` +} + +func (m *EchoResponse) Reset() { *m = EchoResponse{} } +func (m *EchoResponse) String() string { return proto.CompactTextString(m) } +func (*EchoResponse) ProtoMessage() {} +func (*EchoResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_ae1353846770e6e2, []int{6} +} +func (m *EchoResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *EchoResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_EchoResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *EchoResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_EchoResponse.Merge(m, src) +} +func (m *EchoResponse) XXX_Size() int { + return m.Size() +} +func (m *EchoResponse) XXX_DiscardUnknown() { + xxx_messageInfo_EchoResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_EchoResponse proto.InternalMessageInfo + +func (m *EchoResponse) GetMessage() string { + if m != nil { + return m.Message + } + return "" +} + +type SayHelloRequest struct { + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` +} + +func (m *SayHelloRequest) Reset() { *m = SayHelloRequest{} } +func (m *SayHelloRequest) String() string { return proto.CompactTextString(m) } +func (*SayHelloRequest) ProtoMessage() {} +func (*SayHelloRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_ae1353846770e6e2, []int{7} +} +func (m *SayHelloRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *SayHelloRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_SayHelloRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *SayHelloRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_SayHelloRequest.Merge(m, src) +} +func (m *SayHelloRequest) XXX_Size() int { + return m.Size() +} +func (m *SayHelloRequest) XXX_DiscardUnknown() { + xxx_messageInfo_SayHelloRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_SayHelloRequest proto.InternalMessageInfo + +func (m *SayHelloRequest) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +type SayHelloResponse struct { + Greeting string `protobuf:"bytes,1,opt,name=greeting,proto3" json:"greeting,omitempty"` +} + +func (m *SayHelloResponse) Reset() { *m = SayHelloResponse{} } +func (m *SayHelloResponse) String() string { return proto.CompactTextString(m) } +func (*SayHelloResponse) ProtoMessage() {} +func (*SayHelloResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_ae1353846770e6e2, []int{8} +} +func (m *SayHelloResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *SayHelloResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_SayHelloResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *SayHelloResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_SayHelloResponse.Merge(m, src) +} +func (m *SayHelloResponse) XXX_Size() int { + return m.Size() +} +func (m *SayHelloResponse) XXX_DiscardUnknown() { + xxx_messageInfo_SayHelloResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_SayHelloResponse proto.InternalMessageInfo + +func (m *SayHelloResponse) GetGreeting() string { + if m != nil { + return m.Greeting + } + return "" +} + func init() { proto.RegisterType((*Dog)(nil), "cosmos_sdk.codec.v1.Dog") proto.RegisterType((*Cat)(nil), "cosmos_sdk.codec.v1.Cat") proto.RegisterType((*HasAnimal)(nil), "cosmos_sdk.codec.v1.HasAnimal") proto.RegisterType((*HasHasAnimal)(nil), "cosmos_sdk.codec.v1.HasHasAnimal") proto.RegisterType((*HasHasHasAnimal)(nil), "cosmos_sdk.codec.v1.HasHasHasAnimal") + proto.RegisterType((*EchoRequest)(nil), "cosmos_sdk.codec.v1.EchoRequest") + proto.RegisterType((*EchoResponse)(nil), "cosmos_sdk.codec.v1.EchoResponse") + proto.RegisterType((*SayHelloRequest)(nil), "cosmos_sdk.codec.v1.SayHelloRequest") + proto.RegisterType((*SayHelloResponse)(nil), "cosmos_sdk.codec.v1.SayHelloResponse") } func init() { proto.RegisterFile("codec/testdata/proto.proto", fileDescriptor_ae1353846770e6e2) } var fileDescriptor_ae1353846770e6e2 = []byte{ - // 304 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x91, 0xbf, 0x4e, 0xc3, 0x30, - 0x10, 0xc6, 0x6b, 0x4a, 0x8b, 0x7a, 0x54, 0x20, 0x99, 0x0e, 0xa1, 0x83, 0x85, 0x32, 0x21, 0x41, - 0x1d, 0x41, 0xc5, 0xc2, 0x56, 0x0a, 0xa2, 0x0b, 0x4b, 0x46, 0x96, 0xca, 0x49, 0x4c, 0x12, 0xe5, - 0x8f, 0x51, 0xed, 0x56, 0x2d, 0x4f, 0xc1, 0x63, 0x31, 0x76, 0x64, 0x44, 0xc9, 0x8b, 0xa0, 0xd8, - 0x89, 0x0a, 0x5b, 0x17, 0xfb, 0xbb, 0xd3, 0xf7, 0xfd, 0xee, 0xa4, 0x83, 0xa1, 0x2f, 0x02, 0xee, - 0x3b, 0x8a, 0x4b, 0x15, 0x30, 0xc5, 0x9c, 0xf7, 0x85, 0x50, 0x82, 0xea, 0x17, 0x9f, 0xf9, 0x42, - 0x66, 0x42, 0xce, 0x65, 0x90, 0x50, 0x6d, 0xa3, 0xab, 0x9b, 0xe1, 0x79, 0x28, 0x44, 0x98, 0x72, - 0x63, 0xf4, 0x96, 0x6f, 0x0e, 0xcb, 0x37, 0xc6, 0x6f, 0x8f, 0xa0, 0xfd, 0x28, 0x42, 0x8c, 0xe1, - 0x50, 0xc6, 0x1f, 0xdc, 0x42, 0x17, 0xe8, 0xb2, 0xe7, 0x6a, 0x5d, 0xf5, 0x72, 0x96, 0x71, 0xeb, - 0xc0, 0xf4, 0x2a, 0x6d, 0xdf, 0x41, 0x7b, 0xca, 0x14, 0xb6, 0xe0, 0x28, 0x13, 0x79, 0x9c, 0xf0, - 0x45, 0x9d, 0x68, 0x4a, 0x3c, 0x80, 0x4e, 0x1a, 0xaf, 0xb8, 0xd4, 0xa9, 0x8e, 0x6b, 0x0a, 0xfb, - 0x19, 0x7a, 0x33, 0x26, 0x27, 0x79, 0x9c, 0xb1, 0x14, 0x5f, 0x43, 0x97, 0x69, 0xa5, 0xb3, 0xc7, - 0xb7, 0x03, 0x6a, 0xd6, 0xa3, 0xcd, 0x7a, 0x74, 0x92, 0x6f, 0xdc, 0xda, 0x83, 0xfb, 0x80, 0xd6, - 0x1a, 0xd6, 0x76, 0xd1, 0xda, 0x9e, 0x42, 0x7f, 0xc6, 0xe4, 0x8e, 0x35, 0x06, 0x88, 0x98, 0x9c, - 0xef, 0xc1, 0xeb, 0x45, 0x4d, 0xc8, 0x7e, 0x81, 0x53, 0x03, 0xd9, 0x71, 0xee, 0xe1, 0xa4, 0xe2, - 0xec, 0xc9, 0xea, 0x47, 0x7f, 0xb2, 0x0f, 0x4f, 0x5f, 0x05, 0x41, 0xdb, 0x82, 0xa0, 0x9f, 0x82, - 0xa0, 0xcf, 0x92, 0xb4, 0xb6, 0x25, 0x69, 0x7d, 0x97, 0xa4, 0xf5, 0x7a, 0x15, 0xc6, 0x2a, 0x5a, - 0x7a, 0xd4, 0x17, 0x99, 0x63, 0xee, 0x52, 0x7f, 0x23, 0x19, 0x24, 0xce, 0xff, 0x2b, 0x7a, 0x5d, - 0x3d, 0x62, 0xfc, 0x1b, 0x00, 0x00, 0xff, 0xff, 0x65, 0xc6, 0xd8, 0xe9, 0xde, 0x01, 0x00, 0x00, + // 429 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x93, 0xc1, 0x6e, 0xd3, 0x40, + 0x10, 0x40, 0xb3, 0xa4, 0x2d, 0xcd, 0xc4, 0xa2, 0x68, 0xe9, 0x21, 0xf8, 0x60, 0x15, 0x8b, 0x8a, + 0x4a, 0xd0, 0xb5, 0x68, 0xc5, 0x85, 0x5b, 0x29, 0x15, 0x91, 0x10, 0x17, 0x17, 0x09, 0x89, 0x4b, + 0xb5, 0xb1, 0x07, 0xdb, 0x8a, 0xed, 0x2d, 0x9e, 0x4d, 0xd4, 0xf0, 0x15, 0xfc, 0x0b, 0x3f, 0xc1, + 0xb1, 0x47, 0x8e, 0x28, 0xf9, 0x11, 0xe4, 0x5d, 0x3b, 0x09, 0xa8, 0x2a, 0xbd, 0xd8, 0x33, 0xab, + 0x37, 0xcf, 0xb3, 0x3b, 0x5e, 0x70, 0x23, 0x15, 0x63, 0x14, 0x68, 0x24, 0x1d, 0x4b, 0x2d, 0x83, + 0xcb, 0x4a, 0x69, 0x25, 0xcc, 0x93, 0x3f, 0x8a, 0x14, 0x15, 0x8a, 0x2e, 0x28, 0x1e, 0x0b, 0x83, + 0x89, 0xe9, 0x4b, 0xf7, 0x71, 0xa2, 0x54, 0x92, 0xa3, 0x05, 0x47, 0x93, 0x2f, 0x81, 0x2c, 0x67, + 0x96, 0xf7, 0x0f, 0xa1, 0xfb, 0x56, 0x25, 0x9c, 0xc3, 0x06, 0x65, 0xdf, 0x70, 0xc0, 0xf6, 0xd8, + 0x41, 0x2f, 0x34, 0x71, 0xbd, 0x56, 0xca, 0x02, 0x07, 0xf7, 0xec, 0x5a, 0x1d, 0xfb, 0xaf, 0xa0, + 0x7b, 0x2a, 0x35, 0x1f, 0xc0, 0xfd, 0x42, 0x95, 0xd9, 0x18, 0xab, 0xa6, 0xa2, 0x4d, 0xf9, 0x2e, + 0x6c, 0xe6, 0xd9, 0x14, 0xc9, 0x54, 0x6d, 0x86, 0x36, 0xf1, 0xdf, 0x41, 0x6f, 0x28, 0xe9, 0xa4, + 0xcc, 0x0a, 0x99, 0xf3, 0x17, 0xb0, 0x25, 0x4d, 0x64, 0x6a, 0xfb, 0x47, 0xbb, 0xc2, 0xb6, 0x27, + 0xda, 0xf6, 0xc4, 0x49, 0x39, 0x0b, 0x1b, 0x86, 0x3b, 0xc0, 0xae, 0x8c, 0xac, 0x1b, 0xb2, 0x2b, + 0xff, 0x14, 0x9c, 0xa1, 0xa4, 0x95, 0xeb, 0x18, 0x20, 0x95, 0x74, 0x71, 0x07, 0x5f, 0x2f, 0x6d, + 0x8b, 0xfc, 0x0f, 0xb0, 0x63, 0x25, 0x2b, 0xcf, 0x6b, 0x78, 0x50, 0x7b, 0xee, 0xe8, 0x72, 0xd2, + 0xb5, 0x5a, 0xff, 0x19, 0xf4, 0xcf, 0xa2, 0x54, 0x85, 0xf8, 0x75, 0x82, 0x64, 0xcf, 0x06, 0x89, + 0x64, 0x82, 0xcb, 0xb3, 0xb1, 0xa9, 0x7f, 0x00, 0x8e, 0x05, 0xe9, 0x52, 0x95, 0x84, 0xb7, 0x90, + 0xfb, 0xb0, 0x73, 0x2e, 0x67, 0x43, 0xcc, 0xf3, 0xa5, 0xb6, 0x9d, 0x06, 0x5b, 0x9b, 0x86, 0x80, + 0x87, 0x2b, 0xac, 0x91, 0xba, 0xb0, 0x9d, 0x54, 0x88, 0x3a, 0x2b, 0x93, 0x86, 0x5d, 0xe6, 0x47, + 0x3f, 0x18, 0xf4, 0x3f, 0x22, 0xe9, 0x73, 0xac, 0xa6, 0x59, 0x84, 0xfc, 0x3d, 0x6c, 0xd4, 0x0d, + 0xf1, 0x3d, 0x71, 0xc3, 0x5f, 0x23, 0xd6, 0x36, 0xe5, 0x3e, 0xb9, 0x85, 0x68, 0x3e, 0xfc, 0x09, + 0xb6, 0xdb, 0x66, 0xf8, 0xd3, 0x1b, 0xf1, 0x7f, 0xb6, 0xe4, 0xee, 0xff, 0x87, 0xb2, 0xe2, 0x37, + 0x67, 0x3f, 0xe7, 0x1e, 0xbb, 0x9e, 0x7b, 0xec, 0xf7, 0xdc, 0x63, 0xdf, 0x17, 0x5e, 0xe7, 0x7a, + 0xe1, 0x75, 0x7e, 0x2d, 0xbc, 0xce, 0xe7, 0xe7, 0x49, 0xa6, 0xd3, 0xc9, 0x48, 0x44, 0xaa, 0x08, + 0xac, 0xaa, 0x79, 0x1d, 0x52, 0x3c, 0x0e, 0xfe, 0xbe, 0x25, 0xa3, 0x2d, 0x33, 0xc2, 0xe3, 0x3f, + 0x01, 0x00, 0x00, 0xff, 0xff, 0xff, 0x4f, 0x91, 0x9b, 0x3e, 0x03, 0x00, 0x00, +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConn + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion4 + +// TestServiceClient is the client API for TestService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type TestServiceClient interface { + Echo(ctx context.Context, in *EchoRequest, opts ...grpc.CallOption) (*EchoResponse, error) + SayHello(ctx context.Context, in *SayHelloRequest, opts ...grpc.CallOption) (*SayHelloResponse, error) +} + +type testServiceClient struct { + cc grpc1.ClientConn +} + +func NewTestServiceClient(cc grpc1.ClientConn) TestServiceClient { + return &testServiceClient{cc} +} + +func (c *testServiceClient) Echo(ctx context.Context, in *EchoRequest, opts ...grpc.CallOption) (*EchoResponse, error) { + out := new(EchoResponse) + err := c.cc.Invoke(ctx, "/cosmos_sdk.codec.v1.TestService/Echo", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *testServiceClient) SayHello(ctx context.Context, in *SayHelloRequest, opts ...grpc.CallOption) (*SayHelloResponse, error) { + out := new(SayHelloResponse) + err := c.cc.Invoke(ctx, "/cosmos_sdk.codec.v1.TestService/SayHello", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// TestServiceServer is the server API for TestService service. +type TestServiceServer interface { + Echo(context.Context, *EchoRequest) (*EchoResponse, error) + SayHello(context.Context, *SayHelloRequest) (*SayHelloResponse, error) +} + +// UnimplementedTestServiceServer can be embedded to have forward compatible implementations. +type UnimplementedTestServiceServer struct { +} + +func (*UnimplementedTestServiceServer) Echo(ctx context.Context, req *EchoRequest) (*EchoResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Echo not implemented") +} +func (*UnimplementedTestServiceServer) SayHello(ctx context.Context, req *SayHelloRequest) (*SayHelloResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method SayHello not implemented") +} + +func RegisterTestServiceServer(s grpc1.Server, srv TestServiceServer) { + s.RegisterService(&_TestService_serviceDesc, srv) +} + +func _TestService_Echo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(EchoRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(TestServiceServer).Echo(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/cosmos_sdk.codec.v1.TestService/Echo", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(TestServiceServer).Echo(ctx, req.(*EchoRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _TestService_SayHello_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(SayHelloRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(TestServiceServer).SayHello(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/cosmos_sdk.codec.v1.TestService/SayHello", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(TestServiceServer).SayHello(ctx, req.(*SayHelloRequest)) + } + return interceptor(ctx, in, info, handler) +} + +var _TestService_serviceDesc = grpc.ServiceDesc{ + ServiceName: "cosmos_sdk.codec.v1.TestService", + HandlerType: (*TestServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "Echo", + Handler: _TestService_Echo_Handler, + }, + { + MethodName: "SayHello", + Handler: _TestService_SayHello_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "codec/testdata/proto.proto", } func (m *Dog) Marshal() (dAtA []byte, err error) { @@ -482,6 +791,126 @@ func (m *HasHasHasAnimal) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *EchoRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *EchoRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *EchoRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Message) > 0 { + i -= len(m.Message) + copy(dAtA[i:], m.Message) + i = encodeVarintProto(dAtA, i, uint64(len(m.Message))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *EchoResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *EchoResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *EchoResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Message) > 0 { + i -= len(m.Message) + copy(dAtA[i:], m.Message) + i = encodeVarintProto(dAtA, i, uint64(len(m.Message))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *SayHelloRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *SayHelloRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *SayHelloRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Name) > 0 { + i -= len(m.Name) + copy(dAtA[i:], m.Name) + i = encodeVarintProto(dAtA, i, uint64(len(m.Name))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *SayHelloResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *SayHelloResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *SayHelloResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Greeting) > 0 { + i -= len(m.Greeting) + copy(dAtA[i:], m.Greeting) + i = encodeVarintProto(dAtA, i, uint64(len(m.Greeting))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + func encodeVarintProto(dAtA []byte, offset int, v uint64) int { offset -= sovProto(v) base := offset @@ -568,6 +997,58 @@ func (m *HasHasHasAnimal) Size() (n int) { return n } +func (m *EchoRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Message) + if l > 0 { + n += 1 + l + sovProto(uint64(l)) + } + return n +} + +func (m *EchoResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Message) + if l > 0 { + n += 1 + l + sovProto(uint64(l)) + } + return n +} + +func (m *SayHelloRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Name) + if l > 0 { + n += 1 + l + sovProto(uint64(l)) + } + return n +} + +func (m *SayHelloResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Greeting) + if l > 0 { + n += 1 + l + sovProto(uint64(l)) + } + return n +} + func sovProto(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -1081,6 +1562,346 @@ func (m *HasHasHasAnimal) Unmarshal(dAtA []byte) error { } return nil } +func (m *EchoRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowProto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: EchoRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: EchoRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Message", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowProto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthProto + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthProto + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Message = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipProto(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthProto + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthProto + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *EchoResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowProto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: EchoResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: EchoResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Message", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowProto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthProto + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthProto + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Message = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipProto(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthProto + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthProto + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *SayHelloRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowProto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: SayHelloRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: SayHelloRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowProto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthProto + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthProto + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipProto(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthProto + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthProto + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *SayHelloResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowProto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: SayHelloResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: SayHelloResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Greeting", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowProto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthProto + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthProto + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Greeting = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipProto(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthProto + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthProto + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func skipProto(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 diff --git a/codec/testdata/proto.proto b/codec/testdata/proto.proto index 9316a5edee..f0b5f60a0e 100644 --- a/codec/testdata/proto.proto +++ b/codec/testdata/proto.proto @@ -27,3 +27,24 @@ message HasHasAnimal { message HasHasHasAnimal { google.protobuf.Any has_has_animal = 1; } + +service TestService { + rpc Echo(EchoRequest) returns (EchoResponse); + rpc SayHello(SayHelloRequest) returns (SayHelloResponse); +} + +message EchoRequest { + string message = 1; +} + +message EchoResponse { + string message = 1; +} + +message SayHelloRequest { + string name = 1; +} + +message SayHelloResponse { + string greeting = 1; +} diff --git a/go.mod b/go.mod index 05057cbdbf..0b01d98354 100644 --- a/go.mod +++ b/go.mod @@ -32,9 +32,10 @@ require ( github.com/tendermint/iavl v0.13.3 github.com/tendermint/tendermint v0.33.5 github.com/tendermint/tm-db v0.5.1 + google.golang.org/grpc v1.28.1 gopkg.in/yaml.v2 v2.3.0 ) -replace github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.2-alpha.regen.1 +replace github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.2-alpha.regen.4 go 1.14 diff --git a/go.sum b/go.sum index 507be717e0..75923b2dea 100644 --- a/go.sum +++ b/go.sum @@ -406,8 +406,8 @@ github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0 h1:MkV+77GLUNo github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/regen-network/cosmos-proto v0.3.0 h1:24dVpPrPi0GDoPVLesf2Ug98iK5QgVscPl0ga4Eoub0= github.com/regen-network/cosmos-proto v0.3.0/go.mod h1:zuP2jVPHab6+IIyOx3nXHFN+euFNeS3W8XQkcdd4s7A= -github.com/regen-network/protobuf v1.3.2-alpha.regen.1 h1:YdeZbBS0lG1D13COb7b57+nM/RGgIs8WF9DwitU6EBM= -github.com/regen-network/protobuf v1.3.2-alpha.regen.1/go.mod h1:lye6mqhOn/GCw1zRl3uPD5VP8rC+LPMyTyPAyQV872U= +github.com/regen-network/protobuf v1.3.2-alpha.regen.4 h1:c9jEnU+xm6vqyrQe3M94UFWqiXxRIKKnqBOh2EACmBE= +github.com/regen-network/protobuf v1.3.2-alpha.regen.4/go.mod h1:/J8/bR1T/NXyIdQDLUaq15LjNE83nRzkyrLAMcPewig= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik= @@ -563,8 +563,6 @@ golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553 h1:efeOvDhwQ29Dj3SdAV/MJf8oukgn+8D8WgaCaRMchF8= -golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e h1:3G+cUijn7XD+S4eJFddp53Pv7+slrESplyjG25HgL+k= golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -597,7 +595,6 @@ golang.org/x/sys v0.0.0-20190712062909-fae7ac547cb7/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200107162124-548cf772de50/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82 h1:ywK/j/KkyTHcdyYSZNXGjMwgmDSfjglYZ3vStQ/gSCU= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -662,8 +659,8 @@ google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98 google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200108215221-bd8f9a0ef82f h1:2wh8dWY8959cBGQvk1RD+/eQBgRYYDaZ+hT0/zsARoA= -google.golang.org/genproto v0.0.0-20200108215221-bd8f9a0ef82f/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200324203455-a04cca1dde73 h1:+yTMTeazSO5iBqU9NR53hgriivQQbYa5Uuaj8r3qKII= +google.golang.org/genproto v0.0.0-20200324203455-a04cca1dde73/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= 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.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= @@ -675,6 +672,7 @@ google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyac google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.28.0 h1:bO/TA4OxCOummhSf10siHuG7vJOiwh7SpRpFZDkOgl4= google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= diff --git a/scripts/protocgen.sh b/scripts/protocgen.sh index 5737b8aa8a..7f2e72c4d2 100755 --- a/scripts/protocgen.sh +++ b/scripts/protocgen.sh @@ -6,7 +6,7 @@ proto_dirs=$(find . -path ./third_party -prune -o -name '*.proto' -print0 | xarg for dir in $proto_dirs; do protoc \ -I. \ - --gocosmos_out=plugins=interfacetype,paths=source_relative,\ + --gocosmos_out=plugins=interfacetype+grpc,paths=source_relative,\ Mgoogle/protobuf/any.proto=github.com/cosmos/cosmos-sdk/codec/types:. \ $(find "${dir}" -maxdepth 1 -name '*.proto') done diff --git a/types/context.go b/types/context.go index ed4b693c97..71783023c4 100644 --- a/types/context.go +++ b/types/context.go @@ -225,3 +225,22 @@ func (c Context) CacheContext() (cc Context, writeCache func()) { cc = c.WithMultiStore(cms).WithEventManager(NewEventManager()) return cc, cms.Write } + +type sdkContextKeyType string + +const sdkContextKey sdkContextKeyType = "sdk-context" + +// WrapSDKContext returns a stdlib context.Context with the provided sdk.Context's internal +// context as a value. It is useful for passing an sdk.Context through methods that take a +// stdlib context.Context parameter such as generated gRPC methods. To get the original +// sdk.Context back, call UnwrapSDKContext. +func WrapSDKContext(ctx Context) context.Context { + return context.WithValue(ctx.ctx, sdkContextKey, ctx) +} + +// UnwrapSDKContext retrieves a Context from a context.Context instance +// attached with WrapSDKContext. It panics if a Context was not properly +// attached +func UnwrapSDKContext(ctx context.Context) Context { + return ctx.Value(sdkContextKey).(Context) +} diff --git a/types/context_test.go b/types/context_test.go index 97336badeb..a33fe65f64 100644 --- a/types/context_test.go +++ b/types/context_test.go @@ -231,3 +231,15 @@ func TestContextHeaderClone(t *testing.T) { }) } } + +func TestUnwrapSDKContext(t *testing.T) { + sdkCtx := types.NewContext(nil, abci.Header{}, false, nil) + ctx := types.WrapSDKContext(sdkCtx) + sdkCtx2 := types.UnwrapSDKContext(ctx) + require.Equal(t, sdkCtx, sdkCtx2) + + ctx = context.Background() + require.Panics(t, func() { + types.UnwrapSDKContext(ctx) + }) +}