Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

fix: remove grpc replace directive #11089

Merged
merged 20 commits into from
Feb 4, 2022
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions baseapp/baseapp_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1793,6 +1793,7 @@ func TestGRPCQuery(t *testing.T) {
}

app := setupBaseApp(t, grpcQueryOpt)
app.GRPCQueryRouter().SetInterfaceRegistry(codectypes.NewInterfaceRegistry())

app.InitChain(abci.RequestInitChain{})
header := tmproto.Header{Height: app.LastBlockHeight() + 1}
Expand Down
22 changes: 9 additions & 13 deletions baseapp/grpcrouter.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,24 @@ package baseapp

import (
"fmt"
"github.com/cosmos/cosmos-sdk/codec"
"google.golang.org/grpc/encoding"

"github.com/cosmos/cosmos-sdk/client/grpc/reflection"

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"

codectypes "github.com/cosmos/cosmos-sdk/codec/types"
sdk "github.com/cosmos/cosmos-sdk/types"
)

var protoCodec = encoding.GetCodec(proto.Name)

// GRPCQueryRouter routes ABCI Query requests to GRPC handlers
type GRPCQueryRouter struct {
routes map[string]GRPCQueryHandler
interfaceRegistry codectypes.InterfaceRegistry
serviceData []serviceData
routes map[string]GRPCQueryHandler
cdc encoding.Codec
serviceData []serviceData
}

// serviceData represents a gRPC service, along with its handler.
Expand Down Expand Up @@ -83,21 +81,18 @@ func (qrt *GRPCQueryRouter) RegisterService(sd *grpc.ServiceDesc, handler interf
// 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 {
err := protoCodec.Unmarshal(req.Data, i)
err := qrt.cdc.Unmarshal(req.Data, i)
if err != nil {
return err
}
if qrt.interfaceRegistry != nil {
return codectypes.UnpackInterfaces(i, qrt.interfaceRegistry)
}
return nil
}, nil)
if err != nil {
return abci.ResponseQuery{}, err
}

// proto marshal the result bytes
resBytes, err := protoCodec.Marshal(res)
resBytes, err := qrt.cdc.Marshal(res)
if err != nil {
return abci.ResponseQuery{}, err
}
Expand All @@ -119,7 +114,8 @@ func (qrt *GRPCQueryRouter) RegisterService(sd *grpc.ServiceDesc, handler interf
// SetInterfaceRegistry sets the interface registry for the router. This will
// also register the interface reflection gRPC service.
func (qrt *GRPCQueryRouter) SetInterfaceRegistry(interfaceRegistry codectypes.InterfaceRegistry) {
qrt.interfaceRegistry = interfaceRegistry
// instantiate the codec
qrt.cdc = codec.NewProtoCodec(interfaceRegistry).GRPCCodec()
// Once we have an interface registry, we can register the interface
// registry reflection gRPC service.
reflection.RegisterReflectionServiceServer(
Expand Down
8 changes: 2 additions & 6 deletions baseapp/grpcrouter_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ func (q *QueryServiceTestHelper) Invoke(_ gocontext.Context, method string, args
if querier == nil {
return fmt.Errorf("handler not found for %s", method)
}
reqBz, err := protoCodec.Marshal(args)
reqBz, err := q.cdc.Marshal(args)
if err != nil {
return err
}
Expand All @@ -50,15 +50,11 @@ func (q *QueryServiceTestHelper) Invoke(_ gocontext.Context, method string, args
return err
}

err = protoCodec.Unmarshal(res.Value, reply)
err = q.cdc.Unmarshal(res.Value, reply)
if err != nil {
return err
}

if q.interfaceRegistry != nil {
return types.UnpackInterfaces(reply, q.interfaceRegistry)
}

return nil
}

Expand Down
5 changes: 4 additions & 1 deletion client/config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package config_test
import (
"bytes"
"fmt"
"github.com/cosmos/cosmos-sdk/codec"
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
"io"
"os"
"testing"
Expand All @@ -27,7 +29,8 @@ func initClientContext(t *testing.T, envVar string) (client.Context, func()) {
home := t.TempDir()
clientCtx := client.Context{}.
WithHomeDir(home).
WithViper("")
WithViper("").
WithCodec(codec.NewProtoCodec(codectypes.NewInterfaceRegistry()))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

client.Context always expects a Codec (should we relax this?)

How would you relax it? Probably only WithInterfaceRegistry is required?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes given the interface registry we have our codec too.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As far as relaxing goes, we could default to the gogoproto marshaler (if no codec is specified) but IDK how it would behave with Interface unpacking (let's assume WithInterfaceRegistry was not called).

If it worked before with the default gRPC codec then I would assume it also would work this way.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

with orm landing I don't think we can default to gogoproto. I think the force is fine for a single release and but then most teams will have migrated anyways


clientCtx.Viper.BindEnv(nodeEnv)
if envVar != "" {
Expand Down
9 changes: 3 additions & 6 deletions client/grpc_query.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,13 @@ package client
import (
gocontext "context"
"fmt"
"github.com/cosmos/cosmos-sdk/codec"
"reflect"
"strconv"

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"
"google.golang.org/grpc/metadata"

"github.com/cosmos/cosmos-sdk/codec/types"
Expand All @@ -21,8 +20,6 @@ import (

var _ gogogrpc.ClientConn = Context{}

var protoCodec = encoding.GetCodec(proto.Name)

// Invoke implements the grpc ClientConn.Invoke method
func (ctx Context) Invoke(grpcCtx gocontext.Context, method string, req, reply interface{}, opts ...grpc.CallOption) (err error) {
// Two things can happen here:
Expand Down Expand Up @@ -51,7 +48,7 @@ func (ctx Context) Invoke(grpcCtx gocontext.Context, method string, req, reply i
}

// Case 2. Querying state.
reqBz, err := protoCodec.Marshal(req)
reqBz, err := ctx.Codec.(*codec.ProtoCodec).GRPCCodec().Marshal(req)
if err != nil {
return err
}
Expand Down Expand Up @@ -83,7 +80,7 @@ func (ctx Context) Invoke(grpcCtx gocontext.Context, method string, req, reply i
return err
}

err = protoCodec.Unmarshal(res.Value, reply)
err = ctx.Codec.(*codec.ProtoCodec).GRPCCodec().Unmarshal(res.Value, reply)
if err != nil {
return err
}
Expand Down
59 changes: 50 additions & 9 deletions codec/proto_codec.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@ import (
"encoding/binary"
"errors"
"fmt"
legacyproto "github.com/golang/protobuf/proto"
"google.golang.org/grpc/encoding"
"strings"

"github.com/gogo/protobuf/jsonpb"
"github.com/gogo/protobuf/proto"

"github.com/cosmos/cosmos-sdk/codec/types"
"github.com/gogo/protobuf/jsonpb"
gogoproto "github.com/gogo/protobuf/proto"
)

// ProtoCodecMarshaler defines an interface for codecs that utilize Protobuf for both
Expand Down Expand Up @@ -126,7 +127,7 @@ func (pc *ProtoCodec) MustUnmarshalLengthPrefixed(bz []byte, ptr ProtoMarshaler)
// it marshals to JSON using proto codec.
// NOTE: this function must be used with a concrete type which
// implements proto.Message. For interface please use the codec.MarshalInterfaceJSON
func (pc *ProtoCodec) MarshalJSON(o proto.Message) ([]byte, error) {
func (pc *ProtoCodec) MarshalJSON(o gogoproto.Message) ([]byte, error) {
m, ok := o.(ProtoMarshaler)
if !ok {
return nil, fmt.Errorf("cannot protobuf JSON encode unsupported type: %T", o)
Expand All @@ -139,7 +140,7 @@ func (pc *ProtoCodec) MarshalJSON(o proto.Message) ([]byte, error) {
// it executes MarshalJSON except it panics upon failure.
// NOTE: this function must be used with a concrete type which
// implements proto.Message. For interface please use the codec.MarshalInterfaceJSON
func (pc *ProtoCodec) MustMarshalJSON(o proto.Message) []byte {
func (pc *ProtoCodec) MustMarshalJSON(o gogoproto.Message) []byte {
bz, err := pc.MarshalJSON(o)
if err != nil {
panic(err)
Expand All @@ -152,7 +153,7 @@ func (pc *ProtoCodec) MustMarshalJSON(o proto.Message) []byte {
// it unmarshals from JSON using proto codec.
// NOTE: this function must be used with a concrete type which
// implements proto.Message. For interface please use the codec.UnmarshalInterfaceJSON
func (pc *ProtoCodec) UnmarshalJSON(bz []byte, ptr proto.Message) error {
func (pc *ProtoCodec) UnmarshalJSON(bz []byte, ptr gogoproto.Message) error {
m, ok := ptr.(ProtoMarshaler)
if !ok {
return fmt.Errorf("cannot protobuf JSON decode unsupported type: %T", ptr)
Expand All @@ -171,7 +172,7 @@ func (pc *ProtoCodec) UnmarshalJSON(bz []byte, ptr proto.Message) error {
// it executes UnmarshalJSON except it panics upon failure.
// NOTE: this function must be used with a concrete type which
// implements proto.Message. For interface please use the codec.UnmarshalInterfaceJSON
func (pc *ProtoCodec) MustUnmarshalJSON(bz []byte, ptr proto.Message) {
func (pc *ProtoCodec) MustUnmarshalJSON(bz []byte, ptr gogoproto.Message) {
if err := pc.UnmarshalJSON(bz, ptr); err != nil {
panic(err)
}
Expand All @@ -180,7 +181,7 @@ func (pc *ProtoCodec) MustUnmarshalJSON(bz []byte, ptr proto.Message) {
// MarshalInterface is a convenience function for proto marshalling interfaces. It packs
// the provided value, which must be an interface, in an Any and then marshals it to bytes.
// NOTE: to marshal a concrete type, you should use Marshal instead
func (pc *ProtoCodec) MarshalInterface(i proto.Message) ([]byte, error) {
func (pc *ProtoCodec) MarshalInterface(i gogoproto.Message) ([]byte, error) {
if err := assertNotNil(i); err != nil {
return nil, err
}
Expand Down Expand Up @@ -213,7 +214,7 @@ func (pc *ProtoCodec) UnmarshalInterface(bz []byte, ptr interface{}) error {
// MarshalInterfaceJSON is a convenience function for proto marshalling interfaces. It
// packs the provided value in an Any and then marshals it to bytes.
// NOTE: to marshal a concrete type, you should use MarshalJSON instead
func (pc *ProtoCodec) MarshalInterfaceJSON(x proto.Message) ([]byte, error) {
func (pc *ProtoCodec) MarshalInterfaceJSON(x gogoproto.Message) ([]byte, error) {
any, err := types.NewAnyWithValue(x)
if err != nil {
return nil, err
Expand Down Expand Up @@ -250,6 +251,46 @@ func (pc *ProtoCodec) InterfaceRegistry() types.InterfaceRegistry {
return pc.interfaceRegistry
}

// GRPCCodec returns the gRPC Codec for this specific ProtoCodec
func (pc *ProtoCodec) GRPCCodec() encoding.Codec {
return &grpcProtoCodec{cdc: pc}
}

var errUnknownProtoType = errors.New("codec: unknown proto type") // sentinel error

// grpcProtoCodec is the implementation of the gRPC proto codec.
type grpcProtoCodec struct {
cdc *ProtoCodec
}

func (g grpcProtoCodec) Marshal(v interface{}) ([]byte, error) {
// TODO(fdymylja): maybe this is the correct place to support protov2 types too for gRPC
switch m := v.(type) {
case ProtoMarshaler:
return g.cdc.Marshal(m)
case legacyproto.Message:
return legacyproto.Marshal(m)
default:
return nil, fmt.Errorf("%w: cannot marshal type %T", errUnknownProtoType, v)
}
}

func (g grpcProtoCodec) Unmarshal(data []byte, v interface{}) error {
// TODO(fdymylja): maybe this is the correct place to support protov2 types too for gRPC
switch m := v.(type) {
case ProtoMarshaler:
return g.cdc.Unmarshal(data, m)
case legacyproto.Message:
return legacyproto.Unmarshal(data, m)
default:
return fmt.Errorf("%w: cannot unmarshal type %T", errUnknownProtoType, v)
}
}

func (g grpcProtoCodec) Name() string {
return "cosmos-sdk-grpc-codec"
}

func assertNotNil(i interface{}) error {
if i == nil {
return errors.New("can't marshal <nil> value")
Expand Down
1 change: 0 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,6 @@ require (

// latest grpc doesn't work with with our modified proto compiler, so we need to enforce
// the following version across all dependencies.
fdymylja marked this conversation as resolved.
Show resolved Hide resolved
replace google.golang.org/grpc => google.golang.org/grpc v1.33.2

replace github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1

Expand Down
Loading