cosmos-sdk/types/msgservice/msg_service.go

74 lines
1.9 KiB
Go

package msgservice
import (
"bytes"
"compress/gzip"
"fmt"
"io/ioutil"
"reflect"
"github.com/gogo/protobuf/proto"
"google.golang.org/grpc"
proto2 "google.golang.org/protobuf/proto"
"google.golang.org/protobuf/reflect/protodesc"
"google.golang.org/protobuf/reflect/protoreflect"
"google.golang.org/protobuf/types/descriptorpb"
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/tx"
)
// RegisterMsgServiceDesc registers all type_urls from Msg services described
// in `sd` into the registry.
func RegisterMsgServiceDesc(registry codectypes.InterfaceRegistry, sd *grpc.ServiceDesc) {
fdBytesUnzipped := unzip(proto.FileDescriptor(sd.Metadata.(string)))
if fdBytesUnzipped == nil {
panic(fmt.Errorf("error unzipping file description for MsgService %s", sd.ServiceName))
}
fdRaw := &descriptorpb.FileDescriptorProto{}
err := proto2.Unmarshal(fdBytesUnzipped, fdRaw)
if err != nil {
panic(err)
}
fd, err := protodesc.FileOptions{
AllowUnresolvable: true,
}.New(fdRaw, nil)
if err != nil {
panic(err)
}
prefSd := fd.Services().ByName(protoreflect.FullName(sd.ServiceName).Name())
for i := 0; i < prefSd.Methods().Len(); i++ {
md := prefSd.Methods().Get(i)
requestDesc := md.Input()
responseDesc := md.Output()
reqTyp := proto.MessageType(string(requestDesc.FullName()))
respTyp := proto.MessageType(string(responseDesc.FullName()))
// Register sdk.Msg and sdk.MsgResponse to the registry.
registry.RegisterImplementations((*sdk.Msg)(nil), reflect.New(reqTyp).Elem().Interface().(proto.Message))
registry.RegisterImplementations((*tx.MsgResponse)(nil), reflect.New(respTyp).Elem().Interface().(proto.Message))
}
}
func unzip(b []byte) []byte {
if b == nil {
return nil
}
r, err := gzip.NewReader(bytes.NewReader(b))
if err != nil {
panic(err)
}
unzipped, err := ioutil.ReadAll(r)
if err != nil {
panic(err)
}
return unzipped
}