Skip to content

Commit

Permalink
fix: deterministic protov2 marshal
Browse files Browse the repository at this point in the history
  • Loading branch information
julienrbrt committed Nov 7, 2023
1 parent 1e4d1f9 commit a1e491a
Show file tree
Hide file tree
Showing 8 changed files with 30 additions and 17 deletions.
9 changes: 5 additions & 4 deletions baseapp/internal/protocompat/protocompat.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@ import (
)

var (
gogoType = reflect.TypeOf((*gogoproto.Message)(nil)).Elem()
protov2Type = reflect.TypeOf((*proto2.Message)(nil)).Elem()
gogoType = reflect.TypeOf((*gogoproto.Message)(nil)).Elem()
protov2Type = reflect.TypeOf((*proto2.Message)(nil)).Elem()
protov2MarshalOpts = proto2.MarshalOptions{Deterministic: true}
)

type Handler = func(ctx context.Context, request, response protoiface.MessageV1) error
Expand Down Expand Up @@ -97,7 +98,7 @@ func makeProtoV2HybridHandler(prefMethod protoreflect.MethodDescriptor, cdc code
// the response is a protov2 message, so we cannot just return it.
// since the request came as gogoproto, we expect the response
// to also be gogoproto.
respBytes, err := proto2.Marshal(resp.(proto2.Message))
respBytes, err := protov2MarshalOpts.Marshal(resp.(proto2.Message))
if err != nil {
return err
}
Expand Down Expand Up @@ -138,7 +139,7 @@ func makeGogoHybridHandler(prefMethod protoreflect.MethodDescriptor, cdc codec.B
switch m := inReq.(type) {
case proto2.Message:
// we need to marshal and unmarshal the request.
requestBytes, err := proto2.Marshal(m)
requestBytes, err := protov2MarshalOpts.Marshal(m)
if err != nil {
return err
}
Expand Down
3 changes: 2 additions & 1 deletion codec/collections.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,8 @@ type collValue2[T any, PT protoMessageV2[T]] struct {
}

func (c collValue2[T, PT]) Encode(value PT) ([]byte, error) {
return protov2.Marshal(value)
protov2MarshalOpts := protov2.MarshalOptions{Deterministic: true}
return protov2MarshalOpts.Marshal(value)
}

func (c collValue2[T, PT]) Decode(b []byte) (PT, error) {
Expand Down
8 changes: 5 additions & 3 deletions codec/proto_codec.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,17 @@ type ProtoCodecMarshaler interface {
// ProtoCodec defines a codec that utilizes Protobuf for both binary and JSON
// encoding.
type ProtoCodec struct {
interfaceRegistry types.InterfaceRegistry
interfaceRegistry types.InterfaceRegistry
protov2MarshalOpts proto.MarshalOptions
}

var _ Codec = (*ProtoCodec)(nil)

// NewProtoCodec returns a reference to a new ProtoCodec
func NewProtoCodec(interfaceRegistry types.InterfaceRegistry) *ProtoCodec {
return &ProtoCodec{
interfaceRegistry: interfaceRegistry,
interfaceRegistry: interfaceRegistry,
protov2MarshalOpts: proto.MarshalOptions{Deterministic: true},
}
}

Expand Down Expand Up @@ -345,7 +347,7 @@ type grpcProtoCodec struct {
func (g grpcProtoCodec) Marshal(v interface{}) ([]byte, error) {
switch m := v.(type) {
case proto.Message:
return proto.Marshal(m)
return g.cdc.protov2MarshalOpts.Marshal(m)
case gogoproto.Message:
return g.cdc.Marshal(m)
default:
Expand Down
3 changes: 2 additions & 1 deletion codec/types/any.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,8 @@ func NewAnyWithValue(v proto.Message) (*Any, error) {
err error
)
if msg, ok := v.(protov2.Message); ok {
bz, err = protov2.Marshal(msg)
protov2MarshalOpts := protov2.MarshalOptions{Deterministic: true}
bz, err = protov2MarshalOpts.Marshal(msg)
} else {
bz, err = proto.Marshal(v)
}
Expand Down
9 changes: 6 additions & 3 deletions x/tx/signing/direct/direct.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ import (
"cosmossdk.io/x/tx/signing"
)

var (
_ signing.SignModeHandler = SignModeHandler{}
protov2MarshalOpts = proto.MarshalOptions{Deterministic: true}
)

// SignModeHandler is the SIGN_MODE_DIRECT implementation of signing.SignModeHandler.
type SignModeHandler struct{}

Expand All @@ -20,12 +25,10 @@ func (h SignModeHandler) Mode() signingv1beta1.SignMode {

// GetSignBytes implements signing.SignModeHandler.GetSignBytes.
func (SignModeHandler) GetSignBytes(_ context.Context, signerData signing.SignerData, txData signing.TxData) ([]byte, error) {
return proto.Marshal(&txv1beta1.SignDoc{
return protov2MarshalOpts.Marshal(&txv1beta1.SignDoc{
BodyBytes: txData.BodyBytes,
AuthInfoBytes: txData.AuthInfoBytes,
ChainId: signerData.ChainID,
AccountNumber: signerData.AccountNumber,
})
}

var _ signing.SignModeHandler = SignModeHandler{}
4 changes: 3 additions & 1 deletion x/tx/signing/directaux/direct_aux.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,5 +101,7 @@ func (h SignModeHandler) GetSignBytes(
AccountNumber: signerData.AccountNumber,
Sequence: signerData.Sequence,
}
return proto.Marshal(signDocDirectAux)

protov2MarshalOpts := proto.MarshalOptions{Deterministic: true}
return protov2MarshalOpts.Marshal(signDocDirectAux)
}
6 changes: 4 additions & 2 deletions x/tx/signing/testutil/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,13 @@ func MakeHandlerArguments(options HandlerArgumentOptions) (signing.SignerData, s
SignerInfos: signerInfo,
}

bodyBz, err := proto.Marshal(txBody)
protov2MarshalOpts := proto.MarshalOptions{Deterministic: true}
bodyBz, err := protov2MarshalOpts.Marshal(txBody)
if err != nil {
return signing.SignerData{}, signing.TxData{}, err
}
authInfoBz, err := proto.Marshal(authInfo)

authInfoBz, err := protov2MarshalOpts.Marshal(authInfo)
if err != nil {
return signing.SignerData{}, signing.TxData{}, err
}
Expand Down
5 changes: 3 additions & 2 deletions x/tx/signing/textual/tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -272,11 +272,12 @@ func (vr txValueRenderer) Parse(ctx context.Context, screens []Screen) (protoref
// Note that we might not always get back the exact bodyBz and authInfoBz
// that was passed into, because protobuf is not deterministic.
// In tests, we don't check bytes equality, but protobuf object equality.
bodyBz, err := proto.Marshal(txBody)
protov2MarshalOpts := proto.MarshalOptions{Deterministic: true}
bodyBz, err := protov2MarshalOpts.Marshal(txBody)
if err != nil {
return nilValue, err
}
authInfoBz, err := proto.Marshal(authInfo)
authInfoBz, err := protov2MarshalOpts.Marshal(authInfo)
if err != nil {
return nilValue, err
}
Expand Down

0 comments on commit a1e491a

Please sign in to comment.