fix: deterministic protov2 marshal (#18403)
This commit is contained in:
parent
1e4d1f955a
commit
e2b71b7480
@ -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
|
||||
@ -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
|
||||
}
|
||||
@ -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
|
||||
}
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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:
|
||||
|
||||
@ -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)
|
||||
}
|
||||
@ -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)
|
||||
}
|
||||
|
||||
@ -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.
|
||||
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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
|
||||
@ -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
|
||||
|
||||
@ -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{}
|
||||
|
||||
@ -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{}
|
||||
|
||||
@ -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)
|
||||
}
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user