refactor(x/tx): use dynamicpb instead of type resolver in any marshal (#16048)
Co-authored-by: Aaron Craelius <aaron@regen.network>
This commit is contained in:
co-authored by
Aaron Craelius
parent
12923c33ed
commit
2f21cb5050
@@ -11,8 +11,12 @@ import (
|
||||
gogoproto "github.com/cosmos/gogoproto/proto"
|
||||
"google.golang.org/grpc/encoding"
|
||||
"google.golang.org/protobuf/proto"
|
||||
"google.golang.org/protobuf/reflect/protoreflect"
|
||||
"google.golang.org/protobuf/reflect/protoregistry"
|
||||
"google.golang.org/protobuf/types/dynamicpb"
|
||||
"google.golang.org/protobuf/types/known/anypb"
|
||||
|
||||
"cosmossdk.io/x/tx/signing/aminojson"
|
||||
"github.com/cosmos/cosmos-sdk/codec/types"
|
||||
)
|
||||
|
||||
@@ -160,6 +164,41 @@ func (pc *ProtoCodec) MustMarshalJSON(o gogoproto.Message) []byte {
|
||||
return bz
|
||||
}
|
||||
|
||||
// MarshalAminoJSON provides aminojson.Encoder compatibility for gogoproto messages.
|
||||
// x/tx/signing/aminojson cannot marshal gogoproto messages directly since this type does not implement
|
||||
// the standard library google.golang.org/protobuf/proto.Message.
|
||||
// We convert gogo types to dynamicpb messages and then marshal that directly to amino JSON.
|
||||
func (pc *ProtoCodec) MarshalAminoJSON(msg gogoproto.Message) ([]byte, error) {
|
||||
encoder := aminojson.NewEncoder(aminojson.EncoderOptions{FileResolver: pc.interfaceRegistry})
|
||||
gogoBytes, err := gogoproto.Marshal(msg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var protoMsg protoreflect.ProtoMessage
|
||||
typ, err := protoregistry.GlobalTypes.FindMessageByURL(fmt.Sprintf("/%s", gogoproto.MessageName(msg)))
|
||||
if typ != nil && err != nil {
|
||||
protoMsg = typ.New().Interface()
|
||||
} else {
|
||||
desc, err := pc.interfaceRegistry.FindDescriptorByName(protoreflect.FullName(gogoproto.MessageName(msg)))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
dynamicMsgType := dynamicpb.NewMessageType(desc.(protoreflect.MessageDescriptor))
|
||||
protoMsg = dynamicMsgType.New().Interface()
|
||||
}
|
||||
|
||||
err = proto.Unmarshal(gogoBytes, protoMsg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
jsonBytes, err := encoder.Marshal(protoMsg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return jsonBytes, nil
|
||||
}
|
||||
|
||||
// UnmarshalJSON implements JSONCodec.UnmarshalJSON method,
|
||||
// it unmarshals from JSON using proto codec.
|
||||
// NOTE: this function must be used with a concrete type which
|
||||
|
||||
Reference in New Issue
Block a user