Skip to content

Commit

Permalink
fix: deterministic protov2 marshal (#18403)
Browse files Browse the repository at this point in the history
  • Loading branch information
julienrbrt authored Nov 7, 2023
1 parent 1e4d1f9 commit e2b71b7
Show file tree
Hide file tree
Showing 10 changed files with 33 additions and 18 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
3 changes: 2 additions & 1 deletion codec/proto_codec.go
Original file line number Diff line number Diff line change
Expand Up @@ -345,7 +345,8 @@ type grpcProtoCodec struct {
func (g grpcProtoCodec) Marshal(v interface{}) ([]byte, error) {
switch m := v.(type) {
case proto.Message:
return proto.Marshal(m)
protov2MarshalOpts := proto.MarshalOptions{Deterministic: true}
return protov2MarshalOpts.Marshal(m)
case gogoproto.Message:
return g.cdc.Marshal(m)
default:
Expand Down
6 changes: 4 additions & 2 deletions 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 Expand Up @@ -109,7 +110,8 @@ func (any *Any) pack(x proto.Message) error {
err error
)
if msg, ok := x.(protov2.Message); ok {
bz, err = protov2.Marshal(msg)
protov2MarshalOpts := protov2.MarshalOptions{Deterministic: true}
bz, err = protov2MarshalOpts.Marshal(msg)
} else {
bz, err = proto.Marshal(x)
}
Expand Down
4 changes: 3 additions & 1 deletion x/accounts/internal/implementation/api_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ var (
errNoInitHandler = errors.New("no init handler")
errNoExecuteHandler = errors.New("account does not accept messages")
errInvalidMessage = errors.New("invalid message")

protov2MarshalOpts = proto.MarshalOptions{Deterministic: true}
)

// NewInitBuilder creates a new InitBuilder instance.
Expand Down Expand Up @@ -129,7 +131,7 @@ func (r *ExecuteBuilder) makeResponseEncoder() func(executeResponse any) ([]byte

// we do not check if it is part of an account's valid response message set
// as make handler will never allow for an invalid response to be returned.
return proto.Marshal(anyPB)
return protov2MarshalOpts.Marshal(anyPB)
}
}

Expand Down
2 changes: 1 addition & 1 deletion x/auth/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ require (
github.com/cosmos/cosmos-proto v1.0.0-beta.3
github.com/cosmos/cosmos-sdk v0.51.0
github.com/cosmos/gogoproto v1.4.11
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0
github.com/golang/mock v1.6.0
github.com/golang/protobuf v1.5.3
github.com/google/gofuzz v1.2.0
Expand Down Expand Up @@ -60,7 +61,6 @@ require (
github.com/cosmos/ledger-cosmos-go v0.13.3 // indirect
github.com/danieljoos/wincred v1.1.2 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect
github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f // indirect
github.com/dgraph-io/badger/v2 v2.2007.4 // indirect
github.com/dgraph-io/ristretto v0.1.1 // indirect
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 e2b71b7

Please sign in to comment.