diff --git a/client/tx/legacy.go b/client/tx/legacy.go index 71f0fe8c4eeb..62cbf9b7b434 100644 --- a/client/tx/legacy.go +++ b/client/tx/legacy.go @@ -19,7 +19,7 @@ func ConvertTxToStdTx(codec *codec.LegacyAmino, tx signing.Tx) (legacytx.StdTx, aminoTxConfig := legacytx.StdTxConfig{Cdc: codec} builder := aminoTxConfig.NewTxBuilder() - err := CopyTx(tx, builder) + err := CopyTx(tx, builder, true) if err != nil { return legacytx.StdTx{}, err @@ -34,8 +34,9 @@ func ConvertTxToStdTx(codec *codec.LegacyAmino, tx signing.Tx) (legacytx.StdTx, } // CopyTx copies a Tx to a new TxBuilder, allowing conversion between -// different transaction formats. -func CopyTx(tx signing.Tx, builder client.TxBuilder) error { +// different transaction formats. If ignoreSignatureError is true, copying will continue +// tx even if the signature cannot be set in the target builder resulting in an unsigned tx. +func CopyTx(tx signing.Tx, builder client.TxBuilder, ignoreSignatureError bool) error { err := builder.SetMsgs(tx.GetMsgs()...) if err != nil { return err @@ -48,7 +49,13 @@ func CopyTx(tx signing.Tx, builder client.TxBuilder) error { err = builder.SetSignatures(sigs...) if err != nil { - return err + if ignoreSignatureError { + // we call SetSignatures() agan with no args to clear any signatures in case the + // previous call to SetSignatures() had any partial side-effects + _ = builder.SetSignatures() + } else { + return err + } } builder.SetMemo(tx.GetMemo()) @@ -58,6 +65,7 @@ func CopyTx(tx signing.Tx, builder client.TxBuilder) error { return nil } +// ConvertAndEncodeStdTx encodes the stdTx as a transaction in the format specified by txConfig func ConvertAndEncodeStdTx(txConfig client.TxConfig, stdTx legacytx.StdTx) ([]byte, error) { builder := txConfig.NewTxBuilder() @@ -67,7 +75,7 @@ func ConvertAndEncodeStdTx(txConfig client.TxConfig, stdTx legacytx.StdTx) ([]by if _, ok := builder.GetTx().(legacytx.StdTx); ok { theTx = stdTx } else { - err := CopyTx(stdTx, builder) + err := CopyTx(stdTx, builder, false) if err != nil { return nil, err } diff --git a/client/tx/legacy_test.go b/client/tx/legacy_test.go index 4884faa83c5e..704b3ac029f2 100644 --- a/client/tx/legacy_test.go +++ b/client/tx/legacy_test.go @@ -68,10 +68,10 @@ func (s *TestSuite) TestCopyTx() { protoBuilder := s.protoCfg.NewTxBuilder() buildTestTx(s.T(), protoBuilder) aminoBuilder := s.aminoCfg.NewTxBuilder() - err := tx2.CopyTx(protoBuilder.GetTx(), aminoBuilder) + err := tx2.CopyTx(protoBuilder.GetTx(), aminoBuilder, false) s.Require().NoError(err) protoBuilder2 := s.protoCfg.NewTxBuilder() - err = tx2.CopyTx(aminoBuilder.GetTx(), protoBuilder2) + err = tx2.CopyTx(aminoBuilder.GetTx(), protoBuilder2, false) s.Require().NoError(err) bz, err := s.protoCfg.TxEncoder()(protoBuilder.GetTx()) s.Require().NoError(err) @@ -83,10 +83,10 @@ func (s *TestSuite) TestCopyTx() { aminoBuilder = s.aminoCfg.NewTxBuilder() buildTestTx(s.T(), aminoBuilder) protoBuilder = s.protoCfg.NewTxBuilder() - err = tx2.CopyTx(aminoBuilder.GetTx(), protoBuilder) + err = tx2.CopyTx(aminoBuilder.GetTx(), protoBuilder, false) s.Require().NoError(err) aminoBuilder2 := s.aminoCfg.NewTxBuilder() - err = tx2.CopyTx(protoBuilder.GetTx(), aminoBuilder2) + err = tx2.CopyTx(protoBuilder.GetTx(), aminoBuilder2, false) s.Require().NoError(err) bz, err = s.aminoCfg.TxEncoder()(aminoBuilder.GetTx()) s.Require().NoError(err) @@ -108,6 +108,23 @@ func (s *TestSuite) TestConvertTxToStdTx() { s.Require().Equal(sig.PubKey, stdTx.Signatures[0].PubKey) s.Require().Equal(sig.Data.(*signing2.SingleSignatureData).Signature, stdTx.Signatures[0].Signature) + // SIGN_MODE_DIRECT should fall back to an unsigned tx + err = protoBuilder.SetSignatures(signing2.SignatureV2{ + PubKey: pub1, + Data: &signing2.SingleSignatureData{ + SignMode: signing2.SignMode_SIGN_MODE_DIRECT, + Signature: []byte("dummy"), + }, + }) + s.Require().NoError(err) + stdTx, err = tx2.ConvertTxToStdTx(s.encCfg.Amino, protoBuilder.GetTx()) + s.Require().NoError(err) + s.Require().Equal(memo, stdTx.Memo) + s.Require().Equal(gas, stdTx.Fee.Gas) + s.Require().Equal(fee, stdTx.Fee.Amount) + s.Require().Equal(msg, stdTx.Msgs[0]) + s.Require().Empty(stdTx.Signatures) + // std tx aminoBuilder := s.aminoCfg.NewTxBuilder() buildTestTx(s.T(), aminoBuilder) @@ -127,7 +144,7 @@ func (s *TestSuite) TestConvertAndEncodeStdTx() { decodedTx, err := s.protoCfg.TxDecoder()(txBz) s.Require().NoError(err) aminoBuilder2 := s.aminoCfg.NewTxBuilder() - s.Require().NoError(tx2.CopyTx(decodedTx.(signing.Tx), aminoBuilder2)) + s.Require().NoError(tx2.CopyTx(decodedTx.(signing.Tx), aminoBuilder2, false)) s.Require().Equal(stdTx, aminoBuilder2.GetTx()) // just use amino everywhere