diff --git a/client/context.go b/client/context.go index 5580853e3027..21e5a29ac79a 100644 --- a/client/context.go +++ b/client/context.go @@ -195,6 +195,17 @@ func (ctx Context) WithInterfaceRegistry(interfaceRegistry codectypes.InterfaceR return ctx } +// PrintString prints the raw string to ctx.Output or os.Stdout +func (ctx Context) PrintString(str string) error { + writer := ctx.Output + if writer == nil { + writer = os.Stdout + } + + _, err := writer.Write([]byte(str)) + return err +} + // PrintOutput outputs toPrint to the ctx.Output based on ctx.OutputFormat which is // either text or json. If text, toPrint will be YAML encoded. Otherwise, toPrint // will be JSON encoded using ctx.JSONMarshaler. An error is returned upon failure. diff --git a/client/tx/factory.go b/client/tx/factory.go index 779daadd5402..5e8749cc7111 100644 --- a/client/tx/factory.go +++ b/client/tx/factory.go @@ -172,3 +172,14 @@ func (f Factory) WithSimulateAndExecute(sim bool) Factory { f.simulateAndExecute = sim return f } + +// SignMode returns the sign mode configured in the Factory +func (f Factory) SignMode() signing.SignMode { + return f.signMode +} + +// WithSignMode returns a copy of the Factory with an updated sign mode value. +func (f Factory) WithSignMode(mode signing.SignMode) Factory { + f.signMode = mode + return f +} diff --git a/client/tx/tx.go b/client/tx/tx.go index caff6e37400a..30f8269f887a 100644 --- a/client/tx/tx.go +++ b/client/tx/tx.go @@ -64,7 +64,12 @@ func GenerateTx(clientCtx client.Context, txf Factory, msgs ...sdk.Msg) error { return err } - return clientCtx.PrintOutput(tx.GetTx()) + json, err := clientCtx.TxConfig.TxJSONEncoder()(tx.GetTx()) + if err != nil { + return err + } + + return clientCtx.PrintString(fmt.Sprintf("%s\n", json)) } // BroadcastTx attempts to generate, sign and broadcast a transaction with the diff --git a/client/tx_generator.go b/client/tx_generator.go index 37d95db314d1..de1057956abe 100644 --- a/client/tx_generator.go +++ b/client/tx_generator.go @@ -17,6 +17,8 @@ type ( TxDecoder() sdk.TxDecoder TxJSONEncoder() sdk.TxEncoder TxJSONDecoder() sdk.TxDecoder + MarshalSignatureJSON([]signingtypes.SignatureV2) ([]byte, error) + UnmarshalSignatureJSON([]byte) ([]signingtypes.SignatureV2, error) } // TxConfig defines an interface a client can utilize to generate an diff --git a/codec/proto_codec.go b/codec/proto_codec.go index 09853e7a7cc1..c38a5c7febff 100644 --- a/codec/proto_codec.go +++ b/codec/proto_codec.go @@ -16,7 +16,9 @@ type ProtoCodec struct { anyUnpacker types.AnyUnpacker } -func NewProtoCodec(anyUnpacker types.AnyUnpacker) Marshaler { +var _ Marshaler = &ProtoCodec{} + +func NewProtoCodec(anyUnpacker types.AnyUnpacker) *ProtoCodec { return &ProtoCodec{anyUnpacker: anyUnpacker} } diff --git a/codec/proto_codec_test.go b/codec/proto_codec_test.go index fd1fc7a23558..522c80c4e8e5 100644 --- a/codec/proto_codec_test.go +++ b/codec/proto_codec_test.go @@ -204,7 +204,7 @@ func mustAny(msg proto.Message) *types.Any { } func BenchmarkProtoCodecMarshalBinaryLengthPrefixed(b *testing.B) { - var pCdc = codec.NewProtoCodec(types.NewInterfaceRegistry()).(*codec.ProtoCodec) + var pCdc = codec.NewProtoCodec(types.NewInterfaceRegistry()) var msg = &testdata.HasAnimal{ X: 1000, Animal: mustAny(&testdata.HasAnimal{ diff --git a/crypto/types/multisig/pubkey.go b/crypto/types/multisig/pubkey.go index a3935a4bb4d4..51d432f59ca7 100644 --- a/crypto/types/multisig/pubkey.go +++ b/crypto/types/multisig/pubkey.go @@ -17,6 +17,9 @@ type PubKey interface { // GetPubKeys returns the crypto.PubKey's nested within the multi-sig PubKey GetPubKeys() []crypto.PubKey + + // GetThreshold returns the threshold number of signatures that must be obtained to verify a signature. + GetThreshold() uint } // GetSignBytesFunc defines a function type which returns sign bytes for a given SignMode or an error. diff --git a/crypto/types/multisig/threshold_pubkey.go b/crypto/types/multisig/threshold_pubkey.go index 911843e35cc1..44fc48b6ede1 100644 --- a/crypto/types/multisig/threshold_pubkey.go +++ b/crypto/types/multisig/threshold_pubkey.go @@ -154,3 +154,8 @@ func (pk PubKeyMultisigThreshold) Equals(other crypto.PubKey) bool { } return true } + +// GetThreshold implements the PubKey.GetThreshold method +func (pk PubKeyMultisigThreshold) GetThreshold() uint { + return pk.K +} diff --git a/go.sum b/go.sum index b3d075b7647d..a79943ce319c 100644 --- a/go.sum +++ b/go.sum @@ -168,8 +168,6 @@ github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4er github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= -github.com/golang/mock v1.4.3 h1:GV+pQPG/EUUbkh47niozDcADz6go/dUwhVzdUQHIVRw= -github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.4 h1:l75CXGRSwbaYNpl/Z2X1XIIAMSCquvXgpVZDhwEIJsc= github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -646,7 +644,6 @@ golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20u golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1 h1:ogLJMz+qpzav7lGMh10LMvAkM/fAoGlaiiHYiFYdm80= golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= @@ -772,7 +769,5 @@ honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= -rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= -rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= diff --git a/proto/cosmos/tx/signing/signing.proto b/proto/cosmos/tx/signing/signing.proto index c4536e09a5bf..a813882995fd 100644 --- a/proto/cosmos/tx/signing/signing.proto +++ b/proto/cosmos/tx/signing/signing.proto @@ -1,6 +1,8 @@ syntax = "proto3"; package cosmos.tx.signing; +import "cosmos/crypto/crypto.proto"; + option go_package = "github.com/cosmos/cosmos-sdk/types/tx/signing"; // SignMode represents a signing mode with its own security guarantees @@ -20,3 +22,49 @@ enum SignMode { // Amino JSON and will be removed in the future SIGN_MODE_LEGACY_AMINO_JSON = 127; } + +// SignatureDescriptors wraps multiple SignatureDescriptor's. +message SignatureDescriptors { + // signatures are the signature descriptors + repeated SignatureDescriptor signatures = 1; +} + +// SignatureDescriptor is a convenience type which represents the full data for a +// signature including the public key of the signer, signing modes and the signature +// itself. It is primarily used for coordinating signatures between clients. +message SignatureDescriptor { + // public_key is the public key of the signer + cosmos.crypto.PublicKey public_key = 1; + + Data data = 2; + + // Data represents signature data + message Data { + // sum is the oneof that specifies whether this represents single or multi-signature data + oneof sum { + // single represents a single signer + Single single = 1; + + // multi represents a multisig signer + Multi multi = 2; + } + + // Single is the signature data for a single signer + message Single { + // mode is the signing mode of the single signer + cosmos.tx.signing.SignMode mode = 1; + + // signature is the raw signature bytes + bytes signature = 2; + } + + // Multi is the signature data for a multisig public key + message Multi { + // bitarray specifies which keys within the multisig are signing + cosmos.crypto.CompactBitArray bitarray = 1; + + // signatures is the signatures of the multi-signature + repeated Data signatures = 2; + } + } +} diff --git a/simapp/params/proto.go b/simapp/params/proto.go index a5c859ada421..1de96d4a490d 100644 --- a/simapp/params/proto.go +++ b/simapp/params/proto.go @@ -12,15 +12,15 @@ import ( // MakeEncodingConfig creates an EncodingConfig for an amino based test configuration. func MakeEncodingConfig() EncodingConfig { - cdc := codec.New() + amino := codec.New() interfaceRegistry := types.NewInterfaceRegistry() - marshaler := codec.NewHybridCodec(cdc, interfaceRegistry) - txGen := tx.NewTxConfig(interfaceRegistry, std.DefaultPublicKeyCodec{}, tx.DefaultSignModeHandler()) + marshaler := codec.NewHybridCodec(amino, interfaceRegistry) + txGen := tx.NewTxConfig(codec.NewProtoCodec(interfaceRegistry), std.DefaultPublicKeyCodec{}, tx.DefaultSignModeHandler()) return EncodingConfig{ InterfaceRegistry: interfaceRegistry, Marshaler: marshaler, TxConfig: txGen, - Amino: cdc, + Amino: amino, } } diff --git a/testutil/network/network.go b/testutil/network/network.go index 81668ae49666..e49fcc34b130 100644 --- a/testutil/network/network.go +++ b/testutil/network/network.go @@ -13,8 +13,6 @@ import ( "testing" "time" - "github.com/cosmos/cosmos-sdk/client/tx" - "github.com/stretchr/testify/require" tmcfg "github.com/tendermint/tendermint/config" "github.com/tendermint/tendermint/crypto" @@ -29,6 +27,7 @@ import ( "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/client" clientkeys "github.com/cosmos/cosmos-sdk/client/keys" + "github.com/cosmos/cosmos-sdk/client/tx" "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/crypto/keyring" "github.com/cosmos/cosmos-sdk/server" diff --git a/types/tx/sig_desc.pb.go b/types/tx/sig_desc.pb.go new file mode 100644 index 000000000000..4270c8a6d588 --- /dev/null +++ b/types/tx/sig_desc.pb.go @@ -0,0 +1,37 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: cosmos/tx/sig_desc.proto + +package tx + +import ( + fmt "fmt" + _ "github.com/cosmos/cosmos-sdk/types/tx/signing" + proto "github.com/gogo/protobuf/proto" + math "math" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +func init() { proto.RegisterFile("cosmos/tx/sig_desc.proto", fileDescriptor_d560eb6bd3d62ef7) } + +var fileDescriptor_d560eb6bd3d62ef7 = []byte{ + // 129 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x48, 0xce, 0x2f, 0xce, + 0xcd, 0x2f, 0xd6, 0x2f, 0xa9, 0xd0, 0x2f, 0xce, 0x4c, 0x8f, 0x4f, 0x49, 0x2d, 0x4e, 0xd6, 0x2b, + 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xe2, 0x84, 0xc8, 0xe8, 0x95, 0x54, 0x48, 0xc9, 0xa3, 0x28, 0xca, + 0xcb, 0xcc, 0x4b, 0x87, 0xd1, 0x10, 0xb5, 0x4e, 0xf6, 0x27, 0x1e, 0xc9, 0x31, 0x5e, 0x78, 0x24, + 0xc7, 0xf8, 0xe0, 0x91, 0x1c, 0xe3, 0x84, 0xc7, 0x72, 0x0c, 0x17, 0x1e, 0xcb, 0x31, 0xdc, 0x78, + 0x2c, 0xc7, 0x10, 0xa5, 0x9a, 0x9e, 0x59, 0x92, 0x51, 0x9a, 0xa4, 0x97, 0x9c, 0x9f, 0xab, 0x0f, + 0x35, 0x05, 0x42, 0xe9, 0x16, 0xa7, 0x64, 0xeb, 0x97, 0x54, 0x16, 0xa4, 0x82, 0x8c, 0x4d, 0x62, + 0x03, 0x9b, 0x63, 0x0c, 0x08, 0x00, 0x00, 0xff, 0xff, 0x86, 0x8a, 0xa4, 0x8a, 0x8f, 0x00, 0x00, + 0x00, +} diff --git a/types/tx/signing/signature.go b/types/tx/signing/signature.go index 47744de28433..bfe832a5b1ea 100644 --- a/types/tx/signing/signature.go +++ b/types/tx/signing/signature.go @@ -1,6 +1,10 @@ package signing -import "github.com/tendermint/tendermint/crypto" +import ( + "fmt" + + "github.com/tendermint/tendermint/crypto" +) // SignatureV2 is a convenience type that is easier to use in application logic // than the protobuf SignerInfo's and raw signature bytes. It goes beyond the @@ -15,3 +19,64 @@ type SignatureV2 struct { // the signatures themselves for either single or multi-signatures. Data SignatureData } + +// SignatureDataToProto converts a SignatureData to SignatureDescriptor_Data. +// SignatureDescriptor_Data is considered an encoding type whereas SignatureData is used for +// business logic. +func SignatureDataToProto(data SignatureData) *SignatureDescriptor_Data { + switch data := data.(type) { + case *SingleSignatureData: + return &SignatureDescriptor_Data{ + Sum: &SignatureDescriptor_Data_Single_{ + Single: &SignatureDescriptor_Data_Single{ + Mode: data.SignMode, + Signature: data.Signature, + }, + }, + } + case *MultiSignatureData: + descDatas := make([]*SignatureDescriptor_Data, len(data.Signatures)) + + for j, d := range data.Signatures { + descDatas[j] = SignatureDataToProto(d) + } + + return &SignatureDescriptor_Data{ + Sum: &SignatureDescriptor_Data_Multi_{ + Multi: &SignatureDescriptor_Data_Multi{ + Bitarray: data.BitArray, + Signatures: descDatas, + }, + }, + } + default: + panic(fmt.Errorf("unexpected case %+v", data)) + } +} + +// SignatureDataFromProto converts a SignatureDescriptor_Data to SignatureData. +// SignatureDescriptor_Data is considered an encoding type whereas SignatureData is used for +// business logic. +func SignatureDataFromProto(descData *SignatureDescriptor_Data) SignatureData { + switch descData := descData.Sum.(type) { + case *SignatureDescriptor_Data_Single_: + return &SingleSignatureData{ + SignMode: descData.Single.Mode, + Signature: descData.Single.Signature, + } + case *SignatureDescriptor_Data_Multi_: + multi := descData.Multi + datas := make([]SignatureData, len(multi.Signatures)) + + for j, d := range multi.Signatures { + datas[j] = SignatureDataFromProto(d) + } + + return &MultiSignatureData{ + BitArray: multi.Bitarray, + Signatures: datas, + } + default: + panic(fmt.Errorf("unexpected case %+v", descData)) + } +} diff --git a/types/tx/signing/signing.pb.go b/types/tx/signing/signing.pb.go index 26943a171b47..f8c817e7efa0 100644 --- a/types/tx/signing/signing.pb.go +++ b/types/tx/signing/signing.pb.go @@ -5,8 +5,11 @@ package signing import ( fmt "fmt" + types "github.com/cosmos/cosmos-sdk/crypto/types" proto "github.com/gogo/protobuf/proto" + io "io" math "math" + math_bits "math/bits" ) // Reference imports to suppress errors if they are not otherwise used. @@ -59,26 +62,1359 @@ func (SignMode) EnumDescriptor() ([]byte, []int) { return fileDescriptor_8a04324e5f3729bf, []int{0} } +// SignatureDescriptors wraps multiple SignatureDescriptor's. +type SignatureDescriptors struct { + // signatures are the signature descriptors + Signatures []*SignatureDescriptor `protobuf:"bytes,1,rep,name=signatures,proto3" json:"signatures,omitempty"` +} + +func (m *SignatureDescriptors) Reset() { *m = SignatureDescriptors{} } +func (m *SignatureDescriptors) String() string { return proto.CompactTextString(m) } +func (*SignatureDescriptors) ProtoMessage() {} +func (*SignatureDescriptors) Descriptor() ([]byte, []int) { + return fileDescriptor_8a04324e5f3729bf, []int{0} +} +func (m *SignatureDescriptors) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *SignatureDescriptors) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_SignatureDescriptors.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 *SignatureDescriptors) XXX_Merge(src proto.Message) { + xxx_messageInfo_SignatureDescriptors.Merge(m, src) +} +func (m *SignatureDescriptors) XXX_Size() int { + return m.Size() +} +func (m *SignatureDescriptors) XXX_DiscardUnknown() { + xxx_messageInfo_SignatureDescriptors.DiscardUnknown(m) +} + +var xxx_messageInfo_SignatureDescriptors proto.InternalMessageInfo + +func (m *SignatureDescriptors) GetSignatures() []*SignatureDescriptor { + if m != nil { + return m.Signatures + } + return nil +} + +// SignatureDescriptor is a convenience type which represents the full data for a +// signature including the public key of the signer, signing modes and the signature +// itself. It is primarily used for coordinating signatures between clients. +type SignatureDescriptor struct { + // public_key is the public key of the signer + PublicKey *types.PublicKey `protobuf:"bytes,1,opt,name=public_key,json=publicKey,proto3" json:"public_key,omitempty"` + // data represents the signature data + Data *SignatureDescriptor_Data `protobuf:"bytes,2,opt,name=data,proto3" json:"data,omitempty"` +} + +func (m *SignatureDescriptor) Reset() { *m = SignatureDescriptor{} } +func (m *SignatureDescriptor) String() string { return proto.CompactTextString(m) } +func (*SignatureDescriptor) ProtoMessage() {} +func (*SignatureDescriptor) Descriptor() ([]byte, []int) { + return fileDescriptor_8a04324e5f3729bf, []int{1} +} +func (m *SignatureDescriptor) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *SignatureDescriptor) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_SignatureDescriptor.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 *SignatureDescriptor) XXX_Merge(src proto.Message) { + xxx_messageInfo_SignatureDescriptor.Merge(m, src) +} +func (m *SignatureDescriptor) XXX_Size() int { + return m.Size() +} +func (m *SignatureDescriptor) XXX_DiscardUnknown() { + xxx_messageInfo_SignatureDescriptor.DiscardUnknown(m) +} + +var xxx_messageInfo_SignatureDescriptor proto.InternalMessageInfo + +func (m *SignatureDescriptor) GetPublicKey() *types.PublicKey { + if m != nil { + return m.PublicKey + } + return nil +} + +func (m *SignatureDescriptor) GetData() *SignatureDescriptor_Data { + if m != nil { + return m.Data + } + return nil +} + +type SignatureDescriptor_Data struct { + // sum is the oneof that specifies whether this represents single or multi-signature data + // + // Types that are valid to be assigned to Sum: + // *SignatureDescriptor_Data_Single_ + // *SignatureDescriptor_Data_Multi_ + Sum isSignatureDescriptor_Data_Sum `protobuf_oneof:"sum"` +} + +func (m *SignatureDescriptor_Data) Reset() { *m = SignatureDescriptor_Data{} } +func (m *SignatureDescriptor_Data) String() string { return proto.CompactTextString(m) } +func (*SignatureDescriptor_Data) ProtoMessage() {} +func (*SignatureDescriptor_Data) Descriptor() ([]byte, []int) { + return fileDescriptor_8a04324e5f3729bf, []int{1, 0} +} +func (m *SignatureDescriptor_Data) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *SignatureDescriptor_Data) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_SignatureDescriptor_Data.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 *SignatureDescriptor_Data) XXX_Merge(src proto.Message) { + xxx_messageInfo_SignatureDescriptor_Data.Merge(m, src) +} +func (m *SignatureDescriptor_Data) XXX_Size() int { + return m.Size() +} +func (m *SignatureDescriptor_Data) XXX_DiscardUnknown() { + xxx_messageInfo_SignatureDescriptor_Data.DiscardUnknown(m) +} + +var xxx_messageInfo_SignatureDescriptor_Data proto.InternalMessageInfo + +type isSignatureDescriptor_Data_Sum interface { + isSignatureDescriptor_Data_Sum() + MarshalTo([]byte) (int, error) + Size() int +} + +type SignatureDescriptor_Data_Single_ struct { + Single *SignatureDescriptor_Data_Single `protobuf:"bytes,1,opt,name=single,proto3,oneof" json:"single,omitempty"` +} +type SignatureDescriptor_Data_Multi_ struct { + Multi *SignatureDescriptor_Data_Multi `protobuf:"bytes,2,opt,name=multi,proto3,oneof" json:"multi,omitempty"` +} + +func (*SignatureDescriptor_Data_Single_) isSignatureDescriptor_Data_Sum() {} +func (*SignatureDescriptor_Data_Multi_) isSignatureDescriptor_Data_Sum() {} + +func (m *SignatureDescriptor_Data) GetSum() isSignatureDescriptor_Data_Sum { + if m != nil { + return m.Sum + } + return nil +} + +func (m *SignatureDescriptor_Data) GetSingle() *SignatureDescriptor_Data_Single { + if x, ok := m.GetSum().(*SignatureDescriptor_Data_Single_); ok { + return x.Single + } + return nil +} + +func (m *SignatureDescriptor_Data) GetMulti() *SignatureDescriptor_Data_Multi { + if x, ok := m.GetSum().(*SignatureDescriptor_Data_Multi_); ok { + return x.Multi + } + return nil +} + +// XXX_OneofWrappers is for the internal use of the proto package. +func (*SignatureDescriptor_Data) XXX_OneofWrappers() []interface{} { + return []interface{}{ + (*SignatureDescriptor_Data_Single_)(nil), + (*SignatureDescriptor_Data_Multi_)(nil), + } +} + +// Single is the signature data for a single signer +type SignatureDescriptor_Data_Single struct { + // mode is the signing mode of the single signer + Mode SignMode `protobuf:"varint,1,opt,name=mode,proto3,enum=cosmos.tx.signing.SignMode" json:"mode,omitempty"` + // signature is the raw signature bytes + Signature []byte `protobuf:"bytes,2,opt,name=signature,proto3" json:"signature,omitempty"` +} + +func (m *SignatureDescriptor_Data_Single) Reset() { *m = SignatureDescriptor_Data_Single{} } +func (m *SignatureDescriptor_Data_Single) String() string { return proto.CompactTextString(m) } +func (*SignatureDescriptor_Data_Single) ProtoMessage() {} +func (*SignatureDescriptor_Data_Single) Descriptor() ([]byte, []int) { + return fileDescriptor_8a04324e5f3729bf, []int{1, 0, 0} +} +func (m *SignatureDescriptor_Data_Single) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *SignatureDescriptor_Data_Single) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_SignatureDescriptor_Data_Single.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 *SignatureDescriptor_Data_Single) XXX_Merge(src proto.Message) { + xxx_messageInfo_SignatureDescriptor_Data_Single.Merge(m, src) +} +func (m *SignatureDescriptor_Data_Single) XXX_Size() int { + return m.Size() +} +func (m *SignatureDescriptor_Data_Single) XXX_DiscardUnknown() { + xxx_messageInfo_SignatureDescriptor_Data_Single.DiscardUnknown(m) +} + +var xxx_messageInfo_SignatureDescriptor_Data_Single proto.InternalMessageInfo + +func (m *SignatureDescriptor_Data_Single) GetMode() SignMode { + if m != nil { + return m.Mode + } + return SignMode_SIGN_MODE_UNSPECIFIED +} + +func (m *SignatureDescriptor_Data_Single) GetSignature() []byte { + if m != nil { + return m.Signature + } + return nil +} + +// Multi is the signature data for a multisig public key +type SignatureDescriptor_Data_Multi struct { + // bitarray specifies which keys within the multisig are signing + Bitarray *types.CompactBitArray `protobuf:"bytes,1,opt,name=bitarray,proto3" json:"bitarray,omitempty"` + // signatures is the signatures of the multi-signature + Signatures []*SignatureDescriptor_Data `protobuf:"bytes,2,rep,name=signatures,proto3" json:"signatures,omitempty"` +} + +func (m *SignatureDescriptor_Data_Multi) Reset() { *m = SignatureDescriptor_Data_Multi{} } +func (m *SignatureDescriptor_Data_Multi) String() string { return proto.CompactTextString(m) } +func (*SignatureDescriptor_Data_Multi) ProtoMessage() {} +func (*SignatureDescriptor_Data_Multi) Descriptor() ([]byte, []int) { + return fileDescriptor_8a04324e5f3729bf, []int{1, 0, 1} +} +func (m *SignatureDescriptor_Data_Multi) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *SignatureDescriptor_Data_Multi) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_SignatureDescriptor_Data_Multi.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 *SignatureDescriptor_Data_Multi) XXX_Merge(src proto.Message) { + xxx_messageInfo_SignatureDescriptor_Data_Multi.Merge(m, src) +} +func (m *SignatureDescriptor_Data_Multi) XXX_Size() int { + return m.Size() +} +func (m *SignatureDescriptor_Data_Multi) XXX_DiscardUnknown() { + xxx_messageInfo_SignatureDescriptor_Data_Multi.DiscardUnknown(m) +} + +var xxx_messageInfo_SignatureDescriptor_Data_Multi proto.InternalMessageInfo + +func (m *SignatureDescriptor_Data_Multi) GetBitarray() *types.CompactBitArray { + if m != nil { + return m.Bitarray + } + return nil +} + +func (m *SignatureDescriptor_Data_Multi) GetSignatures() []*SignatureDescriptor_Data { + if m != nil { + return m.Signatures + } + return nil +} + func init() { proto.RegisterEnum("cosmos.tx.signing.SignMode", SignMode_name, SignMode_value) + proto.RegisterType((*SignatureDescriptors)(nil), "cosmos.tx.signing.SignatureDescriptors") + proto.RegisterType((*SignatureDescriptor)(nil), "cosmos.tx.signing.SignatureDescriptor") + proto.RegisterType((*SignatureDescriptor_Data)(nil), "cosmos.tx.signing.SignatureDescriptor.Data") + proto.RegisterType((*SignatureDescriptor_Data_Single)(nil), "cosmos.tx.signing.SignatureDescriptor.Data.Single") + proto.RegisterType((*SignatureDescriptor_Data_Multi)(nil), "cosmos.tx.signing.SignatureDescriptor.Data.Multi") } func init() { proto.RegisterFile("cosmos/tx/signing/signing.proto", fileDescriptor_8a04324e5f3729bf) } var fileDescriptor_8a04324e5f3729bf = []byte{ - // 214 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x4f, 0xce, 0x2f, 0xce, - 0xcd, 0x2f, 0xd6, 0x2f, 0xa9, 0xd0, 0x2f, 0xce, 0x4c, 0xcf, 0xcb, 0xcc, 0x4b, 0x87, 0xd1, 0x7a, - 0x05, 0x45, 0xf9, 0x25, 0xf9, 0x42, 0x82, 0x10, 0x05, 0x7a, 0x25, 0x15, 0x7a, 0x50, 0x09, 0xad, - 0x62, 0x2e, 0x8e, 0xe0, 0xcc, 0xf4, 0x3c, 0xdf, 0xfc, 0x94, 0x54, 0x21, 0x49, 0x2e, 0xd1, 0x60, - 0x4f, 0x77, 0xbf, 0x78, 0x5f, 0x7f, 0x17, 0xd7, 0xf8, 0x50, 0xbf, 0xe0, 0x00, 0x57, 0x67, 0x4f, - 0x37, 0x4f, 0x57, 0x17, 0x01, 0x06, 0x21, 0x11, 0x2e, 0x01, 0x84, 0x94, 0x8b, 0x67, 0x90, 0xab, - 0x73, 0x88, 0x00, 0xa3, 0x90, 0x28, 0x97, 0x20, 0x42, 0x34, 0xc4, 0x35, 0x22, 0x24, 0xd4, 0xd1, - 0x47, 0x80, 0x49, 0x48, 0x9e, 0x4b, 0x1a, 0x21, 0xec, 0xe3, 0xea, 0xee, 0xe8, 0x1c, 0x19, 0xef, - 0xe8, 0xeb, 0xe9, 0xe7, 0x1f, 0xef, 0x15, 0xec, 0xef, 0x27, 0x50, 0xef, 0xe4, 0x7e, 0xe2, 0x91, - 0x1c, 0xe3, 0x85, 0x47, 0x72, 0x8c, 0x0f, 0x1e, 0xc9, 0x31, 0x4e, 0x78, 0x2c, 0xc7, 0x70, 0xe1, - 0xb1, 0x1c, 0xc3, 0x8d, 0xc7, 0x72, 0x0c, 0x51, 0xba, 0xe9, 0x99, 0x25, 0x19, 0xa5, 0x49, 0x7a, - 0xc9, 0xf9, 0xb9, 0xfa, 0x50, 0xdf, 0x40, 0x28, 0xdd, 0xe2, 0x94, 0x6c, 0xfd, 0x92, 0xca, 0x82, - 0x54, 0x64, 0xef, 0x25, 0xb1, 0x81, 0xfd, 0x65, 0x0c, 0x08, 0x00, 0x00, 0xff, 0xff, 0xe1, 0x92, - 0x08, 0x61, 0xfa, 0x00, 0x00, 0x00, + // 487 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x53, 0xcb, 0x6e, 0xd3, 0x40, + 0x14, 0xb5, 0x9b, 0x87, 0xda, 0x5b, 0x84, 0xdc, 0xa1, 0x95, 0x82, 0x8b, 0xdc, 0xaa, 0x0b, 0x54, + 0x81, 0x6a, 0x8b, 0xb0, 0x40, 0x62, 0x83, 0x92, 0xd8, 0x4d, 0x4d, 0xf3, 0xa8, 0xc6, 0xa9, 0x78, + 0x2c, 0xb0, 0x1c, 0xc7, 0x32, 0xa3, 0xc6, 0x19, 0xcb, 0x33, 0x96, 0x9a, 0x15, 0xbf, 0x50, 0xf1, + 0x0d, 0x7c, 0x0c, 0xcb, 0x2e, 0x59, 0xa2, 0xe4, 0x47, 0x50, 0xc6, 0x76, 0x13, 0xa0, 0x48, 0x64, + 0x75, 0xed, 0x33, 0xe7, 0x9c, 0x39, 0xbe, 0xbe, 0x17, 0x0e, 0x7c, 0xca, 0x22, 0xca, 0x0c, 0x7e, + 0x6d, 0x30, 0x12, 0x4e, 0xc8, 0x24, 0x2c, 0xaa, 0x1e, 0x27, 0x94, 0x53, 0xb4, 0x93, 0x11, 0x74, + 0x7e, 0xad, 0xe7, 0x07, 0xaa, 0x9a, 0x6b, 0xfc, 0x64, 0x1a, 0x73, 0x9a, 0x97, 0x8c, 0x7e, 0xf4, + 0x09, 0x76, 0x1d, 0x12, 0x4e, 0x3c, 0x9e, 0x26, 0x81, 0x19, 0x30, 0x3f, 0x21, 0x31, 0xa7, 0x09, + 0x43, 0xa7, 0x00, 0xac, 0xc0, 0x59, 0x4d, 0x3e, 0x2c, 0x1d, 0x6f, 0xd7, 0x9f, 0xea, 0x7f, 0x79, + 0xeb, 0xf7, 0x88, 0xf1, 0x8a, 0xf2, 0xe8, 0x5b, 0x19, 0x1e, 0xdd, 0xc3, 0x41, 0xaf, 0x00, 0xe2, + 0x74, 0x38, 0x26, 0xbe, 0x7b, 0x15, 0x4c, 0x6b, 0xf2, 0xa1, 0x7c, 0xbc, 0x5d, 0xaf, 0x15, 0xfe, + 0x79, 0xc2, 0x0b, 0x41, 0x38, 0x0f, 0xa6, 0x78, 0x2b, 0x2e, 0x1e, 0xd1, 0x1b, 0x28, 0x8f, 0x3c, + 0xee, 0xd5, 0x36, 0x84, 0xe4, 0xf9, 0xff, 0x45, 0xd2, 0x4d, 0x8f, 0x7b, 0x58, 0x08, 0xd5, 0xaf, + 0x25, 0x28, 0x2f, 0x5e, 0x51, 0x07, 0xaa, 0x8c, 0x4c, 0xc2, 0x71, 0x90, 0x5f, 0x5f, 0x5f, 0xc3, + 0x4b, 0x77, 0x84, 0xf2, 0x4c, 0xc2, 0xb9, 0x07, 0xb2, 0xa1, 0x12, 0xa5, 0x63, 0x4e, 0xf2, 0x60, + 0x2f, 0xd6, 0x31, 0xeb, 0x2e, 0x84, 0x67, 0x12, 0xce, 0x1c, 0xd4, 0x77, 0x50, 0xcd, 0xec, 0x91, + 0x01, 0xe5, 0x88, 0x8e, 0xb2, 0x80, 0x0f, 0xeb, 0xfb, 0xff, 0xf0, 0xec, 0xd2, 0x51, 0x80, 0x05, + 0x11, 0x3d, 0x81, 0xad, 0xbb, 0xe6, 0x8b, 0x24, 0x0f, 0xf0, 0x12, 0x50, 0x6f, 0x64, 0xa8, 0x88, + 0xbb, 0xd0, 0x6b, 0xd8, 0x1c, 0x12, 0xee, 0x25, 0x89, 0x57, 0x34, 0x5f, 0xfb, 0xa3, 0xf9, 0x2d, + 0x1a, 0xc5, 0x9e, 0xcf, 0x9b, 0x84, 0x37, 0x16, 0x2c, 0x7c, 0xc7, 0x47, 0xe7, 0xbf, 0x8d, 0xc6, + 0x86, 0x18, 0x8d, 0xb5, 0xfe, 0xc3, 0x8a, 0xbc, 0x59, 0x81, 0x12, 0x4b, 0xa3, 0x67, 0x0c, 0x36, + 0x8b, 0x2f, 0x41, 0x8f, 0x61, 0xcf, 0xb1, 0xdb, 0x3d, 0xb7, 0xdb, 0x37, 0x2d, 0xf7, 0xb2, 0xe7, + 0x5c, 0x58, 0x2d, 0xfb, 0xd4, 0xb6, 0x4c, 0x45, 0x42, 0xbb, 0xa0, 0x2c, 0x8f, 0x4c, 0x1b, 0x5b, + 0xad, 0x81, 0x22, 0xa3, 0x3d, 0xd8, 0x59, 0xa2, 0x03, 0xeb, 0xfd, 0xe0, 0xb2, 0xd1, 0x51, 0x36, + 0xd0, 0x01, 0xec, 0x2f, 0xe1, 0x8e, 0xd5, 0x6e, 0xb4, 0x3e, 0xb8, 0x8d, 0xae, 0xdd, 0xeb, 0xbb, + 0x6f, 0x9d, 0x7e, 0x4f, 0xf9, 0xd2, 0x6c, 0x7f, 0x9f, 0x69, 0xf2, 0xed, 0x4c, 0x93, 0x7f, 0xce, + 0x34, 0xf9, 0x66, 0xae, 0x49, 0xb7, 0x73, 0x4d, 0xfa, 0x31, 0xd7, 0xa4, 0x8f, 0x27, 0x21, 0xe1, + 0x9f, 0xd3, 0xa1, 0xee, 0xd3, 0xc8, 0x28, 0x96, 0x47, 0x94, 0x13, 0x36, 0xba, 0x32, 0xf8, 0x34, + 0x0e, 0x56, 0x37, 0x70, 0x58, 0x15, 0xbb, 0xf4, 0xf2, 0x57, 0x00, 0x00, 0x00, 0xff, 0xff, 0x82, + 0x8c, 0xaa, 0x54, 0x9d, 0x03, 0x00, 0x00, +} + +func (m *SignatureDescriptors) 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 *SignatureDescriptors) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *SignatureDescriptors) 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-- { + { + size, err := m.Signatures[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintSigning(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *SignatureDescriptor) 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 *SignatureDescriptor) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *SignatureDescriptor) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Data != nil { + { + size, err := m.Data.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintSigning(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + if m.PublicKey != nil { + { + size, err := m.PublicKey.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintSigning(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *SignatureDescriptor_Data) 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 *SignatureDescriptor_Data) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *SignatureDescriptor_Data) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Sum != nil { + { + size := m.Sum.Size() + i -= size + if _, err := m.Sum.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + } + } + return len(dAtA) - i, nil +} + +func (m *SignatureDescriptor_Data_Single_) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *SignatureDescriptor_Data_Single_) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.Single != nil { + { + size, err := m.Single.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintSigning(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} +func (m *SignatureDescriptor_Data_Multi_) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *SignatureDescriptor_Data_Multi_) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.Multi != nil { + { + size, err := m.Multi.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintSigning(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + return len(dAtA) - i, nil +} +func (m *SignatureDescriptor_Data_Single) 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 *SignatureDescriptor_Data_Single) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *SignatureDescriptor_Data_Single) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Signature) > 0 { + i -= len(m.Signature) + copy(dAtA[i:], m.Signature) + i = encodeVarintSigning(dAtA, i, uint64(len(m.Signature))) + i-- + dAtA[i] = 0x12 + } + if m.Mode != 0 { + i = encodeVarintSigning(dAtA, i, uint64(m.Mode)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *SignatureDescriptor_Data_Multi) 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 *SignatureDescriptor_Data_Multi) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *SignatureDescriptor_Data_Multi) 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-- { + { + size, err := m.Signatures[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintSigning(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } + if m.Bitarray != nil { + { + size, err := m.Bitarray.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintSigning(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func encodeVarintSigning(dAtA []byte, offset int, v uint64) int { + offset -= sovSigning(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *SignatureDescriptors) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Signatures) > 0 { + for _, e := range m.Signatures { + l = e.Size() + n += 1 + l + sovSigning(uint64(l)) + } + } + return n +} + +func (m *SignatureDescriptor) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.PublicKey != nil { + l = m.PublicKey.Size() + n += 1 + l + sovSigning(uint64(l)) + } + if m.Data != nil { + l = m.Data.Size() + n += 1 + l + sovSigning(uint64(l)) + } + return n +} + +func (m *SignatureDescriptor_Data) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Sum != nil { + n += m.Sum.Size() + } + return n +} + +func (m *SignatureDescriptor_Data_Single_) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Single != nil { + l = m.Single.Size() + n += 1 + l + sovSigning(uint64(l)) + } + return n +} +func (m *SignatureDescriptor_Data_Multi_) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Multi != nil { + l = m.Multi.Size() + n += 1 + l + sovSigning(uint64(l)) + } + return n +} +func (m *SignatureDescriptor_Data_Single) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Mode != 0 { + n += 1 + sovSigning(uint64(m.Mode)) + } + l = len(m.Signature) + if l > 0 { + n += 1 + l + sovSigning(uint64(l)) + } + return n } + +func (m *SignatureDescriptor_Data_Multi) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Bitarray != nil { + l = m.Bitarray.Size() + n += 1 + l + sovSigning(uint64(l)) + } + if len(m.Signatures) > 0 { + for _, e := range m.Signatures { + l = e.Size() + n += 1 + l + sovSigning(uint64(l)) + } + } + return n +} + +func sovSigning(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozSigning(x uint64) (n int) { + return sovSigning(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *SignatureDescriptors) 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 ErrIntOverflowSigning + } + 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: SignatureDescriptors: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: SignatureDescriptors: 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 msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSigning + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthSigning + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthSigning + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Signatures = append(m.Signatures, &SignatureDescriptor{}) + if err := m.Signatures[len(m.Signatures)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipSigning(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthSigning + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthSigning + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *SignatureDescriptor) 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 ErrIntOverflowSigning + } + 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: SignatureDescriptor: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: SignatureDescriptor: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PublicKey", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSigning + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthSigning + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthSigning + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.PublicKey == nil { + m.PublicKey = &types.PublicKey{} + } + if err := m.PublicKey.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Data", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSigning + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthSigning + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthSigning + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Data == nil { + m.Data = &SignatureDescriptor_Data{} + } + if err := m.Data.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipSigning(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthSigning + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthSigning + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *SignatureDescriptor_Data) 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 ErrIntOverflowSigning + } + 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: Data: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Data: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Single", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSigning + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthSigning + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthSigning + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + v := &SignatureDescriptor_Data_Single{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Sum = &SignatureDescriptor_Data_Single_{v} + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Multi", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSigning + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthSigning + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthSigning + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + v := &SignatureDescriptor_Data_Multi{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Sum = &SignatureDescriptor_Data_Multi_{v} + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipSigning(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthSigning + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthSigning + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *SignatureDescriptor_Data_Single) 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 ErrIntOverflowSigning + } + 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: Single: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Single: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Mode", wireType) + } + m.Mode = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSigning + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Mode |= SignMode(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Signature", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSigning + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthSigning + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthSigning + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Signature = append(m.Signature[:0], dAtA[iNdEx:postIndex]...) + if m.Signature == nil { + m.Signature = []byte{} + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipSigning(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthSigning + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthSigning + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *SignatureDescriptor_Data_Multi) 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 ErrIntOverflowSigning + } + 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: Multi: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Multi: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Bitarray", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSigning + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthSigning + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthSigning + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Bitarray == nil { + m.Bitarray = &types.CompactBitArray{} + } + if err := m.Bitarray.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Signatures", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSigning + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthSigning + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthSigning + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Signatures = append(m.Signatures, &SignatureDescriptor_Data{}) + if err := m.Signatures[len(m.Signatures)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipSigning(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthSigning + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthSigning + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipSigning(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowSigning + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowSigning + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowSigning + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthSigning + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupSigning + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthSigning + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthSigning = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowSigning = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupSigning = fmt.Errorf("proto: unexpected end of group") +) diff --git a/x/auth/client/cli/cli_test.go b/x/auth/client/cli/cli_test.go index 97949ba3a6f8..df41fc44346f 100644 --- a/x/auth/client/cli/cli_test.go +++ b/x/auth/client/cli/cli_test.go @@ -14,19 +14,16 @@ import ( "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" - "github.com/cosmos/cosmos-sdk/codec" codec2 "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/crypto/hd" "github.com/cosmos/cosmos-sdk/crypto/keyring" "github.com/cosmos/cosmos-sdk/crypto/types/multisig" - simappparams "github.com/cosmos/cosmos-sdk/simapp/params" + "github.com/cosmos/cosmos-sdk/simapp" "github.com/cosmos/cosmos-sdk/testutil" "github.com/cosmos/cosmos-sdk/testutil/network" sdk "github.com/cosmos/cosmos-sdk/types" authcli "github.com/cosmos/cosmos-sdk/x/auth/client/cli" authtest "github.com/cosmos/cosmos-sdk/x/auth/client/testutil" - "github.com/cosmos/cosmos-sdk/x/auth/types" - authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" bankcli "github.com/cosmos/cosmos-sdk/x/bank/client/testutil" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" ) @@ -47,7 +44,21 @@ func (s *IntegrationTestSuite) SetupSuite() { s.cfg = cfg s.network = network.New(s.T(), cfg) - _, err := s.network.WaitForHeight(1) + kb := s.network.Validators[0].ClientCtx.Keyring + _, _, err := kb.NewMnemonic("newAccount", keyring.English, sdk.FullFundraiserPath, hd.Secp256k1) + s.Require().NoError(err) + + account1, _, err := kb.NewMnemonic("newAccount1", keyring.English, sdk.FullFundraiserPath, hd.Secp256k1) + s.Require().NoError(err) + + account2, _, err := kb.NewMnemonic("newAccount2", keyring.English, sdk.FullFundraiserPath, hd.Secp256k1) + s.Require().NoError(err) + + multi := multisig.NewPubKeyMultisigThreshold(2, []tmcrypto.PubKey{account1.GetPubKey(), account2.GetPubKey()}) + _, err = kb.SaveMultisig("multi", multi) + s.Require().NoError(err) + + _, err = s.network.WaitForHeight(1) s.Require().NoError(err) } @@ -73,29 +84,23 @@ func (s *IntegrationTestSuite) TestCLIValidateSignatures() { ) s.Require().NoError(err) - var tx types.StdTx - err = val.ClientCtx.JSONMarshaler.UnmarshalJSON(res.Bytes(), &tx) - s.Require().NoError(err) - // write unsigned tx to file unsignedTx, cleanup := testutil.WriteToNewTempFile(s.T(), res.String()) defer cleanup() res, err = authtest.TxSignExec(val.ClientCtx, val.Address, unsignedTx.Name()) s.Require().NoError(err) - - var signedTx types.StdTx - err = val.ClientCtx.JSONMarshaler.UnmarshalJSON(res.Bytes(), &signedTx) + signedTx, err := val.ClientCtx.TxConfig.TxJSONDecoder()(res.Bytes()) s.Require().NoError(err) signedTxFile, cleanup := testutil.WriteToNewTempFile(s.T(), res.String()) defer cleanup() - + txBuilder, err := val.ClientCtx.TxConfig.WrapTxBuilder(signedTx) res, err = authtest.TxValidateSignaturesExec(val.ClientCtx, signedTxFile.Name()) s.Require().NoError(err) - signedTx.Memo = "MODIFIED STD TX" - bz, err := val.ClientCtx.JSONMarshaler.MarshalJSON(signedTx) + txBuilder.SetMemo("MODIFIED TX") + bz, err := val.ClientCtx.TxConfig.TxJSONEncoder()(txBuilder.GetTx()) s.Require().NoError(err) modifiedTxFile, cleanup := testutil.WriteToNewTempFile(s.T(), string(bz)) @@ -147,28 +152,26 @@ func (s *IntegrationTestSuite) TestCLISignBatch() { defer cleanup2() res, err = authtest.TxSignBatchExec(val.ClientCtx, val.Address, malformedFile.Name(), fmt.Sprintf("--%s=%s", flags.FlagChainID, val.ClientCtx.ChainID)) - s.Require().EqualError(err, "cannot parse disfix JSON wrapper: invalid character 'm' looking for beginning of value") + s.Require().Error(err) // Sign batch malformed tx file signature only. res, err = authtest.TxSignBatchExec(val.ClientCtx, val.Address, malformedFile.Name(), fmt.Sprintf("--%s=%s", flags.FlagChainID, val.ClientCtx.ChainID), "--signature-only") - s.Require().EqualError(err, "cannot parse disfix JSON wrapper: invalid character 'm' looking for beginning of value") + s.Require().Error(err) } func (s *IntegrationTestSuite) TestCLISendGenerateSignAndBroadcast() { val1 := s.network.Validators[0] - account, _, err := val1.ClientCtx.Keyring.NewMnemonic("newAccount", keyring.English, sdk.FullFundraiserPath, hd.Secp256k1) + account, err := val1.ClientCtx.Keyring.Key("newAccount") s.Require().NoError(err) - sendTokens := sdk.TokensFromConsensusPower(10) + sendTokens := sdk.NewCoin(s.cfg.BondDenom, sdk.TokensFromConsensusPower(10)) normalGeneratedTx, err := bankcli.MsgSendExec( val1.ClientCtx, val1.Address, account.GetAddress(), - sdk.NewCoins( - sdk.NewCoin(s.cfg.BondDenom, sendTokens), - ), + sdk.NewCoins(sendTokens), fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), @@ -176,19 +179,22 @@ func (s *IntegrationTestSuite) TestCLISendGenerateSignAndBroadcast() { ) s.Require().NoError(err) - normalGeneratedStdTx := unmarshalStdTx(s.T(), val1.ClientCtx.JSONMarshaler, normalGeneratedTx.String()) - s.Require().Equal(normalGeneratedStdTx.Fee.Gas, uint64(flags.DefaultGasLimit)) - s.Require().Equal(len(normalGeneratedStdTx.Msgs), 1) - s.Require().Equal(0, len(normalGeneratedStdTx.GetSignatures())) + txCfg := val1.ClientCtx.TxConfig + + normalGeneratedStdTx, err := txCfg.TxJSONDecoder()(normalGeneratedTx.Bytes()) + s.Require().NoError(err) + txBuilder, err := txCfg.WrapTxBuilder(normalGeneratedStdTx) + s.Require().NoError(err) + s.Require().Equal(txBuilder.GetTx().GetGas(), uint64(flags.DefaultGasLimit)) + s.Require().Equal(len(txBuilder.GetTx().GetMsgs()), 1) + s.Require().Equal(0, len(txBuilder.GetTx().GetSignatures())) // Test generate sendTx with --gas=$amount limitedGasGeneratedTx, err := bankcli.MsgSendExec( val1.ClientCtx, val1.Address, account.GetAddress(), - sdk.NewCoins( - sdk.NewCoin(s.cfg.BondDenom, sendTokens), - ), + sdk.NewCoins(sendTokens), fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), @@ -197,19 +203,28 @@ func (s *IntegrationTestSuite) TestCLISendGenerateSignAndBroadcast() { ) s.Require().NoError(err) - limitedGasStdTx := unmarshalStdTx(s.T(), val1.ClientCtx.JSONMarshaler, limitedGasGeneratedTx.String()) - s.Require().Equal(limitedGasStdTx.Fee.Gas, uint64(100)) - s.Require().Equal(len(limitedGasStdTx.Msgs), 1) - s.Require().Equal(0, len(limitedGasStdTx.GetSignatures())) + limitedGasStdTx, err := txCfg.TxJSONDecoder()(limitedGasGeneratedTx.Bytes()) + s.Require().NoError(err) + txBuilder, err = txCfg.WrapTxBuilder(limitedGasStdTx) + s.Require().NoError(err) + s.Require().Equal(txBuilder.GetTx().GetGas(), uint64(100)) + s.Require().Equal(len(txBuilder.GetTx().GetMsgs()), 1) + s.Require().Equal(0, len(txBuilder.GetTx().GetSignatures())) + + resp, err := bankcli.QueryBalancesExec(val1.ClientCtx, val1.Address) + s.Require().NoError(err) + + var coins sdk.Coins + err = val1.ClientCtx.JSONMarshaler.UnmarshalJSON(resp.Bytes(), &coins) + s.Require().NoError(err) + startTokens := coins.AmountOf(s.cfg.BondDenom) // Test generate sendTx, estimate gas finalGeneratedTx, err := bankcli.MsgSendExec( val1.ClientCtx, val1.Address, account.GetAddress(), - sdk.NewCoins( - sdk.NewCoin(s.cfg.BondDenom, sendTokens), - ), + sdk.NewCoins(sendTokens), fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), @@ -218,9 +233,12 @@ func (s *IntegrationTestSuite) TestCLISendGenerateSignAndBroadcast() { ) s.Require().NoError(err) - finalStdTx := unmarshalStdTx(s.T(), val1.ClientCtx.JSONMarshaler, finalGeneratedTx.String()) - s.Require().Equal(uint64(flags.DefaultGasLimit), finalStdTx.Fee.Gas) - s.Require().Equal(len(finalStdTx.Msgs), 1) + finalStdTx, err := txCfg.TxJSONDecoder()(finalGeneratedTx.Bytes()) + s.Require().NoError(err) + txBuilder, err = txCfg.WrapTxBuilder(finalStdTx) + s.Require().NoError(err) + s.Require().Equal(uint64(flags.DefaultGasLimit), txBuilder.GetTx().GetGas()) + s.Require().Equal(len(finalStdTx.GetMsgs()), 1) // Write the output to disk unsignedTxFile, cleanup := testutil.WriteToNewTempFile(s.T(), finalGeneratedTx.String()) @@ -245,11 +263,13 @@ func (s *IntegrationTestSuite) TestCLISendGenerateSignAndBroadcast() { // Sign transaction signedTx, err := authtest.TxSignExec(val1.ClientCtx, val1.Address, unsignedTxFile.Name()) s.Require().NoError(err) - - signedFinalTx := unmarshalStdTx(s.T(), val1.ClientCtx.JSONMarshaler, signedTx.String()) - s.Require().Equal(len(signedFinalTx.Msgs), 1) - s.Require().Equal(1, len(signedFinalTx.GetSignatures())) - s.Require().Equal(val1.Address.String(), signedFinalTx.GetSigners()[0].String()) + signedFinalTx, err := txCfg.TxJSONDecoder()(signedTx.Bytes()) + s.Require().NoError(err) + txBuilder, err = val1.ClientCtx.TxConfig.WrapTxBuilder(signedFinalTx) + s.Require().NoError(err) + s.Require().Equal(len(txBuilder.GetTx().GetMsgs()), 1) + s.Require().Equal(1, len(txBuilder.GetTx().GetSignatures())) + s.Require().Equal(val1.Address.String(), txBuilder.GetTx().GetSigners()[0].String()) // Write the output to disk signedTxFile, cleanup2 := testutil.WriteToNewTempFile(s.T(), signedTx.String()) @@ -261,11 +281,9 @@ func (s *IntegrationTestSuite) TestCLISendGenerateSignAndBroadcast() { s.Require().True(strings.Contains(res.String(), "[OK]")) // Ensure foo has right amount of funds - startTokens := sdk.TokensFromConsensusPower(400) - resp, err := bankcli.QueryBalancesExec(val1.ClientCtx, val1.Address) + resp, err = bankcli.QueryBalancesExec(val1.ClientCtx, val1.Address) s.Require().NoError(err) - var coins sdk.Coins err = val1.ClientCtx.JSONMarshaler.UnmarshalJSON(resp.Bytes(), &coins) s.Require().NoError(err) s.Require().Equal(startTokens, coins.AmountOf(s.cfg.BondDenom)) @@ -291,7 +309,7 @@ func (s *IntegrationTestSuite) TestCLISendGenerateSignAndBroadcast() { err = val1.ClientCtx.JSONMarshaler.UnmarshalJSON(resp.Bytes(), &coins) s.Require().NoError(err) - s.Require().Equal(sendTokens, coins.AmountOf(s.cfg.BondDenom)) + s.Require().Equal(sendTokens.Amount, coins.AmountOf(s.cfg.BondDenom)) // Ensure origin account state resp, err = bankcli.QueryBalancesExec(val1.ClientCtx, val1.Address) @@ -299,11 +317,9 @@ func (s *IntegrationTestSuite) TestCLISendGenerateSignAndBroadcast() { err = val1.ClientCtx.JSONMarshaler.UnmarshalJSON(resp.Bytes(), &coins) s.Require().NoError(err) - s.Require().Equal(sdk.NewInt(389999990), coins.AmountOf(s.cfg.BondDenom)) } func (s *IntegrationTestSuite) TestCLIMultisignInsufficientCosigners() { - s.T().SkipNow() // TODO check encoding. val1 := s.network.Validators[0] codec := codec2.New() @@ -312,14 +328,10 @@ func (s *IntegrationTestSuite) TestCLIMultisignInsufficientCosigners() { val1.ClientCtx.Codec = codec // Generate 2 accounts and a multisig. - account1, _, err := val1.ClientCtx.Keyring.NewMnemonic("newAccount1", keyring.English, sdk.FullFundraiserPath, hd.Secp256k1) + account1, err := val1.ClientCtx.Keyring.Key("newAccount1") s.Require().NoError(err) - account2, _, err := val1.ClientCtx.Keyring.NewMnemonic("newAccount2", keyring.English, sdk.FullFundraiserPath, hd.Secp256k1) - s.Require().NoError(err) - - multi := multisig.NewPubKeyMultisigThreshold(2, []tmcrypto.PubKey{account1.GetPubKey(), account2.GetPubKey()}) - multisigInfo, err := val1.ClientCtx.Keyring.SaveMultisig("multi", multi) + multisigInfo, err := val1.ClientCtx.Keyring.Key("multi") s.Require().NoError(err) // Send coins from validator to multisig. @@ -374,7 +386,7 @@ func (s *IntegrationTestSuite) TestCLIMultisignInsufficientCosigners() { defer cleanup3() exec, err := authtest.TxValidateSignaturesExec(val1.ClientCtx, multiSigWith1SignatureFile.Name()) - s.Require().NoError(err) + s.Require().Error(err) fmt.Printf("%s", exec) } @@ -382,15 +394,13 @@ func (s *IntegrationTestSuite) TestCLIMultisignInsufficientCosigners() { func (s *IntegrationTestSuite) TestCLIEncode() { val1 := s.network.Validators[0] - sendTokens := sdk.TokensFromConsensusPower(10) + sendTokens := sdk.NewCoin(s.cfg.BondDenom, sdk.TokensFromConsensusPower(10)) normalGeneratedTx, err := bankcli.MsgSendExec( val1.ClientCtx, val1.Address, val1.Address, - sdk.NewCoins( - sdk.NewCoin(s.cfg.BondDenom, sendTokens), - ), + sdk.NewCoins(sendTokens), fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), @@ -402,7 +412,7 @@ func (s *IntegrationTestSuite) TestCLIEncode() { savedTxFile, cleanup := testutil.WriteToNewTempFile(s.T(), normalGeneratedTx.String()) defer cleanup() - // Enconde + // Encode encodeExec, err := authtest.TxEncodeExec(val1.ClientCtx, savedTxFile.Name()) s.Require().NoError(err) @@ -412,12 +422,15 @@ func (s *IntegrationTestSuite) TestCLIEncode() { decodedTx, err := authtest.TxDecodeExec(val1.ClientCtx, trimmedBase64) s.Require().NoError(err) - theTx := unmarshalStdTx(s.T(), val1.ClientCtx.JSONMarshaler, decodedTx.String()) - s.Require().Equal("deadbeef", theTx.Memo) + txCfg := val1.ClientCtx.TxConfig + theTx, err := txCfg.TxJSONDecoder()(decodedTx.Bytes()) + s.Require().NoError(err) + txBuilder, err := val1.ClientCtx.TxConfig.WrapTxBuilder(theTx) + s.Require().NoError(err) + s.Require().Equal("deadbeef", txBuilder.GetTx().GetMemo()) } func (s *IntegrationTestSuite) TestCLIMultisignSortSignatures() { - s.T().SkipNow() val1 := s.network.Validators[0] codec := codec2.New() @@ -426,25 +439,30 @@ func (s *IntegrationTestSuite) TestCLIMultisignSortSignatures() { val1.ClientCtx.Codec = codec // Generate 2 accounts and a multisig. - account1, _, err := val1.ClientCtx.Keyring.NewMnemonic("newAccount1", keyring.English, sdk.FullFundraiserPath, hd.Secp256k1) + account1, err := val1.ClientCtx.Keyring.Key("newAccount1") s.Require().NoError(err) - account2, _, err := val1.ClientCtx.Keyring.NewMnemonic("newAccount2", keyring.English, sdk.FullFundraiserPath, hd.Secp256k1) + account2, err := val1.ClientCtx.Keyring.Key("newAccount2") s.Require().NoError(err) - multi := multisig.NewPubKeyMultisigThreshold(2, []tmcrypto.PubKey{account1.GetPubKey(), account2.GetPubKey()}) - multisigInfo, err := val1.ClientCtx.Keyring.SaveMultisig("multi", multi) + multisigInfo, err := val1.ClientCtx.Keyring.Key("multi") + s.Require().NoError(err) + + resp, err := bankcli.QueryBalancesExec(val1.ClientCtx, multisigInfo.GetAddress()) s.Require().NoError(err) + var coins sdk.Coins + err = val1.ClientCtx.JSONMarshaler.UnmarshalJSON(resp.Bytes(), &coins) + s.Require().NoError(err) + intialCoins := coins + // Send coins from validator to multisig. sendTokens := sdk.NewInt64Coin(s.cfg.BondDenom, 10) _, err = bankcli.MsgSendExec( val1.ClientCtx, val1.Address, multisigInfo.GetAddress(), - sdk.NewCoins( - sendTokens, - ), + sdk.NewCoins(sendTokens), fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), @@ -454,13 +472,13 @@ func (s *IntegrationTestSuite) TestCLIMultisignSortSignatures() { s.Require().NoError(s.network.WaitForNextBlock()) - resp, err := bankcli.QueryBalancesExec(val1.ClientCtx, multisigInfo.GetAddress()) + resp, err = bankcli.QueryBalancesExec(val1.ClientCtx, multisigInfo.GetAddress()) s.Require().NoError(err) - var coins sdk.Coins err = val1.ClientCtx.JSONMarshaler.UnmarshalJSON(resp.Bytes(), &coins) s.Require().NoError(err) - s.Require().Equal(sendTokens.Amount, coins.AmountOf(s.cfg.BondDenom)) + diff, _ := coins.SafeSub(intialCoins) + s.Require().Equal(sendTokens.Amount, diff.AmountOf(s.cfg.BondDenom)) // Generate multisig transaction. multiGeneratedTx, err := bankcli.MsgSendExec( @@ -514,7 +532,6 @@ func (s *IntegrationTestSuite) TestCLIMultisignSortSignatures() { } func (s *IntegrationTestSuite) TestCLIMultisign() { - s.T().SkipNow() val1 := s.network.Validators[0] codec := codec2.New() @@ -523,14 +540,13 @@ func (s *IntegrationTestSuite) TestCLIMultisign() { val1.ClientCtx.Codec = codec // Generate 2 accounts and a multisig. - account1, _, err := val1.ClientCtx.Keyring.NewMnemonic("newAccount1", keyring.English, sdk.FullFundraiserPath, hd.Secp256k1) + account1, err := val1.ClientCtx.Keyring.Key("newAccount1") s.Require().NoError(err) - account2, _, err := val1.ClientCtx.Keyring.NewMnemonic("newAccount2", keyring.English, sdk.FullFundraiserPath, hd.Secp256k1) + account2, err := val1.ClientCtx.Keyring.Key("newAccount2") s.Require().NoError(err) - multi := multisig.NewPubKeyMultisigThreshold(2, []tmcrypto.PubKey{account1.GetPubKey(), account2.GetPubKey()}) - multisigInfo, err := val1.ClientCtx.Keyring.SaveMultisig("multi", multi) + multisigInfo, err := val1.ClientCtx.Keyring.Key("multi") s.Require().NoError(err) // Send coins from validator to multisig. @@ -539,9 +555,7 @@ func (s *IntegrationTestSuite) TestCLIMultisign() { val1.ClientCtx, val1.Address, multisigInfo.GetAddress(), - sdk.NewCoins( - sendTokens, - ), + sdk.NewCoins(sendTokens), fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), @@ -593,8 +607,7 @@ func (s *IntegrationTestSuite) TestCLIMultisign() { defer cleanup3() // Does not work in offline mode. - val1.ClientCtx.Offline = true - _, err = authtest.TxMultiSignExec(val1.ClientCtx, multisigInfo.GetName(), multiGeneratedTxFile.Name(), sign1File.Name(), sign2File.Name()) + _, err = authtest.TxMultiSignExec(val1.ClientCtx, multisigInfo.GetName(), multiGeneratedTxFile.Name(), "--offline", sign1File.Name(), sign2File.Name()) s.Require().EqualError(err, "couldn't verify signature") val1.ClientCtx.Offline = false @@ -617,7 +630,7 @@ func (s *IntegrationTestSuite) TestCLIMultisign() { func TestGetBroadcastCommand_OfflineFlag(t *testing.T) { clientCtx := client.Context{}.WithOffline(true) - clientCtx = clientCtx.WithTxConfig(simappparams.MakeEncodingConfig().TxConfig) + clientCtx = clientCtx.WithTxConfig(simapp.MakeEncodingConfig().TxConfig) cmd := authcli.GetBroadcastCommand() _ = testutil.ApplyMockIODiscardOutErr(cmd) @@ -628,7 +641,8 @@ func TestGetBroadcastCommand_OfflineFlag(t *testing.T) { func TestGetBroadcastCommand_WithoutOfflineFlag(t *testing.T) { clientCtx := client.Context{} - clientCtx = clientCtx.WithTxConfig(simappparams.MakeEncodingConfig().TxConfig) + txCfg := simapp.MakeEncodingConfig().TxConfig + clientCtx = clientCtx.WithTxConfig(txCfg) ctx := context.Background() ctx = context.WithValue(ctx, client.ClientContextKey, &clientCtx) @@ -639,9 +653,17 @@ func TestGetBroadcastCommand_WithoutOfflineFlag(t *testing.T) { t.Cleanup(cleanFunc) // Create new file with tx - txContents := []byte("{\"type\":\"cosmos-sdk/StdTx\",\"value\":{\"msg\":[{\"type\":\"cosmos-sdk/MsgSend\",\"value\":{\"from_address\":\"cosmos1cxlt8kznps92fwu3j6npahx4mjfutydyene2qw\",\"to_address\":\"cosmos1wc8mpr8m3sy3ap3j7fsgqfzx36um05pystems4\",\"amount\":[{\"denom\":\"stake\",\"amount\":\"10000\"}]}}],\"fee\":{\"amount\":[],\"gas\":\"200000\"},\"signatures\":null,\"memo\":\"\"}}") + builder := txCfg.NewTxBuilder() + builder.SetGasLimit(200000) + from, err := sdk.AccAddressFromBech32("cosmos1cxlt8kznps92fwu3j6npahx4mjfutydyene2qw") + require.NoError(t, err) + to, err := sdk.AccAddressFromBech32("cosmos1cxlt8kznps92fwu3j6npahx4mjfutydyene2qw") + require.NoError(t, err) + err = builder.SetMsgs(banktypes.NewMsgSend(from, to, sdk.Coins{sdk.NewInt64Coin("stake", 10000)})) + require.NoError(t, err) + txContents, err := txCfg.TxJSONEncoder()(builder.GetTx()) txFileName := filepath.Join(testDir, "tx.json") - err := ioutil.WriteFile(txFileName, txContents, 0644) + err = ioutil.WriteFile(txFileName, txContents, 0644) require.NoError(t, err) cmd.SetArgs([]string{txFileName}) @@ -654,8 +676,3 @@ func TestGetBroadcastCommand_WithoutOfflineFlag(t *testing.T) { func TestIntegrationTestSuite(t *testing.T) { suite.Run(t, new(IntegrationTestSuite)) } - -func unmarshalStdTx(t require.TestingT, c codec.JSONMarshaler, s string) (stdTx authtypes.StdTx) { - require.Nil(t, c.UnmarshalJSON([]byte(s), &stdTx)) - return stdTx -} diff --git a/x/auth/client/cli/decode.go b/x/auth/client/cli/decode.go index 513b23d45eb9..b83e8e405969 100644 --- a/x/auth/client/cli/decode.go +++ b/x/auth/client/cli/decode.go @@ -3,6 +3,7 @@ package cli import ( "encoding/base64" "encoding/hex" + "fmt" "github.com/spf13/cobra" @@ -37,7 +38,12 @@ func GetDecodeCommand() *cobra.Command { return err } - return clientCtx.PrintOutput(tx) + json, err := clientCtx.TxConfig.TxJSONEncoder()(tx) + if err != nil { + return err + } + + return clientCtx.PrintString(fmt.Sprintf("%s\n", json)) }, } diff --git a/x/auth/client/cli/encode.go b/x/auth/client/cli/encode.go index 73fcfb450af1..92db2e0a8171 100644 --- a/x/auth/client/cli/encode.go +++ b/x/auth/client/cli/encode.go @@ -2,6 +2,7 @@ package cli import ( "encoding/base64" + "fmt" "github.com/spf13/cobra" @@ -10,13 +11,6 @@ import ( authclient "github.com/cosmos/cosmos-sdk/x/auth/client" ) -// txEncodeRespStr implements a simple Stringer wrapper for a encoded tx. -type txEncodeRespStr string - -func (txr txEncodeRespStr) String() string { - return string(txr) -} - // GetEncodeCommand returns the encode command to take a JSONified transaction and turn it into // Amino-serialized bytes func GetEncodeCommand() *cobra.Command { @@ -44,8 +38,7 @@ If you supply a dash (-) argument in place of an input filename, the command rea // base64 encode the encoded tx bytes txBytesBase64 := base64.StdEncoding.EncodeToString(txBytes) - response := txEncodeRespStr(txBytesBase64) - return clientCtx.PrintOutput(response) + return clientCtx.PrintString(fmt.Sprintf("%s\n", txBytesBase64)) }, } diff --git a/x/auth/client/cli/encode_test.go b/x/auth/client/cli/encode_test.go index 2458b5532157..8b245af985f3 100644 --- a/x/auth/client/cli/encode_test.go +++ b/x/auth/client/cli/encode_test.go @@ -23,15 +23,17 @@ func TestGetCommandEncode(t *testing.T) { authtypes.RegisterCodec(encodingConfig.Amino) sdk.RegisterCodec(encodingConfig.Amino) - txGen := encodingConfig.TxConfig + txCfg := encodingConfig.TxConfig // Build a test transaction - fee := authtypes.NewStdFee(50000, sdk.Coins{sdk.NewInt64Coin("atom", 150)}) - stdTx := authtypes.NewStdTx([]sdk.Msg{}, fee, []authtypes.StdSignature{}, "foomemo") - JSONEncoded, err := txGen.TxJSONEncoder()(stdTx) + builder := txCfg.NewTxBuilder() + builder.SetGasLimit(50000) + builder.SetFeeAmount(sdk.Coins{sdk.NewInt64Coin("atom", 150)}) + builder.SetMemo("foomemo") + jsonEncoded, err := txCfg.TxJSONEncoder()(builder.GetTx()) require.NoError(t, err) - txFile, cleanup := testutil.WriteToNewTempFile(t, string(JSONEncoded)) + txFile, cleanup := testutil.WriteToNewTempFile(t, string(jsonEncoded)) txFileName := txFile.Name() t.Cleanup(cleanup) @@ -58,15 +60,17 @@ func TestGetCommandDecode(t *testing.T) { sdk.RegisterCodec(encodingConfig.Amino) - txGen := encodingConfig.TxConfig - clientCtx = clientCtx.WithTxConfig(txGen) + txCfg := encodingConfig.TxConfig + clientCtx = clientCtx.WithTxConfig(txCfg) // Build a test transaction - fee := authtypes.NewStdFee(50000, sdk.Coins{sdk.NewInt64Coin("atom", 150)}) - stdTx := authtypes.NewStdTx([]sdk.Msg{}, fee, []authtypes.StdSignature{}, "foomemo") + builder := txCfg.NewTxBuilder() + builder.SetGasLimit(50000) + builder.SetFeeAmount(sdk.Coins{sdk.NewInt64Coin("atom", 150)}) + builder.SetMemo("foomemo") // Encode transaction - txBytes, err := clientCtx.TxConfig.TxEncoder()(stdTx) + txBytes, err := clientCtx.TxConfig.TxEncoder()(builder.GetTx()) require.NoError(t, err) // Convert the transaction into base64 encoded string diff --git a/x/auth/client/cli/tx_multisign.go b/x/auth/client/cli/tx_multisign.go index 0633e43c73e6..39c28e28391a 100644 --- a/x/auth/client/cli/tx_multisign.go +++ b/x/auth/client/cli/tx_multisign.go @@ -11,13 +11,14 @@ import ( "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" - "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/client/tx" "github.com/cosmos/cosmos-sdk/crypto/keyring" "github.com/cosmos/cosmos-sdk/crypto/types/multisig" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/types/errors" + signingtypes "github.com/cosmos/cosmos-sdk/types/tx/signing" "github.com/cosmos/cosmos-sdk/version" authclient "github.com/cosmos/cosmos-sdk/x/auth/client" + "github.com/cosmos/cosmos-sdk/x/auth/signing" "github.com/cosmos/cosmos-sdk/x/auth/types" ) @@ -60,13 +61,27 @@ recommended to set such parameters manually. func makeMultiSignCmd() func(cmd *cobra.Command, args []string) error { return func(cmd *cobra.Command, args []string) (err error) { clientCtx := client.GetClientContextFromCmd(cmd) - cdc := clientCtx.Codec - tx, err := authclient.ReadTxFromFile(clientCtx, args[0]) - stdTx := tx.(types.StdTx) + clientCtx, err = client.ReadTxCommandFlags(clientCtx, cmd.Flags()) + if err != nil { + return err + } + + parsedTx, err := authclient.ReadTxFromFile(clientCtx, args[0]) if err != nil { return } + txFactory := tx.NewFactoryCLI(clientCtx, cmd.Flags()) + if txFactory.SignMode() == signingtypes.SignMode_SIGN_MODE_UNSPECIFIED { + txFactory = txFactory.WithSignMode(signingtypes.SignMode_SIGN_MODE_LEGACY_AMINO_JSON) + } + + txCfg := clientCtx.TxConfig + txBuilder, err := txCfg.WrapTxBuilder(parsedTx) + if err != nil { + return err + } + backend, _ := cmd.Flags().GetString(flags.FlagKeyringBackend) inBuf := bufio.NewReader(cmd.InOrStdin()) @@ -85,63 +100,53 @@ func makeMultiSignCmd() func(cmd *cobra.Command, args []string) error { multisigPub := multisigInfo.GetPubKey().(multisig.PubKeyMultisigThreshold) multisigSig := multisig.NewMultisig(len(multisigPub.PubKeys)) - txBldr, err := types.NewTxBuilderFromFlags(inBuf, cmd.Flags(), clientCtx.HomeDir) - if err != nil { - return errors.Wrap(err, "error creating tx builder from flags") - } - if !clientCtx.Offline { accnum, seq, err := types.NewAccountRetriever(clientCtx.JSONMarshaler).GetAccountNumberSequence(clientCtx, multisigInfo.GetAddress()) if err != nil { return err } - txBldr = txBldr.WithAccountNumber(accnum).WithSequence(seq) + txFactory = txFactory.WithAccountNumber(accnum).WithSequence(seq) } // read each signature and add it to the multisig if valid for i := 2; i < len(args); i++ { - stdSig, err := readAndUnmarshalStdSignature(cdc, args[i]) + sigs, err := unmarshalSignatureJSON(clientCtx, args[i]) if err != nil { return err } - // Validate each signature - sigBytes := types.StdSignBytes( - txBldr.ChainID(), txBldr.AccountNumber(), txBldr.Sequence(), - stdTx.Fee, stdTx.GetMsgs(), stdTx.GetMemo(), - ) - if ok := stdSig.GetPubKey().VerifyBytes(sigBytes, stdSig.Signature); !ok { - return fmt.Errorf("couldn't verify signature") + signingData := signing.SignerData{ + ChainID: txFactory.ChainID(), + AccountNumber: txFactory.AccountNumber(), + AccountSequence: txFactory.Sequence(), } - sigV2, err := types.StdSignatureToSignatureV2(cdc, stdSig) - if err != nil { - return nil - } + for _, sig := range sigs { + err = signing.VerifySignature(sig.PubKey, signingData, sig.Data, txCfg.SignModeHandler(), txBuilder.GetTx()) + if err != nil { + return fmt.Errorf("couldn't verify signature") + } - if err := multisig.AddSignatureV2(multisigSig, sigV2, multisigPub.PubKeys); err != nil { - return err + if err := multisig.AddSignatureV2(multisigSig, sig, multisigPub.PubKeys); err != nil { + return err + } } } - sigBz, err := types.SignatureDataToAminoSignature(cdc, multisigSig) + sigV2 := signingtypes.SignatureV2{ + PubKey: multisigPub, + Data: multisigSig, + } + + err = txBuilder.SetSignatures(sigV2) if err != nil { return err } - newStdSig := types.StdSignature{Signature: sigBz, PubKey: multisigPub.Bytes()} //nolint:staticcheck - newTx := types.NewStdTx(stdTx.GetMsgs(), stdTx.Fee, []types.StdSignature{newStdSig}, stdTx.GetMemo()) //nolint:staticcheck - - var json []byte - sigOnly, _ := cmd.Flags().GetBool(flagSigOnly) - if sigOnly { - json, err = cdc.MarshalJSON(newTx.Signatures[0]) - } else { - json, err = cdc.MarshalJSON(newTx) - } + json, err := marshalSignatureJSON(txCfg, txBuilder, sigOnly) if err != nil { return err } @@ -158,18 +163,14 @@ func makeMultiSignCmd() func(cmd *cobra.Command, args []string) error { } defer fp.Close() - fmt.Fprintf(fp, "%s\n", json) - return + return clientCtx.PrintString(fmt.Sprintf("%s\n", json)) } } -func readAndUnmarshalStdSignature(cdc *codec.Codec, filename string) (stdSig types.StdSignature, err error) { //nolint:staticcheck +func unmarshalSignatureJSON(clientCtx client.Context, filename string) (sigs []signingtypes.SignatureV2, err error) { var bytes []byte if bytes, err = ioutil.ReadFile(filename); err != nil { return } - if err = cdc.UnmarshalJSON(bytes, &stdSig); err != nil { - return - } - return + return clientCtx.TxConfig.UnmarshalSignatureJSON(bytes) } diff --git a/x/auth/client/cli/tx_sign.go b/x/auth/client/cli/tx_sign.go index 3dc052d12927..423968b628b7 100644 --- a/x/auth/client/cli/tx_sign.go +++ b/x/auth/client/cli/tx_sign.go @@ -1,7 +1,6 @@ package cli import ( - "bufio" "fmt" "os" @@ -9,10 +8,10 @@ import ( "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" - "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/client/tx" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/tx/signing" authclient "github.com/cosmos/cosmos-sdk/x/auth/client" - "github.com/cosmos/cosmos-sdk/x/auth/types" ) const ( @@ -61,12 +60,13 @@ account key. It implies --signature-only. func makeSignBatchCmd() func(cmd *cobra.Command, args []string) error { return func(cmd *cobra.Command, args []string) error { clientCtx := client.GetClientContextFromCmd(cmd) - - txBldr, err := types.NewTxBuilderFromFlags(bufio.NewReader(cmd.InOrStdin()), cmd.Flags(), clientCtx.HomeDir) + clientCtx, err := client.ReadTxCommandFlags(clientCtx, cmd.Flags()) if err != nil { return err } + txFactory := tx.NewFactoryCLI(clientCtx, cmd.Flags()) + txCfg := clientCtx.TxConfig generateSignatureOnly, _ := cmd.Flags().GetBool(flagSigOnly) var ( @@ -97,34 +97,34 @@ func makeSignBatchCmd() func(cmd *cobra.Command, args []string) error { return err } } + scanner := authclient.NewBatchScanner(txCfg, infile) - scanner := authclient.NewBatchScanner(clientCtx.JSONMarshaler, infile) - - for sequence := txBldr.Sequence(); scanner.Scan(); sequence++ { - var stdTx types.StdTx - - unsignedStdTx := scanner.StdTx() - txBldr = txBldr.WithSequence(sequence) - + for sequence := txFactory.Sequence(); scanner.Scan(); sequence++ { + unsignedStdTx := scanner.Tx() + txFactory = txFactory.WithSequence(sequence) + txBuilder, err := txCfg.WrapTxBuilder(unsignedStdTx) + if err != nil { + return err + } if multisigAddr.Empty() { from, _ := cmd.Flags().GetString(flags.FlagFrom) - _, fromName, err := client.GetFromFields(txBldr.Keybase(), from, clientCtx.GenerateOnly) + _, fromName, err := client.GetFromFields(txFactory.Keybase(), from, clientCtx.GenerateOnly) if err != nil { return fmt.Errorf("error getting account from keybase: %w", err) } - - stdTx, err = authclient.SignStdTx(txBldr, clientCtx, fromName, unsignedStdTx, false, true) + err = authclient.SignTx(txFactory, clientCtx, fromName, txBuilder, true) if err != nil { return err } } else { - stdTx, err = authclient.SignStdTxWithSignerAddress(txBldr, clientCtx, multisigAddr, clientCtx.GetFromName(), unsignedStdTx, true) - if err != nil { - return err - } + err = authclient.SignTxWithSignerAddress(txFactory, clientCtx, multisigAddr, clientCtx.GetFromName(), txBuilder, true) } - json, err := getSignatureJSON(clientCtx.JSONMarshaler, stdTx, generateSignatureOnly) + if err != nil { + return err + } + + json, err := marshalSignatureJSON(txCfg, txBuilder, generateSignatureOnly) if err != nil { return err } @@ -206,20 +206,31 @@ func preSignCmd(cmd *cobra.Command, _ []string) { func makeSignCmd() func(cmd *cobra.Command, args []string) error { return func(cmd *cobra.Command, args []string) error { clientCtx := client.GetClientContextFromCmd(cmd) + clientCtx, err := client.ReadTxCommandFlags(clientCtx, cmd.Flags()) + if err != nil { + return err + } + txFactory := tx.NewFactoryCLI(clientCtx, cmd.Flags()) - clientCtx, txBldr, tx, err := readStdTxAndInitContexts(clientCtx, cmd, args[0]) + clientCtx, txF, newTx, err := readTxAndInitContexts(clientCtx, cmd, args[0]) + if err != nil { + return err + } + if txF.SignMode() == signing.SignMode_SIGN_MODE_UNSPECIFIED { + txF = txF.WithSignMode(signing.SignMode_SIGN_MODE_LEGACY_AMINO_JSON) + } + txCfg := clientCtx.TxConfig + txBuilder, err := txCfg.WrapTxBuilder(newTx) if err != nil { return err } - stdTx := tx.(types.StdTx) // if --signature-only is on, then override --append - var newTx types.StdTx generateSignatureOnly, _ := cmd.Flags().GetBool(flagSigOnly) multisigAddrStr, _ := cmd.Flags().GetString(flagMultisig) from, _ := cmd.Flags().GetString(flags.FlagFrom) - _, fromName, err := client.GetFromFields(txBldr.Keybase(), from, clientCtx.GenerateOnly) + _, fromName, err := client.GetFromFields(txFactory.Keybase(), from, clientCtx.GenerateOnly) if err != nil { return fmt.Errorf("error getting account from keybase: %w", err) } @@ -232,23 +243,22 @@ func makeSignCmd() func(cmd *cobra.Command, args []string) error { return err } - newTx, err = authclient.SignStdTxWithSignerAddress( - txBldr, clientCtx, multisigAddr, fromName, stdTx, clientCtx.Offline, + err = authclient.SignTxWithSignerAddress( + txF, clientCtx, multisigAddr, fromName, txBuilder, clientCtx.Offline, ) generateSignatureOnly = true } else { - append, _ := cmd.Flags().GetBool(flagAppend) - appendSig := append && !generateSignatureOnly - newTx, err = authclient.SignStdTx(txBldr, clientCtx, fromName, stdTx, appendSig, clientCtx.Offline) - if err != nil { - return err + flagAppend, _ := cmd.Flags().GetBool(flagAppend) + appendSig := flagAppend && !generateSignatureOnly + if appendSig { + err = authclient.SignTx(txF, clientCtx, clientCtx.GetFromName(), txBuilder, clientCtx.Offline) } } if err != nil { return err } - json, err := getSignatureJSON(clientCtx.JSONMarshaler, newTx, generateSignatureOnly) + json, err := marshalSignatureJSON(txCfg, txBuilder, generateSignatureOnly) if err != nil { return err } @@ -265,15 +275,20 @@ func makeSignCmd() func(cmd *cobra.Command, args []string) error { } defer fp.Close() - fmt.Fprintf(fp, "%s\n", json) - return nil + return clientCtx.PrintString(fmt.Sprintf("%s\n", json)) } } -func getSignatureJSON(cdc codec.JSONMarshaler, newTx types.StdTx, generateSignatureOnly bool) ([]byte, error) { +func marshalSignatureJSON(txConfig client.TxConfig, txBldr client.TxBuilder, generateSignatureOnly bool) ([]byte, error) { + parsedTx := txBldr.GetTx() + if generateSignatureOnly { - return cdc.MarshalJSON(newTx.Signatures[0]) + sigs, err := parsedTx.GetSignaturesV2() + if err != nil { + return nil, err + } + return txConfig.MarshalSignatureJSON(sigs) } - return cdc.MarshalJSON(newTx) + return txConfig.TxJSONEncoder()(parsedTx) } diff --git a/x/auth/client/cli/validate_sigs.go b/x/auth/client/cli/validate_sigs.go index 7d39335b2500..3d1c50b8115a 100644 --- a/x/auth/client/cli/validate_sigs.go +++ b/x/auth/client/cli/validate_sigs.go @@ -1,18 +1,16 @@ package cli import ( - "bufio" "fmt" - "strings" "github.com/spf13/cobra" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" - "github.com/cosmos/cosmos-sdk/crypto/types/multisig" + "github.com/cosmos/cosmos-sdk/client/tx" sdk "github.com/cosmos/cosmos-sdk/types" authclient "github.com/cosmos/cosmos-sdk/x/auth/client" - "github.com/cosmos/cosmos-sdk/x/auth/types" + authsigning "github.com/cosmos/cosmos-sdk/x/auth/signing" ) func GetValidateSignaturesCommand() *cobra.Command { @@ -41,11 +39,15 @@ transaction will be not be performed as that will require RPC communication with func makeValidateSignaturesCmd() func(cmd *cobra.Command, args []string) error { return func(cmd *cobra.Command, args []string) error { clientCtx := client.GetClientContextFromCmd(cmd) - clientCtx, txBldr, tx, err := readStdTxAndInitContexts(clientCtx, cmd, args[0]) + clientCtx, err := client.ReadTxCommandFlags(clientCtx, cmd.Flags()) + if err != nil { + return err + } + + clientCtx, txBldr, stdTx, err := readTxAndInitContexts(clientCtx, cmd, args[0]) if err != nil { return err } - stdTx := tx.(types.StdTx) if !printAndValidateSigs(cmd, clientCtx, txBldr.ChainID(), stdTx, clientCtx.Offline) { return fmt.Errorf("signatures validation failed") @@ -59,17 +61,22 @@ func makeValidateSignaturesCmd() func(cmd *cobra.Command, args []string) error { // expected signers. In addition, if offline has not been supplied, the signature is // verified over the transaction sign bytes. Returns false if the validation fails. func printAndValidateSigs( - cmd *cobra.Command, clientCtx client.Context, chainID string, stdTx types.StdTx, offline bool, + cmd *cobra.Command, clientCtx client.Context, chainID string, tx sdk.Tx, offline bool, ) bool { - cmd.Println("Signers:") - signers := stdTx.GetSigners() + sigTx := tx.(authsigning.SigVerifiableTx) + signModeHandler := clientCtx.TxConfig.SignModeHandler() + cmd.Println("Signers:") + signers := sigTx.GetSigners() for i, signer := range signers { cmd.Printf(" %v: %v\n", i, signer.String()) } success := true - sigs := stdTx.Signatures + sigs, err := sigTx.GetSignaturesV2() + if err != nil { + panic(err) + } cmd.Println("") cmd.Println("Signatures:") @@ -79,9 +86,10 @@ func printAndValidateSigs( for i, sig := range sigs { var ( + pubKey = sig.PubKey multiSigHeader string multiSigMsg string - sigAddr = sdk.AccAddress(sig.GetPubKey().Address()) + sigAddr = sdk.AccAddress(pubKey.Address()) sigSanity = "OK" ) @@ -93,40 +101,21 @@ func printAndValidateSigs( // Validate the actual signature over the transaction bytes since we can // reach out to a full node to query accounts. if !offline && success { - acc, err := types.NewAccountRetriever(clientCtx.JSONMarshaler).GetAccount(clientCtx, sigAddr) + accNum, accSeq, err := clientCtx.AccountRetriever.GetAccountNumberSequence(clientCtx, sigAddr) if err != nil { cmd.Printf("failed to get account: %s\n", sigAddr) return false } - sigBytes := types.StdSignBytes( - chainID, acc.GetAccountNumber(), acc.GetSequence(), - stdTx.Fee, stdTx.GetMsgs(), stdTx.GetMemo(), - ) - - if ok := sig.GetPubKey().VerifyBytes(sigBytes, sig.Signature); !ok { - sigSanity = "ERROR: signature invalid" - success = false + signingData := authsigning.SignerData{ + ChainID: chainID, + AccountNumber: accNum, + AccountSequence: accSeq, } - } - - multiPK, ok := sig.GetPubKey().(multisig.PubKeyMultisigThreshold) - if ok { - var multiSig multisig.AminoMultisignature - clientCtx.Codec.MustUnmarshalBinaryBare(sig.Signature, &multiSig) - - var b strings.Builder - b.WriteString("\n MultiSig Signatures:\n") - - 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)) - } + err = authsigning.VerifySignature(pubKey, signingData, sig.Data, signModeHandler, sigTx) + if err != nil { + return false } - - multiSigHeader = fmt.Sprintf(" [multisig threshold: %d/%d]", multiPK.K, len(multiPK.PubKeys)) - multiSigMsg = b.String() } cmd.Printf(" %d: %s\t\t\t[%s]%s%s\n", i, sigAddr.String(), sigSanity, multiSigHeader, multiSigMsg) @@ -137,21 +126,13 @@ func printAndValidateSigs( return success } -func readStdTxAndInitContexts(clientCtx client.Context, cmd *cobra.Command, filename string) ( - client.Context, types.TxBuilder, sdk.Tx, error, -) { +func readTxAndInitContexts(clientCtx client.Context, cmd *cobra.Command, filename string) (client.Context, tx.Factory, sdk.Tx, error) { stdTx, err := authclient.ReadTxFromFile(clientCtx, filename) if err != nil { - return client.Context{}, types.TxBuilder{}, types.StdTx{}, err + return clientCtx, tx.Factory{}, nil, err } - inBuf := bufio.NewReader(cmd.InOrStdin()) - clientCtx = clientCtx.WithInput(inBuf) - - txBldr, err := types.NewTxBuilderFromFlags(inBuf, cmd.Flags(), clientCtx.HomeDir) - if err != nil { - return client.Context{}, types.TxBuilder{}, types.StdTx{}, err - } + txFactory := tx.NewFactoryCLI(clientCtx, cmd.Flags()) - return clientCtx, txBldr, stdTx, nil + return clientCtx, txFactory, stdTx, nil } diff --git a/x/auth/client/tx.go b/x/auth/client/tx.go index c8b3464ad866..079da7df32fb 100644 --- a/x/auth/client/tx.go +++ b/x/auth/client/tx.go @@ -10,10 +10,9 @@ import ( "strings" "github.com/gogo/protobuf/jsonpb" - "github.com/pkg/errors" "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/client/input" + "github.com/cosmos/cosmos-sdk/client/tx" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" @@ -38,81 +37,6 @@ func (gr GasEstimateResponse) String() string { return fmt.Sprintf("gas estimate: %d", gr.GasEstimate) } -// GenerateOrBroadcastMsgs creates a StdTx given a series of messages. If -// the provided context has generate-only enabled, the tx will only be printed -// to STDOUT in a fully offline manner. Otherwise, the tx will be signed and -// broadcasted. -func GenerateOrBroadcastMsgs(clientCtx client.Context, txBldr authtypes.TxBuilder, msgs []sdk.Msg) error { - if clientCtx.GenerateOnly { - return PrintUnsignedStdTx(txBldr, clientCtx, msgs) - } - - return CompleteAndBroadcastTxCLI(txBldr, clientCtx, msgs) -} - -// CompleteAndBroadcastTxCLI implements a utility function that facilitates -// sending a series of messages in a signed transaction given a TxBuilder and a -// QueryContext. It ensures that the account exists, has a proper number and -// sequence set. In addition, it builds and signs a transaction with the -// supplied messages. Finally, it broadcasts the signed transaction to a node. -func CompleteAndBroadcastTxCLI(txBldr authtypes.TxBuilder, clientCtx client.Context, msgs []sdk.Msg) error { - txBldr, err := PrepareTxBuilder(txBldr, clientCtx) - if err != nil { - return err - } - - fromName := clientCtx.GetFromName() - - if txBldr.SimulateAndExecute() || clientCtx.Simulate { - txBldr, err = EnrichWithGas(txBldr, clientCtx, msgs) - if err != nil { - return err - } - - gasEst := GasEstimateResponse{GasEstimate: txBldr.Gas()} - _, _ = fmt.Fprintf(os.Stderr, "%s\n", gasEst.String()) - } - - if clientCtx.Simulate { - return nil - } - - if !clientCtx.SkipConfirm { - stdSignMsg, err := txBldr.BuildSignMsg(msgs) - if err != nil { - return err - } - - json, err := clientCtx.JSONMarshaler.MarshalJSON(stdSignMsg) - if err != nil { - return err - } - - _, _ = fmt.Fprintf(os.Stderr, "%s\n\n", json) - - buf := bufio.NewReader(os.Stdin) - ok, err := input.GetConfirmation("confirm transaction before signing and broadcasting", buf, os.Stderr) - if err != nil || !ok { - _, _ = fmt.Fprintf(os.Stderr, "%s\n", "cancelled transaction") - return err - } - } - - // build and sign the transaction - txBytes, err := txBldr.BuildAndSign(fromName, msgs) - if err != nil { - return err - } - - // broadcast to a Tendermint node - res, err := clientCtx.BroadcastTx(txBytes) - if err != nil { - return err - } - - return clientCtx.PrintOutput(res) -} - // EnrichWithGas calculates the gas estimate that would be consumed by the // transaction and set the transaction's respective value accordingly. func EnrichWithGas(txBldr authtypes.TxBuilder, clientCtx client.Context, msgs []sdk.Msg) (authtypes.TxBuilder, error) { @@ -148,74 +72,52 @@ func CalculateGas( } // PrintUnsignedStdTx builds an unsigned StdTx and prints it to os.Stdout. -func PrintUnsignedStdTx(txBldr authtypes.TxBuilder, clientCtx client.Context, msgs []sdk.Msg) error { - stdTx, err := buildUnsignedStdTxOffline(txBldr, clientCtx, msgs) - if err != nil { - return err - } - - json, err := clientCtx.JSONMarshaler.MarshalJSON(stdTx) - if err != nil { - return err - } - - _, _ = fmt.Fprintf(clientCtx.Output, "%s\n", json) - return nil +func PrintUnsignedStdTx(txBldr tx.Factory, clientCtx client.Context, msgs []sdk.Msg) error { + err := tx.GenerateOrBroadcastTxWithFactory(clientCtx, txBldr, msgs...) + return err } -// SignStdTx appends a signature to a StdTx and returns a copy of it. If appendSig +// SignTx appends a signature to a transaction. If appendSig // is false, it replaces the signatures already attached with the new signature. // Don't perform online validation or lookups if offline is true. -func SignStdTx( - txBldr authtypes.TxBuilder, clientCtx client.Context, name string, - stdTx authtypes.StdTx, appendSig bool, offline bool, -) (authtypes.StdTx, error) { - - var signedStdTx authtypes.StdTx - - info, err := txBldr.Keybase().Key(name) +func SignTx(txFactory tx.Factory, clientCtx client.Context, name string, stdTx client.TxBuilder, offline bool) error { + info, err := txFactory.Keybase().Key(name) if err != nil { - return signedStdTx, err + return err } - - addr := info.GetPubKey().Address() - - // check whether the address is a signer - if !isTxSigner(sdk.AccAddress(addr), stdTx.GetSigners()) { - return signedStdTx, fmt.Errorf("%s: %s", sdkerrors.ErrorInvalidSigner, name) + addr := sdk.AccAddress(info.GetPubKey().Address()) + if !isTxSigner(addr, stdTx.GetTx().GetSigners()) { + return fmt.Errorf("%s: %s", sdkerrors.ErrorInvalidSigner, name) } - if !offline { - txBldr, err = populateAccountFromState(txBldr, clientCtx, sdk.AccAddress(addr)) + txFactory, err = populateAccountFromState(txFactory, clientCtx, addr) if err != nil { - return signedStdTx, err + return err } } - return txBldr.SignStdTx(name, stdTx, appendSig) + return tx.Sign(txFactory, name, stdTx) } -// SignStdTxWithSignerAddress attaches a signature to a StdTx and returns a copy of a it. +// SignTxWithSignerAddress attaches a signature to a transaction. // Don't perform online validation or lookups if offline is true, else // populate account and sequence numbers from a foreign account. -func SignStdTxWithSignerAddress( - txBldr authtypes.TxBuilder, clientCtx client.Context, - addr sdk.AccAddress, name string, stdTx authtypes.StdTx, offline bool, -) (signedStdTx authtypes.StdTx, err error) { +func SignTxWithSignerAddress(txFactory tx.Factory, clientCtx client.Context, addr sdk.AccAddress, + name string, txBuilder client.TxBuilder, offline bool) (err error) { // check whether the address is a signer - if !isTxSigner(addr, stdTx.GetSigners()) { - return signedStdTx, fmt.Errorf("%s: %s", sdkerrors.ErrorInvalidSigner, name) + if !isTxSigner(addr, txBuilder.GetTx().GetSigners()) { + return fmt.Errorf("%s: %s", sdkerrors.ErrorInvalidSigner, name) } if !offline { - txBldr, err = populateAccountFromState(txBldr, clientCtx, addr) + txFactory, err = populateAccountFromState(txFactory, clientCtx, addr) if err != nil { - return signedStdTx, err + return err } } - return txBldr.SignStdTx(name, stdTx, false) + return tx.Sign(txFactory, name, txBuilder) } // Read and decode a StdTx from the given filename. Can pass "-" to read from stdin. @@ -236,21 +138,21 @@ func ReadTxFromFile(ctx client.Context, filename string) (tx sdk.Tx, err error) } // NewBatchScanner returns a new BatchScanner to read newline-delimited StdTx transactions from r. -func NewBatchScanner(cdc codec.JSONMarshaler, r io.Reader) *BatchScanner { - return &BatchScanner{Scanner: bufio.NewScanner(r), cdc: cdc} +func NewBatchScanner(cfg client.TxConfig, r io.Reader) *BatchScanner { + return &BatchScanner{Scanner: bufio.NewScanner(r), cfg: cfg} } // BatchScanner provides a convenient interface for reading batch data such as a file // of newline-delimited JSON encoded StdTx. type BatchScanner struct { *bufio.Scanner - stdTx authtypes.StdTx - cdc codec.JSONMarshaler + theTx sdk.Tx + cfg client.TxConfig unmarshalErr error } -// StdTx returns the most recent StdTx unmarshalled by a call to Scan. -func (bs BatchScanner) StdTx() authtypes.StdTx { return bs.stdTx } +// Tx returns the most recent Tx unmarshalled by a call to Scan. +func (bs BatchScanner) Tx() sdk.Tx { return bs.theTx } // UnmarshalErr returns the first unmarshalling error that was encountered by the scanner. func (bs BatchScanner) UnmarshalErr() error { return bs.unmarshalErr } @@ -261,7 +163,9 @@ func (bs *BatchScanner) Scan() bool { return false } - if err := bs.cdc.UnmarshalJSON(bs.Bytes(), &bs.stdTx); err != nil && bs.unmarshalErr == nil { + tx, err := bs.cfg.TxJSONDecoder()(bs.Bytes()) + bs.theTx = tx + if err != nil && bs.unmarshalErr == nil { bs.unmarshalErr = err return false } @@ -270,8 +174,8 @@ func (bs *BatchScanner) Scan() bool { } func populateAccountFromState( - txBldr authtypes.TxBuilder, clientCtx client.Context, addr sdk.AccAddress, -) (authtypes.TxBuilder, error) { + txBldr tx.Factory, clientCtx client.Context, addr sdk.AccAddress, +) (tx.Factory, error) { num, seq, err := clientCtx.AccountRetriever.GetAccountNumberSequence(clientCtx, addr) if err != nil { @@ -316,56 +220,6 @@ func parseQueryResponse(bz []byte) (sdk.SimulationResponse, error) { return simRes, nil } -// PrepareTxBuilder populates a TxBuilder in preparation for the build of a Tx. -func PrepareTxBuilder(txBldr authtypes.TxBuilder, clientCtx client.Context) (authtypes.TxBuilder, error) { - from := clientCtx.GetFromAddress() - accGetter := clientCtx.AccountRetriever - if err := accGetter.EnsureExists(clientCtx, from); err != nil { - return txBldr, err - } - - txbldrAccNum, txbldrAccSeq := txBldr.AccountNumber(), txBldr.Sequence() - // TODO: (ref #1903) Allow for user supplied account number without - // automatically doing a manual lookup. - if txbldrAccNum == 0 || txbldrAccSeq == 0 { - num, seq, err := accGetter.GetAccountNumberSequence(clientCtx, from) - if err != nil { - return txBldr, err - } - - if txbldrAccNum == 0 { - txBldr = txBldr.WithAccountNumber(num) - } - if txbldrAccSeq == 0 { - txBldr = txBldr.WithSequence(seq) - } - } - - return txBldr, nil -} - -func buildUnsignedStdTxOffline(txBldr authtypes.TxBuilder, clientCtx client.Context, msgs []sdk.Msg) (stdTx authtypes.StdTx, err error) { - if txBldr.SimulateAndExecute() { - if clientCtx.Offline { - return stdTx, errors.New("cannot estimate gas in offline mode") - } - - txBldr, err = EnrichWithGas(txBldr, clientCtx, msgs) - if err != nil { - return stdTx, err - } - - _, _ = fmt.Fprintf(os.Stderr, "estimated gas = %v\n", txBldr.Gas()) - } - - stdSignMsg, err := txBldr.BuildSignMsg(msgs) - if err != nil { - return stdTx, err - } - - return authtypes.NewStdTx(stdSignMsg.Msgs, stdSignMsg.Fee, nil, stdSignMsg.Memo), nil -} - func isTxSigner(user sdk.AccAddress, signers []sdk.AccAddress) bool { for _, s := range signers { if bytes.Equal(user.Bytes(), s.Bytes()) { diff --git a/x/auth/client/tx_test.go b/x/auth/client/tx_test.go index cb5169625329..b3af17af76d4 100644 --- a/x/auth/client/tx_test.go +++ b/x/auth/client/tx_test.go @@ -6,6 +6,7 @@ import ( "strings" "testing" + "github.com/cosmos/cosmos-sdk/std" "github.com/cosmos/cosmos-sdk/testutil" "github.com/cosmos/cosmos-sdk/testutil/testdata" @@ -149,8 +150,12 @@ func TestReadStdTxFromFile(t *testing.T) { func TestBatchScanner_Scan(t *testing.T) { t.Parallel() - cdc := codec.New() - sdk.RegisterCodec(cdc) + encodingConfig := simappparams.MakeEncodingConfig() + std.RegisterCodec(encodingConfig.Amino) + + txGen := encodingConfig.TxConfig + clientCtx := client.Context{} + clientCtx = clientCtx.WithTxConfig(txGen) batch1 := `{"msg":[],"fee":{"amount":[{"denom":"atom","amount":"150"}],"gas":"50000"},"signatures":[],"memo":"foomemo"} {"msg":[],"fee":{"amount":[{"denom":"atom","amount":"150"}],"gas":"10000"},"signatures":[],"memo":"foomemo"} @@ -182,12 +187,12 @@ malformed for _, tt := range tests { tt := tt t.Run(tt.name, func(t *testing.T) { - scanner, i := NewBatchScanner(cdc, strings.NewReader(tt.batch)), 0 + scanner, i := NewBatchScanner(clientCtx.TxConfig, strings.NewReader(tt.batch)), 0 for scanner.Scan() { - _ = scanner.StdTx() + _ = scanner.Tx() i++ } - + t.Log(scanner.theTx) require.Equal(t, tt.wantScannerError, scanner.Err() != nil) require.Equal(t, tt.wantUnmarshalError, scanner.UnmarshalErr() != nil) require.Equal(t, tt.numTxs, i) @@ -206,48 +211,6 @@ func compareEncoders(t *testing.T, expected sdk.TxEncoder, actual sdk.TxEncoder) require.Equal(t, defaultEncoderBytes, encoderBytes) } -func TestPrepareTxBuilder(t *testing.T) { - cdc := makeCodec() - - encodingConfig := simappparams.MakeEncodingConfig() - sdk.RegisterCodec(encodingConfig.Amino) - - fromAddr := sdk.AccAddress("test-addr0000000000") - fromAddrStr := fromAddr.String() - - var accNum uint64 = 10 - var accSeq uint64 = 17 - - txGen := encodingConfig.TxConfig - clientCtx := client.Context{} - clientCtx = clientCtx. - WithTxConfig(txGen). - WithJSONMarshaler(encodingConfig.Marshaler). - WithAccountRetriever(client.TestAccountRetriever{Accounts: map[string]struct { - Address sdk.AccAddress - Num uint64 - Seq uint64 - }{ - fromAddrStr: { - Address: fromAddr, - Num: accNum, - Seq: accSeq, - }, - }}). - WithFromAddress(fromAddr) - - bldr := authtypes.NewTxBuilder( - authtypes.DefaultTxEncoder(cdc), 0, 0, - 200000, 1.1, false, "test-chain", - "test-builder", sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(1))), - sdk.DecCoins{sdk.NewDecCoinFromDec(sdk.DefaultBondDenom, sdk.NewDecWithPrec(10000, sdk.Precision))}) - - bldr, err := PrepareTxBuilder(bldr, clientCtx) - require.NoError(t, err) - require.Equal(t, accNum, bldr.AccountNumber()) - require.Equal(t, accSeq, bldr.Sequence()) -} - func makeCodec() *codec.Codec { var cdc = codec.New() sdk.RegisterCodec(cdc) diff --git a/x/auth/tx/generator.go b/x/auth/tx/generator.go index f70ddaafca7f..04d6896e5b36 100644 --- a/x/auth/tx/generator.go +++ b/x/auth/tx/generator.go @@ -3,8 +3,9 @@ package tx import ( "fmt" + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/client" - codectypes "github.com/cosmos/cosmos-sdk/codec/types" "github.com/cosmos/cosmos-sdk/crypto/types" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/auth/signing" @@ -17,17 +18,19 @@ type generator struct { encoder sdk.TxEncoder jsonDecoder sdk.TxDecoder jsonEncoder sdk.TxEncoder + protoCodec *codec.ProtoCodec } -// NewTxConfig returns a new protobuf TxConfig using the provided Marshaler, PublicKeyCodec and SignModeHandler. -func NewTxConfig(anyUnpacker codectypes.AnyUnpacker, pubkeyCodec types.PublicKeyCodec, signModeHandler signing.SignModeHandler) client.TxConfig { +// NewTxConfig returns a new protobuf TxConfig using the provided ProtoCodec, PublicKeyCodec and SignModeHandler. +func NewTxConfig(protoCodec *codec.ProtoCodec, pubkeyCodec types.PublicKeyCodec, signModeHandler signing.SignModeHandler) client.TxConfig { return &generator{ pubkeyCodec: pubkeyCodec, handler: signModeHandler, - decoder: DefaultTxDecoder(anyUnpacker, pubkeyCodec), + decoder: DefaultTxDecoder(protoCodec, pubkeyCodec), encoder: DefaultTxEncoder(), - jsonDecoder: DefaultJSONTxDecoder(anyUnpacker, pubkeyCodec), + jsonDecoder: DefaultJSONTxDecoder(protoCodec, pubkeyCodec), jsonEncoder: DefaultJSONTxEncoder(), + protoCodec: protoCodec, } } diff --git a/x/auth/tx/sigs.go b/x/auth/tx/sigs.go index 2752fa8da4c3..1d13277f37f5 100644 --- a/x/auth/tx/sigs.go +++ b/x/auth/tx/sigs.go @@ -3,6 +3,8 @@ package tx import ( "fmt" + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/crypto/types" "github.com/cosmos/cosmos-sdk/types/tx" "github.com/cosmos/cosmos-sdk/types/tx/signing" @@ -102,3 +104,50 @@ func decodeMultisignatures(bz []byte) ([][]byte, error) { } return multisig.Signatures, nil } + +func (g generator) MarshalSignatureJSON(sigs []signing.SignatureV2) ([]byte, error) { + descs := make([]*signing.SignatureDescriptor, len(sigs)) + + for i, sig := range sigs { + publicKey, err := g.pubkeyCodec.Encode(sig.PubKey) + if err != nil { + return nil, err + } + + descData := signing.SignatureDataToProto(sig.Data) + + descs[i] = &signing.SignatureDescriptor{ + PublicKey: publicKey, + Data: descData, + } + } + + toJSON := &signing.SignatureDescriptors{Signatures: descs} + + return codec.ProtoMarshalJSON(toJSON) +} + +func (g generator) UnmarshalSignatureJSON(bz []byte) ([]signing.SignatureV2, error) { + var sigDescs signing.SignatureDescriptors + err := g.protoCodec.UnmarshalJSON(bz, &sigDescs) + if err != nil { + return nil, err + } + + sigs := make([]signing.SignatureV2, len(sigDescs.Signatures)) + for i, desc := range sigDescs.Signatures { + pubKey, err := g.pubkeyCodec.Decode(desc.PublicKey) + if err != nil { + return nil, err + } + + data := signing.SignatureDataFromProto(desc.Data) + + sigs[i] = signing.SignatureV2{ + PubKey: pubKey, + Data: data, + } + } + + return sigs, nil +} diff --git a/x/auth/types/client_tx.go b/x/auth/types/client_tx.go index ecede31bd68e..9a73a8c7e024 100644 --- a/x/auth/types/client_tx.go +++ b/x/auth/types/client_tx.go @@ -7,7 +7,6 @@ import ( "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/codec" - "github.com/cosmos/cosmos-sdk/codec/legacy" sdk "github.com/cosmos/cosmos-sdk/types" txtypes "github.com/cosmos/cosmos-sdk/types/tx" "github.com/cosmos/cosmos-sdk/types/tx/signing" @@ -46,29 +45,12 @@ func (s *StdTxBuilder) SetSignatures(signatures ...signing.SignatureV2) error { sigs := make([]StdSignature, len(signatures)) for i, sig := range signatures { - var pubKeyBz []byte - - pubKey := sig.PubKey - if pubKey != nil { - pubKeyBz = pubKey.Bytes() + stdSig, err := SignatureV2ToStdSignature(s.cdc, sig) + if err != nil { + return err } - var ( - sigBz []byte - err error - ) - - if sig.Data != nil { - sigBz, err = SignatureDataToAminoSignature(legacy.Cdc, sig.Data) - if err != nil { - return err - } - } - - sigs[i] = StdSignature{ - PubKey: pubKeyBz, - Signature: sigBz, - } + sigs[i] = stdSig } s.Signatures = sigs @@ -131,6 +113,38 @@ func (s StdTxConfig) TxJSONDecoder() sdk.TxDecoder { return DefaultJSONTxDecoder(s.Cdc) } +func (s StdTxConfig) MarshalSignatureJSON(sigs []signing.SignatureV2) ([]byte, error) { + stdSigs := make([]StdSignature, len(sigs)) + for i, sig := range sigs { + stdSig, err := SignatureV2ToStdSignature(s.Cdc, sig) + if err != nil { + return nil, err + } + + stdSigs[i] = stdSig + } + return s.Cdc.MarshalJSON(stdSigs) +} + +func (s StdTxConfig) UnmarshalSignatureJSON(bz []byte) ([]signing.SignatureV2, error) { + var stdSigs []StdSignature + err := s.Cdc.UnmarshalJSON(bz, &stdSigs) + if err != nil { + return nil, err + } + + sigs := make([]signing.SignatureV2, len(stdSigs)) + for i, stdSig := range stdSigs { + sig, err := StdSignatureToSignatureV2(s.Cdc, stdSig) + if err != nil { + return nil, err + } + sigs[i] = sig + } + + return sigs, nil +} + func (s StdTxConfig) SignModeHandler() authsigning.SignModeHandler { return LegacyAminoJSONHandler{} } diff --git a/x/auth/types/stdtx.go b/x/auth/types/stdtx.go index 589e494285c8..d8402c06cb2d 100644 --- a/x/auth/types/stdtx.go +++ b/x/auth/types/stdtx.go @@ -395,6 +395,33 @@ func StdSignatureToSignatureV2(cdc *codec.Codec, sig StdSignature) (signing.Sign }, nil } +// SignatureV2ToStdSignature converts a SignatureV2 to a StdSignature +func SignatureV2ToStdSignature(cdc *codec.Codec, sig signing.SignatureV2) (StdSignature, error) { + var pubKeyBz []byte + + pubKey := sig.PubKey + if pubKey != nil { + pubKeyBz = pubKey.Bytes() + } + + var ( + sigBz []byte + err error + ) + + if sig.Data != nil { + sigBz, err = SignatureDataToAminoSignature(cdc, sig.Data) + if err != nil { + return StdSignature{}, err + } + } + + return StdSignature{ + PubKey: pubKeyBz, + Signature: sigBz, + }, nil +} + func pubKeySigToSigData(cdc *codec.Codec, key crypto.PubKey, sig []byte) (signing.SignatureData, error) { multiPK, ok := key.(multisig.PubKey) if !ok { diff --git a/x/genutil/client/cli/gentx.go b/x/genutil/client/cli/gentx.go index 328f0815d1f3..55709874b32b 100644 --- a/x/genutil/client/cli/gentx.go +++ b/x/genutil/client/cli/gentx.go @@ -17,6 +17,7 @@ import ( "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/client/tx" "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/crypto/keyring" "github.com/cosmos/cosmos-sdk/server" @@ -133,16 +134,17 @@ $ %s gentx my-key-name --home=/path/to/home/dir --keyring-backend=os --chain-id= return errors.Wrap(err, "failed to validate account in genesis") } - txBldr, err := authtypes.NewTxBuilderFromFlags(inBuf, cmd.Flags(), clientCtx.HomeDir) + txFactory := tx.NewFactoryCLI(clientCtx, cmd.Flags()) if err != nil { return errors.Wrap(err, "error creating tx builder") } - txBldr = txBldr.WithTxEncoder(authclient.GetTxEncoder(clientCtx.Codec)) + txGen := clientCtx.TxConfig + txBuilder := txGen.NewTxBuilder() clientCtx = clientCtx.WithInput(inBuf).WithFromAddress(key.GetAddress()) // create a 'create-validator' message - txBldr, msg, err := cli.BuildCreateValidatorMsg(clientCtx, createValCfg, txBldr, true) + txBldr, msg, err := cli.BuildCreateValidatorMsg(clientCtx, createValCfg, txFactory, true) if err != nil { return errors.Wrap(err, "failed to build create-validator message") } @@ -167,7 +169,7 @@ $ %s gentx my-key-name --home=/path/to/home/dir --keyring-backend=os --chain-id= } // sign the transaction and write it to the output file - signedTx, err := authclient.SignStdTx(txBldr, clientCtx, name, stdTx, false, true) + err = authclient.SignTx(txFactory, clientCtx, name, txBuilder, true) if err != nil { return errors.Wrap(err, "failed to sign std tx") } @@ -180,7 +182,7 @@ $ %s gentx my-key-name --home=/path/to/home/dir --keyring-backend=os --chain-id= } } - if err := writeSignedGenTx(cdc, outputDocument, signedTx); err != nil { + if err := writeSignedGenTx(cdc, outputDocument, stdTx); err != nil { return errors.Wrap(err, "failed to write signed gen tx") } @@ -219,7 +221,7 @@ func readUnsignedGenTxFile(cdc codec.JSONMarshaler, r io.Reader) (authtypes.StdT return stdTx, err } -func writeSignedGenTx(cdc codec.JSONMarshaler, outputDocument string, tx authtypes.StdTx) error { +func writeSignedGenTx(cdc codec.JSONMarshaler, outputDocument string, tx sdk.Tx) error { outputFile, err := os.OpenFile(outputDocument, os.O_CREATE|os.O_EXCL|os.O_WRONLY, 0644) if err != nil { return err diff --git a/x/gov/client/cli/cli_test.go b/x/gov/client/cli/cli_test.go index 0b707fe012f9..9c387992b344 100644 --- a/x/gov/client/cli/cli_test.go +++ b/x/gov/client/cli/cli_test.go @@ -109,6 +109,7 @@ func (s *IntegrationTestSuite) TestNewCmdSubmitProposal() { fmt.Sprintf("--%s=%s", cli.FlagProposal, validPropFile.Name()), fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()), fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), }, false, &sdk.TxResponse{}, 0, @@ -122,6 +123,7 @@ func (s *IntegrationTestSuite) TestNewCmdSubmitProposal() { fmt.Sprintf("--%s=%s", cli.FlagDeposit, sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(5431)).String()), fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()), fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), }, false, &sdk.TxResponse{}, 0, diff --git a/x/staking/client/cli/tx.go b/x/staking/client/cli/tx.go index 2a44c7b01d77..16ce2e3ecfde 100644 --- a/x/staking/client/cli/tx.go +++ b/x/staking/client/cli/tx.go @@ -14,7 +14,6 @@ import ( "github.com/cosmos/cosmos-sdk/client/tx" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/version" - authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" "github.com/cosmos/cosmos-sdk/x/staking/types" ) @@ -503,7 +502,7 @@ func PrepareConfigForTxCreateValidator(flagSet *flag.FlagSet, moniker, nodeID, c } // BuildCreateValidatorMsg makes a new MsgCreateValidator. -func BuildCreateValidatorMsg(clientCtx client.Context, config TxCreateValidatorConfig, txBldr authtypes.TxBuilder, generateOnly bool) (authtypes.TxBuilder, sdk.Msg, error) { +func BuildCreateValidatorMsg(clientCtx client.Context, config TxCreateValidatorConfig, txBldr tx.Factory, generateOnly bool) (tx.Factory, sdk.Msg, error) { amounstStr := config.Amount amount, err := sdk.ParseCoin(amounstStr)