diff --git a/client/grpc_query.go b/client/grpc_query.go index 73aaf2e99..4f9a5aa45 100644 --- a/client/grpc_query.go +++ b/client/grpc_query.go @@ -4,11 +4,12 @@ import ( gocontext "context" "fmt" - "github.com/cosmos/cosmos-sdk/codec/types" gogogrpc "github.com/gogo/protobuf/grpc" "google.golang.org/grpc" "google.golang.org/grpc/encoding" "google.golang.org/grpc/encoding/proto" + + "github.com/cosmos/cosmos-sdk/codec/types" ) var _ gogogrpc.ClientConn = Context{} diff --git a/client/testutil/suite.go b/client/testutil/suite.go index 8ec3c1de2..c85dcf51b 100644 --- a/client/testutil/suite.go +++ b/client/testutil/suite.go @@ -1,9 +1,14 @@ package testutil import ( + "bytes" + + "github.com/cosmos/cosmos-sdk/codec/testdata" + "github.com/cosmos/cosmos-sdk/crypto/types/multisig" + "github.com/cosmos/cosmos-sdk/x/auth/signing" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" "github.com/stretchr/testify/suite" "github.com/tendermint/tendermint/crypto" - "github.com/tendermint/tendermint/crypto/secp256k1" "github.com/cosmos/cosmos-sdk/client" @@ -25,86 +30,259 @@ func NewTxGeneratorTestSuite(txGenerator client.TxGenerator) *TxGeneratorTestSui } func (s *TxGeneratorTestSuite) TestTxBuilderGetTx() { - stdTxBuilder := s.TxGenerator.NewTxBuilder() - tx := stdTxBuilder.GetTx() + txBuilder := s.TxGenerator.NewTxBuilder() + tx := txBuilder.GetTx() s.Require().NotNil(tx) s.Require().Equal(len(tx.GetMsgs()), 0) } func (s *TxGeneratorTestSuite) TestTxBuilderSetFeeAmount() { - stdTxBuilder := s.TxGenerator.NewTxBuilder() + txBuilder := s.TxGenerator.NewTxBuilder() feeAmount := sdk.Coins{ sdk.NewInt64Coin("atom", 20000000), } - stdTxBuilder.SetFeeAmount(feeAmount) - feeTx := stdTxBuilder.GetTx().(sdk.FeeTx) + txBuilder.SetFeeAmount(feeAmount) + feeTx := txBuilder.GetTx() s.Require().Equal(feeAmount, feeTx.GetFee()) } func (s *TxGeneratorTestSuite) TestTxBuilderSetGasLimit() { const newGas uint64 = 300000 - stdTxBuilder := s.TxGenerator.NewTxBuilder() - stdTxBuilder.SetGasLimit(newGas) - feeTx := stdTxBuilder.GetTx().(sdk.FeeTx) + txBuilder := s.TxGenerator.NewTxBuilder() + txBuilder.SetGasLimit(newGas) + feeTx := txBuilder.GetTx() s.Require().Equal(newGas, feeTx.GetGas()) } func (s *TxGeneratorTestSuite) TestTxBuilderSetMemo() { const newMemo string = "newfoomemo" - stdTxBuilder := s.TxGenerator.NewTxBuilder() - stdTxBuilder.SetMemo(newMemo) - txWithMemo := stdTxBuilder.GetTx().(sdk.TxWithMemo) + txBuilder := s.TxGenerator.NewTxBuilder() + txBuilder.SetMemo(newMemo) + txWithMemo := txBuilder.GetTx() s.Require().Equal(txWithMemo.GetMemo(), newMemo) } func (s *TxGeneratorTestSuite) TestTxBuilderSetMsgs() { - stdTxBuilder := s.TxGenerator.NewTxBuilder() - tx := stdTxBuilder.GetTx() - err := stdTxBuilder.SetMsgs(sdk.NewTestMsg(), sdk.NewTestMsg()) - s.Require().NoError(err) - s.Require().NotEqual(tx, stdTxBuilder.GetTx()) - s.Require().Equal(len(stdTxBuilder.GetTx().GetMsgs()), 2) -} + _, _, addr1 := authtypes.KeyTestPubAddr() + _, _, addr2 := authtypes.KeyTestPubAddr() + msg1 := testdata.NewTestMsg(addr1) + msg2 := testdata.NewTestMsg(addr2) + msgs := []sdk.Msg{msg1, msg2} -type HasSignaturesTx interface { - GetSignatures() [][]byte - GetSigners() []sdk.AccAddress - GetPubKeys() []crypto.PubKey // If signer already has pubkey in context, this list will have nil in its place + txBuilder := s.TxGenerator.NewTxBuilder() + + err := txBuilder.SetMsgs(msgs...) + s.Require().NoError(err) + tx := txBuilder.GetTx() + s.Require().Equal(msgs, tx.GetMsgs()) + s.Require().Equal([]sdk.AccAddress{addr1, addr2}, tx.GetSigners()) + s.Require().Equal(addr1, tx.FeePayer()) + s.Require().Error(tx.ValidateBasic()) // should fail because of no signatures } func (s *TxGeneratorTestSuite) TestTxBuilderSetSignatures() { - priv := secp256k1.GenPrivKey() + privKey, pubkey, addr := authtypes.KeyTestPubAddr() + privKey2, pubkey2, _ := authtypes.KeyTestPubAddr() + multisigPk := multisig.NewPubKeyMultisigThreshold(2, []crypto.PubKey{pubkey, pubkey2}) - stdTxBuilder := s.TxGenerator.NewTxBuilder() - tx := stdTxBuilder.GetTx() - singleSignatureData := signingtypes.SingleSignatureData{ - Signature: priv.PubKey().Bytes(), - SignMode: signingtypes.SignMode_SIGN_MODE_LEGACY_AMINO_JSON, + txBuilder := s.TxGenerator.NewTxBuilder() + + // set test msg + msg := testdata.NewTestMsg(addr) + msigAddr := sdk.AccAddress(multisigPk.Address()) + msg2 := testdata.NewTestMsg(msigAddr) + err := txBuilder.SetMsgs(msg, msg2) + s.Require().NoError(err) + + // check that validation fails + s.Require().Error(txBuilder.GetTx().ValidateBasic()) + + signModeHandler := s.TxGenerator.SignModeHandler() + s.Require().Contains(signModeHandler.Modes(), signModeHandler.DefaultMode()) + + // set SignatureV2 without actual signature bytes + sigData1 := &signingtypes.SingleSignatureData{SignMode: signModeHandler.DefaultMode()} + sig1 := signingtypes.SignatureV2{PubKey: pubkey, Data: sigData1} + + msigData := multisig.NewMultisig(2) + multisig.AddSignature(msigData, &signingtypes.SingleSignatureData{SignMode: signModeHandler.DefaultMode()}, 0) + multisig.AddSignature(msigData, &signingtypes.SingleSignatureData{SignMode: signModeHandler.DefaultMode()}, 1) + msig := signingtypes.SignatureV2{PubKey: multisigPk, Data: msigData} + + // fail validation without required signers + err = txBuilder.SetSignatures(sig1) + s.Require().NoError(err) + sigTx := txBuilder.GetTx() + s.Require().Error(sigTx.ValidateBasic()) + + err = txBuilder.SetSignatures(sig1, msig) + s.Require().NoError(err) + sigTx = txBuilder.GetTx() + s.Require().Len(sigTx.GetSignatures(), 2) + sigsV2, err := sigTx.GetSignaturesV2() + s.Require().NoError(err) + s.Require().Len(sigsV2, 2) + s.Require().True(sigEquals(sig1, sigsV2[0])) + s.Require().True(sigEquals(msig, sigsV2[1])) + s.Require().Equal([]sdk.AccAddress{addr, msigAddr}, sigTx.GetSigners()) + s.Require().NoError(sigTx.ValidateBasic()) + + // sign transaction + signerData := signing.SignerData{ + ChainID: "test", + AccountNumber: 1, + AccountSequence: 2, + } + signBytes, err := signModeHandler.GetSignBytes(signModeHandler.DefaultMode(), signerData, sigTx) + s.Require().NoError(err) + sigBz, err := privKey.Sign(signBytes) + s.Require().NoError(err) + + signerData = signing.SignerData{ + ChainID: "test", + AccountNumber: 3, + AccountSequence: 4, + } + mSignBytes, err := signModeHandler.GetSignBytes(signModeHandler.DefaultMode(), signerData, sigTx) + s.Require().NoError(err) + mSigBz1, err := privKey.Sign(mSignBytes) + s.Require().NoError(err) + mSigBz2, err := privKey2.Sign(mSignBytes) + s.Require().NoError(err) + msigData = multisig.NewMultisig(2) + multisig.AddSignature(msigData, &signingtypes.SingleSignatureData{ + SignMode: signModeHandler.DefaultMode(), Signature: mSigBz1}, 0) + multisig.AddSignature(msigData, &signingtypes.SingleSignatureData{ + SignMode: signModeHandler.DefaultMode(), Signature: mSigBz2}, 0) + + // set signature + sigData1.Signature = sigBz + sig1 = signingtypes.SignatureV2{PubKey: pubkey, Data: sigData1} + msig = signingtypes.SignatureV2{PubKey: multisigPk, Data: msigData} + err = txBuilder.SetSignatures(sig1, msig) + s.Require().NoError(err) + sigTx = txBuilder.GetTx() + s.Require().Len(sigTx.GetSignatures(), 2) + sigsV2, err = sigTx.GetSignaturesV2() + s.Require().NoError(err) + s.Require().Len(sigsV2, 2) + s.Require().True(sigEquals(sig1, sigsV2[0])) + s.Require().True(sigEquals(msig, sigsV2[1])) + s.Require().Equal([]sdk.AccAddress{addr, msigAddr}, sigTx.GetSigners()) + s.Require().NoError(sigTx.ValidateBasic()) +} + +func sigEquals(sig1, sig2 signingtypes.SignatureV2) bool { + if !sig1.PubKey.Equals(sig2.PubKey) { + return false } - err := stdTxBuilder.SetSignatures(signingtypes.SignatureV2{ - PubKey: priv.PubKey(), - Data: &singleSignatureData, - }) - sigTx := stdTxBuilder.GetTx().(HasSignaturesTx) - s.Require().NoError(err) - s.Require().NotEqual(tx, stdTxBuilder.GetTx()) - s.Require().Equal(sigTx.GetSignatures()[0], priv.PubKey().Bytes()) + if sig1.Data == nil && sig2.Data == nil { + return true + } + + return sigDataEquals(sig1.Data, sig2.Data) +} + +func sigDataEquals(data1, data2 signingtypes.SignatureData) bool { + switch data1 := data1.(type) { + case *signingtypes.SingleSignatureData: + data2, ok := data2.(*signingtypes.SingleSignatureData) + if !ok { + return false + } + + if data1.SignMode != data2.SignMode { + return false + } + + return bytes.Equal(data1.Signature, data2.Signature) + case *signingtypes.MultiSignatureData: + data2, ok := data2.(*signingtypes.MultiSignatureData) + if !ok { + return false + } + + if data1.BitArray.ExtraBitsStored != data2.BitArray.ExtraBitsStored { + return false + } + + if !bytes.Equal(data1.BitArray.Elems, data2.BitArray.Elems) { + return false + } + + if len(data1.Signatures) != len(data2.Signatures) { + return false + } + + for i, s := range data1.Signatures { + if !sigDataEquals(s, data2.Signatures[i]) { + return false + } + } + + return true + default: + return false + } } func (s *TxGeneratorTestSuite) TestTxEncodeDecode() { + _, pubkey, addr := authtypes.KeyTestPubAddr() + feeAmount := sdk.Coins{sdk.NewInt64Coin("atom", 150)} + gasLimit := uint64(50000) + memo := "foomemo" + msg := testdata.NewTestMsg(addr) + dummySig := []byte("dummySig") + sig := signingtypes.SignatureV2{ + PubKey: pubkey, + Data: &signingtypes.SingleSignatureData{ + SignMode: signingtypes.SignMode_SIGN_MODE_LEGACY_AMINO_JSON, + Signature: dummySig, + }, + } + txBuilder := s.TxGenerator.NewTxBuilder() - txBuilder.SetFeeAmount(sdk.Coins{sdk.NewInt64Coin("atom", 150)}) - txBuilder.SetGasLimit(50000) - txBuilder.SetMemo("foomemo") + txBuilder.SetFeeAmount(feeAmount) + txBuilder.SetGasLimit(gasLimit) + txBuilder.SetMemo(memo) + err := txBuilder.SetMsgs(msg) + s.Require().NoError(err) + err = txBuilder.SetSignatures(sig) + s.Require().NoError(err) tx := txBuilder.GetTx() - // Encode transaction + s.T().Log("encode transaction") txBytes, err := s.TxGenerator.TxEncoder()(tx) s.Require().NoError(err) s.Require().NotNil(txBytes) + s.T().Log("decode transaction") tx2, err := s.TxGenerator.TxDecoder()(txBytes) s.Require().NoError(err) - s.Require().Equal(tx, tx2) + tx3, ok := tx2.(signing.SigFeeMemoTx) + s.Require().True(ok) + s.Require().Equal([]sdk.Msg{msg}, tx3.GetMsgs()) + s.Require().Equal(feeAmount, tx3.GetFee()) + s.Require().Equal(gasLimit, tx3.GetGas()) + s.Require().Equal(memo, tx3.GetMemo()) + s.Require().Equal([][]byte{dummySig}, tx3.GetSignatures()) + s.Require().Equal([]crypto.PubKey{pubkey}, tx3.GetPubKeys()) + + s.T().Log("JSON encode transaction") + jsonTxBytes, err := s.TxGenerator.TxJSONEncoder()(tx) + s.Require().NoError(err) + s.Require().NotNil(jsonTxBytes) + + s.T().Log("JSON decode transaction") + tx2, err = s.TxGenerator.TxJSONDecoder()(jsonTxBytes) + s.Require().NoError(err) + tx3, ok = tx2.(signing.SigFeeMemoTx) + s.Require().True(ok) + s.Require().Equal([]sdk.Msg{msg}, tx3.GetMsgs()) + s.Require().Equal(feeAmount, tx3.GetFee()) + s.Require().Equal(gasLimit, tx3.GetGas()) + s.Require().Equal(memo, tx3.GetMemo()) + s.Require().Equal([][]byte{dummySig}, tx3.GetSignatures()) + s.Require().Equal([]crypto.PubKey{pubkey}, tx3.GetPubKeys()) } diff --git a/client/tx/tx_test.go b/client/tx/tx_test.go index daa0dea73..dd95e2df4 100644 --- a/client/tx/tx_test.go +++ b/client/tx/tx_test.go @@ -4,12 +4,12 @@ import ( "errors" "testing" + "github.com/cosmos/cosmos-sdk/x/auth/signing" + "github.com/cosmos/cosmos-sdk/crypto/hd" "github.com/cosmos/cosmos-sdk/crypto/keyring" "github.com/cosmos/cosmos-sdk/tests" - "github.com/cosmos/cosmos-sdk/x/auth/ante" - "github.com/stretchr/testify/require" "github.com/cosmos/cosmos-sdk/client" @@ -111,7 +111,7 @@ func TestBuildUnsignedTx(t *testing.T) { tx, err := tx.BuildUnsignedTx(txf, msg) require.NoError(t, err) require.NotNil(t, tx) - require.Empty(t, tx.GetTx().(ante.SigVerifiableTx).GetSignatures()) + require.Empty(t, tx.GetTx().(signing.SigVerifiableTx).GetSignatures()) } func TestSign(t *testing.T) { diff --git a/client/tx_generator.go b/client/tx_generator.go index 70b2d3368..6718a603d 100644 --- a/client/tx_generator.go +++ b/client/tx_generator.go @@ -25,7 +25,7 @@ type ( // signatures, and provide canonical bytes to sign over. The transaction must // also know how to encode itself. TxBuilder interface { - GetTx() sdk.Tx + GetTx() signing.SigFeeMemoTx SetMsgs(msgs ...sdk.Msg) error SetSignatures(signatures ...signingtypes.SignatureV2) error diff --git a/codec/any_test.go b/codec/any_test.go index dbca83100..a3914f888 100644 --- a/codec/any_test.go +++ b/codec/any_test.go @@ -1,8 +1,10 @@ -package codec +package codec_test import ( "testing" + "github.com/cosmos/cosmos-sdk/codec" + "github.com/stretchr/testify/require" "github.com/cosmos/cosmos-sdk/codec/testdata" @@ -23,32 +25,32 @@ func NewTestInterfaceRegistry() types.InterfaceRegistry { func TestMarshalAny(t *testing.T) { registry := types.NewInterfaceRegistry() - cdc := NewProtoCodec(registry) + cdc := codec.NewProtoCodec(registry) kitty := &testdata.Cat{Moniker: "Kitty"} - bz, err := MarshalAny(cdc, kitty) + bz, err := codec.MarshalAny(cdc, kitty) require.NoError(t, err) var animal testdata.Animal // empty registry should fail - err = UnmarshalAny(cdc, &animal, bz) + err = codec.UnmarshalAny(cdc, &animal, bz) require.Error(t, err) // wrong type registration should fail registry.RegisterImplementations((*testdata.Animal)(nil), &testdata.Dog{}) - err = UnmarshalAny(cdc, &animal, bz) + err = codec.UnmarshalAny(cdc, &animal, bz) require.Error(t, err) // should pass registry = NewTestInterfaceRegistry() - cdc = NewProtoCodec(registry) - err = UnmarshalAny(cdc, &animal, bz) + cdc = codec.NewProtoCodec(registry) + err = codec.UnmarshalAny(cdc, &animal, bz) require.NoError(t, err) require.Equal(t, kitty, animal) // nil should fail registry = NewTestInterfaceRegistry() - err = UnmarshalAny(cdc, nil, bz) + err = codec.UnmarshalAny(cdc, nil, bz) require.Error(t, err) } diff --git a/codec/proto_codec.go b/codec/proto_codec.go index 2c9825db7..2a2befc33 100644 --- a/codec/proto_codec.go +++ b/codec/proto_codec.go @@ -125,7 +125,12 @@ func (pc *ProtoCodec) UnmarshalJSON(bz []byte, ptr interface{}) error { return fmt.Errorf("cannot protobuf JSON decode unsupported type: %T", ptr) } - return jsonpb.Unmarshal(strings.NewReader(string(bz)), m) + err := jsonpb.Unmarshal(strings.NewReader(string(bz)), m) + if err != nil { + return err + } + + return types.UnpackInterfaces(ptr, pc.anyUnpacker) } func (pc *ProtoCodec) MustUnmarshalJSON(bz []byte, ptr interface{}) { diff --git a/codec/testdata/proto.pb.go b/codec/testdata/proto.pb.go index 01e5f19ed..e83df04d9 100644 --- a/codec/testdata/proto.pb.go +++ b/codec/testdata/proto.pb.go @@ -7,6 +7,8 @@ import ( context "context" fmt "fmt" types "github.com/cosmos/cosmos-sdk/codec/types" + github_com_cosmos_cosmos_sdk_types "github.com/cosmos/cosmos-sdk/types" + _ "github.com/gogo/protobuf/gogoproto" grpc1 "github.com/gogo/protobuf/grpc" proto "github.com/gogo/protobuf/proto" grpc "google.golang.org/grpc" @@ -536,6 +538,105 @@ func (m *TestAnyResponse) GetHasAnimal() *HasAnimal { return nil } +// msg type for testing +type TestMsg struct { + Signers []github_com_cosmos_cosmos_sdk_types.AccAddress `protobuf:"bytes,1,rep,name=signers,proto3,casttype=github.com/cosmos/cosmos-sdk/types.AccAddress" json:"signers,omitempty"` +} + +func (m *TestMsg) Reset() { *m = TestMsg{} } +func (m *TestMsg) String() string { return proto.CompactTextString(m) } +func (*TestMsg) ProtoMessage() {} +func (*TestMsg) Descriptor() ([]byte, []int) { + return fileDescriptor_2fcc84b9998d60d8, []int{11} +} +func (m *TestMsg) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *TestMsg) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_TestMsg.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *TestMsg) XXX_Merge(src proto.Message) { + xxx_messageInfo_TestMsg.Merge(m, src) +} +func (m *TestMsg) XXX_Size() int { + return m.Size() +} +func (m *TestMsg) XXX_DiscardUnknown() { + xxx_messageInfo_TestMsg.DiscardUnknown(m) +} + +var xxx_messageInfo_TestMsg proto.InternalMessageInfo + +func (m *TestMsg) GetSigners() []github_com_cosmos_cosmos_sdk_types.AccAddress { + if m != nil { + return m.Signers + } + return nil +} + +// bad MultiSignature with extra fields +type BadMultiSignature struct { + Signatures [][]byte `protobuf:"bytes,1,rep,name=signatures,proto3" json:"signatures,omitempty"` + MaliciousField []byte `protobuf:"bytes,5,opt,name=malicious_field,json=maliciousField,proto3" json:"malicious_field,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *BadMultiSignature) Reset() { *m = BadMultiSignature{} } +func (m *BadMultiSignature) String() string { return proto.CompactTextString(m) } +func (*BadMultiSignature) ProtoMessage() {} +func (*BadMultiSignature) Descriptor() ([]byte, []int) { + return fileDescriptor_2fcc84b9998d60d8, []int{12} +} +func (m *BadMultiSignature) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *BadMultiSignature) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_BadMultiSignature.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *BadMultiSignature) XXX_Merge(src proto.Message) { + xxx_messageInfo_BadMultiSignature.Merge(m, src) +} +func (m *BadMultiSignature) XXX_Size() int { + return m.Size() +} +func (m *BadMultiSignature) XXX_DiscardUnknown() { + xxx_messageInfo_BadMultiSignature.DiscardUnknown(m) +} + +var xxx_messageInfo_BadMultiSignature proto.InternalMessageInfo + +func (m *BadMultiSignature) GetSignatures() [][]byte { + if m != nil { + return m.Signatures + } + return nil +} + +func (m *BadMultiSignature) GetMaliciousField() []byte { + if m != nil { + return m.MaliciousField + } + return nil +} + func init() { proto.RegisterType((*Dog)(nil), "testdata.Dog") proto.RegisterType((*Cat)(nil), "testdata.Cat") @@ -548,42 +649,51 @@ func init() { proto.RegisterType((*SayHelloResponse)(nil), "testdata.SayHelloResponse") proto.RegisterType((*TestAnyRequest)(nil), "testdata.TestAnyRequest") proto.RegisterType((*TestAnyResponse)(nil), "testdata.TestAnyResponse") + proto.RegisterType((*TestMsg)(nil), "testdata.TestMsg") + proto.RegisterType((*BadMultiSignature)(nil), "testdata.BadMultiSignature") } func init() { proto.RegisterFile("proto.proto", fileDescriptor_2fcc84b9998d60d8) } var fileDescriptor_2fcc84b9998d60d8 = []byte{ - // 467 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x92, 0x4f, 0x6f, 0xd3, 0x30, - 0x18, 0xc6, 0x6b, 0xba, 0x3f, 0xed, 0xdb, 0x6a, 0x45, 0x66, 0xa0, 0x36, 0x87, 0x08, 0x45, 0x42, - 0x4c, 0x82, 0x25, 0x52, 0xab, 0x5d, 0x38, 0x20, 0x95, 0x51, 0xd1, 0x0b, 0x97, 0x8c, 0x13, 0x17, - 0xe4, 0xa6, 0x2f, 0x49, 0xb4, 0xc4, 0x1e, 0x75, 0x3a, 0x2d, 0x7c, 0x0a, 0xbe, 0x15, 0x1c, 0x77, - 0xe4, 0x88, 0xda, 0x2f, 0x82, 0x62, 0x3b, 0x7f, 0x98, 0x2a, 0xd4, 0x4b, 0xeb, 0xf7, 0xf5, 0xf3, - 0xfc, 0x6c, 0x3f, 0x6f, 0xa0, 0x77, 0xb3, 0x12, 0x99, 0x70, 0xd5, 0x2f, 0xed, 0x64, 0x28, 0xb3, - 0x25, 0xcb, 0x98, 0x35, 0x0a, 0x85, 0x08, 0x13, 0xf4, 0x54, 0x7f, 0xb1, 0xfe, 0xea, 0x31, 0x9e, - 0x6b, 0x91, 0x73, 0x0e, 0xed, 0xf7, 0x22, 0xa4, 0x14, 0x0e, 0x64, 0xfc, 0x1d, 0x87, 0xe4, 0x39, - 0x39, 0xeb, 0xfa, 0x6a, 0x5d, 0xf4, 0x38, 0x4b, 0x71, 0xf8, 0x48, 0xf7, 0x8a, 0xb5, 0x73, 0x01, - 0xed, 0x4b, 0x96, 0xd1, 0x21, 0x1c, 0xa7, 0x82, 0xc7, 0xd7, 0xb8, 0x32, 0x8e, 0xb2, 0xa4, 0xa7, - 0x70, 0x98, 0xc4, 0xb7, 0x28, 0x95, 0xeb, 0xd0, 0xd7, 0x85, 0xf3, 0x01, 0xba, 0x73, 0x26, 0xa7, - 0x3c, 0x4e, 0x59, 0x42, 0x5f, 0xc3, 0x11, 0x53, 0x2b, 0xe5, 0xed, 0x8d, 0x4f, 0x5d, 0x7d, 0x3d, - 0xb7, 0xbc, 0x9e, 0x3b, 0xe5, 0xb9, 0x6f, 0x34, 0xb4, 0x0f, 0xe4, 0x4e, 0xc1, 0xda, 0x3e, 0xb9, - 0x73, 0x2e, 0xa1, 0x3f, 0x67, 0xb2, 0x66, 0x4d, 0x00, 0x22, 0x26, 0xbf, 0xec, 0xc1, 0xeb, 0x46, - 0xa5, 0xc9, 0xf9, 0x08, 0x03, 0x0d, 0xa9, 0x39, 0x6f, 0xe0, 0xa4, 0xe0, 0xec, 0xc9, 0xea, 0x47, - 0x0d, 0xaf, 0xf3, 0x12, 0x7a, 0xb3, 0x20, 0x12, 0x3e, 0x7e, 0x5b, 0xa3, 0xd4, 0xd9, 0xa0, 0x94, - 0x2c, 0xc4, 0x2a, 0x1b, 0x5d, 0x3a, 0x67, 0xd0, 0xd7, 0x42, 0x79, 0x23, 0xb8, 0xc4, 0xff, 0x28, - 0x5f, 0xc0, 0xe0, 0x8a, 0xe5, 0x73, 0x4c, 0x92, 0x0a, 0x5b, 0x4e, 0x83, 0x34, 0xa6, 0xe1, 0xc2, - 0xe3, 0x5a, 0x66, 0xa0, 0x16, 0x74, 0xc2, 0x15, 0x62, 0x16, 0xf3, 0xd0, 0x68, 0xab, 0xda, 0x99, - 0xc1, 0xc9, 0x27, 0x94, 0x59, 0xf1, 0x04, 0x43, 0x9d, 0x00, 0x30, 0x9e, 0xef, 0x95, 0x1f, 0xe3, - 0xb9, 0x79, 0xf0, 0x0c, 0x06, 0x15, 0xc6, 0x9c, 0x3a, 0xde, 0x31, 0x87, 0x27, 0x6e, 0xf9, 0x01, - 0xba, 0x55, 0x58, 0x8d, 0x31, 0x8c, 0x7f, 0x12, 0xe8, 0x15, 0x9c, 0x2b, 0x5c, 0xdd, 0xc6, 0x01, - 0xd2, 0x0b, 0x38, 0x28, 0xe2, 0xa1, 0x4f, 0x6b, 0x5f, 0x23, 0x57, 0xeb, 0xd9, 0xc3, 0xb6, 0x39, - 0x7a, 0x0a, 0x9d, 0x32, 0x04, 0x3a, 0xaa, 0x35, 0x0f, 0xf2, 0xb3, 0xac, 0x5d, 0x5b, 0x06, 0xf1, - 0x16, 0x8e, 0xcd, 0x83, 0xe8, 0xb0, 0x96, 0xfd, 0x1b, 0x95, 0x35, 0xda, 0xb1, 0xa3, 0xfd, 0xef, - 0x66, 0xbf, 0x36, 0x36, 0xb9, 0xdf, 0xd8, 0xe4, 0xcf, 0xc6, 0x26, 0x3f, 0xb6, 0x76, 0xeb, 0x7e, - 0x6b, 0xb7, 0x7e, 0x6f, 0xed, 0xd6, 0xe7, 0x57, 0x61, 0x9c, 0x45, 0xeb, 0x85, 0x1b, 0x88, 0xd4, - 0x0b, 0x84, 0x4c, 0x85, 0x34, 0x7f, 0xe7, 0x72, 0x79, 0xed, 0x05, 0x62, 0x89, 0x81, 0x57, 0x62, - 0x17, 0x47, 0x2a, 0xf0, 0xc9, 0xdf, 0x00, 0x00, 0x00, 0xff, 0xff, 0x82, 0x85, 0xb8, 0x56, 0xc6, - 0x03, 0x00, 0x00, + // 583 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x92, 0xcd, 0x6e, 0xd4, 0x30, + 0x10, 0xc7, 0x6b, 0xb6, 0x9f, 0xb3, 0x51, 0x17, 0x4c, 0x41, 0x69, 0x0e, 0x69, 0x15, 0x09, 0x75, + 0x25, 0x68, 0x22, 0x5a, 0xf5, 0xd2, 0x03, 0x52, 0x5a, 0x16, 0x2a, 0xa1, 0x5e, 0x52, 0xc4, 0x81, + 0x4b, 0xe5, 0x4d, 0x5c, 0xaf, 0xd5, 0xc4, 0x2e, 0x71, 0x52, 0x35, 0x3c, 0x05, 0xaf, 0xc0, 0xd3, + 0xc0, 0x71, 0x8f, 0x9c, 0x10, 0xda, 0x7d, 0x0b, 0x4e, 0x28, 0xdf, 0x4b, 0xb5, 0xaa, 0xf6, 0x92, + 0xcc, 0x8c, 0xff, 0xf3, 0xb3, 0x3d, 0x7f, 0x43, 0xf7, 0x26, 0x96, 0x89, 0xb4, 0x8b, 0x2f, 0x5e, + 0x4f, 0xa8, 0x4a, 0x02, 0x92, 0x10, 0x63, 0x9b, 0x49, 0xc9, 0x42, 0xea, 0x14, 0xf5, 0x61, 0x7a, + 0xe5, 0x10, 0x91, 0x95, 0x22, 0x63, 0x8b, 0x49, 0x26, 0x8b, 0xd0, 0xc9, 0xa3, 0xb2, 0x6a, 0xed, + 0x43, 0xe7, 0xad, 0x64, 0x18, 0xc3, 0xb2, 0xe2, 0x5f, 0xa9, 0x8e, 0x76, 0x51, 0x7f, 0xc3, 0x2b, + 0xe2, 0xbc, 0x26, 0x48, 0x44, 0xf5, 0x47, 0x65, 0x2d, 0x8f, 0xad, 0x23, 0xe8, 0x9c, 0x92, 0x04, + 0xeb, 0xb0, 0x16, 0x49, 0xc1, 0xaf, 0x69, 0x5c, 0x75, 0xd4, 0x29, 0xde, 0x82, 0x95, 0x90, 0xdf, + 0x52, 0x55, 0x74, 0xad, 0x78, 0x65, 0x62, 0xbd, 0x87, 0x8d, 0x33, 0xa2, 0x5c, 0xc1, 0x23, 0x12, + 0xe2, 0x57, 0xb0, 0x4a, 0x8a, 0xa8, 0xe8, 0xed, 0x1e, 0x6c, 0xd9, 0xe5, 0xa1, 0xed, 0xfa, 0xd0, + 0xb6, 0x2b, 0x32, 0xaf, 0xd2, 0x60, 0x0d, 0xd0, 0x5d, 0x01, 0xeb, 0x78, 0xe8, 0xce, 0x3a, 0x05, + 0xed, 0x8c, 0xa8, 0x96, 0x75, 0x08, 0x30, 0x22, 0xea, 0x72, 0x01, 0xde, 0xc6, 0xa8, 0x6e, 0xb2, + 0xce, 0xa1, 0x57, 0x42, 0x5a, 0xce, 0x31, 0x6c, 0xe6, 0x9c, 0x05, 0x59, 0xda, 0x68, 0xa6, 0xd7, + 0xda, 0x83, 0xee, 0xc0, 0x1f, 0x49, 0x8f, 0x7e, 0x49, 0xa9, 0x2a, 0x67, 0x43, 0x95, 0x22, 0x8c, + 0x36, 0xb3, 0x29, 0x53, 0xab, 0x0f, 0x5a, 0x29, 0x54, 0x37, 0x52, 0x28, 0xfa, 0x80, 0xf2, 0x05, + 0xf4, 0x2e, 0x48, 0x76, 0x46, 0xc3, 0xb0, 0xc1, 0xd6, 0x6e, 0xa0, 0x19, 0x37, 0x6c, 0x78, 0xdc, + 0xca, 0x2a, 0xa8, 0x01, 0xeb, 0x2c, 0xa6, 0x34, 0xe1, 0x82, 0x55, 0xda, 0x26, 0xb7, 0x06, 0xb0, + 0xf9, 0x91, 0xaa, 0x24, 0xbf, 0x42, 0x45, 0x3d, 0x04, 0x20, 0x22, 0x5b, 0x68, 0x7e, 0x44, 0x64, + 0xd5, 0x85, 0x07, 0xd0, 0x6b, 0x30, 0xd5, 0xae, 0x07, 0x73, 0x7c, 0x78, 0x6a, 0xd7, 0xcf, 0xd2, + 0x6e, 0x86, 0x35, 0x6b, 0xc3, 0x27, 0x58, 0xcb, 0x31, 0xe7, 0x8a, 0xe1, 0x0f, 0xb0, 0xa6, 0x38, + 0x13, 0x34, 0x56, 0x3a, 0xda, 0xed, 0xf4, 0xb5, 0x93, 0xd7, 0x7f, 0x7f, 0xef, 0xec, 0x33, 0x9e, + 0x8c, 0xd2, 0xa1, 0xed, 0xcb, 0xc8, 0xf1, 0xa5, 0x8a, 0xa4, 0xaa, 0x7e, 0xfb, 0x2a, 0xb8, 0x76, + 0x92, 0xec, 0x86, 0x2a, 0xdb, 0xf5, 0x7d, 0x37, 0x08, 0x62, 0xaa, 0x94, 0x57, 0x13, 0xac, 0x21, + 0x3c, 0x39, 0x21, 0xc1, 0x79, 0x1a, 0x26, 0xfc, 0x82, 0x33, 0x41, 0x92, 0x34, 0xa6, 0xd8, 0x04, + 0x50, 0x75, 0x52, 0x6d, 0xe2, 0xcd, 0x54, 0xf0, 0x1e, 0xf4, 0x22, 0x12, 0x72, 0x9f, 0xcb, 0x54, + 0x5d, 0x5e, 0x71, 0x1a, 0x06, 0xfa, 0xca, 0x2e, 0xea, 0x6b, 0xde, 0x66, 0x53, 0x7e, 0x97, 0x57, + 0x8f, 0x97, 0xc7, 0xdf, 0x77, 0xd0, 0xc1, 0x0f, 0x04, 0xdd, 0xfc, 0xf0, 0x17, 0x34, 0xbe, 0xe5, + 0x3e, 0xc5, 0x47, 0xb0, 0x9c, 0x5b, 0x8b, 0x9f, 0xb5, 0x77, 0x9e, 0x79, 0x13, 0xc6, 0xf3, 0xfb, + 0xe5, 0x6a, 0x6c, 0x2e, 0xac, 0xd7, 0x06, 0xe2, 0xed, 0x56, 0x73, 0xcf, 0x7b, 0xc3, 0x98, 0xb7, + 0x54, 0x21, 0xde, 0x94, 0x53, 0x74, 0x45, 0x86, 0xf5, 0x56, 0xf6, 0xbf, 0xcd, 0xc6, 0xf6, 0x9c, + 0x95, 0xb2, 0xff, 0x64, 0xf0, 0x73, 0x62, 0xa2, 0xf1, 0xc4, 0x44, 0x7f, 0x26, 0x26, 0xfa, 0x36, + 0x35, 0x97, 0xc6, 0x53, 0x73, 0xe9, 0xd7, 0xd4, 0x5c, 0xfa, 0xfc, 0xf2, 0xc1, 0xf9, 0xfb, 0x32, + 0xa0, 0xbe, 0x53, 0x63, 0x87, 0xab, 0xc5, 0x63, 0x39, 0xfc, 0x17, 0x00, 0x00, 0xff, 0xff, 0x6f, + 0x03, 0x13, 0xf7, 0x98, 0x04, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -1110,6 +1220,81 @@ func (m *TestAnyResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *TestMsg) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *TestMsg) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *TestMsg) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Signers) > 0 { + for iNdEx := len(m.Signers) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.Signers[iNdEx]) + copy(dAtA[i:], m.Signers[iNdEx]) + i = encodeVarintProto(dAtA, i, uint64(len(m.Signers[iNdEx]))) + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *BadMultiSignature) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *BadMultiSignature) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *BadMultiSignature) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if len(m.MaliciousField) > 0 { + i -= len(m.MaliciousField) + copy(dAtA[i:], m.MaliciousField) + i = encodeVarintProto(dAtA, i, uint64(len(m.MaliciousField))) + i-- + dAtA[i] = 0x2a + } + if len(m.Signatures) > 0 { + for iNdEx := len(m.Signatures) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.Signatures[iNdEx]) + copy(dAtA[i:], m.Signatures[iNdEx]) + i = encodeVarintProto(dAtA, i, uint64(len(m.Signatures[iNdEx]))) + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + func encodeVarintProto(dAtA []byte, offset int, v uint64) int { offset -= sovProto(v) base := offset @@ -1274,6 +1459,43 @@ func (m *TestAnyResponse) Size() (n int) { return n } +func (m *TestMsg) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Signers) > 0 { + for _, b := range m.Signers { + l = len(b) + n += 1 + l + sovProto(uint64(l)) + } + } + return n +} + +func (m *BadMultiSignature) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Signatures) > 0 { + for _, b := range m.Signatures { + l = len(b) + n += 1 + l + sovProto(uint64(l)) + } + } + l = len(m.MaliciousField) + if l > 0 { + n += 1 + l + sovProto(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + func sovProto(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -2305,6 +2527,211 @@ func (m *TestAnyResponse) Unmarshal(dAtA []byte) error { } return nil } +func (m *TestMsg) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowProto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: TestMsg: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: TestMsg: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Signers", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowProto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthProto + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthProto + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Signers = append(m.Signers, make([]byte, postIndex-iNdEx)) + copy(m.Signers[len(m.Signers)-1], dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipProto(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthProto + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthProto + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *BadMultiSignature) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowProto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: BadMultiSignature: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: BadMultiSignature: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Signatures", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowProto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthProto + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthProto + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Signatures = append(m.Signatures, make([]byte, postIndex-iNdEx)) + copy(m.Signatures[len(m.Signatures)-1], dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field MaliciousField", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowProto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthProto + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthProto + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.MaliciousField = append(m.MaliciousField[:0], dAtA[iNdEx:postIndex]...) + if m.MaliciousField == nil { + m.MaliciousField = []byte{} + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipProto(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthProto + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthProto + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func skipProto(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 diff --git a/codec/testdata/proto.proto b/codec/testdata/proto.proto index 3b6cf3dda..5767bbd3b 100644 --- a/codec/testdata/proto.proto +++ b/codec/testdata/proto.proto @@ -2,6 +2,7 @@ syntax = "proto3"; package testdata; import "google/protobuf/any.proto"; +import "gogoproto/gogo.proto"; option go_package = "github.com/cosmos/cosmos-sdk/codec/testdata"; @@ -57,3 +58,15 @@ message TestAnyRequest { message TestAnyResponse { HasAnimal has_animal = 1; } + +// msg type for testing +message TestMsg { + repeated bytes signers = 1 [(gogoproto.casttype) = "github.com/cosmos/cosmos-sdk/types.AccAddress"]; +} + +// bad MultiSignature with extra fields +message BadMultiSignature { + option (gogoproto.goproto_unrecognized) = true; + repeated bytes signatures = 1; + bytes malicious_field = 5; +} diff --git a/codec/testdata/test_msg.go b/codec/testdata/test_msg.go new file mode 100644 index 000000000..9ae3088e9 --- /dev/null +++ b/codec/testdata/test_msg.go @@ -0,0 +1,26 @@ +package testdata + +import ( + "encoding/json" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +func NewTestMsg(addrs ...sdk.AccAddress) *TestMsg { + return &TestMsg{ + Signers: addrs, + } +} + +var _ sdk.Msg = (*TestMsg)(nil) + +func (msg *TestMsg) Route() string { return "TestMsg" } +func (msg *TestMsg) Type() string { return "Test message" } +func (msg *TestMsg) GetSignBytes() []byte { + bz, err := json.Marshal(msg.Signers) + if err != nil { + panic(err) + } + return sdk.MustSortJSON(bz) +} +func (msg *TestMsg) ValidateBasic() error { return nil } diff --git a/crypto/types/compact_bit_array.go b/crypto/types/compact_bit_array.go index f2d68100e..7c7188f6a 100644 --- a/crypto/types/compact_bit_array.go +++ b/crypto/types/compact_bit_array.go @@ -26,8 +26,8 @@ func NewCompactBitArray(bits int) *CompactBitArray { } } -// Size returns the number of bits in the bitarray -func (bA *CompactBitArray) Size() int { +// Count returns the number of bits in the bitarray +func (bA *CompactBitArray) Count() int { if bA == nil { return 0 } else if bA.ExtraBitsStored == uint32(0) { @@ -38,12 +38,12 @@ func (bA *CompactBitArray) Size() int { } // GetIndex returns the bit at index i within the bit array. -// The behavior is undefined if i >= bA.Size() +// The behavior is undefined if i >= bA.Count() func (bA *CompactBitArray) GetIndex(i int) bool { if bA == nil { return false } - if i >= bA.Size() { + if i >= bA.Count() { return false } @@ -51,13 +51,13 @@ func (bA *CompactBitArray) GetIndex(i int) bool { } // SetIndex sets the bit at index i within the bit array. -// The behavior is undefined if i >= bA.Size() +// The behavior is undefined if i >= bA.Count() func (bA *CompactBitArray) SetIndex(i int, v bool) bool { if bA == nil { return false } - if i >= bA.Size() { + if i >= bA.Count() { return false } @@ -115,7 +115,7 @@ func (bA *CompactBitArray) StringIndented(indent string) string { } lines := []string{} bits := "" - size := bA.Size() + size := bA.Count() for i := 0; i < size; i++ { if bA.GetIndex(i) { bits += "x" @@ -152,7 +152,7 @@ func (bA *CompactBitArray) MarshalJSON() ([]byte, error) { } bits := `"` - size := bA.Size() + size := bA.Count() for i := 0; i < size; i++ { if bA.GetIndex(i) { bits += `x` @@ -204,7 +204,7 @@ func (bA *CompactBitArray) UnmarshalJSON(bz []byte) error { // CompactMarshal is a space efficient encoding for CompactBitArray. // It is not amino compatible. func (bA *CompactBitArray) CompactMarshal() []byte { - size := bA.Size() + size := bA.Count() if size <= 0 { return []byte("null") } diff --git a/crypto/types/crypto.pb.go b/crypto/types/crypto.pb.go index 8fbc185d1..54455a928 100644 --- a/crypto/types/crypto.pb.go +++ b/crypto/types/crypto.pb.go @@ -299,7 +299,7 @@ func (m *CompactBitArray) XXX_Merge(src proto.Message) { xxx_messageInfo_CompactBitArray.Merge(m, src) } func (m *CompactBitArray) XXX_Size() int { - return xxx_messageInfo_CompactBitArray.Size(m) + return m.Size() } func (m *CompactBitArray) XXX_DiscardUnknown() { xxx_messageInfo_CompactBitArray.DiscardUnknown(m) @@ -331,39 +331,38 @@ func init() { func init() { proto.RegisterFile("cosmos/crypto/crypto.proto", fileDescriptor_5fa415c569c5d31a) } var fileDescriptor_5fa415c569c5d31a = []byte{ - // 500 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x92, 0xc1, 0x6e, 0xd3, 0x30, - 0x18, 0xc7, 0xe3, 0x76, 0x65, 0xab, 0xbb, 0xad, 0x60, 0x55, 0x22, 0xab, 0x44, 0x52, 0xe5, 0x80, - 0x0a, 0x12, 0xa9, 0x5a, 0xd4, 0x21, 0x7a, 0x5b, 0xc6, 0x61, 0x52, 0x85, 0x54, 0x65, 0x1c, 0x10, - 0x12, 0xaa, 0x92, 0xd4, 0xa4, 0x51, 0x93, 0x38, 0xb2, 0x1d, 0x09, 0x3f, 0x01, 0x57, 0x8e, 0x1c, - 0xb7, 0x3b, 0x0f, 0xc2, 0xb1, 0x47, 0x4e, 0x15, 0x4a, 0xdf, 0x60, 0x4f, 0x80, 0x6a, 0x27, 0xdb, - 0x00, 0x71, 0x72, 0xbe, 0xff, 0xef, 0x73, 0xfc, 0xff, 0x7f, 0x36, 0xec, 0x06, 0x84, 0x25, 0x84, - 0x0d, 0x02, 0x2a, 0x32, 0x4e, 0xca, 0xc5, 0xce, 0x28, 0xe1, 0x04, 0x1d, 0x29, 0x66, 0x2b, 0xb1, - 0xdb, 0x09, 0x49, 0x48, 0x24, 0x19, 0xec, 0xbe, 0x54, 0x53, 0xf7, 0x24, 0x24, 0x24, 0x8c, 0xf1, - 0x40, 0x56, 0x7e, 0xfe, 0x69, 0xe0, 0xa5, 0x42, 0x21, 0xeb, 0x4b, 0x0d, 0x36, 0x67, 0xb9, 0x1f, - 0x47, 0xc1, 0x14, 0x0b, 0x64, 0xc0, 0x26, 0xc3, 0x41, 0x36, 0x1a, 0x9f, 0xae, 0x86, 0x3a, 0xe8, - 0x81, 0xfe, 0xe1, 0x85, 0xe6, 0xde, 0x49, 0xa8, 0x0b, 0xf7, 0xf1, 0x62, 0x34, 0x1e, 0x0f, 0x5f, - 0xeb, 0xb5, 0x92, 0x56, 0xc2, 0x8e, 0x31, 0xaa, 0x58, 0xbd, 0x62, 0xa5, 0x80, 0xde, 0xc0, 0x83, - 0x24, 0x8f, 0x79, 0xc4, 0xa2, 0x50, 0xdf, 0xeb, 0x81, 0x7e, 0x6b, 0xf4, 0xd4, 0xfe, 0xc3, 0xb8, - 0x3d, 0xcb, 0xfd, 0x29, 0x16, 0x6f, 0xcb, 0xa6, 0x77, 0x4b, 0x8a, 0xd9, 0x92, 0xc4, 0x8b, 0x0b, - 0xcd, 0xbd, 0xdd, 0x79, 0xcf, 0x1d, 0x1d, 0xea, 0x8d, 0xbf, 0xdc, 0xd1, 0x21, 0x1a, 0x43, 0xe8, - 0xa5, 0x62, 0x9e, 0xe5, 0xfe, 0x0a, 0x0b, 0xbd, 0x2d, 0xcf, 0xe9, 0xd8, 0x2a, 0xbb, 0x5d, 0x65, - 0xb7, 0xcf, 0x52, 0xb1, 0xdb, 0xe6, 0xa5, 0x62, 0x26, 0x1b, 0x9d, 0x06, 0xac, 0xb3, 0x3c, 0xb1, - 0xbe, 0x03, 0xf8, 0xf8, 0x3f, 0x2e, 0xd0, 0x2b, 0xd8, 0xe4, 0x55, 0x21, 0xe7, 0x72, 0xe4, 0x9c, - 0x14, 0x1b, 0x13, 0x4c, 0x6f, 0x36, 0xe6, 0x43, 0xe1, 0x25, 0xf1, 0xc4, 0xba, 0xe5, 0x96, 0x7b, - 0xd7, 0x8b, 0xde, 0xc3, 0x56, 0x26, 0xa7, 0x3b, 0x5f, 0x61, 0xc1, 0xf4, 0x5a, 0xaf, 0xde, 0x6f, - 0x8d, 0xf4, 0x7f, 0xb3, 0xab, 0xf9, 0x3b, 0x4f, 0x8a, 0x8d, 0xb9, 0xaf, 0x4c, 0xb0, 0x9b, 0x8d, - 0x79, 0xac, 0x7e, 0xad, 0x02, 0x31, 0xcb, 0x85, 0x59, 0xd5, 0xc9, 0xac, 0x53, 0x78, 0x2c, 0x7d, - 0x5e, 0x46, 0x61, 0xea, 0xf1, 0x9c, 0x62, 0x64, 0x40, 0xc8, 0xaa, 0x82, 0xe9, 0xa0, 0x57, 0xef, - 0x1f, 0xba, 0xf7, 0x94, 0xc9, 0xde, 0xfa, 0xda, 0x04, 0xd6, 0x47, 0xd8, 0x3e, 0x27, 0x49, 0xe6, - 0x05, 0xdc, 0x89, 0xf8, 0x19, 0xa5, 0x9e, 0x40, 0xcf, 0xe1, 0x23, 0xfc, 0x99, 0x53, 0x6f, 0xee, - 0x47, 0x9c, 0xcd, 0x19, 0x27, 0x14, 0x97, 0x29, 0xdd, 0xb6, 0x04, 0x4e, 0xc4, 0xd9, 0xa5, 0x94, - 0x51, 0x07, 0x36, 0x70, 0x8c, 0x13, 0xa6, 0xee, 0xdf, 0x55, 0xc5, 0xe4, 0xe0, 0xdb, 0x95, 0xa9, - 0x5d, 0x5d, 0x9b, 0x9a, 0x73, 0xfe, 0xa3, 0x30, 0xc0, 0xba, 0x30, 0xc0, 0xaf, 0xc2, 0x00, 0x5f, - 0xb7, 0x86, 0xb6, 0xde, 0x1a, 0xda, 0xcf, 0xad, 0xa1, 0x7d, 0x78, 0x16, 0x46, 0x7c, 0x99, 0xfb, - 0x76, 0x40, 0x92, 0x41, 0xf5, 0xa0, 0xe5, 0xf2, 0x82, 0x2d, 0x56, 0xd5, 0xdb, 0xe6, 0x22, 0xc3, - 0xcc, 0x7f, 0x20, 0x2f, 0xeb, 0xe5, 0xef, 0x00, 0x00, 0x00, 0xff, 0xff, 0x1c, 0xa2, 0x1f, 0xee, - 0xf9, 0x02, 0x00, 0x00, + // 495 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x92, 0x4f, 0x6f, 0xd3, 0x30, + 0x18, 0xc6, 0xe3, 0xfe, 0x61, 0xd4, 0xdd, 0x56, 0xb0, 0x2a, 0x91, 0x55, 0x22, 0xa9, 0x72, 0x40, + 0x05, 0x89, 0x54, 0x2d, 0xea, 0x10, 0xbd, 0x2d, 0xe3, 0x30, 0xa9, 0x42, 0xaa, 0x32, 0x0e, 0xc0, + 0xa5, 0x4a, 0x52, 0x93, 0x46, 0x4d, 0xe2, 0xc8, 0x76, 0x24, 0xfc, 0x09, 0xb8, 0x72, 0xe4, 0x08, + 0x77, 0x3e, 0x08, 0xc7, 0x1e, 0x39, 0x55, 0x28, 0xfd, 0x06, 0xfb, 0x04, 0xa8, 0x76, 0xb2, 0x0d, + 0xd0, 0x4e, 0xce, 0xfb, 0xfc, 0x5e, 0xc7, 0xcf, 0xf3, 0xda, 0xb0, 0x17, 0x10, 0x96, 0x10, 0x36, + 0x0c, 0xa8, 0xc8, 0x38, 0x29, 0x17, 0x3b, 0xa3, 0x84, 0x13, 0x74, 0xa4, 0x98, 0xad, 0xc4, 0x5e, + 0x37, 0x24, 0x21, 0x91, 0x64, 0xb8, 0xff, 0x52, 0x4d, 0xbd, 0x93, 0x90, 0x90, 0x30, 0xc6, 0x43, + 0x59, 0xf9, 0xf9, 0xc7, 0xa1, 0x97, 0x0a, 0x85, 0xac, 0xcf, 0x35, 0xd8, 0x9a, 0xe7, 0x7e, 0x1c, + 0x05, 0x33, 0x2c, 0x90, 0x01, 0x5b, 0x0c, 0x07, 0xd9, 0x78, 0x72, 0xba, 0x1e, 0xe9, 0xa0, 0x0f, + 0x06, 0x87, 0x17, 0x9a, 0x7b, 0x23, 0xa1, 0x1e, 0x3c, 0xc0, 0xcb, 0xf1, 0x64, 0x32, 0x7a, 0xa5, + 0xd7, 0x4a, 0x5a, 0x09, 0x7b, 0xc6, 0xa8, 0x62, 0xf5, 0x8a, 0x95, 0x02, 0x7a, 0x0d, 0xef, 0x27, + 0x79, 0xcc, 0x23, 0x16, 0x85, 0x7a, 0xa3, 0x0f, 0x06, 0xed, 0xf1, 0x13, 0xfb, 0x2f, 0xe3, 0xf6, + 0x3c, 0xf7, 0x67, 0x58, 0xbc, 0x29, 0x9b, 0xde, 0xae, 0x28, 0x66, 0x2b, 0x12, 0x2f, 0x2f, 0x34, + 0xf7, 0x7a, 0xe7, 0x2d, 0x77, 0x74, 0xa4, 0x37, 0xff, 0x71, 0x47, 0x47, 0x68, 0x02, 0xa1, 0x97, + 0x8a, 0x45, 0x96, 0xfb, 0x6b, 0x2c, 0xf4, 0x8e, 0x3c, 0xa7, 0x6b, 0xab, 0xec, 0x76, 0x95, 0xdd, + 0x3e, 0x4b, 0xc5, 0x7e, 0x9b, 0x97, 0x8a, 0xb9, 0x6c, 0x74, 0x9a, 0xb0, 0xce, 0xf2, 0xc4, 0xfa, + 0x01, 0xe0, 0xa3, 0x3b, 0x5c, 0xa0, 0x97, 0xb0, 0xc5, 0xab, 0x42, 0xce, 0xe5, 0xc8, 0x39, 0x29, + 0xb6, 0x26, 0x98, 0x5d, 0x6d, 0xcd, 0x07, 0xc2, 0x4b, 0xe2, 0xa9, 0x75, 0xcd, 0x2d, 0xf7, 0xa6, + 0x17, 0xbd, 0x83, 0xed, 0x4c, 0x4e, 0x77, 0xb1, 0xc6, 0x82, 0xe9, 0xb5, 0x7e, 0x7d, 0xd0, 0x1e, + 0xeb, 0xff, 0x67, 0x57, 0xf3, 0x77, 0x1e, 0x17, 0x5b, 0xf3, 0x40, 0x99, 0x60, 0x57, 0x5b, 0xf3, + 0x58, 0xfd, 0x5a, 0x05, 0x62, 0x96, 0x0b, 0xb3, 0xaa, 0x93, 0x59, 0xa7, 0xf0, 0x58, 0xfa, 0xbc, + 0x8c, 0xc2, 0xd4, 0xe3, 0x39, 0xc5, 0xc8, 0x80, 0x90, 0x55, 0x05, 0xd3, 0x41, 0xbf, 0x3e, 0x38, + 0x74, 0x6f, 0x29, 0xd3, 0xc6, 0xe6, 0xbb, 0x09, 0xac, 0xf7, 0xb0, 0x73, 0x4e, 0x92, 0xcc, 0x0b, + 0xb8, 0x13, 0xf1, 0x33, 0x4a, 0x3d, 0x81, 0x9e, 0xc1, 0x87, 0xf8, 0x13, 0xa7, 0xde, 0xc2, 0x8f, + 0x38, 0x5b, 0x30, 0x4e, 0x28, 0x2e, 0x53, 0xba, 0x1d, 0x09, 0x9c, 0x88, 0xb3, 0x4b, 0x29, 0xa3, + 0x2e, 0x6c, 0xe2, 0x18, 0x27, 0x4c, 0xdd, 0xbf, 0xab, 0x8a, 0x69, 0xe3, 0xeb, 0x37, 0x53, 0x73, + 0xce, 0x7f, 0x16, 0x06, 0xd8, 0x14, 0x06, 0xf8, 0x5d, 0x18, 0xe0, 0xcb, 0xce, 0xd0, 0x36, 0x3b, + 0x43, 0xfb, 0xb5, 0x33, 0xb4, 0x0f, 0x4f, 0xc3, 0x88, 0xaf, 0x72, 0xdf, 0x0e, 0x48, 0x32, 0xac, + 0x1e, 0xb3, 0x5c, 0x9e, 0xb3, 0xe5, 0xba, 0x7a, 0xd7, 0x5c, 0x64, 0x98, 0xf9, 0xf7, 0xe4, 0x45, + 0xbd, 0xf8, 0x13, 0x00, 0x00, 0xff, 0xff, 0x73, 0x8c, 0x25, 0x71, 0xf5, 0x02, 0x00, 0x00, } func (m *PublicKey) Marshal() (dAtA []byte, err error) { @@ -748,6 +747,22 @@ func (m *MultiSignature) Size() (n int) { return n } +func (m *CompactBitArray) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.ExtraBitsStored != 0 { + n += 1 + sovCrypto(uint64(m.ExtraBitsStored)) + } + l = len(m.Elems) + if l > 0 { + n += 1 + l + sovCrypto(uint64(l)) + } + return n +} + func sovCrypto(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } diff --git a/crypto/types/multisig/threshold_pubkey.go b/crypto/types/multisig/threshold_pubkey.go index f27f2001c..911843e35 100644 --- a/crypto/types/multisig/threshold_pubkey.go +++ b/crypto/types/multisig/threshold_pubkey.go @@ -48,7 +48,7 @@ func (pk PubKeyMultisigThreshold) VerifyBytes(msg []byte, marshalledSig []byte) if err != nil { return false } - size := sig.BitArray.Size() + size := sig.BitArray.Count() // ensure bit array is the correct size if len(pk.PubKeys) != size { return false @@ -78,7 +78,7 @@ func (pk PubKeyMultisigThreshold) VerifyBytes(msg []byte, marshalledSig []byte) func (pk PubKeyMultisigThreshold) VerifyMultisignature(getSignBytes GetSignBytesFunc, sig *signing.MultiSignatureData) error { bitarray := sig.BitArray sigs := sig.Signatures - size := bitarray.Size() + size := bitarray.Count() // ensure bit array is the correct size if len(pk.PubKeys) != size { return fmt.Errorf("bit array size is incorrect %d", len(pk.PubKeys)) diff --git a/proto/cosmos/crypto/crypto.proto b/proto/cosmos/crypto/crypto.proto index ad31f6686..7c5e31280 100644 --- a/proto/cosmos/crypto/crypto.proto +++ b/proto/cosmos/crypto/crypto.proto @@ -42,7 +42,6 @@ message MultiSignature { // space after proto encoding. // This is not thread safe, and is not intended for concurrent usage. message CompactBitArray { - option (gogoproto.sizer) = false; option (gogoproto.goproto_stringer) = false; uint32 extra_bits_stored = 1; diff --git a/proto/cosmos/tx/tx.proto b/proto/cosmos/tx/tx.proto index 4405d9c77..91c92a70c 100644 --- a/proto/cosmos/tx/tx.proto +++ b/proto/cosmos/tx/tx.proto @@ -18,17 +18,34 @@ message Tx { // signers, signer modes and fee AuthInfo auth_info = 2; - // signatures are the raw binary signatures of signers specified by body and auth_info + // signatures is a list of signatures that matches the length and order of AuthInfo's signer_infos to + // allow connecting signature meta information like public key and signing mode by position. repeated bytes signatures = 3; } -// SignDoc is the standard type used for signing transaction in SIGN_MODE_DIRECT -message SignDoc { - // body is the TxBody from Tx - TxBody body = 1; +// TxRaw is a variant of Tx that pins the signer's exact binary representation of body and +// auth_info. This is used for signing, broadcasting and verification. The binary +// `serialize(tx: TxRaw)` is stored in Tendermint and the hash `sha256(serialize(tx: TxRaw))` +// becomes the "txhash", commonly used as the transaction ID. +message TxRaw { + // body_bytes is a protobuf serialization of a TxBody that matches the representation in SignDoc. + bytes body_bytes = 1; - // auth_info is the AuthInfo from Tx - AuthInfo auth_info = 2; + // auth_info_bytes is a protobuf serialization of an AuthInfo that matches the representation in SignDoc. + bytes auth_info_bytes = 2; + + // signatures is a list of signatures that matches the length and order of AuthInfo's signer_infos to + // allow connecting signature meta information like public key and signing mode by position. + repeated bytes signatures = 3; +} + +// SignDoc is the type used for generating sign bytes for SIGN_MODE_DIRECT +message SignDoc { + // body_bytes is protobuf serialization of a TxBody that matches the representation in TxRaw. + bytes body_bytes = 1; + + // auth_info_bytes is a protobuf serialization of an AuthInfo that matches the representation in TxRaw. + bytes auth_info_bytes = 2; // chain_id is the unique identifier of the chain this transaction targets. // It prevents signed transactions from being used on another chain by an @@ -45,7 +62,12 @@ message SignDoc { // TxBody is the body of a transaction that all signers sign over message TxBody { - // messages are the processable content of the transaction + // messages is a list of messages to be executed. The required signers of those messages define + // the number and order of elements in AuthInfo's signer_infos and Tx's signatures. + // Each required signer address is added to the list only the first time it occurs. + // + // By convention, the first required signer (usually from the first message) is referred + // to as the primary signer and pays the fee for the whole transaction. repeated google.protobuf.Any messages = 1; // memo is any arbitrary memo to be added to the transaction @@ -68,21 +90,24 @@ message TxBody { // AuthInfo describes the fee and signer modes that are used to sign a transaction message AuthInfo { - // signer_infos is the list of signer infos which corresponds with - // Tx.signatures and expected signers derived from TxBody.messages. All signers - // are expected to occur in the same order in each of these locations + // signer_infos defines the signing modes for the required signers. The number + // and order of elements must match the required signers from TxBody's messages. + // The first element is the primary signer and the one which pays the fee. repeated SignerInfo signer_infos = 1; // Fee is the fee and gas limit for the transaction. The first signer is the - // primary signer and the one which pays the fee + // primary signer and the one which pays the fee. The fee can be calculated + // based on the cost of evaluating the body and doing signature verification + // of the signers. This can be estimated via simulation. Fee fee = 2; } // SignerInfo describes the public key and signing mode of a single top-level signer message SignerInfo { // public_key is the public key of the signer. It is optional for accounts - // that already exist in state - google.protobuf.Any public_key = 1; + // that already exist in state. If unset, the verifier can use the required \ + // signer address for this position and lookup the public key. + cosmos.crypto.PublicKey public_key = 1; // mode_info describes the signing mode of the signer and is a nested // structure to support nested multisig pubkey's diff --git a/types/tx/signing/signature_data.go b/types/tx/signing/signature_data.go index 174902ac1..0dd61fe63 100644 --- a/types/tx/signing/signature_data.go +++ b/types/tx/signing/signature_data.go @@ -5,7 +5,7 @@ import ( ) // SignatureData represents either a *SingleSignatureData or *MultiSignatureData. -// It is a convenience type that is easier to use in buiness logic than the encoded +// It is a convenience type that is easier to use in business logic than the encoded // protobuf ModeInfo's and raw signatures. type SignatureData interface { isSignatureData() diff --git a/types/tx/tx.pb.go b/types/tx/tx.pb.go index 9fb635b81..35b8564c6 100644 --- a/types/tx/tx.pb.go +++ b/types/tx/tx.pb.go @@ -35,7 +35,8 @@ type Tx struct { // auth_info is the authorization related content of the transaction, specifically // signers, signer modes and fee AuthInfo *AuthInfo `protobuf:"bytes,2,opt,name=auth_info,json=authInfo,proto3" json:"auth_info,omitempty"` - // signatures are the raw binary signatures of signers specified by body and auth_info + // signatures is a list of signatures that matches the length and order of AuthInfo's signer_infos to + // allow connecting signature meta information like public key and signing mode by position. Signatures [][]byte `protobuf:"bytes,3,rep,name=signatures,proto3" json:"signatures,omitempty"` } @@ -93,12 +94,80 @@ func (m *Tx) GetSignatures() [][]byte { return nil } -// SignDoc is the standard type used for signing transaction in SIGN_MODE_DIRECT +// TxRaw is a variant of Tx that pins the signer's exact binary representation of body and +// auth_info. This is used for signing, broadcasting and verification. The binary +// `serialize(tx: TxRaw)` is stored in Tendermint and the hash `sha256(serialize(tx: TxRaw))` +// becomes the "txhash", commonly used as the transaction ID. +type TxRaw struct { + // body_bytes is a protobuf serialization of a TxBody that matches the representation in SignDoc. + BodyBytes []byte `protobuf:"bytes,1,opt,name=body_bytes,json=bodyBytes,proto3" json:"body_bytes,omitempty"` + // auth_info_bytes is a protobuf serialization of an AuthInfo that matches the representation in SignDoc. + AuthInfoBytes []byte `protobuf:"bytes,2,opt,name=auth_info_bytes,json=authInfoBytes,proto3" json:"auth_info_bytes,omitempty"` + // signatures is a list of signatures that matches the length and order of AuthInfo's signer_infos to + // allow connecting signature meta information like public key and signing mode by position. + Signatures [][]byte `protobuf:"bytes,3,rep,name=signatures,proto3" json:"signatures,omitempty"` +} + +func (m *TxRaw) Reset() { *m = TxRaw{} } +func (m *TxRaw) String() string { return proto.CompactTextString(m) } +func (*TxRaw) ProtoMessage() {} +func (*TxRaw) Descriptor() ([]byte, []int) { + return fileDescriptor_9b35c9d5d6b7bce8, []int{1} +} +func (m *TxRaw) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *TxRaw) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_TxRaw.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *TxRaw) XXX_Merge(src proto.Message) { + xxx_messageInfo_TxRaw.Merge(m, src) +} +func (m *TxRaw) XXX_Size() int { + return m.Size() +} +func (m *TxRaw) XXX_DiscardUnknown() { + xxx_messageInfo_TxRaw.DiscardUnknown(m) +} + +var xxx_messageInfo_TxRaw proto.InternalMessageInfo + +func (m *TxRaw) GetBodyBytes() []byte { + if m != nil { + return m.BodyBytes + } + return nil +} + +func (m *TxRaw) GetAuthInfoBytes() []byte { + if m != nil { + return m.AuthInfoBytes + } + return nil +} + +func (m *TxRaw) GetSignatures() [][]byte { + if m != nil { + return m.Signatures + } + return nil +} + +// SignDoc is the type used for generating sign bytes for SIGN_MODE_DIRECT type SignDoc struct { - // body is the TxBody from Tx - Body *TxBody `protobuf:"bytes,1,opt,name=body,proto3" json:"body,omitempty"` - // auth_info is the AuthInfo from Tx - AuthInfo *AuthInfo `protobuf:"bytes,2,opt,name=auth_info,json=authInfo,proto3" json:"auth_info,omitempty"` + // body_bytes is protobuf serialization of a TxBody that matches the representation in TxRaw. + BodyBytes []byte `protobuf:"bytes,1,opt,name=body_bytes,json=bodyBytes,proto3" json:"body_bytes,omitempty"` + // auth_info_bytes is a protobuf serialization of an AuthInfo that matches the representation in TxRaw. + AuthInfoBytes []byte `protobuf:"bytes,2,opt,name=auth_info_bytes,json=authInfoBytes,proto3" json:"auth_info_bytes,omitempty"` // chain_id is the unique identifier of the chain this transaction targets. // It prevents signed transactions from being used on another chain by an // attacker @@ -114,7 +183,7 @@ func (m *SignDoc) Reset() { *m = SignDoc{} } func (m *SignDoc) String() string { return proto.CompactTextString(m) } func (*SignDoc) ProtoMessage() {} func (*SignDoc) Descriptor() ([]byte, []int) { - return fileDescriptor_9b35c9d5d6b7bce8, []int{1} + return fileDescriptor_9b35c9d5d6b7bce8, []int{2} } func (m *SignDoc) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -143,16 +212,16 @@ func (m *SignDoc) XXX_DiscardUnknown() { var xxx_messageInfo_SignDoc proto.InternalMessageInfo -func (m *SignDoc) GetBody() *TxBody { +func (m *SignDoc) GetBodyBytes() []byte { if m != nil { - return m.Body + return m.BodyBytes } return nil } -func (m *SignDoc) GetAuthInfo() *AuthInfo { +func (m *SignDoc) GetAuthInfoBytes() []byte { if m != nil { - return m.AuthInfo + return m.AuthInfoBytes } return nil } @@ -180,7 +249,12 @@ func (m *SignDoc) GetAccountSequence() uint64 { // TxBody is the body of a transaction that all signers sign over type TxBody struct { - // messages are the processable content of the transaction + // messages is a list of messages to be executed. The required signers of those messages define + // the number and order of elements in AuthInfo's signer_infos and Tx's signatures. + // Each required signer address is added to the list only the first time it occurs. + // + // By convention, the first required signer (usually from the first message) is referred + // to as the primary signer and pays the fee for the whole transaction. Messages []*types.Any `protobuf:"bytes,1,rep,name=messages,proto3" json:"messages,omitempty"` // memo is any arbitrary memo to be added to the transaction Memo string `protobuf:"bytes,2,opt,name=memo,proto3" json:"memo,omitempty"` @@ -201,7 +275,7 @@ func (m *TxBody) Reset() { *m = TxBody{} } func (m *TxBody) String() string { return proto.CompactTextString(m) } func (*TxBody) ProtoMessage() {} func (*TxBody) Descriptor() ([]byte, []int) { - return fileDescriptor_9b35c9d5d6b7bce8, []int{2} + return fileDescriptor_9b35c9d5d6b7bce8, []int{3} } func (m *TxBody) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -267,12 +341,14 @@ func (m *TxBody) GetNonCriticalExtensionOptions() []*types.Any { // AuthInfo describes the fee and signer modes that are used to sign a transaction type AuthInfo struct { - // signer_infos is the list of signer infos which corresponds with - // Tx.signatures and expected signers derived from TxBody.messages. All signers - // are expected to occur in the same order in each of these locations + // signer_infos defines the signing modes for the required signers. The number + // and order of elements must match the required signers from TxBody's messages. + // The first element is the primary signer and the one which pays the fee. SignerInfos []*SignerInfo `protobuf:"bytes,1,rep,name=signer_infos,json=signerInfos,proto3" json:"signer_infos,omitempty"` // Fee is the fee and gas limit for the transaction. The first signer is the - // primary signer and the one which pays the fee + // primary signer and the one which pays the fee. The fee can be calculated + // based on the cost of evaluating the body and doing signature verification + // of the signers. This can be estimated via simulation. Fee *Fee `protobuf:"bytes,2,opt,name=fee,proto3" json:"fee,omitempty"` } @@ -280,7 +356,7 @@ func (m *AuthInfo) Reset() { *m = AuthInfo{} } func (m *AuthInfo) String() string { return proto.CompactTextString(m) } func (*AuthInfo) ProtoMessage() {} func (*AuthInfo) Descriptor() ([]byte, []int) { - return fileDescriptor_9b35c9d5d6b7bce8, []int{3} + return fileDescriptor_9b35c9d5d6b7bce8, []int{4} } func (m *AuthInfo) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -326,8 +402,9 @@ func (m *AuthInfo) GetFee() *Fee { // SignerInfo describes the public key and signing mode of a single top-level signer type SignerInfo struct { // public_key is the public key of the signer. It is optional for accounts - // that already exist in state - PublicKey *types.Any `protobuf:"bytes,1,opt,name=public_key,json=publicKey,proto3" json:"public_key,omitempty"` + // that already exist in state. If unset, the verifier can use the required \ + // signer address for this position and lookup the public key. + PublicKey *types1.PublicKey `protobuf:"bytes,1,opt,name=public_key,json=publicKey,proto3" json:"public_key,omitempty"` // mode_info describes the signing mode of the signer and is a nested // structure to support nested multisig pubkey's ModeInfo *ModeInfo `protobuf:"bytes,2,opt,name=mode_info,json=modeInfo,proto3" json:"mode_info,omitempty"` @@ -337,7 +414,7 @@ func (m *SignerInfo) Reset() { *m = SignerInfo{} } func (m *SignerInfo) String() string { return proto.CompactTextString(m) } func (*SignerInfo) ProtoMessage() {} func (*SignerInfo) Descriptor() ([]byte, []int) { - return fileDescriptor_9b35c9d5d6b7bce8, []int{4} + return fileDescriptor_9b35c9d5d6b7bce8, []int{5} } func (m *SignerInfo) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -366,7 +443,7 @@ func (m *SignerInfo) XXX_DiscardUnknown() { var xxx_messageInfo_SignerInfo proto.InternalMessageInfo -func (m *SignerInfo) GetPublicKey() *types.Any { +func (m *SignerInfo) GetPublicKey() *types1.PublicKey { if m != nil { return m.PublicKey } @@ -395,7 +472,7 @@ func (m *ModeInfo) Reset() { *m = ModeInfo{} } func (m *ModeInfo) String() string { return proto.CompactTextString(m) } func (*ModeInfo) ProtoMessage() {} func (*ModeInfo) Descriptor() ([]byte, []int) { - return fileDescriptor_9b35c9d5d6b7bce8, []int{5} + return fileDescriptor_9b35c9d5d6b7bce8, []int{6} } func (m *ModeInfo) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -480,7 +557,7 @@ func (m *ModeInfo_Single) Reset() { *m = ModeInfo_Single{} } func (m *ModeInfo_Single) String() string { return proto.CompactTextString(m) } func (*ModeInfo_Single) ProtoMessage() {} func (*ModeInfo_Single) Descriptor() ([]byte, []int) { - return fileDescriptor_9b35c9d5d6b7bce8, []int{5, 0} + return fileDescriptor_9b35c9d5d6b7bce8, []int{6, 0} } func (m *ModeInfo_Single) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -529,7 +606,7 @@ func (m *ModeInfo_Multi) Reset() { *m = ModeInfo_Multi{} } func (m *ModeInfo_Multi) String() string { return proto.CompactTextString(m) } func (*ModeInfo_Multi) ProtoMessage() {} func (*ModeInfo_Multi) Descriptor() ([]byte, []int) { - return fileDescriptor_9b35c9d5d6b7bce8, []int{5, 1} + return fileDescriptor_9b35c9d5d6b7bce8, []int{6, 1} } func (m *ModeInfo_Multi) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -587,7 +664,7 @@ func (m *Fee) Reset() { *m = Fee{} } func (m *Fee) String() string { return proto.CompactTextString(m) } func (*Fee) ProtoMessage() {} func (*Fee) Descriptor() ([]byte, []int) { - return fileDescriptor_9b35c9d5d6b7bce8, []int{6} + return fileDescriptor_9b35c9d5d6b7bce8, []int{7} } func (m *Fee) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -632,6 +709,7 @@ func (m *Fee) GetGasLimit() uint64 { func init() { proto.RegisterType((*Tx)(nil), "cosmos.tx.Tx") + proto.RegisterType((*TxRaw)(nil), "cosmos.tx.TxRaw") proto.RegisterType((*SignDoc)(nil), "cosmos.tx.SignDoc") proto.RegisterType((*TxBody)(nil), "cosmos.tx.TxBody") proto.RegisterType((*AuthInfo)(nil), "cosmos.tx.AuthInfo") @@ -645,54 +723,57 @@ func init() { func init() { proto.RegisterFile("cosmos/tx/tx.proto", fileDescriptor_9b35c9d5d6b7bce8) } var fileDescriptor_9b35c9d5d6b7bce8 = []byte{ - // 749 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x54, 0xcd, 0x6e, 0xdb, 0x38, - 0x10, 0xb6, 0x2c, 0xdb, 0xb1, 0x27, 0xff, 0x4c, 0x16, 0x50, 0x1c, 0x40, 0x31, 0x0c, 0x04, 0xf0, - 0x1e, 0x56, 0xca, 0x3a, 0x7b, 0xd8, 0xdd, 0xcb, 0x22, 0xce, 0x6e, 0x90, 0x60, 0x9b, 0x16, 0xa0, - 0x83, 0x1e, 0x72, 0x11, 0x64, 0x99, 0x96, 0x89, 0x58, 0xa4, 0x2b, 0x52, 0xa8, 0x5d, 0xa0, 0xef, - 0xd0, 0x4b, 0x5f, 0xa2, 0x87, 0x3e, 0x47, 0x6e, 0xcd, 0xb1, 0xa7, 0xb6, 0x48, 0x1e, 0xa4, 0x85, - 0x28, 0xca, 0x71, 0x0b, 0x37, 0x3d, 0xf5, 0xa4, 0xe1, 0x37, 0xdf, 0x37, 0x33, 0x9c, 0x19, 0x11, - 0x50, 0xc0, 0x45, 0xc4, 0x85, 0x2b, 0x27, 0xae, 0x9c, 0x38, 0xe3, 0x98, 0x4b, 0x8e, 0x6a, 0x19, - 0xe6, 0xc8, 0x49, 0x7d, 0x3b, 0xe4, 0x21, 0x57, 0xa8, 0x9b, 0x5a, 0x19, 0xa1, 0x5e, 0xd7, 0xa2, - 0x20, 0x9e, 0x8e, 0x25, 0xd7, 0x1f, 0xed, 0xdb, 0xca, 0x7d, 0x59, 0x8c, 0x0c, 0xdc, 0xbb, 0xcf, - 0x22, 0x68, 0xc8, 0x28, 0x0b, 0xf3, 0xaf, 0x26, 0xec, 0x84, 0x9c, 0x87, 0x23, 0xe2, 0xaa, 0x53, - 0x2f, 0x19, 0xb8, 0x3e, 0x9b, 0x66, 0xae, 0xe6, 0x4b, 0x28, 0x5e, 0x4c, 0xd0, 0x3e, 0x94, 0x7a, - 0xbc, 0x3f, 0xb5, 0x8c, 0x86, 0xd1, 0x5a, 0x6e, 0x6f, 0x3a, 0xb3, 0x12, 0x9d, 0x8b, 0x49, 0x87, - 0xf7, 0xa7, 0x58, 0xb9, 0xd1, 0x01, 0xd4, 0xfc, 0x44, 0x0e, 0x3d, 0xca, 0x06, 0xdc, 0x2a, 0x2a, - 0xee, 0xd6, 0x1c, 0xf7, 0x28, 0x91, 0xc3, 0x33, 0x36, 0xe0, 0xb8, 0xea, 0x6b, 0x0b, 0xd9, 0x00, - 0x69, 0x29, 0xbe, 0x4c, 0x62, 0x22, 0x2c, 0xb3, 0x61, 0xb6, 0x56, 0xf0, 0x1c, 0xd2, 0x7c, 0x67, - 0xc0, 0x52, 0x97, 0x86, 0xec, 0x5f, 0x1e, 0xfc, 0xbc, 0x22, 0x76, 0xa0, 0x1a, 0x0c, 0x7d, 0xca, - 0x3c, 0xda, 0xb7, 0xcc, 0x86, 0xd1, 0xaa, 0xe1, 0x25, 0x75, 0x3e, 0xeb, 0xa3, 0x7d, 0x58, 0xf3, - 0x83, 0x80, 0x27, 0x4c, 0x7a, 0x2c, 0x89, 0x7a, 0x24, 0xb6, 0x4a, 0x0d, 0xa3, 0x55, 0xc2, 0xab, - 0x1a, 0x7d, 0xac, 0x40, 0xf4, 0x2b, 0x6c, 0xe4, 0x34, 0x41, 0x9e, 0x25, 0x84, 0x05, 0xc4, 0x2a, - 0x2b, 0xe2, 0xba, 0xc6, 0xbb, 0x1a, 0x6e, 0xbe, 0x2e, 0x42, 0x25, 0xab, 0x17, 0x1d, 0x40, 0x35, - 0x22, 0x42, 0xf8, 0x21, 0x11, 0x96, 0xd1, 0x30, 0x5b, 0xcb, 0xed, 0x6d, 0x27, 0x9b, 0x84, 0x93, - 0x4f, 0xc2, 0x39, 0x62, 0x53, 0x3c, 0x63, 0x21, 0x04, 0xa5, 0x88, 0x44, 0xd9, 0xb5, 0x6a, 0x58, - 0xd9, 0x69, 0x89, 0x92, 0x46, 0x84, 0x27, 0xd2, 0x1b, 0x12, 0x1a, 0x0e, 0xa5, 0xba, 0x83, 0x89, - 0x57, 0x35, 0x7a, 0xaa, 0x40, 0xd4, 0x81, 0x4d, 0x32, 0x91, 0x84, 0x09, 0xca, 0x99, 0xc7, 0xc7, - 0x92, 0x72, 0x26, 0xac, 0xcf, 0x4b, 0x0f, 0xa4, 0xdd, 0x98, 0xf1, 0x9f, 0x64, 0x74, 0x74, 0x09, - 0x36, 0xe3, 0xcc, 0x0b, 0x62, 0x2a, 0x69, 0xe0, 0x8f, 0xbc, 0x05, 0x01, 0xd7, 0x1f, 0x08, 0xb8, - 0xcb, 0x38, 0x3b, 0xd6, 0xda, 0xff, 0xbe, 0x89, 0xdd, 0x1c, 0x40, 0x35, 0x1f, 0x0d, 0xfa, 0x13, - 0x56, 0xd2, 0x1d, 0x20, 0xb1, 0x1a, 0x62, 0xde, 0x9c, 0x5f, 0xe6, 0xa6, 0xd8, 0x55, 0x6e, 0x35, - 0xc7, 0x65, 0x31, 0xb3, 0x05, 0x6a, 0x80, 0x39, 0x20, 0x44, 0x8f, 0x7d, 0x6d, 0x4e, 0x70, 0x42, - 0x08, 0x4e, 0x5d, 0x4d, 0x01, 0x70, 0x2f, 0x46, 0x87, 0x00, 0xe3, 0xa4, 0x37, 0xa2, 0x81, 0x77, - 0x45, 0xf2, 0xcd, 0x5a, 0x5c, 0x7c, 0x2d, 0xe3, 0xfd, 0x4f, 0xd4, 0x86, 0x45, 0xbc, 0x4f, 0xbe, - 0xb7, 0x61, 0xe7, 0xbc, 0x4f, 0xb2, 0x0d, 0x8b, 0xb4, 0xd5, 0x7c, 0x5b, 0x84, 0x6a, 0x0e, 0xa3, - 0x3f, 0xa0, 0x22, 0x28, 0x0b, 0x47, 0x44, 0xe7, 0xab, 0x2f, 0xd0, 0x3a, 0x5d, 0xc5, 0x38, 0x2d, - 0x60, 0xcd, 0x45, 0xbf, 0x43, 0x39, 0x4a, 0x46, 0x92, 0xea, 0x84, 0x3b, 0x8b, 0x44, 0xe7, 0x29, - 0xe1, 0xb4, 0x80, 0x33, 0x66, 0xfd, 0x2f, 0xa8, 0x64, 0x61, 0x90, 0x0b, 0xa5, 0xb4, 0x16, 0x95, - 0x70, 0xad, 0xbd, 0x3b, 0xa7, 0xcd, 0x1f, 0x82, 0xb4, 0x27, 0x69, 0x1c, 0xac, 0x88, 0xf5, 0xe7, - 0x50, 0x56, 0xc1, 0xd0, 0xdf, 0x50, 0xed, 0x51, 0xe9, 0xc7, 0xb1, 0x9f, 0xb7, 0xc7, 0xce, 0xd5, - 0xfa, 0xe1, 0x39, 0xe6, 0xd1, 0xd8, 0x0f, 0x64, 0x87, 0xca, 0xa3, 0x94, 0x85, 0x67, 0x7c, 0xd4, - 0x06, 0x98, 0xf5, 0x49, 0x58, 0x45, 0x35, 0xc4, 0x85, 0x8d, 0xaa, 0xe5, 0x8d, 0x12, 0x9d, 0x32, - 0x98, 0x22, 0x89, 0x9a, 0x2f, 0xc0, 0x3c, 0x21, 0x04, 0x3d, 0x85, 0x8a, 0x1f, 0xa5, 0xbf, 0x8f, - 0x5e, 0x81, 0x95, 0x5c, 0x7d, 0xcc, 0x29, 0xeb, 0x1c, 0x5c, 0x7f, 0xd8, 0x2b, 0xbc, 0xf9, 0xb8, - 0xd7, 0x0a, 0xa9, 0x1c, 0x26, 0x3d, 0x27, 0xe0, 0x91, 0xfb, 0xd5, 0xfb, 0xf7, 0x9b, 0xe8, 0x5f, - 0xb9, 0x72, 0x3a, 0x26, 0x99, 0x40, 0x60, 0x1d, 0x0d, 0xed, 0x42, 0x2d, 0xf4, 0x85, 0x37, 0xa2, - 0x11, 0x95, 0xaa, 0xa1, 0x25, 0x5c, 0x0d, 0x7d, 0xf1, 0x28, 0x3d, 0x77, 0xfe, 0xb9, 0xbe, 0xb5, - 0x8d, 0x9b, 0x5b, 0xdb, 0xf8, 0x74, 0x6b, 0x1b, 0xaf, 0xee, 0xec, 0xc2, 0xcd, 0x9d, 0x5d, 0x78, - 0x7f, 0x67, 0x17, 0x2e, 0xf7, 0x7f, 0x9c, 0xc8, 0x95, 0x93, 0x5e, 0x45, 0x2d, 0xce, 0xe1, 0x97, - 0x00, 0x00, 0x00, 0xff, 0xff, 0x14, 0xf8, 0x98, 0x8a, 0xde, 0x05, 0x00, 0x00, + // 795 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x54, 0x4f, 0x6f, 0xe3, 0x44, + 0x14, 0x8f, 0xe3, 0x24, 0x8d, 0x5f, 0xff, 0xed, 0xce, 0x2e, 0x92, 0x9b, 0x0a, 0x37, 0x8a, 0x54, + 0x14, 0x0e, 0xd8, 0xa5, 0x20, 0xf1, 0xe7, 0x82, 0x9a, 0xc2, 0xaa, 0x2b, 0x58, 0x40, 0x93, 0x8a, + 0xc3, 0x5e, 0x2c, 0xdb, 0x99, 0x38, 0xa3, 0x8d, 0x67, 0x82, 0x67, 0xac, 0xda, 0x48, 0x7c, 0x07, + 0x2e, 0x7c, 0x09, 0x0e, 0x7c, 0x03, 0xee, 0x7b, 0xdc, 0x23, 0x27, 0x40, 0xed, 0x07, 0x01, 0xcd, + 0x78, 0x9c, 0x0d, 0xab, 0xee, 0xf6, 0xb2, 0xa7, 0xbc, 0xf9, 0xbd, 0xdf, 0x7b, 0xbf, 0x97, 0xf7, + 0xc7, 0x80, 0x12, 0x2e, 0x32, 0x2e, 0x02, 0x59, 0x06, 0xb2, 0xf4, 0x57, 0x39, 0x97, 0x1c, 0x39, + 0x35, 0xe6, 0xcb, 0x72, 0xf0, 0x30, 0xe5, 0x29, 0xd7, 0x68, 0xa0, 0xac, 0x9a, 0x30, 0x18, 0x98, + 0xa0, 0x24, 0xaf, 0x56, 0x92, 0x9b, 0x1f, 0xe3, 0x7b, 0xd0, 0xf8, 0xea, 0x1c, 0x35, 0x78, 0xf4, + 0x52, 0x45, 0xd0, 0x94, 0x51, 0x96, 0x36, 0xbf, 0x86, 0x70, 0x90, 0x72, 0x9e, 0x2e, 0x49, 0xa0, + 0x5f, 0x71, 0x31, 0x0f, 0x22, 0x56, 0xd5, 0xae, 0xd1, 0xcf, 0xd0, 0xbe, 0x2c, 0xd1, 0x31, 0x74, + 0x62, 0x3e, 0xab, 0x5c, 0x6b, 0x68, 0x8d, 0xb7, 0x4f, 0xef, 0xfb, 0xeb, 0x12, 0xfd, 0xcb, 0x72, + 0xc2, 0x67, 0x15, 0xd6, 0x6e, 0x74, 0x02, 0x4e, 0x54, 0xc8, 0x45, 0x48, 0xd9, 0x9c, 0xbb, 0x6d, + 0xcd, 0x7d, 0xb0, 0xc1, 0x3d, 0x2b, 0xe4, 0xe2, 0x31, 0x9b, 0x73, 0xdc, 0x8f, 0x8c, 0x85, 0x3c, + 0x00, 0x55, 0x4a, 0x24, 0x8b, 0x9c, 0x08, 0xd7, 0x1e, 0xda, 0xe3, 0x1d, 0xbc, 0x81, 0x8c, 0x18, + 0x74, 0x2f, 0x4b, 0x1c, 0x5d, 0xa1, 0x77, 0x01, 0x94, 0x44, 0x18, 0x57, 0x92, 0x08, 0x5d, 0xc7, + 0x0e, 0x76, 0x14, 0x32, 0x51, 0x00, 0x7a, 0x0f, 0xf6, 0xd7, 0xca, 0x86, 0xd3, 0xd6, 0x9c, 0xdd, + 0x46, 0xaa, 0xe6, 0xdd, 0xa5, 0xf7, 0x87, 0x05, 0x5b, 0x53, 0x9a, 0xb2, 0x2f, 0x79, 0xf2, 0xb6, + 0x24, 0x0f, 0xa0, 0x9f, 0x2c, 0x22, 0xca, 0x42, 0x3a, 0x73, 0xed, 0xa1, 0x35, 0x76, 0xf0, 0x96, + 0x7e, 0x3f, 0x9e, 0xa1, 0x63, 0xd8, 0x8b, 0x92, 0x84, 0x17, 0x4c, 0x86, 0xac, 0xc8, 0x62, 0x92, + 0xbb, 0x9d, 0xa1, 0x35, 0xee, 0xe0, 0x5d, 0x83, 0x7e, 0xab, 0x41, 0xf4, 0x3e, 0xdc, 0x6b, 0x68, + 0x82, 0xfc, 0x58, 0x10, 0x96, 0x10, 0xb7, 0xab, 0x89, 0xfb, 0x06, 0x9f, 0x1a, 0x78, 0xf4, 0x6b, + 0x1b, 0x7a, 0xf5, 0x48, 0xd0, 0x09, 0xf4, 0x33, 0x22, 0x44, 0x94, 0xea, 0xe2, 0xed, 0xf1, 0xf6, + 0xe9, 0x43, 0xbf, 0x9e, 0xb3, 0xdf, 0xcc, 0xd9, 0x3f, 0x63, 0x15, 0x5e, 0xb3, 0x10, 0x82, 0x4e, + 0x46, 0xb2, 0x7a, 0x72, 0x0e, 0xd6, 0xb6, 0x2a, 0x51, 0xd2, 0x8c, 0xf0, 0x42, 0x86, 0x0b, 0x42, + 0xd3, 0x85, 0xd4, 0xff, 0xc1, 0xc6, 0xbb, 0x06, 0xbd, 0xd0, 0x20, 0x9a, 0xc0, 0x7d, 0x52, 0x4a, + 0xc2, 0x04, 0xe5, 0x2c, 0xe4, 0x2b, 0x49, 0x39, 0x13, 0xee, 0xbf, 0x5b, 0x6f, 0x90, 0xbd, 0xb7, + 0xe6, 0x7f, 0x57, 0xd3, 0xd1, 0x53, 0xf0, 0x18, 0x67, 0x61, 0x92, 0x53, 0x49, 0x93, 0x68, 0x19, + 0xde, 0x92, 0x70, 0xff, 0x0d, 0x09, 0x0f, 0x19, 0x67, 0xe7, 0x26, 0xf6, 0xab, 0x57, 0x72, 0x8f, + 0xe6, 0xd0, 0x6f, 0xb6, 0x0f, 0x7d, 0x0a, 0x3b, 0x6a, 0xe2, 0x24, 0xd7, 0xa3, 0x6b, 0x9a, 0xf3, + 0xce, 0xc6, 0xa2, 0x4e, 0xb5, 0x5b, 0xaf, 0xea, 0xb6, 0x58, 0xdb, 0x02, 0x0d, 0xc1, 0x9e, 0x13, + 0x62, 0x36, 0x7b, 0x6f, 0x23, 0xe0, 0x11, 0x21, 0x58, 0xb9, 0x46, 0x57, 0x00, 0x2f, 0x83, 0xd1, + 0x27, 0x00, 0xab, 0x22, 0x5e, 0xd2, 0x24, 0x7c, 0x46, 0x9a, 0xe3, 0x71, 0x9b, 0x30, 0x73, 0xb7, + 0xdf, 0x6b, 0xc2, 0xd7, 0xa4, 0xc2, 0xce, 0xaa, 0x31, 0xd5, 0x21, 0x65, 0x7c, 0x46, 0x5e, 0x77, + 0x48, 0x4f, 0xf8, 0x8c, 0xd4, 0x87, 0x94, 0x19, 0x6b, 0xf4, 0x7b, 0x1b, 0xfa, 0x0d, 0x8c, 0x3e, + 0x86, 0x9e, 0xa0, 0x2c, 0x5d, 0x12, 0xa3, 0x39, 0xb8, 0x25, 0xd6, 0x9f, 0x6a, 0xc6, 0x45, 0x0b, + 0x1b, 0x2e, 0xfa, 0x10, 0xba, 0x59, 0xb1, 0x94, 0xd4, 0x08, 0x1e, 0xdc, 0x16, 0xf4, 0x44, 0x11, + 0x2e, 0x5a, 0xb8, 0x66, 0x0e, 0x3e, 0x83, 0x5e, 0x9d, 0x06, 0x05, 0xd0, 0x51, 0xb5, 0x68, 0xc1, + 0xbd, 0xd3, 0xc3, 0x8d, 0xd8, 0xe6, 0x53, 0xa3, 0xfa, 0xa2, 0xf2, 0x60, 0x4d, 0x1c, 0x5c, 0x41, + 0x57, 0x27, 0x43, 0x9f, 0x43, 0x3f, 0xa6, 0x32, 0xca, 0xf3, 0xa8, 0x69, 0x91, 0xf7, 0x4a, 0x8b, + 0xce, 0x79, 0xb6, 0x8a, 0x12, 0x39, 0xa1, 0xf2, 0x4c, 0xb1, 0xf0, 0x9a, 0x8f, 0x4e, 0x01, 0xd6, + 0x7d, 0x52, 0xe7, 0x67, 0xbf, 0xae, 0x51, 0x4e, 0xd3, 0x28, 0x31, 0xe9, 0x82, 0x2d, 0x8a, 0x6c, + 0xf4, 0x13, 0xd8, 0x8f, 0x08, 0x41, 0x3f, 0x40, 0x2f, 0xca, 0xd4, 0x09, 0x99, 0x35, 0xd8, 0x69, + 0xa2, 0xcf, 0x39, 0x65, 0x93, 0x93, 0xe7, 0x7f, 0x1d, 0xb5, 0x7e, 0xfb, 0xfb, 0x68, 0x9c, 0x52, + 0xb9, 0x28, 0x62, 0x3f, 0xe1, 0x59, 0xf0, 0xbf, 0x2f, 0xec, 0x07, 0x62, 0xf6, 0x2c, 0x90, 0xd5, + 0x8a, 0xd4, 0x01, 0x02, 0x9b, 0x6c, 0xe8, 0x10, 0x9c, 0x34, 0x12, 0xe1, 0x92, 0x66, 0x54, 0xea, + 0x86, 0x76, 0x70, 0x3f, 0x8d, 0xc4, 0x37, 0xea, 0x3d, 0xf9, 0xe2, 0xf9, 0xb5, 0x67, 0xbd, 0xb8, + 0xf6, 0xac, 0x7f, 0xae, 0x3d, 0xeb, 0x97, 0x1b, 0xaf, 0xf5, 0xe2, 0xc6, 0x6b, 0xfd, 0x79, 0xe3, + 0xb5, 0x9e, 0x1e, 0xdf, 0x2d, 0x14, 0xc8, 0x32, 0xee, 0xe9, 0xcd, 0xff, 0xe8, 0xbf, 0x00, 0x00, + 0x00, 0xff, 0xff, 0x40, 0xba, 0x1f, 0xb6, 0x40, 0x06, 0x00, 0x00, } func (m *Tx) Marshal() (dAtA []byte, err error) { @@ -751,6 +832,52 @@ func (m *Tx) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *TxRaw) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *TxRaw) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *TxRaw) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Signatures) > 0 { + for iNdEx := len(m.Signatures) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.Signatures[iNdEx]) + copy(dAtA[i:], m.Signatures[iNdEx]) + i = encodeVarintTx(dAtA, i, uint64(len(m.Signatures[iNdEx]))) + i-- + dAtA[i] = 0x1a + } + } + if len(m.AuthInfoBytes) > 0 { + i -= len(m.AuthInfoBytes) + copy(dAtA[i:], m.AuthInfoBytes) + i = encodeVarintTx(dAtA, i, uint64(len(m.AuthInfoBytes))) + i-- + dAtA[i] = 0x12 + } + if len(m.BodyBytes) > 0 { + i -= len(m.BodyBytes) + copy(dAtA[i:], m.BodyBytes) + i = encodeVarintTx(dAtA, i, uint64(len(m.BodyBytes))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + func (m *SignDoc) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -788,27 +915,17 @@ func (m *SignDoc) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x1a } - if m.AuthInfo != nil { - { - size, err := m.AuthInfo.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintTx(dAtA, i, uint64(size)) - } + if len(m.AuthInfoBytes) > 0 { + i -= len(m.AuthInfoBytes) + copy(dAtA[i:], m.AuthInfoBytes) + i = encodeVarintTx(dAtA, i, uint64(len(m.AuthInfoBytes))) i-- dAtA[i] = 0x12 } - if m.Body != nil { - { - size, err := m.Body.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintTx(dAtA, i, uint64(size)) - } + if len(m.BodyBytes) > 0 { + i -= len(m.BodyBytes) + copy(dAtA[i:], m.BodyBytes) + i = encodeVarintTx(dAtA, i, uint64(len(m.BodyBytes))) i-- dAtA[i] = 0xa } @@ -1219,18 +1336,41 @@ func (m *Tx) Size() (n int) { return n } +func (m *TxRaw) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.BodyBytes) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.AuthInfoBytes) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + if len(m.Signatures) > 0 { + for _, b := range m.Signatures { + l = len(b) + n += 1 + l + sovTx(uint64(l)) + } + } + return n +} + func (m *SignDoc) Size() (n int) { if m == nil { return 0 } var l int _ = l - if m.Body != nil { - l = m.Body.Size() + l = len(m.BodyBytes) + if l > 0 { n += 1 + l + sovTx(uint64(l)) } - if m.AuthInfo != nil { - l = m.AuthInfo.Size() + l = len(m.AuthInfoBytes) + if l > 0 { n += 1 + l + sovTx(uint64(l)) } l = len(m.ChainId) @@ -1564,6 +1704,159 @@ func (m *Tx) Unmarshal(dAtA []byte) error { } return nil } +func (m *TxRaw) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: TxRaw: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: TxRaw: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field BodyBytes", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.BodyBytes = append(m.BodyBytes[:0], dAtA[iNdEx:postIndex]...) + if m.BodyBytes == nil { + m.BodyBytes = []byte{} + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AuthInfoBytes", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.AuthInfoBytes = append(m.AuthInfoBytes[:0], dAtA[iNdEx:postIndex]...) + if m.AuthInfoBytes == nil { + m.AuthInfoBytes = []byte{} + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Signatures", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Signatures = append(m.Signatures, make([]byte, postIndex-iNdEx)) + copy(m.Signatures[len(m.Signatures)-1], dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *SignDoc) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 @@ -1595,9 +1888,9 @@ func (m *SignDoc) Unmarshal(dAtA []byte) error { switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Body", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field BodyBytes", wireType) } - var msglen int + var byteLen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowTx @@ -1607,33 +1900,31 @@ func (m *SignDoc) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + byteLen |= int(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + if byteLen < 0 { return ErrInvalidLengthTx } - postIndex := iNdEx + msglen + postIndex := iNdEx + byteLen if postIndex < 0 { return ErrInvalidLengthTx } if postIndex > l { return io.ErrUnexpectedEOF } - if m.Body == nil { - m.Body = &TxBody{} - } - if err := m.Body.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err + m.BodyBytes = append(m.BodyBytes[:0], dAtA[iNdEx:postIndex]...) + if m.BodyBytes == nil { + m.BodyBytes = []byte{} } iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field AuthInfo", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field AuthInfoBytes", wireType) } - var msglen int + var byteLen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowTx @@ -1643,26 +1934,24 @@ func (m *SignDoc) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + byteLen |= int(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + if byteLen < 0 { return ErrInvalidLengthTx } - postIndex := iNdEx + msglen + postIndex := iNdEx + byteLen if postIndex < 0 { return ErrInvalidLengthTx } if postIndex > l { return io.ErrUnexpectedEOF } - if m.AuthInfo == nil { - m.AuthInfo = &AuthInfo{} - } - if err := m.AuthInfo.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err + m.AuthInfoBytes = append(m.AuthInfoBytes[:0], dAtA[iNdEx:postIndex]...) + if m.AuthInfoBytes == nil { + m.AuthInfoBytes = []byte{} } iNdEx = postIndex case 3: @@ -2147,7 +2436,7 @@ func (m *SignerInfo) Unmarshal(dAtA []byte) error { return io.ErrUnexpectedEOF } if m.PublicKey == nil { - m.PublicKey = &types.Any{} + m.PublicKey = &types1.PublicKey{} } if err := m.PublicKey.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err diff --git a/types/tx/types.go b/types/tx/types.go new file mode 100644 index 000000000..ed56de13e --- /dev/null +++ b/types/tx/types.go @@ -0,0 +1,28 @@ +package tx + +import ( + codectypes "github.com/cosmos/cosmos-sdk/codec/types" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +var _, _ codectypes.UnpackInterfacesMessage = &Tx{}, &TxBody{} + +// UnpackInterfaces implements the UnpackInterfaceMessages.UnpackInterfaces method +func (m *Tx) UnpackInterfaces(unpacker codectypes.AnyUnpacker) error { + if m.Body != nil { + return m.Body.UnpackInterfaces(unpacker) + } + return nil +} + +// UnpackInterfaces implements the UnpackInterfaceMessages.UnpackInterfaces method +func (m *TxBody) UnpackInterfaces(unpacker codectypes.AnyUnpacker) error { + for _, any := range m.Messages { + var msg sdk.Msg + err := unpacker.UnpackAny(any, &msg) + if err != nil { + return err + } + } + return nil +} diff --git a/types/tx_msg.go b/types/tx_msg.go index 3524d9e75..45bf8bf85 100644 --- a/types/tx_msg.go +++ b/types/tx_msg.go @@ -1,8 +1,6 @@ package types import ( - "encoding/json" - "github.com/gogo/protobuf/proto" "github.com/tendermint/tendermint/crypto" @@ -80,35 +78,3 @@ type TxDecoder func(txBytes []byte) (Tx, error) type TxEncoder func(tx Tx) ([]byte, error) //__________________________________________________________ - -var _ Msg = (*TestMsg)(nil) - -// msg type for testing -type TestMsg struct { - signers []AccAddress -} - -// dummy implementation of proto.Message -func (msg *TestMsg) Reset() {} -func (msg *TestMsg) String() string { return "TODO" } -func (msg *TestMsg) ProtoMessage() {} - -func NewTestMsg(addrs ...AccAddress) *TestMsg { - return &TestMsg{ - signers: addrs, - } -} - -func (msg *TestMsg) Route() string { return "TestMsg" } -func (msg *TestMsg) Type() string { return "Test message" } -func (msg *TestMsg) GetSignBytes() []byte { - bz, err := json.Marshal(msg.signers) - if err != nil { - panic(err) - } - return MustSortJSON(bz) -} -func (msg *TestMsg) ValidateBasic() error { return nil } -func (msg *TestMsg) GetSigners() []AccAddress { - return msg.signers -} diff --git a/types/tx_msg_test.go b/types/tx_msg_test.go index 5023cbec5..9f7d0a26d 100644 --- a/types/tx_msg_test.go +++ b/types/tx_msg_test.go @@ -3,6 +3,8 @@ package types_test import ( "testing" + "github.com/cosmos/cosmos-sdk/codec/testdata" + "github.com/stretchr/testify/require" sdk "github.com/cosmos/cosmos-sdk/types" @@ -13,7 +15,7 @@ func TestTestMsg(t *testing.T) { addr := []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9} accAddr := sdk.AccAddress(addr) - msg := sdk.NewTestMsg(accAddr) + msg := testdata.NewTestMsg(accAddr) require.NotNil(t, msg) require.Equal(t, "TestMsg", msg.Route()) require.Equal(t, "Test message", msg.Type()) diff --git a/x/auth/ante/ante_test.go b/x/auth/ante/ante_test.go index 1c77e44ba..44366659d 100644 --- a/x/auth/ante/ante_test.go +++ b/x/auth/ante/ante_test.go @@ -7,6 +7,8 @@ import ( "strings" "testing" + "github.com/cosmos/cosmos-sdk/codec/testdata" + "github.com/cosmos/cosmos-sdk/types/tx/signing" "github.com/stretchr/testify/require" @@ -65,9 +67,9 @@ func TestSimulateGasCost(t *testing.T) { // set up msgs and fee var tx sdk.Tx - msg1 := types.NewTestMsg(addr1, addr2) - msg2 := types.NewTestMsg(addr3, addr1) - msg3 := types.NewTestMsg(addr2, addr3) + msg1 := testdata.NewTestMsg(addr1, addr2) + msg2 := testdata.NewTestMsg(addr3, addr1) + msg3 := testdata.NewTestMsg(addr2, addr3) msgs := []sdk.Msg{msg1, msg2, msg3} fee := types.NewTestStdFee() @@ -102,8 +104,8 @@ func TestAnteHandlerSigErrors(t *testing.T) { // msg and signatures var tx sdk.Tx - msg1 := types.NewTestMsg(addr1, addr2) - msg2 := types.NewTestMsg(addr1, addr3) + msg1 := testdata.NewTestMsg(addr1, addr2) + msg2 := testdata.NewTestMsg(addr1, addr3) fee := types.NewTestStdFee() msgs := []sdk.Msg{msg1, msg2} @@ -163,7 +165,7 @@ func TestAnteHandlerAccountNumbers(t *testing.T) { // msg and signatures var tx sdk.Tx - msg := types.NewTestMsg(addr1) + msg := testdata.NewTestMsg(addr1) fee := types.NewTestStdFee() msgs := []sdk.Msg{msg} @@ -184,8 +186,8 @@ func TestAnteHandlerAccountNumbers(t *testing.T) { checkValidTx(t, anteHandler, ctx, tx, false) // new tx with another signer and incorrect account numbers - msg1 := types.NewTestMsg(addr1, addr2) - msg2 := types.NewTestMsg(addr2, addr1) + msg1 := testdata.NewTestMsg(addr1, addr2) + msg2 := testdata.NewTestMsg(addr2, addr1) msgs = []sdk.Msg{msg1, msg2} privs, accnums, seqs = []crypto.PrivKey{priv1, priv2}, []uint64{1, 0}, []uint64{2, 0} tx = types.NewTestTx(ctx, msgs, privs, accnums, seqs, fee) @@ -221,7 +223,7 @@ func TestAnteHandlerAccountNumbersAtBlockHeightZero(t *testing.T) { // msg and signatures var tx sdk.Tx - msg := types.NewTestMsg(addr1) + msg := testdata.NewTestMsg(addr1) fee := types.NewTestStdFee() msgs := []sdk.Msg{msg} @@ -242,8 +244,8 @@ func TestAnteHandlerAccountNumbersAtBlockHeightZero(t *testing.T) { checkValidTx(t, anteHandler, ctx, tx, false) // new tx with another signer and incorrect account numbers - msg1 := types.NewTestMsg(addr1, addr2) - msg2 := types.NewTestMsg(addr2, addr1) + msg1 := testdata.NewTestMsg(addr1, addr2) + msg2 := testdata.NewTestMsg(addr2, addr1) msgs = []sdk.Msg{msg1, msg2} privs, accnums, seqs = []crypto.PrivKey{priv1, priv2}, []uint64{1, 0}, []uint64{2, 0} tx = types.NewTestTx(ctx, msgs, privs, accnums, seqs, fee) @@ -283,7 +285,7 @@ func TestAnteHandlerSequences(t *testing.T) { // msg and signatures var tx sdk.Tx - msg := types.NewTestMsg(addr1) + msg := testdata.NewTestMsg(addr1) fee := types.NewTestStdFee() msgs := []sdk.Msg{msg} @@ -302,8 +304,8 @@ func TestAnteHandlerSequences(t *testing.T) { checkValidTx(t, anteHandler, ctx, tx, false) // new tx with another signer and correct sequences - msg1 := types.NewTestMsg(addr1, addr2) - msg2 := types.NewTestMsg(addr3, addr1) + msg1 := testdata.NewTestMsg(addr1, addr2) + msg2 := testdata.NewTestMsg(addr3, addr1) msgs = []sdk.Msg{msg1, msg2} privs, accnums, seqs = []crypto.PrivKey{priv1, priv2, priv3}, []uint64{0, 1, 2}, []uint64{2, 0, 0} @@ -314,7 +316,7 @@ func TestAnteHandlerSequences(t *testing.T) { checkInvalidTx(t, anteHandler, ctx, tx, false, sdkerrors.ErrUnauthorized) // tx from just second signer with incorrect sequence fails - msg = types.NewTestMsg(addr2) + msg = testdata.NewTestMsg(addr2) msgs = []sdk.Msg{msg} privs, accnums, seqs = []crypto.PrivKey{priv2}, []uint64{1}, []uint64{0} tx = types.NewTestTx(ctx, msgs, privs, accnums, seqs, fee) @@ -325,7 +327,7 @@ func TestAnteHandlerSequences(t *testing.T) { checkValidTx(t, anteHandler, ctx, tx, false) // another tx from both of them that passes - msg = types.NewTestMsg(addr1, addr2) + msg = testdata.NewTestMsg(addr1, addr2) msgs = []sdk.Msg{msg} privs, accnums, seqs = []crypto.PrivKey{priv1, priv2}, []uint64{0, 1}, []uint64{3, 2} tx = types.NewTestTx(ctx, msgs, privs, accnums, seqs, fee) @@ -347,7 +349,7 @@ func TestAnteHandlerFees(t *testing.T) { // msg and signatures var tx sdk.Tx - msg := types.NewTestMsg(addr1) + msg := testdata.NewTestMsg(addr1) privs, accnums, seqs := []crypto.PrivKey{priv1}, []uint64{0}, []uint64{0} fee := types.NewTestStdFee() msgs := []sdk.Msg{msg} @@ -390,7 +392,7 @@ func TestAnteHandlerMemoGas(t *testing.T) { // msg and signatures var tx sdk.Tx - msg := types.NewTestMsg(addr1) + msg := testdata.NewTestMsg(addr1) privs, accnums, seqs := []crypto.PrivKey{priv1}, []uint64{0}, []uint64{0} fee := types.NewStdFee(0, sdk.NewCoins(sdk.NewInt64Coin("atom", 0))) @@ -441,9 +443,9 @@ func TestAnteHandlerMultiSigner(t *testing.T) { // set up msgs and fee var tx sdk.Tx - msg1 := types.NewTestMsg(addr1, addr2) - msg2 := types.NewTestMsg(addr3, addr1) - msg3 := types.NewTestMsg(addr2, addr3) + msg1 := testdata.NewTestMsg(addr1, addr2) + msg2 := testdata.NewTestMsg(addr3, addr1) + msg3 := testdata.NewTestMsg(addr2, addr3) msgs := []sdk.Msg{msg1, msg2, msg3} fee := types.NewTestStdFee() @@ -485,7 +487,7 @@ func TestAnteHandlerBadSignBytes(t *testing.T) { app.BankKeeper.SetBalances(ctx, addr2, types.NewTestCoins()) var tx sdk.Tx - msg := types.NewTestMsg(addr1) + msg := testdata.NewTestMsg(addr1) msgs := []sdk.Msg{msg} fee := types.NewTestStdFee() fee2 := types.NewTestStdFee() @@ -510,12 +512,12 @@ func TestAnteHandlerBadSignBytes(t *testing.T) { msgs []sdk.Msg err error }{ - {chainID2, 0, 1, fee, msgs, errUnauth}, // test wrong chain_id - {chainID, 0, 2, fee, msgs, errUnauth}, // test wrong seqs - {chainID, 1, 1, fee, msgs, errUnauth}, // test wrong accnum - {chainID, 0, 1, fee, []sdk.Msg{types.NewTestMsg(addr2)}, errUnauth}, // test wrong msg - {chainID, 0, 1, fee2, msgs, errUnauth}, // test wrong fee - {chainID, 0, 1, fee3, msgs, errUnauth}, // test wrong fee + {chainID2, 0, 1, fee, msgs, errUnauth}, // test wrong chain_id + {chainID, 0, 2, fee, msgs, errUnauth}, // test wrong seqs + {chainID, 1, 1, fee, msgs, errUnauth}, // test wrong accnum + {chainID, 0, 1, fee, []sdk.Msg{testdata.NewTestMsg(addr2)}, errUnauth}, // test wrong msg + {chainID, 0, 1, fee2, msgs, errUnauth}, // test wrong fee + {chainID, 0, 1, fee3, msgs, errUnauth}, // test wrong fee } privs, seqs = []crypto.PrivKey{priv1}, []uint64{1} @@ -534,7 +536,7 @@ func TestAnteHandlerBadSignBytes(t *testing.T) { checkInvalidTx(t, anteHandler, ctx, tx, false, sdkerrors.ErrInvalidPubKey) // test wrong signer if public doesn't exist - msg = types.NewTestMsg(addr2) + msg = testdata.NewTestMsg(addr2) msgs = []sdk.Msg{msg} privs, accnums, seqs = []crypto.PrivKey{priv1}, []uint64{1}, []uint64{0} tx = types.NewTestTx(ctx, msgs, privs, accnums, seqs, fee) @@ -564,7 +566,7 @@ func TestAnteHandlerSetPubKey(t *testing.T) { var tx sdk.Tx // test good tx and set public key - msg := types.NewTestMsg(addr1) + msg := testdata.NewTestMsg(addr1) msgs := []sdk.Msg{msg} privs, accnums, seqs := []crypto.PrivKey{priv1}, []uint64{0}, []uint64{0} fee := types.NewTestStdFee() @@ -575,7 +577,7 @@ func TestAnteHandlerSetPubKey(t *testing.T) { require.Equal(t, acc1.GetPubKey(), priv1.PubKey()) // test public key not found - msg = types.NewTestMsg(addr2) + msg = testdata.NewTestMsg(addr2) msgs = []sdk.Msg{msg} tx = types.NewTestTx(ctx, msgs, privs, []uint64{1}, seqs, fee) sigs := tx.(types.StdTx).Signatures @@ -693,7 +695,7 @@ func TestAnteHandlerSigLimitExceeded(t *testing.T) { } var tx sdk.Tx - msg := types.NewTestMsg(addr1, addr2, addr3, addr4, addr5, addr6, addr7, addr8) + msg := testdata.NewTestMsg(addr1, addr2, addr3, addr4, addr5, addr6, addr7, addr8) msgs := []sdk.Msg{msg} fee := types.NewTestStdFee() @@ -727,7 +729,7 @@ func TestCustomSignatureVerificationGasConsumer(t *testing.T) { app.BankKeeper.SetBalances(ctx, addr1, sdk.NewCoins(sdk.NewInt64Coin("atom", 150))) var tx sdk.Tx - msg := types.NewTestMsg(addr1) + msg := testdata.NewTestMsg(addr1) privs, accnums, seqs := []crypto.PrivKey{priv1}, []uint64{0}, []uint64{0} fee := types.NewTestStdFee() msgs := []sdk.Msg{msg} @@ -743,7 +745,7 @@ func TestCustomSignatureVerificationGasConsumer(t *testing.T) { require.NoError(t, app.BankKeeper.SetBalances(ctx, addr2, sdk.NewCoins(sdk.NewInt64Coin("atom", 150)))) require.NoError(t, acc2.SetAccountNumber(1)) app.AccountKeeper.SetAccount(ctx, acc2) - msg = types.NewTestMsg(addr2) + msg = testdata.NewTestMsg(addr2) privs, accnums, seqs = []crypto.PrivKey{priv2}, []uint64{1}, []uint64{0} fee = types.NewTestStdFee() msgs = []sdk.Msg{msg} @@ -772,7 +774,7 @@ func TestAnteHandlerReCheck(t *testing.T) { // test that operations skipped on recheck do not run - msg := types.NewTestMsg(addr1) + msg := testdata.NewTestMsg(addr1) msgs := []sdk.Msg{msg} fee := types.NewTestStdFee() diff --git a/x/auth/ante/basic.go b/x/auth/ante/basic.go index f7120e627..9fca3521d 100644 --- a/x/auth/ante/basic.go +++ b/x/auth/ante/basic.go @@ -1,6 +1,7 @@ package ante import ( + "github.com/cosmos/cosmos-sdk/x/auth/signing" "github.com/tendermint/tendermint/crypto" "github.com/cosmos/cosmos-sdk/codec/legacy" @@ -89,7 +90,7 @@ func NewConsumeGasForTxSizeDecorator(ak AccountKeeper) ConsumeTxSizeGasDecorator } func (cgts ConsumeTxSizeGasDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (sdk.Context, error) { - sigTx, ok := tx.(SigVerifiableTx) + sigTx, ok := tx.(signing.SigVerifiableTx) if !ok { return ctx, sdkerrors.Wrap(sdkerrors.ErrTxDecode, "invalid tx type") } diff --git a/x/auth/ante/basic_test.go b/x/auth/ante/basic_test.go index 145137f4c..ce97bc43e 100644 --- a/x/auth/ante/basic_test.go +++ b/x/auth/ante/basic_test.go @@ -5,6 +5,8 @@ import ( "strings" "testing" + "github.com/cosmos/cosmos-sdk/codec/testdata" + "github.com/stretchr/testify/require" "github.com/tendermint/tendermint/crypto" @@ -21,7 +23,7 @@ func TestValidateBasic(t *testing.T) { priv1, _, addr1 := types.KeyTestPubAddr() // msg and signatures - msg1 := types.NewTestMsg(addr1) + msg1 := testdata.NewTestMsg(addr1) fee := types.NewTestStdFee() msgs := []sdk.Msg{msg1} @@ -58,7 +60,7 @@ func TestValidateMemo(t *testing.T) { priv1, _, addr1 := types.KeyTestPubAddr() // msg and signatures - msg1 := types.NewTestMsg(addr1) + msg1 := testdata.NewTestMsg(addr1) fee := types.NewTestStdFee() msgs := []sdk.Msg{msg1} @@ -88,7 +90,7 @@ func TestConsumeGasForTxSize(t *testing.T) { priv1, _, addr1 := types.KeyTestPubAddr() // msg and signatures - msg1 := types.NewTestMsg(addr1) + msg1 := testdata.NewTestMsg(addr1) fee := types.NewTestStdFee() msgs := []sdk.Msg{msg1} diff --git a/x/auth/ante/fee_test.go b/x/auth/ante/fee_test.go index 23e5b7e9b..c56ca7219 100644 --- a/x/auth/ante/fee_test.go +++ b/x/auth/ante/fee_test.go @@ -3,6 +3,8 @@ package ante_test import ( "testing" + "github.com/cosmos/cosmos-sdk/codec/testdata" + "github.com/stretchr/testify/require" "github.com/tendermint/tendermint/crypto" @@ -22,7 +24,7 @@ func TestEnsureMempoolFees(t *testing.T) { priv1, _, addr1 := types.KeyTestPubAddr() // msg and signatures - msg1 := types.NewTestMsg(addr1) + msg1 := testdata.NewTestMsg(addr1) fee := types.NewTestStdFee() msgs := []sdk.Msg{msg1} @@ -68,7 +70,7 @@ func TestDeductFees(t *testing.T) { priv1, _, addr1 := types.KeyTestPubAddr() // msg and signatures - msg1 := types.NewTestMsg(addr1) + msg1 := testdata.NewTestMsg(addr1) fee := types.NewTestStdFee() msgs := []sdk.Msg{msg1} diff --git a/x/auth/ante/setup_test.go b/x/auth/ante/setup_test.go index 698a0eced..ad1346760 100644 --- a/x/auth/ante/setup_test.go +++ b/x/auth/ante/setup_test.go @@ -3,6 +3,8 @@ package ante_test import ( "testing" + "github.com/cosmos/cosmos-sdk/codec/testdata" + "github.com/stretchr/testify/require" "github.com/tendermint/tendermint/crypto" @@ -20,7 +22,7 @@ func TestSetup(t *testing.T) { priv1, _, addr1 := types.KeyTestPubAddr() // msg and signatures - msg1 := types.NewTestMsg(addr1) + msg1 := testdata.NewTestMsg(addr1) fee := types.NewTestStdFee() msgs := []sdk.Msg{msg1} @@ -52,7 +54,7 @@ func TestRecoverPanic(t *testing.T) { priv1, _, addr1 := types.KeyTestPubAddr() // msg and signatures - msg1 := types.NewTestMsg(addr1) + msg1 := testdata.NewTestMsg(addr1) fee := types.NewTestStdFee() msgs := []sdk.Msg{msg1} diff --git a/x/auth/ante/sigverify.go b/x/auth/ante/sigverify.go index b7d7d46de..c04217b58 100644 --- a/x/auth/ante/sigverify.go +++ b/x/auth/ante/sigverify.go @@ -9,7 +9,6 @@ import ( "github.com/cosmos/cosmos-sdk/types/tx/signing" - "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/crypto/ed25519" "github.com/tendermint/tendermint/crypto/secp256k1" @@ -24,7 +23,7 @@ var ( simSecp256k1Pubkey secp256k1.PubKeySecp256k1 simSecp256k1Sig [64]byte - _ SigVerifiableTx = (*types.StdTx)(nil) // assert StdTx implements SigVerifiableTx + _ authsigning.SigVerifiableTx = (*types.StdTx)(nil) // assert StdTx implements SigVerifiableTx ) func init() { @@ -38,15 +37,6 @@ func init() { // This is where apps can define their own PubKey type SignatureVerificationGasConsumer = func(meter sdk.GasMeter, sig signing.SignatureV2, params types.Params) error -// SigVerifiableTx defines a Tx interface for all signature verification decorators -type SigVerifiableTx interface { - sdk.Tx - GetSigners() []sdk.AccAddress - GetPubKeys() []crypto.PubKey // If signer already has pubkey in context, this list will have nil in its place - GetSignatures() [][]byte - GetSignaturesV2() ([]signing.SignatureV2, error) -} - // SetPubKeyDecorator sets PubKeys in context for any signer which does not already have pubkey set // PubKeys must be set in context for all signers before any other sigverify decorators run // CONTRACT: Tx must implement SigVerifiableTx interface @@ -61,7 +51,7 @@ func NewSetPubKeyDecorator(ak AccountKeeper) SetPubKeyDecorator { } func (spkd SetPubKeyDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (sdk.Context, error) { - sigTx, ok := tx.(SigVerifiableTx) + sigTx, ok := tx.(authsigning.SigVerifiableTx) if !ok { return ctx, sdkerrors.Wrap(sdkerrors.ErrTxDecode, "invalid tx type") } @@ -118,7 +108,7 @@ func NewSigGasConsumeDecorator(ak AccountKeeper, sigGasConsumer SignatureVerific } func (sgcd SigGasConsumeDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (newCtx sdk.Context, err error) { - sigTx, ok := tx.(SigVerifiableTx) + sigTx, ok := tx.(authsigning.SigVerifiableTx) if !ok { return ctx, sdkerrors.Wrap(sdkerrors.ErrTxDecode, "invalid transaction type") } @@ -186,7 +176,7 @@ func (svd SigVerificationDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simul if ctx.IsReCheckTx() { return next(ctx, tx, simulate) } - sigTx, ok := tx.(SigVerifiableTx) + sigTx, ok := tx.(authsigning.SigVerifiableTx) if !ok { return ctx, sdkerrors.Wrap(sdkerrors.ErrTxDecode, "invalid transaction type") } @@ -268,7 +258,7 @@ func NewIncrementSequenceDecorator(ak AccountKeeper) IncrementSequenceDecorator } func (isd IncrementSequenceDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (sdk.Context, error) { - sigTx, ok := tx.(SigVerifiableTx) + sigTx, ok := tx.(authsigning.SigVerifiableTx) if !ok { return ctx, sdkerrors.Wrap(sdkerrors.ErrTxDecode, "invalid transaction type") } @@ -301,7 +291,7 @@ func NewValidateSigCountDecorator(ak AccountKeeper) ValidateSigCountDecorator { } func (vscd ValidateSigCountDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (sdk.Context, error) { - sigTx, ok := tx.(SigVerifiableTx) + sigTx, ok := tx.(authsigning.SigVerifiableTx) if !ok { return ctx, sdkerrors.Wrap(sdkerrors.ErrTxDecode, "Tx must be a sigTx") } @@ -359,7 +349,7 @@ func ConsumeMultisignatureVerificationGas( meter sdk.GasMeter, sig *signing.MultiSignatureData, pubkey multisig.PubKey, params types.Params, ) error { - size := sig.BitArray.Size() + size := sig.BitArray.Count() sigIndex := 0 for i := 0; i < size; i++ { diff --git a/x/auth/ante/sigverify_test.go b/x/auth/ante/sigverify_test.go index 2f65478af..cdbd88888 100644 --- a/x/auth/ante/sigverify_test.go +++ b/x/auth/ante/sigverify_test.go @@ -2,6 +2,7 @@ package ante_test import ( "fmt" + "github.com/cosmos/cosmos-sdk/codec/testdata" "testing" "github.com/cosmos/cosmos-sdk/types/tx/signing" @@ -37,7 +38,7 @@ func TestSetPubKey(t *testing.T) { acc := app.AccountKeeper.NewAccountWithAddress(ctx, addr) require.NoError(t, acc.SetAccountNumber(uint64(i))) app.AccountKeeper.SetAccount(ctx, acc) - msgs[i] = types.NewTestMsg(addr) + msgs[i] = testdata.NewTestMsg(addr) } fee := types.NewTestStdFee() @@ -131,7 +132,7 @@ func TestSigVerification(t *testing.T) { acc := app.AccountKeeper.NewAccountWithAddress(ctx, addr) require.NoError(t, acc.SetAccountNumber(uint64(i))) app.AccountKeeper.SetAccount(ctx, acc) - msgs[i] = types.NewTestMsg(addr) + msgs[i] = testdata.NewTestMsg(addr) } fee := types.NewTestStdFee() @@ -203,7 +204,7 @@ func runSigDecorators(t *testing.T, params types.Params, _ bool, privs ...crypto acc := app.AccountKeeper.NewAccountWithAddress(ctx, addr) require.NoError(t, acc.SetAccountNumber(uint64(i))) app.AccountKeeper.SetAccount(ctx, acc) - msgs[i] = types.NewTestMsg(addr) + msgs[i] = testdata.NewTestMsg(addr) accNums[i] = uint64(i) seqs[i] = uint64(0) } @@ -233,7 +234,7 @@ func TestIncrementSequenceDecorator(t *testing.T) { require.NoError(t, acc.SetAccountNumber(uint64(50))) app.AccountKeeper.SetAccount(ctx, acc) - msgs := []sdk.Msg{types.NewTestMsg(addr)} + msgs := []sdk.Msg{testdata.NewTestMsg(addr)} privKeys := []crypto.PrivKey{priv} accNums := []uint64{app.AccountKeeper.GetAccount(ctx, addr).GetAccountNumber()} accSeqs := []uint64{app.AccountKeeper.GetAccount(ctx, addr).GetSequence()} diff --git a/x/auth/client/cli/validate_sigs.go b/x/auth/client/cli/validate_sigs.go index e961f98bb..e6d90509f 100644 --- a/x/auth/client/cli/validate_sigs.go +++ b/x/auth/client/cli/validate_sigs.go @@ -114,7 +114,7 @@ func printAndValidateSigs( var b strings.Builder b.WriteString("\n MultiSig Signatures:\n") - for i := 0; i < multiSig.BitArray.Size(); i++ { + for i := 0; i < multiSig.BitArray.Count(); i++ { if multiSig.BitArray.GetIndex(i) { addr := sdk.AccAddress(multiPK.PubKeys[i].Address().Bytes()) b.WriteString(fmt.Sprintf(" %d: %s (weight: %d)\n", i, addr, 1)) diff --git a/x/auth/client/tx_test.go b/x/auth/client/tx_test.go index ed09f3158..0bc4f2fbb 100644 --- a/x/auth/client/tx_test.go +++ b/x/auth/client/tx_test.go @@ -8,6 +8,8 @@ import ( "strings" "testing" + "github.com/cosmos/cosmos-sdk/codec/testdata" + simappparams "github.com/cosmos/cosmos-sdk/simapp/params" "github.com/cosmos/cosmos-sdk/client" @@ -195,7 +197,7 @@ malformed } func compareEncoders(t *testing.T, expected sdk.TxEncoder, actual sdk.TxEncoder) { - msgs := []sdk.Msg{sdk.NewTestMsg(addr)} + msgs := []sdk.Msg{testdata.NewTestMsg(addr)} tx := authtypes.NewStdTx(msgs, authtypes.StdFee{}, []authtypes.StdSignature{}, "") defaultEncoderBytes, err := expected(tx) @@ -262,6 +264,6 @@ func makeCodec() *codec.Codec { sdk.RegisterCodec(cdc) cryptocodec.RegisterCrypto(cdc) authtypes.RegisterCodec(cdc) - cdc.RegisterConcrete(sdk.TestMsg{}, "cosmos-sdk/Test", nil) + cdc.RegisterConcrete(testdata.TestMsg{}, "cosmos-sdk/Test", nil) return cdc } diff --git a/x/auth/signing/direct/direct.go b/x/auth/signing/direct/direct.go new file mode 100644 index 000000000..8377f4403 --- /dev/null +++ b/x/auth/signing/direct/direct.go @@ -0,0 +1,66 @@ +package direct + +import ( + "fmt" + + signingtypes "github.com/cosmos/cosmos-sdk/types/tx/signing" + + sdk "github.com/cosmos/cosmos-sdk/types" + types "github.com/cosmos/cosmos-sdk/types/tx" + "github.com/cosmos/cosmos-sdk/x/auth/signing" +) + +// ProtoTx defines an interface which protobuf transactions must implement for +// signature verification via SignModeDirect +type ProtoTx interface { + // GetBodyBytes returns the raw serialized bytes for TxBody + GetBodyBytes() []byte + + // GetBodyBytes returns the raw serialized bytes for AuthInfo + GetAuthInfoBytes() []byte +} + +// ModeHandler defines the SIGN_MODE_DIRECT SignModeHandler +type ModeHandler struct{} + +var _ signing.SignModeHandler = ModeHandler{} + +// DefaultMode implements SignModeHandler.DefaultMode +func (ModeHandler) DefaultMode() signingtypes.SignMode { + return signingtypes.SignMode_SIGN_MODE_DIRECT +} + +// Modes implements SignModeHandler.Modes +func (ModeHandler) Modes() []signingtypes.SignMode { + return []signingtypes.SignMode{signingtypes.SignMode_SIGN_MODE_DIRECT} +} + +// GetSignBytes implements SignModeHandler.GetSignBytes +func (ModeHandler) GetSignBytes(mode signingtypes.SignMode, data signing.SignerData, tx sdk.Tx) ([]byte, error) { + if mode != signingtypes.SignMode_SIGN_MODE_DIRECT { + return nil, fmt.Errorf("expected %s, got %s", signingtypes.SignMode_SIGN_MODE_DIRECT, mode) + } + + protoTx, ok := tx.(ProtoTx) + if !ok { + return nil, fmt.Errorf("can only get direct sign bytes for a ProtoTx, got %T", tx) + } + + bodyBz := protoTx.GetBodyBytes() + authInfoBz := protoTx.GetAuthInfoBytes() + + return SignBytes(bodyBz, authInfoBz, data.ChainID, data.AccountNumber, data.AccountSequence) +} + +// SignBytes returns the SIGN_MODE_DIRECT sign bytes for the provided TxBody bytes, AuthInfo bytes, chain ID, +// account number and sequence. +func SignBytes(bodyBytes, authInfoBytes []byte, chainID string, accnum, sequence uint64) ([]byte, error) { + signDoc := types.SignDoc{ + BodyBytes: bodyBytes, + AuthInfoBytes: authInfoBytes, + ChainId: chainID, + AccountNumber: accnum, + AccountSequence: sequence, + } + return signDoc.Marshal() +} diff --git a/x/auth/signing/direct/direct_test.go b/x/auth/signing/direct/direct_test.go new file mode 100644 index 000000000..442ebbfac --- /dev/null +++ b/x/auth/signing/direct/direct_test.go @@ -0,0 +1,139 @@ +package direct_test + +import ( + "testing" + + "github.com/cosmos/cosmos-sdk/x/auth/tx" + + "github.com/cosmos/cosmos-sdk/x/auth/signing/direct" + + "github.com/cosmos/cosmos-sdk/codec/testdata" + + "github.com/cosmos/cosmos-sdk/codec" + + signingtypes "github.com/cosmos/cosmos-sdk/types/tx/signing" + + "github.com/stretchr/testify/require" + + codectypes "github.com/cosmos/cosmos-sdk/codec/types" + "github.com/cosmos/cosmos-sdk/std" + sdk "github.com/cosmos/cosmos-sdk/types" + txtypes "github.com/cosmos/cosmos-sdk/types/tx" + "github.com/cosmos/cosmos-sdk/x/auth/signing" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" +) + +func TestDirectModeHandler(t *testing.T) { + privKey, pubkey, addr := authtypes.KeyTestPubAddr() + interfaceRegistry := codectypes.NewInterfaceRegistry() + interfaceRegistry.RegisterImplementations((*sdk.Msg)(nil), &testdata.TestMsg{}) + marshaler := codec.NewProtoCodec(interfaceRegistry) + pubKeyCdc := std.DefaultPublicKeyCodec{} + + txGen := tx.NewTxGenerator(marshaler, pubKeyCdc, tx.DefaultSignModeHandler()) + txBuilder := txGen.NewTxBuilder() + + memo := "sometestmemo" + msgs := []sdk.Msg{testdata.NewTestMsg(addr)} + + pk, err := pubKeyCdc.Encode(pubkey) + require.NoError(t, err) + + var signerInfo []*txtypes.SignerInfo + signerInfo = append(signerInfo, &txtypes.SignerInfo{ + PublicKey: pk, + ModeInfo: &txtypes.ModeInfo{ + Sum: &txtypes.ModeInfo_Single_{ + Single: &txtypes.ModeInfo_Single{ + Mode: signingtypes.SignMode_SIGN_MODE_DIRECT, + }, + }, + }, + }) + + sigData := &signingtypes.SingleSignatureData{ + SignMode: signingtypes.SignMode_SIGN_MODE_DIRECT, + } + sig := signingtypes.SignatureV2{ + PubKey: pubkey, + Data: sigData, + } + + fee := txtypes.Fee{Amount: sdk.NewCoins(sdk.NewInt64Coin("atom", 150)), GasLimit: 20000} + + err = txBuilder.SetMsgs(msgs...) + require.NoError(t, err) + txBuilder.SetMemo(memo) + txBuilder.SetFeeAmount(fee.Amount) + txBuilder.SetGasLimit(fee.GasLimit) + + err = txBuilder.SetSignatures(sig) + require.NoError(t, err) + + t.Log("verify modes and default-mode") + directModeHandler := direct.ModeHandler{} + require.Equal(t, directModeHandler.DefaultMode(), signingtypes.SignMode_SIGN_MODE_DIRECT) + require.Len(t, directModeHandler.Modes(), 1) + + signingData := signing.SignerData{ + ChainID: "test-chain", + AccountNumber: 1, + AccountSequence: 1, + } + + signBytes, err := directModeHandler.GetSignBytes(signingtypes.SignMode_SIGN_MODE_DIRECT, signingData, txBuilder.GetTx()) + + require.NoError(t, err) + require.NotNil(t, signBytes) + + authInfo := &txtypes.AuthInfo{ + Fee: &fee, + SignerInfos: signerInfo, + } + + authInfoBytes := marshaler.MustMarshalBinaryBare(authInfo) + + anys := make([]*codectypes.Any, len(msgs)) + + for i, msg := range msgs { + var err error + anys[i], err = codectypes.NewAnyWithValue(msg) + if err != nil { + panic(err) + } + } + + txBody := &txtypes.TxBody{ + Memo: memo, + Messages: anys, + } + bodyBytes := marshaler.MustMarshalBinaryBare(txBody) + + t.Log("verify GetSignBytes with generating sign bytes by marshaling SignDoc") + signDoc := txtypes.SignDoc{ + AccountNumber: 1, + AccountSequence: 1, + AuthInfoBytes: authInfoBytes, + BodyBytes: bodyBytes, + ChainId: "test-chain", + } + + expectedSignBytes, err := signDoc.Marshal() + require.NoError(t, err) + require.Equal(t, expectedSignBytes, signBytes) + + t.Log("verify that setting signature doesn't change sign bytes") + sigData.Signature, err = privKey.Sign(signBytes) + require.NoError(t, err) + err = txBuilder.SetSignatures(sig) + require.NoError(t, err) + signBytes, err = directModeHandler.GetSignBytes(signingtypes.SignMode_SIGN_MODE_DIRECT, signingData, txBuilder.GetTx()) + require.NoError(t, err) + require.Equal(t, expectedSignBytes, signBytes) + + t.Log("verify GetSignBytes with false txBody data") + signDoc.BodyBytes = []byte("dfafdasfds") + expectedSignBytes, err = signDoc.Marshal() + require.NoError(t, err) + require.NotEqual(t, expectedSignBytes, signBytes) +} diff --git a/x/auth/signing/sig_verifiable_tx.go b/x/auth/signing/sig_verifiable_tx.go new file mode 100644 index 000000000..599a544ea --- /dev/null +++ b/x/auth/signing/sig_verifiable_tx.go @@ -0,0 +1,24 @@ +package signing + +import ( + "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/tx/signing" + "github.com/tendermint/tendermint/crypto" +) + +// SigVerifiableTx defines a Tx interface for all signature verification decorators +type SigVerifiableTx interface { + types.Tx + GetSigners() []types.AccAddress + GetPubKeys() []crypto.PubKey // If signer already has pubkey in context, this list will have nil in its place + GetSignatures() [][]byte + GetSignaturesV2() ([]signing.SignatureV2, error) +} + +// SigFeeMemoTx defines an interface for transactions that support all standard message, signature, +// fee and memo interfaces. +type SigFeeMemoTx interface { + SigVerifiableTx + types.TxWithMemo + types.FeeTx +} diff --git a/x/auth/signing/verify_test.go b/x/auth/signing/verify_test.go index e93aae75f..98b820478 100644 --- a/x/auth/signing/verify_test.go +++ b/x/auth/signing/verify_test.go @@ -3,6 +3,8 @@ package signing_test import ( "testing" + "github.com/cosmos/cosmos-sdk/codec/testdata" + "github.com/stretchr/testify/require" abci "github.com/tendermint/tendermint/abci/types" "github.com/tendermint/tendermint/crypto" @@ -31,7 +33,7 @@ func TestVerifySignature(t *testing.T) { cdc := codec.New() sdk.RegisterCodec(cdc) types.RegisterCodec(cdc) - cdc.RegisterConcrete(sdk.TestMsg{}, "cosmos-sdk/Test", nil) + cdc.RegisterConcrete(testdata.TestMsg{}, "cosmos-sdk/Test", nil) acc1 := app.AccountKeeper.NewAccountWithAddress(ctx, addr) _ = app.AccountKeeper.NewAccountWithAddress(ctx, addr1) @@ -41,7 +43,7 @@ func TestVerifySignature(t *testing.T) { acc, err := ante.GetSignerAcc(ctx, app.AccountKeeper, addr) require.NoError(t, app.BankKeeper.SetBalances(ctx, addr, balances)) - msgs := []sdk.Msg{types.NewTestMsg(addr)} + msgs := []sdk.Msg{testdata.NewTestMsg(addr)} fee := types.NewStdFee(50000, sdk.Coins{sdk.NewInt64Coin("atom", 150)}) signerData := signing.SignerData{ ChainID: chainId, @@ -65,7 +67,7 @@ func TestVerifySignature(t *testing.T) { pkSet := []crypto.PubKey{pubKey, pubKey1} multisigKey := multisig.NewPubKeyMultisigThreshold(2, pkSet) multisignature := multisig.NewMultisig(2) - msgs = []sdk.Msg{types.NewTestMsg(addr, addr1)} + msgs = []sdk.Msg{testdata.NewTestMsg(addr, addr1)} multiSignBytes := types.StdSignBytes(signerData.ChainID, signerData.AccountNumber, signerData.AccountSequence, fee, msgs, memo) diff --git a/x/auth/tx/builder.go b/x/auth/tx/builder.go new file mode 100644 index 000000000..7df625aa7 --- /dev/null +++ b/x/auth/tx/builder.go @@ -0,0 +1,317 @@ +package tx + +import ( + "fmt" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/x/auth/signing/direct" + + authsigning "github.com/cosmos/cosmos-sdk/x/auth/signing" + + "github.com/cosmos/cosmos-sdk/types/tx" + + "github.com/cosmos/cosmos-sdk/types/tx/signing" + + codectypes "github.com/cosmos/cosmos-sdk/codec/types" + + "github.com/tendermint/tendermint/crypto" + + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/crypto/types" + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" +) + +type builder struct { + tx *tx.Tx + + // bodyBz represents the protobuf encoding of TxBody. This should be encoding + // from the client using TxRaw if the tx was decoded from the wire + bodyBz []byte + + // authInfoBz represents the protobuf encoding of TxBody. This should be encoding + // from the client using TxRaw if the tx was decoded from the wire + authInfoBz []byte + + // pubKeys represents the cached crypto.PubKey's that were set either from tx decoding + // or decoded from AuthInfo when GetPubKey's was called + pubKeys []crypto.PubKey + + marshaler codec.Marshaler + pubkeyCodec types.PublicKeyCodec +} + +var ( + _ authsigning.SigFeeMemoTx = &builder{} + _ client.TxBuilder = &builder{} + _ direct.ProtoTx = &builder{} +) + +func newBuilder(marshaler codec.Marshaler, pubkeyCodec types.PublicKeyCodec) *builder { + return &builder{ + tx: &tx.Tx{ + Body: &tx.TxBody{}, + AuthInfo: &tx.AuthInfo{ + Fee: &tx.Fee{}, + }, + }, + marshaler: marshaler, + pubkeyCodec: pubkeyCodec, + } +} + +func (t *builder) GetMsgs() []sdk.Msg { + anys := t.tx.Body.Messages + res := make([]sdk.Msg, len(anys)) + for i, any := range anys { + msg := any.GetCachedValue().(sdk.Msg) + res[i] = msg + } + return res +} + +// MaxGasWanted defines the max gas allowed. +const MaxGasWanted = uint64((1 << 63) - 1) + +func (t *builder) ValidateBasic() error { + theTx := t.tx + if theTx == nil { + return fmt.Errorf("bad Tx") + } + + body := t.tx.Body + if body == nil { + return fmt.Errorf("missing TxBody") + } + + authInfo := t.tx.AuthInfo + if authInfo == nil { + return fmt.Errorf("missing AuthInfo") + } + + fee := authInfo.Fee + if fee == nil { + return fmt.Errorf("missing fee") + } + + if fee.GasLimit > MaxGasWanted { + return sdkerrors.Wrapf( + sdkerrors.ErrInvalidRequest, + "invalid gas supplied; %d > %d", fee.GasLimit, MaxGasWanted, + ) + } + + if fee.Amount.IsAnyNegative() { + return sdkerrors.Wrapf( + sdkerrors.ErrInsufficientFee, + "invalid fee provided: %s", fee.Amount, + ) + } + + sigs := theTx.Signatures + + if len(sigs) == 0 { + return sdkerrors.ErrNoSignatures + } + + if len(sigs) != len(t.GetSigners()) { + return sdkerrors.Wrapf( + sdkerrors.ErrUnauthorized, + "wrong number of signers; expected %d, got %d", t.GetSigners(), len(sigs), + ) + } + + return nil +} + +func (t *builder) GetBodyBytes() []byte { + if len(t.bodyBz) == 0 { + // if bodyBz is empty, then marshal the body. bodyBz will generally + // be set to nil whenever SetBody is called so the result of calling + // this method should always return the correct bytes. Note that after + // decoding bodyBz is derived from TxRaw so that it matches what was + // transmitted over the wire + t.bodyBz = t.marshaler.MustMarshalBinaryBare(t.tx.Body) + } + return t.bodyBz +} + +func (t *builder) GetAuthInfoBytes() []byte { + if len(t.authInfoBz) == 0 { + // if authInfoBz is empty, then marshal the body. authInfoBz will generally + // be set to nil whenever SetAuthInfo is called so the result of calling + // this method should always return the correct bytes. Note that after + // decoding authInfoBz is derived from TxRaw so that it matches what was + // transmitted over the wire + t.authInfoBz = t.marshaler.MustMarshalBinaryBare(t.tx.AuthInfo) + } + return t.authInfoBz +} + +func (t *builder) GetSigners() []sdk.AccAddress { + var signers []sdk.AccAddress + seen := map[string]bool{} + + for _, msg := range t.GetMsgs() { + for _, addr := range msg.GetSigners() { + if !seen[addr.String()] { + signers = append(signers, addr) + seen[addr.String()] = true + } + } + } + + return signers +} + +func (t *builder) GetPubKeys() []crypto.PubKey { + if t.pubKeys == nil { + signerInfos := t.tx.AuthInfo.SignerInfos + pubKeys := make([]crypto.PubKey, len(signerInfos)) + + for i, si := range signerInfos { + var err error + pk := si.PublicKey + if pk != nil { + pubKeys[i], err = t.pubkeyCodec.Decode(si.PublicKey) + if err != nil { + panic(err) + } + } + } + + t.pubKeys = pubKeys + } + + return t.pubKeys +} + +func (t *builder) GetGas() uint64 { + return t.tx.AuthInfo.Fee.GasLimit +} + +func (t *builder) GetFee() sdk.Coins { + return t.tx.AuthInfo.Fee.Amount +} + +func (t *builder) FeePayer() sdk.AccAddress { + return t.GetSigners()[0] +} + +func (t *builder) GetMemo() string { + return t.tx.Body.Memo +} + +func (t *builder) GetSignatures() [][]byte { + return t.tx.Signatures +} + +func (t *builder) GetSignaturesV2() ([]signing.SignatureV2, error) { + signerInfos := t.tx.AuthInfo.SignerInfos + sigs := t.tx.Signatures + pubKeys := t.GetPubKeys() + n := len(signerInfos) + res := make([]signing.SignatureV2, n) + + for i, si := range signerInfos { + var err error + sigData, err := ModeInfoAndSigToSignatureData(si.ModeInfo, sigs[i]) + if err != nil { + return nil, err + } + res[i] = signing.SignatureV2{ + PubKey: pubKeys[i], + Data: sigData, + } + } + + return res, nil +} + +func (t *builder) SetMsgs(msgs ...sdk.Msg) error { + anys := make([]*codectypes.Any, len(msgs)) + + for i, msg := range msgs { + var err error + anys[i], err = codectypes.NewAnyWithValue(msg) + if err != nil { + return err + } + } + + t.tx.Body.Messages = anys + + // set bodyBz to nil because the cached bodyBz no longer matches tx.Body + t.bodyBz = nil + + return nil +} + +func (t *builder) SetMemo(memo string) { + t.tx.Body.Memo = memo + + // set bodyBz to nil because the cached bodyBz no longer matches tx.Body + t.bodyBz = nil +} + +func (t *builder) SetGasLimit(limit uint64) { + if t.tx.AuthInfo.Fee == nil { + t.tx.AuthInfo.Fee = &tx.Fee{} + } + + t.tx.AuthInfo.Fee.GasLimit = limit + + // set authInfoBz to nil because the cached authInfoBz no longer matches tx.AuthInfo + t.authInfoBz = nil +} + +func (t *builder) SetFeeAmount(coins sdk.Coins) { + if t.tx.AuthInfo.Fee == nil { + t.tx.AuthInfo.Fee = &tx.Fee{} + } + + t.tx.AuthInfo.Fee.Amount = coins + + // set authInfoBz to nil because the cached authInfoBz no longer matches tx.AuthInfo + t.authInfoBz = nil +} + +func (t *builder) SetSignatures(signatures ...signing.SignatureV2) error { + n := len(signatures) + signerInfos := make([]*tx.SignerInfo, n) + rawSigs := make([][]byte, n) + + for i, sig := range signatures { + var modeInfo *tx.ModeInfo + modeInfo, rawSigs[i] = SignatureDataToModeInfoAndSig(sig.Data) + pk, err := t.pubkeyCodec.Encode(sig.PubKey) + if err != nil { + return err + } + signerInfos[i] = &tx.SignerInfo{ + PublicKey: pk, + ModeInfo: modeInfo, + } + } + + t.setSignerInfos(signerInfos) + t.setSignatures(rawSigs) + + return nil +} + +func (t *builder) setSignerInfos(infos []*tx.SignerInfo) { + t.tx.AuthInfo.SignerInfos = infos + // set authInfoBz to nil because the cached authInfoBz no longer matches tx.AuthInfo + t.authInfoBz = nil + // set cached pubKeys to nil because they no longer match tx.AuthInfo + t.pubKeys = nil +} + +func (t *builder) setSignatures(sigs [][]byte) { + t.tx.Signatures = sigs +} + +func (t *builder) GetTx() authsigning.SigFeeMemoTx { + return t +} diff --git a/x/auth/tx/builder_test.go b/x/auth/tx/builder_test.go new file mode 100644 index 000000000..64040c953 --- /dev/null +++ b/x/auth/tx/builder_test.go @@ -0,0 +1,234 @@ +package tx + +import ( + "testing" + + "github.com/cosmos/cosmos-sdk/codec/testdata" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + + tx2 "github.com/cosmos/cosmos-sdk/types/tx" + + "github.com/cosmos/cosmos-sdk/types/tx/signing" + + "github.com/stretchr/testify/require" + + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + + "github.com/cosmos/cosmos-sdk/codec" + codectypes "github.com/cosmos/cosmos-sdk/codec/types" + "github.com/cosmos/cosmos-sdk/std" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +func TestTxBuilder(t *testing.T) { + _, pubkey, addr := authtypes.KeyTestPubAddr() + + marshaler := codec.NewHybridCodec(codec.New(), codectypes.NewInterfaceRegistry()) + tx := newBuilder(marshaler, std.DefaultPublicKeyCodec{}) + + cdc := std.DefaultPublicKeyCodec{} + + memo := "sometestmemo" + + msgs := []sdk.Msg{testdata.NewTestMsg(addr)} + + pk, err := cdc.Encode(pubkey) + require.NoError(t, err) + + var signerInfo []*tx2.SignerInfo + signerInfo = append(signerInfo, &tx2.SignerInfo{ + PublicKey: pk, + ModeInfo: &tx2.ModeInfo{ + Sum: &tx2.ModeInfo_Single_{ + Single: &tx2.ModeInfo_Single{ + Mode: signing.SignMode_SIGN_MODE_DIRECT, + }, + }, + }, + }) + + var sig signing.SignatureV2 + sig = signing.SignatureV2{ + PubKey: pubkey, + Data: &signing.SingleSignatureData{ + SignMode: signing.SignMode_SIGN_MODE_DIRECT, + Signature: pubkey.Bytes(), + }, + } + + fee := tx2.Fee{Amount: sdk.NewCoins(sdk.NewInt64Coin("atom", 150)), GasLimit: 20000} + + t.Log("verify that authInfo bytes encoded with DefaultTxEncoder and decoded with DefaultTxDecoder can be retrieved from GetAuthInfoBytes") + authInfo := &tx2.AuthInfo{ + Fee: &fee, + SignerInfos: signerInfo, + } + + authInfoBytes := marshaler.MustMarshalBinaryBare(authInfo) + + require.NotEmpty(t, authInfoBytes) + + t.Log("verify that body bytes encoded with DefaultTxEncoder and decoded with DefaultTxDecoder can be retrieved from GetBodyBytes") + anys := make([]*codectypes.Any, len(msgs)) + + for i, msg := range msgs { + var err error + anys[i], err = codectypes.NewAnyWithValue(msg) + if err != nil { + panic(err) + } + } + + txBody := &tx2.TxBody{ + Memo: memo, + Messages: anys, + } + bodyBytes := marshaler.MustMarshalBinaryBare(txBody) + require.NotEmpty(t, bodyBytes) + require.Empty(t, tx.GetBodyBytes()) + + t.Log("verify that calling the SetMsgs, SetMemo results in the correct GetBodyBytes") + require.NotEqual(t, bodyBytes, tx.GetBodyBytes()) + err = tx.SetMsgs(msgs...) + require.NoError(t, err) + require.NotEqual(t, bodyBytes, tx.GetBodyBytes()) + tx.SetMemo(memo) + require.Equal(t, bodyBytes, tx.GetBodyBytes()) + require.Equal(t, len(msgs), len(tx.GetMsgs())) + require.Equal(t, 0, len(tx.GetPubKeys())) + + t.Log("verify that updated AuthInfo results in the correct GetAuthInfoBytes and GetPubKeys") + require.NotEqual(t, authInfoBytes, tx.GetAuthInfoBytes()) + tx.SetFeeAmount(fee.Amount) + require.NotEqual(t, authInfoBytes, tx.GetAuthInfoBytes()) + tx.SetGasLimit(fee.GasLimit) + require.NotEqual(t, authInfoBytes, tx.GetAuthInfoBytes()) + err = tx.SetSignatures(sig) + require.NoError(t, err) + + // once fee, gas and signerInfos are all set, AuthInfo bytes should match + require.Equal(t, authInfoBytes, tx.GetAuthInfoBytes()) + + require.Equal(t, len(msgs), len(tx.GetMsgs())) + require.Equal(t, 1, len(tx.GetPubKeys())) + require.Equal(t, pubkey.Bytes(), tx.GetPubKeys()[0].Bytes()) +} + +func TestBuilderValidateBasic(t *testing.T) { + // keys and addresses + _, pubKey1, addr1 := authtypes.KeyTestPubAddr() + _, pubKey2, addr2 := authtypes.KeyTestPubAddr() + + // msg and signatures + msg1 := testdata.NewTestMsg(addr1, addr2) + fee := authtypes.NewTestStdFee() + + msgs := []sdk.Msg{msg1} + + // require to fail validation upon invalid fee + badFee := authtypes.NewTestStdFee() + badFee.Amount[0].Amount = sdk.NewInt(-5) + marshaler := codec.NewHybridCodec(codec.New(), codectypes.NewInterfaceRegistry()) + bldr := newBuilder(marshaler, std.DefaultPublicKeyCodec{}) + + var sig1, sig2 signing.SignatureV2 + sig1 = signing.SignatureV2{ + PubKey: pubKey1, + Data: &signing.SingleSignatureData{ + SignMode: signing.SignMode_SIGN_MODE_DIRECT, + Signature: pubKey1.Bytes(), + }, + } + + sig2 = signing.SignatureV2{ + PubKey: pubKey2, + Data: &signing.SingleSignatureData{ + SignMode: signing.SignMode_SIGN_MODE_DIRECT, + Signature: pubKey2.Bytes(), + }, + } + + err := bldr.SetMsgs(msgs...) + require.NoError(t, err) + bldr.SetGasLimit(200000) + err = bldr.SetSignatures(sig1, sig2) + require.NoError(t, err) + bldr.SetFeeAmount(badFee.Amount) + err = bldr.ValidateBasic() + require.Error(t, err) + _, code, _ := sdkerrors.ABCIInfo(err, false) + require.Equal(t, sdkerrors.ErrInsufficientFee.ABCICode(), code) + + // require to fail validation when no signatures exist + err = bldr.SetSignatures() + require.NoError(t, err) + bldr.SetFeeAmount(fee.Amount) + err = bldr.ValidateBasic() + require.Error(t, err) + _, code, _ = sdkerrors.ABCIInfo(err, false) + require.Equal(t, sdkerrors.ErrNoSignatures.ABCICode(), code) + + // require to fail with nil values for tx, authinfo + err = bldr.SetMsgs(msgs...) + require.NoError(t, err) + err = bldr.ValidateBasic() + require.Error(t, err) + + // require to fail validation when signatures do not match expected signers + err = bldr.SetSignatures(sig1) + require.NoError(t, err) + + err = bldr.ValidateBasic() + require.Error(t, err) + _, code, _ = sdkerrors.ABCIInfo(err, false) + require.Equal(t, sdkerrors.ErrUnauthorized.ABCICode(), code) + + require.Error(t, err) + bldr.SetFeeAmount(fee.Amount) + err = bldr.SetSignatures(sig1, sig2) + require.NoError(t, err) + err = bldr.ValidateBasic() + require.NoError(t, err) + + // gas limit too high + bldr.SetGasLimit(MaxGasWanted + 1) + err = bldr.ValidateBasic() + require.Error(t, err) + bldr.SetGasLimit(MaxGasWanted - 1) + err = bldr.ValidateBasic() + require.NoError(t, err) + + // bad builder structs + + // missing body + body := bldr.tx.Body + bldr.tx.Body = nil + err = bldr.ValidateBasic() + require.Error(t, err) + bldr.tx.Body = body + err = bldr.ValidateBasic() + require.NoError(t, err) + + // missing fee + f := bldr.tx.AuthInfo.Fee + bldr.tx.AuthInfo.Fee = nil + err = bldr.ValidateBasic() + require.Error(t, err) + bldr.tx.AuthInfo.Fee = f + err = bldr.ValidateBasic() + require.NoError(t, err) + + // missing AuthInfo + authInfo := bldr.tx.AuthInfo + bldr.tx.AuthInfo = nil + err = bldr.ValidateBasic() + require.Error(t, err) + bldr.tx.AuthInfo = authInfo + err = bldr.ValidateBasic() + require.NoError(t, err) + + // missing tx + bldr.tx = nil + err = bldr.ValidateBasic() + require.Error(t, err) +} diff --git a/x/auth/tx/decoder.go b/x/auth/tx/decoder.go new file mode 100644 index 000000000..8ce3b06fa --- /dev/null +++ b/x/auth/tx/decoder.go @@ -0,0 +1,82 @@ +package tx + +import ( + "github.com/tendermint/tendermint/crypto" + + "github.com/cosmos/cosmos-sdk/types/tx" + + "github.com/cosmos/cosmos-sdk/codec" + cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// DefaultTxDecoder returns a default protobuf TxDecoder using the provided Marshaler and PublicKeyCodec +func DefaultTxDecoder(cdc codec.Marshaler, keyCodec cryptotypes.PublicKeyCodec) sdk.TxDecoder { + return func(txBytes []byte) (sdk.Tx, error) { + var raw tx.TxRaw + err := cdc.UnmarshalBinaryBare(txBytes, &raw) + if err != nil { + return nil, err + } + + var theTx tx.Tx + err = cdc.UnmarshalBinaryBare(txBytes, &theTx) + if err != nil { + return nil, err + } + + pks, err := extractPubKeys(theTx, keyCodec) + if err != nil { + return nil, err + } + + return &builder{ + tx: &theTx, + bodyBz: raw.BodyBytes, + authInfoBz: raw.AuthInfoBytes, + pubKeys: pks, + marshaler: cdc, + pubkeyCodec: keyCodec, + }, nil + } +} + +// DefaultTxDecoder returns a default protobuf JSON TxDecoder using the provided Marshaler and PublicKeyCodec +func DefaultJSONTxDecoder(cdc codec.Marshaler, keyCodec cryptotypes.PublicKeyCodec) sdk.TxDecoder { + return func(txBytes []byte) (sdk.Tx, error) { + var theTx tx.Tx + err := cdc.UnmarshalJSON(txBytes, &theTx) + if err != nil { + return nil, err + } + + pks, err := extractPubKeys(theTx, keyCodec) + if err != nil { + return nil, err + } + + return &builder{ + tx: &theTx, + pubKeys: pks, + marshaler: cdc, + pubkeyCodec: keyCodec, + }, nil + } +} + +func extractPubKeys(tx tx.Tx, keyCodec cryptotypes.PublicKeyCodec) ([]crypto.PubKey, error) { + if tx.AuthInfo == nil { + return []crypto.PubKey{}, nil + } + + signerInfos := tx.AuthInfo.SignerInfos + pks := make([]crypto.PubKey, len(signerInfos)) + for i, si := range signerInfos { + pk, err := keyCodec.Decode(si.PublicKey) + if err != nil { + return nil, err + } + pks[i] = pk + } + return pks, nil +} diff --git a/x/auth/tx/encoder.go b/x/auth/tx/encoder.go new file mode 100644 index 000000000..3c39a20a6 --- /dev/null +++ b/x/auth/tx/encoder.go @@ -0,0 +1,39 @@ +package tx + +import ( + "fmt" + + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/types" + txtypes "github.com/cosmos/cosmos-sdk/types/tx" +) + +// DefaultTxEncoder returns a default protobuf TxEncoder using the provided Marshaler +func DefaultTxEncoder(marshaler codec.Marshaler) types.TxEncoder { + return func(tx types.Tx) ([]byte, error) { + wrapper, ok := tx.(*builder) + if !ok { + return nil, fmt.Errorf("expected %T, got %T", &builder{}, tx) + } + + raw := &txtypes.TxRaw{ + BodyBytes: wrapper.GetBodyBytes(), + AuthInfoBytes: wrapper.GetAuthInfoBytes(), + Signatures: wrapper.tx.Signatures, + } + + return marshaler.MarshalBinaryBare(raw) + } +} + +// DefaultTxEncoder returns a default protobuf JSON TxEncoder using the provided Marshaler +func DefaultJSONTxEncoder(marshaler codec.Marshaler) types.TxEncoder { + return func(tx types.Tx) ([]byte, error) { + wrapper, ok := tx.(*builder) + if !ok { + return nil, fmt.Errorf("expected %T, got %T", &builder{}, tx) + } + + return marshaler.MarshalJSON(wrapper.tx) + } +} diff --git a/x/auth/tx/generator.go b/x/auth/tx/generator.go new file mode 100644 index 000000000..de54b017b --- /dev/null +++ b/x/auth/tx/generator.go @@ -0,0 +1,56 @@ +package tx + +import ( + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/crypto/types" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/auth/signing" +) + +type generator struct { + marshaler codec.Marshaler + pubkeyCodec types.PublicKeyCodec + handler signing.SignModeHandler + decoder sdk.TxDecoder + encoder sdk.TxEncoder + jsonDecoder sdk.TxDecoder + jsonEncoder sdk.TxEncoder +} + +// NewTxGenerator returns a new protobuf TxGenerator using the provided Marshaler, PublicKeyCodec and SignModeHandler. +func NewTxGenerator(marshaler codec.Marshaler, pubkeyCodec types.PublicKeyCodec, signModeHandler signing.SignModeHandler) client.TxGenerator { + return &generator{ + marshaler: marshaler, + pubkeyCodec: pubkeyCodec, + handler: signModeHandler, + decoder: DefaultTxDecoder(marshaler, pubkeyCodec), + encoder: DefaultTxEncoder(marshaler), + jsonDecoder: DefaultJSONTxDecoder(marshaler, pubkeyCodec), + jsonEncoder: DefaultJSONTxEncoder(marshaler), + } +} + +func (g generator) NewTxBuilder() client.TxBuilder { + return newBuilder(g.marshaler, g.pubkeyCodec) +} + +func (g generator) SignModeHandler() signing.SignModeHandler { + return g.handler +} + +func (g generator) TxEncoder() sdk.TxEncoder { + return g.encoder +} + +func (g generator) TxDecoder() sdk.TxDecoder { + return g.decoder +} + +func (g generator) TxJSONEncoder() sdk.TxEncoder { + return g.jsonEncoder +} + +func (g generator) TxJSONDecoder() sdk.TxDecoder { + return g.jsonDecoder +} diff --git a/x/auth/tx/generator_test.go b/x/auth/tx/generator_test.go new file mode 100644 index 000000000..ca63ecfc1 --- /dev/null +++ b/x/auth/tx/generator_test.go @@ -0,0 +1,25 @@ +package tx + +import ( + "testing" + + "github.com/cosmos/cosmos-sdk/codec/testdata" + + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/stretchr/testify/suite" + + "github.com/cosmos/cosmos-sdk/client/testutil" + "github.com/cosmos/cosmos-sdk/codec" + codectypes "github.com/cosmos/cosmos-sdk/codec/types" + "github.com/cosmos/cosmos-sdk/std" +) + +func TestGenerator(t *testing.T) { + interfaceRegistry := codectypes.NewInterfaceRegistry() + interfaceRegistry.RegisterImplementations((*sdk.Msg)(nil), &testdata.TestMsg{}) + marshaler := codec.NewProtoCodec(interfaceRegistry) + pubKeyCodec := std.DefaultPublicKeyCodec{} + signModeHandler := DefaultSignModeHandler() + suite.Run(t, testutil.NewTxGeneratorTestSuite(NewTxGenerator(marshaler, pubKeyCodec, signModeHandler))) +} diff --git a/x/auth/tx/mode_handler.go b/x/auth/tx/mode_handler.go new file mode 100644 index 000000000..ef45d90db --- /dev/null +++ b/x/auth/tx/mode_handler.go @@ -0,0 +1,20 @@ +package tx + +import ( + signing2 "github.com/cosmos/cosmos-sdk/types/tx/signing" + "github.com/cosmos/cosmos-sdk/x/auth/signing" + "github.com/cosmos/cosmos-sdk/x/auth/signing/direct" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" +) + +// DefaultSignModeHandler returns the default protobuf SignModeHandler supporting +// SIGN_MODE_DIRECT and SIGN_MODE_LEGACY_AMINO_JSON. +func DefaultSignModeHandler() signing.SignModeHandler { + return signing.NewSignModeHandlerMap( + signing2.SignMode_SIGN_MODE_DIRECT, + []signing.SignModeHandler{ + authtypes.LegacyAminoJSONHandler{}, + direct.ModeHandler{}, + }, + ) +} diff --git a/x/auth/tx/sigs.go b/x/auth/tx/sigs.go new file mode 100644 index 000000000..2752fa8da --- /dev/null +++ b/x/auth/tx/sigs.go @@ -0,0 +1,104 @@ +package tx + +import ( + "fmt" + + "github.com/cosmos/cosmos-sdk/crypto/types" + "github.com/cosmos/cosmos-sdk/types/tx" + "github.com/cosmos/cosmos-sdk/types/tx/signing" +) + +// SignatureDataToModeInfoAndSig converts a SignatureData to a ModeInfo and raw bytes signature +func SignatureDataToModeInfoAndSig(data signing.SignatureData) (*tx.ModeInfo, []byte) { + if data == nil { + return nil, nil + } + + switch data := data.(type) { + case *signing.SingleSignatureData: + return &tx.ModeInfo{ + Sum: &tx.ModeInfo_Single_{ + Single: &tx.ModeInfo_Single{Mode: data.SignMode}, + }, + }, data.Signature + case *signing.MultiSignatureData: + n := len(data.Signatures) + modeInfos := make([]*tx.ModeInfo, n) + sigs := make([][]byte, n) + + for i, d := range data.Signatures { + modeInfos[i], sigs[i] = SignatureDataToModeInfoAndSig(d) + } + + multisig := types.MultiSignature{ + Signatures: sigs, + } + sig, err := multisig.Marshal() + if err != nil { + panic(err) + } + + return &tx.ModeInfo{ + Sum: &tx.ModeInfo_Multi_{ + Multi: &tx.ModeInfo_Multi{ + Bitarray: data.BitArray, + ModeInfos: modeInfos, + }, + }, + }, sig + default: + panic(fmt.Sprintf("unexpected signature data type %T", data)) + } +} + +// ModeInfoAndSigToSignatureData converts a ModeInfo and raw bytes signature to a SignatureData or returns +// an error +func ModeInfoAndSigToSignatureData(modeInfo *tx.ModeInfo, sig []byte) (signing.SignatureData, error) { + switch modeInfo := modeInfo.Sum.(type) { + case *tx.ModeInfo_Single_: + return &signing.SingleSignatureData{ + SignMode: modeInfo.Single.Mode, + Signature: sig, + }, nil + + case *tx.ModeInfo_Multi_: + multi := modeInfo.Multi + + sigs, err := decodeMultisignatures(sig) + if err != nil { + return nil, err + } + + sigv2s := make([]signing.SignatureData, len(sigs)) + for i, mi := range multi.ModeInfos { + sigv2s[i], err = ModeInfoAndSigToSignatureData(mi, sigs[i]) + if err != nil { + return nil, err + } + } + + return &signing.MultiSignatureData{ + BitArray: multi.Bitarray, + Signatures: sigv2s, + }, nil + + default: + panic(fmt.Errorf("unexpected ModeInfo data type %T", modeInfo)) + } +} + +// decodeMultisignatures safely decodes the the raw bytes as a MultiSignature protobuf message +func decodeMultisignatures(bz []byte) ([][]byte, error) { + multisig := types.MultiSignature{} + err := multisig.Unmarshal(bz) + if err != nil { + return nil, err + } + // NOTE: it is import to reject multi-signatures that contain unrecognized fields because this is an exploitable + // malleability in the protobuf message. Basically an attacker could bloat a MultiSignature message with unknown + // fields, thus bloating the transaction and causing it to fail. + if len(multisig.XXX_unrecognized) > 0 { + return nil, fmt.Errorf("rejecting unrecognized fields found in MultiSignature") + } + return multisig.Signatures, nil +} diff --git a/x/auth/tx/sigs_test.go b/x/auth/tx/sigs_test.go new file mode 100644 index 000000000..7280188d0 --- /dev/null +++ b/x/auth/tx/sigs_test.go @@ -0,0 +1,40 @@ +package tx + +import ( + "testing" + + "github.com/stretchr/testify/require" + + "github.com/cosmos/cosmos-sdk/crypto/types" + + "github.com/cosmos/cosmos-sdk/codec/testdata" +) + +func TestDecodeMultisignatures(t *testing.T) { + testSigs := [][]byte{ + []byte("dummy1"), + []byte("dummy2"), + []byte("dummy3"), + } + + badMultisig := testdata.BadMultiSignature{ + Signatures: testSigs, + MaliciousField: []byte("bad stuff..."), + } + bz, err := badMultisig.Marshal() + require.NoError(t, err) + + _, err = decodeMultisignatures(bz) + require.Error(t, err) + + goodMultisig := types.MultiSignature{ + Signatures: testSigs, + } + bz, err = goodMultisig.Marshal() + require.NoError(t, err) + + decodedSigs, err := decodeMultisignatures(bz) + require.NoError(t, err) + + require.Equal(t, testSigs, decodedSigs) +} diff --git a/x/auth/types/client_tx.go b/x/auth/types/client_tx.go index dc42613d4..3175cc89c 100644 --- a/x/auth/types/client_tx.go +++ b/x/auth/types/client_tx.go @@ -20,7 +20,7 @@ type StdTxBuilder struct { var _ client.TxBuilder = &StdTxBuilder{} // GetTx implements TxBuilder.GetTx -func (s *StdTxBuilder) GetTx() sdk.Tx { +func (s *StdTxBuilder) GetTx() authsigning.SigFeeMemoTx { return s.StdTx } diff --git a/x/auth/types/client_tx_test.go b/x/auth/types/client_tx_test.go index b1d7c9387..600a20af3 100644 --- a/x/auth/types/client_tx_test.go +++ b/x/auth/types/client_tx_test.go @@ -3,6 +3,8 @@ package types_test import ( "testing" + "github.com/cosmos/cosmos-sdk/codec/testdata" + "github.com/cosmos/cosmos-sdk/client/testutil" "github.com/stretchr/testify/suite" @@ -15,7 +17,7 @@ import ( func testCodec() *codec.Codec { cdc := codec.New() sdk.RegisterCodec(cdc) - cdc.RegisterConcrete(sdk.TestMsg{}, "cosmos-sdk/Test", nil) + cdc.RegisterConcrete(&testdata.TestMsg{}, "cosmos-sdk/Test", nil) return cdc } diff --git a/x/auth/types/stdtx.go b/x/auth/types/stdtx.go index 7bcc550f9..589e49428 100644 --- a/x/auth/types/stdtx.go +++ b/x/auth/types/stdtx.go @@ -413,7 +413,7 @@ func pubKeySigToSigData(cdc *codec.Codec, key crypto.PubKey, sig []byte) (signin sigDatas := make([]signing.SignatureData, len(sigs)) pubKeys := multiPK.GetPubKeys() bitArray := multiSig.BitArray - n := multiSig.BitArray.Size() + n := multiSig.BitArray.Count() signatures := multisig.NewMultisig(n) sigIdx := 0 for i := 0; i < n; i++ { diff --git a/x/auth/types/stdtx_test.go b/x/auth/types/stdtx_test.go index bdd94d333..15d3f89eb 100644 --- a/x/auth/types/stdtx_test.go +++ b/x/auth/types/stdtx_test.go @@ -4,6 +4,8 @@ import ( "fmt" "testing" + "github.com/cosmos/cosmos-sdk/codec/testdata" + "github.com/cosmos/cosmos-sdk/crypto/types" "github.com/cosmos/cosmos-sdk/crypto/types/multisig" @@ -27,7 +29,7 @@ var ( ) func TestStdTx(t *testing.T) { - msgs := []sdk.Msg{sdk.NewTestMsg(addr)} + msgs := []sdk.Msg{testdata.NewTestMsg(addr)} fee := NewTestStdFee() sigs := []StdSignature{} @@ -54,7 +56,7 @@ func TestStdSignBytes(t *testing.T) { want string }{ { - args{"1234", 3, 6, defaultFee, []sdk.Msg{sdk.NewTestMsg(addr)}, "memo"}, + args{"1234", 3, 6, defaultFee, []sdk.Msg{testdata.NewTestMsg(addr)}, "memo"}, fmt.Sprintf("{\"account_number\":\"3\",\"chain_id\":\"1234\",\"fee\":{\"amount\":[{\"amount\":\"150\",\"denom\":\"atom\"}],\"gas\":\"100000\"},\"memo\":\"memo\",\"msgs\":[[\"%s\"]],\"sequence\":\"6\"}", addr), }, } @@ -72,7 +74,7 @@ func TestTxValidateBasic(t *testing.T) { priv2, _, addr2 := KeyTestPubAddr() // msg and signatures - msg1 := NewTestMsg(addr1, addr2) + msg1 := testdata.NewTestMsg(addr1, addr2) fee := NewTestStdFee() msgs := []sdk.Msg{msg1} @@ -127,10 +129,10 @@ func TestDefaultTxEncoder(t *testing.T) { cdc := codec.New() sdk.RegisterCodec(cdc) RegisterCodec(cdc) - cdc.RegisterConcrete(sdk.TestMsg{}, "cosmos-sdk/Test", nil) + cdc.RegisterConcrete(testdata.TestMsg{}, "cosmos-sdk/Test", nil) encoder := DefaultTxEncoder(cdc) - msgs := []sdk.Msg{sdk.NewTestMsg(addr)} + msgs := []sdk.Msg{testdata.NewTestMsg(addr)} fee := NewTestStdFee() sigs := []StdSignature{} @@ -238,7 +240,7 @@ func TestGetSignaturesV2(t *testing.T) { fee := NewStdFee(50000, sdk.Coins{sdk.NewInt64Coin("atom", 150)}) sig := StdSignature{PubKey: pubKey.Bytes(), Signature: dummy} - stdTx := NewStdTx([]sdk.Msg{NewTestMsg()}, fee, []StdSignature{sig}, "testsigs") + stdTx := NewStdTx([]sdk.Msg{testdata.NewTestMsg()}, fee, []StdSignature{sig}, "testsigs") sigs, err := stdTx.GetSignaturesV2() require.Nil(t, err) diff --git a/x/auth/types/test_utils.go b/x/auth/types/test_utils.go index 4c0d801af..c25f8d89c 100644 --- a/x/auth/types/test_utils.go +++ b/x/auth/types/test_utils.go @@ -7,10 +7,6 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" ) -func NewTestMsg(addrs ...sdk.AccAddress) *sdk.TestMsg { - return sdk.NewTestMsg(addrs...) -} - func NewTestStdFee() StdFee { return NewStdFee(100000, sdk.NewCoins(sdk.NewInt64Coin("atom", 150)), diff --git a/x/auth/types/txbuilder_test.go b/x/auth/types/txbuilder_test.go index c0a0e337a..19d4e101b 100644 --- a/x/auth/types/txbuilder_test.go +++ b/x/auth/types/txbuilder_test.go @@ -4,6 +4,8 @@ import ( "reflect" "testing" + "github.com/cosmos/cosmos-sdk/codec/testdata" + "github.com/stretchr/testify/require" "github.com/cosmos/cosmos-sdk/codec" @@ -23,7 +25,7 @@ func TestTxBuilderBuild(t *testing.T) { Fees sdk.Coins GasPrices sdk.DecCoins } - defaultMsg := []sdk.Msg{sdk.NewTestMsg(addr)} + defaultMsg := []sdk.Msg{testdata.NewTestMsg(addr)} tests := []struct { name string fields fields diff --git a/x/auth/vesting/types/test_common.go b/x/auth/vesting/types/test_common.go index 0287bde80..0ccb5e62f 100644 --- a/x/auth/vesting/types/test_common.go +++ b/x/auth/vesting/types/test_common.go @@ -4,12 +4,14 @@ import ( "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/crypto/secp256k1" + "github.com/cosmos/cosmos-sdk/codec/testdata" + sdk "github.com/cosmos/cosmos-sdk/types" ) // NewTestMsg generates a test message -func NewTestMsg(addrs ...sdk.AccAddress) *sdk.TestMsg { - return sdk.NewTestMsg(addrs...) +func NewTestMsg(addrs ...sdk.AccAddress) *testdata.TestMsg { + return testdata.NewTestMsg(addrs...) } // NewTestCoins coins to more than cover the fee diff --git a/x/bank/handler_test.go b/x/bank/handler_test.go index f9d313385..ab6338d1d 100644 --- a/x/bank/handler_test.go +++ b/x/bank/handler_test.go @@ -4,6 +4,8 @@ import ( "strings" "testing" + "github.com/cosmos/cosmos-sdk/codec/testdata" + "github.com/stretchr/testify/require" abci "github.com/tendermint/tendermint/abci/types" @@ -14,7 +16,7 @@ import ( func TestInvalidMsg(t *testing.T) { h := NewHandler(nil) - res, err := h(sdk.NewContext(nil, abci.Header{}, false, nil), sdk.NewTestMsg()) + res, err := h(sdk.NewContext(nil, abci.Header{}, false, nil), testdata.NewTestMsg()) require.Error(t, err) require.Nil(t, res) diff --git a/x/crisis/handler_test.go b/x/crisis/handler_test.go index 21e92512f..b4aa14e70 100644 --- a/x/crisis/handler_test.go +++ b/x/crisis/handler_test.go @@ -4,6 +4,8 @@ import ( "fmt" "testing" + "github.com/cosmos/cosmos-sdk/codec/testdata" + "github.com/stretchr/testify/require" abci "github.com/tendermint/tendermint/abci/types" "github.com/tendermint/tendermint/libs/log" @@ -60,7 +62,7 @@ func TestHandleMsgVerifyInvariant(t *testing.T) { {"bad invariant route", types.NewMsgVerifyInvariant(sender, testModuleName, "route-that-doesnt-exist"), "fail"}, {"invariant broken", types.NewMsgVerifyInvariant(sender, testModuleName, dummyRouteWhichFails.Route), "panic"}, {"invariant passing", types.NewMsgVerifyInvariant(sender, testModuleName, dummyRouteWhichPasses.Route), "pass"}, - {"invalid msg", sdk.NewTestMsg(), "fail"}, + {"invalid msg", testdata.NewTestMsg(), "fail"}, } for _, tc := range cases { diff --git a/x/distribution/client/cli/tx_test.go b/x/distribution/client/cli/tx_test.go index 2b5f27ca5..7a00e9720 100644 --- a/x/distribution/client/cli/tx_test.go +++ b/x/distribution/client/cli/tx_test.go @@ -4,6 +4,8 @@ import ( "io/ioutil" "testing" + "github.com/cosmos/cosmos-sdk/codec/testdata" + "github.com/stretchr/testify/require" "github.com/stretchr/testify/assert" @@ -28,11 +30,11 @@ func Test_splitAndCall_Splitting(t *testing.T) { // Add five messages msgs := []sdk.Msg{ - sdk.NewTestMsg(addr), - sdk.NewTestMsg(addr), - sdk.NewTestMsg(addr), - sdk.NewTestMsg(addr), - sdk.NewTestMsg(addr), + testdata.NewTestMsg(addr), + testdata.NewTestMsg(addr), + testdata.NewTestMsg(addr), + testdata.NewTestMsg(addr), + testdata.NewTestMsg(addr), } // Keep track of number of calls diff --git a/x/gov/handler_test.go b/x/gov/handler_test.go index c8d0d3a9c..96728accd 100644 --- a/x/gov/handler_test.go +++ b/x/gov/handler_test.go @@ -4,6 +4,8 @@ import ( "strings" "testing" + "github.com/cosmos/cosmos-sdk/codec/testdata" + "github.com/stretchr/testify/require" abci "github.com/tendermint/tendermint/abci/types" @@ -16,7 +18,7 @@ func TestInvalidMsg(t *testing.T) { k := keeper.Keeper{} h := gov.NewHandler(k) - res, err := h(sdk.NewContext(nil, abci.Header{}, false, nil), sdk.NewTestMsg()) + res, err := h(sdk.NewContext(nil, abci.Header{}, false, nil), testdata.NewTestMsg()) require.Error(t, err) require.Nil(t, res) require.True(t, strings.Contains(err.Error(), "unrecognized gov message type")) diff --git a/x/ibc/04-channel/keeper/packet_test.go b/x/ibc/04-channel/keeper/packet_test.go index 38afba707..aaa30ad46 100644 --- a/x/ibc/04-channel/keeper/packet_test.go +++ b/x/ibc/04-channel/keeper/packet_test.go @@ -430,7 +430,7 @@ func (suite *KeeperTestSuite) TestPacketExecuted() { tc := tc suite.Run(fmt.Sprintf("Case %s, %d/%d tests", tc.msg, i, len(testCases)), func() { suite.SetupTest() // reset - ack = ibctesting.TestHash // must explicity be changed in malleate + ack = ibctesting.TestHash // must explicitly be changed in malleate tc.malleate() diff --git a/x/slashing/handler_test.go b/x/slashing/handler_test.go index 23d6ba609..38a3014af 100644 --- a/x/slashing/handler_test.go +++ b/x/slashing/handler_test.go @@ -6,6 +6,8 @@ import ( "testing" "time" + "github.com/cosmos/cosmos-sdk/codec/testdata" + "github.com/stretchr/testify/require" abci "github.com/tendermint/tendermint/abci/types" @@ -162,7 +164,7 @@ func TestInvalidMsg(t *testing.T) { k := keeper.Keeper{} h := slashing.NewHandler(k) - res, err := h(sdk.NewContext(nil, abci.Header{}, false, nil), sdk.NewTestMsg()) + res, err := h(sdk.NewContext(nil, abci.Header{}, false, nil), testdata.NewTestMsg()) require.Error(t, err) require.Nil(t, res) require.True(t, strings.Contains(err.Error(), "unrecognized slashing message type")) diff --git a/x/staking/handler_test.go b/x/staking/handler_test.go index 9c8404269..462ee92be 100644 --- a/x/staking/handler_test.go +++ b/x/staking/handler_test.go @@ -5,6 +5,8 @@ import ( "testing" "time" + "github.com/cosmos/cosmos-sdk/codec/testdata" + gogotypes "github.com/gogo/protobuf/types" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -1439,7 +1441,7 @@ func TestInvalidMsg(t *testing.T) { k := keeper.Keeper{} h := staking.NewHandler(k) - res, err := h(sdk.NewContext(nil, abci.Header{}, false, nil), sdk.NewTestMsg()) + res, err := h(sdk.NewContext(nil, abci.Header{}, false, nil), testdata.NewTestMsg()) require.Error(t, err) require.Nil(t, res) require.True(t, strings.Contains(err.Error(), "unrecognized staking message type")) diff --git a/x/upgrade/types/query.pb.go b/x/upgrade/types/query.pb.go index 5494897fa..6c1218611 100644 --- a/x/upgrade/types/query.pb.go +++ b/x/upgrade/types/query.pb.go @@ -66,7 +66,7 @@ var xxx_messageInfo_QueryCurrentPlanRequest proto.InternalMessageInfo // QueryCurrentPlanResponse is the response type for the Query/CurrentPlan RPC method type QueryCurrentPlanResponse struct { - // plan is the current plan + // plan is the current upgrade plan Plan *Plan `protobuf:"bytes,1,opt,name=plan,proto3" json:"plan,omitempty"` } @@ -245,9 +245,9 @@ const _ = grpc.SupportPackageIsVersion4 // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. type QueryClient interface { - // CurrentPlan queries the current plan + // CurrentPlan queries the current upgrade plan CurrentPlan(ctx context.Context, in *QueryCurrentPlanRequest, opts ...grpc.CallOption) (*QueryCurrentPlanResponse, error) - // AppliedPlan queries a previously applied plan by its name + // AppliedPlan queries a previously applied upgrade plan by its name AppliedPlan(ctx context.Context, in *QueryAppliedPlanRequest, opts ...grpc.CallOption) (*QueryAppliedPlanResponse, error) } @@ -279,9 +279,9 @@ func (c *queryClient) AppliedPlan(ctx context.Context, in *QueryAppliedPlanReque // QueryServer is the server API for Query service. type QueryServer interface { - // CurrentPlan queries the current plan + // CurrentPlan queries the current upgrade plan CurrentPlan(context.Context, *QueryCurrentPlanRequest) (*QueryCurrentPlanResponse, error) - // AppliedPlan queries a previously applied plan by its name + // AppliedPlan queries a previously applied upgrade plan by its name AppliedPlan(context.Context, *QueryAppliedPlanRequest) (*QueryAppliedPlanResponse, error) }