diff --git a/CHANGELOG.md b/CHANGELOG.md index 45e38b93aa18..6974528ceea5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -56,6 +56,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ ### State Machine Breaking +* (x/bank) [#12610](https://github.com/cosmos/cosmos-sdk/pull/12610) `MsgMultiSend` now allows only a single input. * (x/auth) [#12475](https://github.com/cosmos/cosmos-sdk/pull/12475) Migrate `x/auth` to self-managed parameters and deprecate its usage of `x/params`. * (x/slashing) [#12399](https://github.com/cosmos/cosmos-sdk/pull/12399) Migrate `x/slashing` to self-managed parameters and deprecate its usage of `x/params`. * (x/mint) [#12363](https://github.com/cosmos/cosmos-sdk/pull/12363) Migrate `x/mint` to self-managed parameters and deprecate it's usage of `x/params`. diff --git a/api/cosmos/bank/v1beta1/tx.pulsar.go b/api/cosmos/bank/v1beta1/tx.pulsar.go index b56f4a194c4f..e59dd39670da 100644 --- a/api/cosmos/bank/v1beta1/tx.pulsar.go +++ b/api/cosmos/bank/v1beta1/tx.pulsar.go @@ -994,57 +994,6 @@ func (x *fastReflection_MsgSendResponse) ProtoMethods() *protoiface.Methods { } } -var _ protoreflect.List = (*_MsgMultiSend_1_list)(nil) - -type _MsgMultiSend_1_list struct { - list *[]*Input -} - -func (x *_MsgMultiSend_1_list) Len() int { - if x.list == nil { - return 0 - } - return len(*x.list) -} - -func (x *_MsgMultiSend_1_list) Get(i int) protoreflect.Value { - return protoreflect.ValueOfMessage((*x.list)[i].ProtoReflect()) -} - -func (x *_MsgMultiSend_1_list) Set(i int, value protoreflect.Value) { - valueUnwrapped := value.Message() - concreteValue := valueUnwrapped.Interface().(*Input) - (*x.list)[i] = concreteValue -} - -func (x *_MsgMultiSend_1_list) Append(value protoreflect.Value) { - valueUnwrapped := value.Message() - concreteValue := valueUnwrapped.Interface().(*Input) - *x.list = append(*x.list, concreteValue) -} - -func (x *_MsgMultiSend_1_list) AppendMutable() protoreflect.Value { - v := new(Input) - *x.list = append(*x.list, v) - return protoreflect.ValueOfMessage(v.ProtoReflect()) -} - -func (x *_MsgMultiSend_1_list) Truncate(n int) { - for i := n; i < len(*x.list); i++ { - (*x.list)[i] = nil - } - *x.list = (*x.list)[:n] -} - -func (x *_MsgMultiSend_1_list) NewElement() protoreflect.Value { - v := new(Input) - return protoreflect.ValueOfMessage(v.ProtoReflect()) -} - -func (x *_MsgMultiSend_1_list) IsValid() bool { - return x.list != nil -} - var _ protoreflect.List = (*_MsgMultiSend_2_list)(nil) type _MsgMultiSend_2_list struct { @@ -1098,14 +1047,14 @@ func (x *_MsgMultiSend_2_list) IsValid() bool { var ( md_MsgMultiSend protoreflect.MessageDescriptor - fd_MsgMultiSend_inputs protoreflect.FieldDescriptor + fd_MsgMultiSend_input protoreflect.FieldDescriptor fd_MsgMultiSend_outputs protoreflect.FieldDescriptor ) func init() { file_cosmos_bank_v1beta1_tx_proto_init() md_MsgMultiSend = File_cosmos_bank_v1beta1_tx_proto.Messages().ByName("MsgMultiSend") - fd_MsgMultiSend_inputs = md_MsgMultiSend.Fields().ByName("inputs") + fd_MsgMultiSend_input = md_MsgMultiSend.Fields().ByName("input") fd_MsgMultiSend_outputs = md_MsgMultiSend.Fields().ByName("outputs") } @@ -1174,9 +1123,9 @@ func (x *fastReflection_MsgMultiSend) Interface() protoreflect.ProtoMessage { // While iterating, mutating operations may only be performed // on the current field descriptor. func (x *fastReflection_MsgMultiSend) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { - if len(x.Inputs) != 0 { - value := protoreflect.ValueOfList(&_MsgMultiSend_1_list{list: &x.Inputs}) - if !f(fd_MsgMultiSend_inputs, value) { + if x.Input != nil { + value := protoreflect.ValueOfMessage(x.Input.ProtoReflect()) + if !f(fd_MsgMultiSend_input, value) { return } } @@ -1201,8 +1150,8 @@ func (x *fastReflection_MsgMultiSend) Range(f func(protoreflect.FieldDescriptor, // a repeated field is populated if it is non-empty. func (x *fastReflection_MsgMultiSend) Has(fd protoreflect.FieldDescriptor) bool { switch fd.FullName() { - case "cosmos.bank.v1beta1.MsgMultiSend.inputs": - return len(x.Inputs) != 0 + case "cosmos.bank.v1beta1.MsgMultiSend.input": + return x.Input != nil case "cosmos.bank.v1beta1.MsgMultiSend.outputs": return len(x.Outputs) != 0 default: @@ -1221,8 +1170,8 @@ func (x *fastReflection_MsgMultiSend) Has(fd protoreflect.FieldDescriptor) bool // Clear is a mutating operation and unsafe for concurrent use. func (x *fastReflection_MsgMultiSend) Clear(fd protoreflect.FieldDescriptor) { switch fd.FullName() { - case "cosmos.bank.v1beta1.MsgMultiSend.inputs": - x.Inputs = nil + case "cosmos.bank.v1beta1.MsgMultiSend.input": + x.Input = nil case "cosmos.bank.v1beta1.MsgMultiSend.outputs": x.Outputs = nil default: @@ -1241,12 +1190,9 @@ func (x *fastReflection_MsgMultiSend) Clear(fd protoreflect.FieldDescriptor) { // of the value; to obtain a mutable reference, use Mutable. func (x *fastReflection_MsgMultiSend) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { switch descriptor.FullName() { - case "cosmos.bank.v1beta1.MsgMultiSend.inputs": - if len(x.Inputs) == 0 { - return protoreflect.ValueOfList(&_MsgMultiSend_1_list{}) - } - listValue := &_MsgMultiSend_1_list{list: &x.Inputs} - return protoreflect.ValueOfList(listValue) + case "cosmos.bank.v1beta1.MsgMultiSend.input": + value := x.Input + return protoreflect.ValueOfMessage(value.ProtoReflect()) case "cosmos.bank.v1beta1.MsgMultiSend.outputs": if len(x.Outputs) == 0 { return protoreflect.ValueOfList(&_MsgMultiSend_2_list{}) @@ -1273,10 +1219,8 @@ func (x *fastReflection_MsgMultiSend) Get(descriptor protoreflect.FieldDescripto // Set is a mutating operation and unsafe for concurrent use. func (x *fastReflection_MsgMultiSend) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { switch fd.FullName() { - case "cosmos.bank.v1beta1.MsgMultiSend.inputs": - lv := value.List() - clv := lv.(*_MsgMultiSend_1_list) - x.Inputs = *clv.list + case "cosmos.bank.v1beta1.MsgMultiSend.input": + x.Input = value.Message().Interface().(*Input) case "cosmos.bank.v1beta1.MsgMultiSend.outputs": lv := value.List() clv := lv.(*_MsgMultiSend_2_list) @@ -1301,12 +1245,11 @@ func (x *fastReflection_MsgMultiSend) Set(fd protoreflect.FieldDescriptor, value // Mutable is a mutating operation and unsafe for concurrent use. func (x *fastReflection_MsgMultiSend) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { switch fd.FullName() { - case "cosmos.bank.v1beta1.MsgMultiSend.inputs": - if x.Inputs == nil { - x.Inputs = []*Input{} + case "cosmos.bank.v1beta1.MsgMultiSend.input": + if x.Input == nil { + x.Input = new(Input) } - value := &_MsgMultiSend_1_list{list: &x.Inputs} - return protoreflect.ValueOfList(value) + return protoreflect.ValueOfMessage(x.Input.ProtoReflect()) case "cosmos.bank.v1beta1.MsgMultiSend.outputs": if x.Outputs == nil { x.Outputs = []*Output{} @@ -1326,9 +1269,9 @@ func (x *fastReflection_MsgMultiSend) Mutable(fd protoreflect.FieldDescriptor) p // For lists, maps, and messages, this returns a new, empty, mutable value. func (x *fastReflection_MsgMultiSend) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { switch fd.FullName() { - case "cosmos.bank.v1beta1.MsgMultiSend.inputs": - list := []*Input{} - return protoreflect.ValueOfList(&_MsgMultiSend_1_list{list: &list}) + case "cosmos.bank.v1beta1.MsgMultiSend.input": + m := new(Input) + return protoreflect.ValueOfMessage(m.ProtoReflect()) case "cosmos.bank.v1beta1.MsgMultiSend.outputs": list := []*Output{} return protoreflect.ValueOfList(&_MsgMultiSend_2_list{list: &list}) @@ -1401,11 +1344,9 @@ func (x *fastReflection_MsgMultiSend) ProtoMethods() *protoiface.Methods { var n int var l int _ = l - if len(x.Inputs) > 0 { - for _, e := range x.Inputs { - l = options.Size(e) - n += 1 + l + runtime.Sov(uint64(l)) - } + if x.Input != nil { + l = options.Size(x.Input) + n += 1 + l + runtime.Sov(uint64(l)) } if len(x.Outputs) > 0 { for _, e := range x.Outputs { @@ -1458,21 +1399,19 @@ func (x *fastReflection_MsgMultiSend) ProtoMethods() *protoiface.Methods { dAtA[i] = 0x12 } } - if len(x.Inputs) > 0 { - for iNdEx := len(x.Inputs) - 1; iNdEx >= 0; iNdEx-- { - encoded, err := options.Marshal(x.Inputs[iNdEx]) - if err != nil { - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, err - } - i -= len(encoded) - copy(dAtA[i:], encoded) - i = runtime.EncodeVarint(dAtA, i, uint64(len(encoded))) - i-- - dAtA[i] = 0xa + if x.Input != nil { + encoded, err := options.Marshal(x.Input) + if err != nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, err } + i -= len(encoded) + copy(dAtA[i:], encoded) + i = runtime.EncodeVarint(dAtA, i, uint64(len(encoded))) + i-- + dAtA[i] = 0xa } if input.Buf != nil { input.Buf = append(input.Buf, dAtA...) @@ -1525,7 +1464,7 @@ func (x *fastReflection_MsgMultiSend) ProtoMethods() *protoiface.Methods { switch fieldNum { case 1: if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Inputs", wireType) + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Input", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -1552,8 +1491,10 @@ func (x *fastReflection_MsgMultiSend) ProtoMethods() *protoiface.Methods { if postIndex > l { return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF } - x.Inputs = append(x.Inputs, &Input{}) - if err := options.Unmarshal(dAtA[iNdEx:postIndex], x.Inputs[len(x.Inputs)-1]); err != nil { + if x.Input == nil { + x.Input = &Input{} + } + if err := options.Unmarshal(dAtA[iNdEx:postIndex], x.Input); err != nil { return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err } iNdEx = postIndex @@ -2074,13 +2015,13 @@ func (*MsgSendResponse) Descriptor() ([]byte, []int) { return file_cosmos_bank_v1beta1_tx_proto_rawDescGZIP(), []int{1} } -// MsgMultiSend represents an arbitrary multi-in, multi-out send message. +// MsgMultiSend represents a single input, multi-out send message. type MsgMultiSend struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Inputs []*Input `protobuf:"bytes,1,rep,name=inputs,proto3" json:"inputs,omitempty"` + Input *Input `protobuf:"bytes,1,opt,name=input,proto3" json:"input,omitempty"` Outputs []*Output `protobuf:"bytes,2,rep,name=outputs,proto3" json:"outputs,omitempty"` } @@ -2104,9 +2045,9 @@ func (*MsgMultiSend) Descriptor() ([]byte, []int) { return file_cosmos_bank_v1beta1_tx_proto_rawDescGZIP(), []int{2} } -func (x *MsgMultiSend) GetInputs() []*Input { +func (x *MsgMultiSend) GetInput() *Input { if x != nil { - return x.Inputs + return x.Input } return nil } @@ -2177,41 +2118,41 @@ var file_cosmos_bank_v1beta1_tx_proto_rawDesc = []byte{ 0x6f, 0x75, 0x6e, 0x74, 0x3a, 0x19, 0x88, 0xa0, 0x1f, 0x00, 0xe8, 0xa0, 0x1f, 0x00, 0x82, 0xe7, 0xb0, 0x2a, 0x0c, 0x66, 0x72, 0x6f, 0x6d, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x22, 0x11, 0x0a, 0x0f, 0x4d, 0x73, 0x67, 0x53, 0x65, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x96, 0x01, 0x0a, 0x0c, 0x4d, 0x73, 0x67, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x53, - 0x65, 0x6e, 0x64, 0x12, 0x38, 0x0a, 0x06, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x73, 0x18, 0x01, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x62, 0x61, 0x6e, - 0x6b, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x42, - 0x04, 0xc8, 0xde, 0x1f, 0x00, 0x52, 0x06, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x73, 0x12, 0x3b, 0x0a, - 0x07, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, + 0x73, 0x65, 0x22, 0x93, 0x01, 0x0a, 0x0c, 0x4d, 0x73, 0x67, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x53, + 0x65, 0x6e, 0x64, 0x12, 0x36, 0x0a, 0x05, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x62, 0x61, 0x6e, 0x6b, + 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x42, 0x04, + 0xc8, 0xde, 0x1f, 0x00, 0x52, 0x05, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x12, 0x3b, 0x0a, 0x07, 0x6f, + 0x75, 0x74, 0x70, 0x75, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x63, + 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x62, 0x61, 0x6e, 0x6b, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, + 0x61, 0x31, 0x2e, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x42, 0x04, 0xc8, 0xde, 0x1f, 0x00, 0x52, + 0x07, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x73, 0x3a, 0x0e, 0xe8, 0xa0, 0x1f, 0x00, 0x82, 0xe7, + 0xb0, 0x2a, 0x05, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x22, 0x16, 0x0a, 0x14, 0x4d, 0x73, 0x67, 0x4d, + 0x75, 0x6c, 0x74, 0x69, 0x53, 0x65, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x32, 0xac, 0x01, 0x0a, 0x03, 0x4d, 0x73, 0x67, 0x12, 0x4a, 0x0a, 0x04, 0x53, 0x65, 0x6e, 0x64, + 0x12, 0x1c, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x62, 0x61, 0x6e, 0x6b, 0x2e, 0x76, + 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x53, 0x65, 0x6e, 0x64, 0x1a, 0x24, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x62, 0x61, 0x6e, 0x6b, 0x2e, 0x76, 0x31, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x42, 0x04, 0xc8, 0xde, 0x1f, - 0x00, 0x52, 0x07, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x73, 0x3a, 0x0f, 0xe8, 0xa0, 0x1f, 0x00, - 0x82, 0xe7, 0xb0, 0x2a, 0x06, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x73, 0x22, 0x16, 0x0a, 0x14, 0x4d, - 0x73, 0x67, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x53, 0x65, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x32, 0xac, 0x01, 0x0a, 0x03, 0x4d, 0x73, 0x67, 0x12, 0x4a, 0x0a, 0x04, 0x53, - 0x65, 0x6e, 0x64, 0x12, 0x1c, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x62, 0x61, 0x6e, - 0x6b, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x53, 0x65, 0x6e, - 0x64, 0x1a, 0x24, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x62, 0x61, 0x6e, 0x6b, 0x2e, - 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x53, 0x65, 0x6e, 0x64, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x59, 0x0a, 0x09, 0x4d, 0x75, 0x6c, 0x74, 0x69, - 0x53, 0x65, 0x6e, 0x64, 0x12, 0x21, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x62, 0x61, + 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x53, 0x65, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x59, 0x0a, 0x09, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x53, 0x65, 0x6e, + 0x64, 0x12, 0x21, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x62, 0x61, 0x6e, 0x6b, 0x2e, + 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x4d, 0x75, 0x6c, 0x74, 0x69, + 0x53, 0x65, 0x6e, 0x64, 0x1a, 0x29, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x62, 0x61, 0x6e, 0x6b, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x4d, 0x75, - 0x6c, 0x74, 0x69, 0x53, 0x65, 0x6e, 0x64, 0x1a, 0x29, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, - 0x2e, 0x62, 0x61, 0x6e, 0x6b, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4d, 0x73, - 0x67, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x53, 0x65, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x42, 0xc2, 0x01, 0x0a, 0x17, 0x63, 0x6f, 0x6d, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, - 0x73, 0x2e, 0x62, 0x61, 0x6e, 0x6b, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x42, 0x07, - 0x54, 0x78, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x30, 0x63, 0x6f, 0x73, 0x6d, 0x6f, - 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, 0x6f, 0x73, 0x6d, - 0x6f, 0x73, 0x2f, 0x62, 0x61, 0x6e, 0x6b, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x3b, - 0x62, 0x61, 0x6e, 0x6b, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0xa2, 0x02, 0x03, 0x43, 0x42, - 0x58, 0xaa, 0x02, 0x13, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x42, 0x61, 0x6e, 0x6b, 0x2e, - 0x56, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0xca, 0x02, 0x13, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, - 0x5c, 0x42, 0x61, 0x6e, 0x6b, 0x5c, 0x56, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0xe2, 0x02, 0x1f, - 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x5c, 0x42, 0x61, 0x6e, 0x6b, 0x5c, 0x56, 0x31, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, - 0x02, 0x15, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x3a, 0x3a, 0x42, 0x61, 0x6e, 0x6b, 0x3a, 0x3a, - 0x56, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x6c, 0x74, 0x69, 0x53, 0x65, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, + 0xc2, 0x01, 0x0a, 0x17, 0x63, 0x6f, 0x6d, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x62, + 0x61, 0x6e, 0x6b, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x42, 0x07, 0x54, 0x78, 0x50, + 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x30, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, + 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, + 0x62, 0x61, 0x6e, 0x6b, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x3b, 0x62, 0x61, 0x6e, + 0x6b, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0xa2, 0x02, 0x03, 0x43, 0x42, 0x58, 0xaa, 0x02, + 0x13, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x42, 0x61, 0x6e, 0x6b, 0x2e, 0x56, 0x31, 0x62, + 0x65, 0x74, 0x61, 0x31, 0xca, 0x02, 0x13, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x5c, 0x42, 0x61, + 0x6e, 0x6b, 0x5c, 0x56, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0xe2, 0x02, 0x1f, 0x43, 0x6f, 0x73, + 0x6d, 0x6f, 0x73, 0x5c, 0x42, 0x61, 0x6e, 0x6b, 0x5c, 0x56, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, + 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x15, 0x43, + 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x3a, 0x3a, 0x42, 0x61, 0x6e, 0x6b, 0x3a, 0x3a, 0x56, 0x31, 0x62, + 0x65, 0x74, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -2238,7 +2179,7 @@ var file_cosmos_bank_v1beta1_tx_proto_goTypes = []interface{}{ } var file_cosmos_bank_v1beta1_tx_proto_depIdxs = []int32{ 4, // 0: cosmos.bank.v1beta1.MsgSend.amount:type_name -> cosmos.base.v1beta1.Coin - 5, // 1: cosmos.bank.v1beta1.MsgMultiSend.inputs:type_name -> cosmos.bank.v1beta1.Input + 5, // 1: cosmos.bank.v1beta1.MsgMultiSend.input:type_name -> cosmos.bank.v1beta1.Input 6, // 2: cosmos.bank.v1beta1.MsgMultiSend.outputs:type_name -> cosmos.bank.v1beta1.Output 0, // 3: cosmos.bank.v1beta1.Msg.Send:input_type -> cosmos.bank.v1beta1.MsgSend 2, // 4: cosmos.bank.v1beta1.Msg.MultiSend:input_type -> cosmos.bank.v1beta1.MsgMultiSend diff --git a/proto/cosmos/bank/v1beta1/tx.proto b/proto/cosmos/bank/v1beta1/tx.proto index bcf567906b52..acb7ad6a82d2 100644 --- a/proto/cosmos/bank/v1beta1/tx.proto +++ b/proto/cosmos/bank/v1beta1/tx.proto @@ -34,13 +34,13 @@ message MsgSend { // MsgSendResponse defines the Msg/Send response type. message MsgSendResponse {} -// MsgMultiSend represents an arbitrary multi-in, multi-out send message. +// MsgMultiSend represents a single input, multi-out send message. message MsgMultiSend { - option (cosmos.msg.v1.signer) = "inputs"; + option (cosmos.msg.v1.signer) = "input"; option (gogoproto.equal) = false; - repeated Input inputs = 1 [(gogoproto.nullable) = false]; + Input input = 1 [(gogoproto.nullable) = false]; repeated Output outputs = 2 [(gogoproto.nullable) = false]; } diff --git a/x/bank/app_test.go b/x/bank/app_test.go index d1e810277edd..1dcd269b7d4a 100644 --- a/x/bank/app_test.go +++ b/x/bank/app_test.go @@ -39,8 +39,6 @@ var ( priv2 = secp256k1.GenPrivKey() addr2 = sdk.AccAddress(priv2.PubKey().Address()) addr3 = sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()) - priv4 = secp256k1.GenPrivKey() - addr4 = sdk.AccAddress(priv4.PubKey().Address()) coins = sdk.Coins{sdk.NewInt64Coin("foocoin", 10)} halfCoins = sdk.Coins{sdk.NewInt64Coin("foocoin", 5)} @@ -48,38 +46,24 @@ var ( sendMsg1 = types.NewMsgSend(addr1, addr2, coins) multiSendMsg1 = &types.MsgMultiSend{ - Inputs: []types.Input{types.NewInput(addr1, coins)}, + Input: types.NewInput(addr1, coins), Outputs: []types.Output{types.NewOutput(addr2, coins)}, } multiSendMsg2 = &types.MsgMultiSend{ - Inputs: []types.Input{types.NewInput(addr1, coins)}, + Input: types.NewInput(addr1, coins), Outputs: []types.Output{ types.NewOutput(addr2, halfCoins), types.NewOutput(addr3, halfCoins), }, } multiSendMsg3 = &types.MsgMultiSend{ - Inputs: []types.Input{ - types.NewInput(addr1, coins), - types.NewInput(addr4, coins), - }, - Outputs: []types.Output{ - types.NewOutput(addr2, coins), - types.NewOutput(addr3, coins), - }, - } - multiSendMsg4 = &types.MsgMultiSend{ - Inputs: []types.Input{ - types.NewInput(addr2, coins), - }, + Input: types.NewInput(addr2, coins), Outputs: []types.Output{ types.NewOutput(addr1, coins), }, } - multiSendMsg5 = &types.MsgMultiSend{ - Inputs: []types.Input{ - types.NewInput(addr1, coins), - }, + multiSendMsg4 = &types.MsgMultiSend{ + Input: types.NewInput(addr1, coins), Outputs: []types.Output{ types.NewOutput(moduleAccAddr, coins), }, @@ -163,7 +147,7 @@ func TestMsgMultiSendWithAccounts(t *testing.T) { }, { desc: "wrong accSeq should not pass Simulate", - msgs: []sdk.Msg{multiSendMsg5}, + msgs: []sdk.Msg{multiSendMsg4}, accNums: []uint64{0}, accSeqs: []uint64{0}, // wrong account sequence expSimPass: false, @@ -234,58 +218,6 @@ func TestMsgMultiSendMultipleOut(t *testing.T) { } } -func TestMsgMultiSendMultipleInOut(t *testing.T) { - acc1 := &authtypes.BaseAccount{ - Address: addr1.String(), - } - acc2 := &authtypes.BaseAccount{ - Address: addr2.String(), - } - acc4 := &authtypes.BaseAccount{ - Address: addr4.String(), - } - - genAccs := []authtypes.GenesisAccount{acc1, acc2, acc4} - app := simapp.SetupWithGenesisAccounts(t, genAccs) - ctx := app.BaseApp.NewContext(false, tmproto.Header{}) - - require.NoError(t, testutil.FundAccount(app.BankKeeper, ctx, addr1, sdk.NewCoins(sdk.NewInt64Coin("foocoin", 42)))) - - require.NoError(t, testutil.FundAccount(app.BankKeeper, ctx, addr2, sdk.NewCoins(sdk.NewInt64Coin("foocoin", 42)))) - - require.NoError(t, testutil.FundAccount(app.BankKeeper, ctx, addr4, sdk.NewCoins(sdk.NewInt64Coin("foocoin", 42)))) - - app.Commit() - - testCases := []appTestCase{ - { - msgs: []sdk.Msg{multiSendMsg3}, - accNums: []uint64{0, 2}, - accSeqs: []uint64{0, 0}, - expSimPass: true, - expPass: true, - privKeys: []cryptotypes.PrivKey{priv1, priv4}, - expectedBalances: []expectedBalance{ - {addr1, sdk.Coins{sdk.NewInt64Coin("foocoin", 32)}}, - {addr4, sdk.Coins{sdk.NewInt64Coin("foocoin", 32)}}, - {addr2, sdk.Coins{sdk.NewInt64Coin("foocoin", 52)}}, - {addr3, sdk.Coins{sdk.NewInt64Coin("foocoin", 10)}}, - }, - }, - } - - for _, tc := range testCases { - header := tmproto.Header{Height: app.LastBlockHeight() + 1} - txGen := simapp.MakeTestEncodingConfig().TxConfig - _, _, err := simapp.SignCheckDeliver(t, txGen, app.BaseApp, header, tc.msgs, "", tc.accNums, tc.accSeqs, tc.expSimPass, tc.expPass, tc.privKeys...) - require.NoError(t, err) - - for _, eb := range tc.expectedBalances { - simapp.CheckBalance(t, app, eb.addr, eb.coins) - } - } -} - func TestMsgMultiSendDependent(t *testing.T) { acc1 := authtypes.NewBaseAccountWithAddress(addr1) acc2 := authtypes.NewBaseAccountWithAddress(addr2) @@ -314,7 +246,7 @@ func TestMsgMultiSendDependent(t *testing.T) { }, }, { - msgs: []sdk.Msg{multiSendMsg4}, + msgs: []sdk.Msg{multiSendMsg3}, accNums: []uint64{1}, accSeqs: []uint64{0}, expSimPass: true, diff --git a/x/bank/client/cli/tx.go b/x/bank/client/cli/tx.go index 5deb617b8952..156bdaf5b8b2 100644 --- a/x/bank/client/cli/tx.go +++ b/x/bank/client/cli/tx.go @@ -131,7 +131,7 @@ When using '--dry-run' a key name cannot be used, only a bech32 address. amount = coins.MulInt(totalAddrs) } - msg := types.NewMsgMultiSend([]types.Input{types.NewInput(clientCtx.FromAddress, amount)}, output) + msg := types.NewMsgMultiSend(types.NewInput(clientCtx.FromAddress, amount), output) return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) }, diff --git a/x/bank/keeper/keeper_test.go b/x/bank/keeper/keeper_test.go index 1c4390abbcbd..8d71ecff230e 100644 --- a/x/bank/keeper/keeper_test.go +++ b/x/bank/keeper/keeper_test.go @@ -359,14 +359,15 @@ func (suite *IntegrationTestSuite) TestInputOutputNewAccount() { suite.Require().Nil(app.AccountKeeper.GetAccount(ctx, addr2)) suite.Require().Empty(app.BankKeeper.GetAllBalances(ctx, addr2)) - inputs := []types.Input{ - {Address: addr1.String(), Coins: sdk.NewCoins(newFooCoin(30), newBarCoin(10))}, + input := types.Input{ + Address: addr1.String(), + Coins: sdk.NewCoins(newFooCoin(30), newBarCoin(10)), } outputs := []types.Output{ {Address: addr2.String(), Coins: sdk.NewCoins(newFooCoin(30), newBarCoin(10))}, } - suite.Require().NoError(app.BankKeeper.InputOutputCoins(ctx, inputs, outputs)) + suite.Require().NoError(app.BankKeeper.InputOutputCoins(ctx, input, outputs)) expected := sdk.NewCoins(newFooCoin(30), newBarCoin(10)) acc2Balances := app.BankKeeper.GetAllBalances(ctx, addr2) @@ -390,30 +391,30 @@ func (suite *IntegrationTestSuite) TestInputOutputCoins() { acc3 := app.AccountKeeper.NewAccountWithAddress(ctx, addr3) app.AccountKeeper.SetAccount(ctx, acc3) - inputs := []types.Input{ - {Address: addr1.String(), Coins: sdk.NewCoins(newFooCoin(30), newBarCoin(10))}, - {Address: addr1.String(), Coins: sdk.NewCoins(newFooCoin(30), newBarCoin(10))}, + input := types.Input{ + Address: addr1.String(), + Coins: sdk.NewCoins(newFooCoin(60), newBarCoin(20)), } outputs := []types.Output{ {Address: addr2.String(), Coins: sdk.NewCoins(newFooCoin(30), newBarCoin(10))}, {Address: addr3.String(), Coins: sdk.NewCoins(newFooCoin(30), newBarCoin(10))}, } - suite.Require().Error(app.BankKeeper.InputOutputCoins(ctx, inputs, []types.Output{})) - suite.Require().Error(app.BankKeeper.InputOutputCoins(ctx, inputs, outputs)) + suite.Require().Error(app.BankKeeper.InputOutputCoins(ctx, input, []types.Output{})) + suite.Require().Error(app.BankKeeper.InputOutputCoins(ctx, input, outputs)) suite.Require().NoError(testutil.FundAccount(app.BankKeeper, ctx, addr1, balances)) - insufficientInputs := []types.Input{ - {Address: addr1.String(), Coins: sdk.NewCoins(newFooCoin(300), newBarCoin(100))}, - {Address: addr1.String(), Coins: sdk.NewCoins(newFooCoin(300), newBarCoin(100))}, + insufficientInput := types.Input{ + Address: addr1.String(), + Coins: sdk.NewCoins(newFooCoin(300), newBarCoin(100)), } insufficientOutputs := []types.Output{ {Address: addr2.String(), Coins: sdk.NewCoins(newFooCoin(300), newBarCoin(100))}, {Address: addr3.String(), Coins: sdk.NewCoins(newFooCoin(300), newBarCoin(100))}, } - suite.Require().Error(app.BankKeeper.InputOutputCoins(ctx, insufficientInputs, insufficientOutputs)) - suite.Require().NoError(app.BankKeeper.InputOutputCoins(ctx, inputs, outputs)) + suite.Require().Error(app.BankKeeper.InputOutputCoins(ctx, insufficientInput, insufficientOutputs)) + suite.Require().NoError(app.BankKeeper.InputOutputCoins(ctx, input, outputs)) acc1Balances := app.BankKeeper.GetAllBalances(ctx, addr1) expected := sdk.NewCoins(newFooCoin(30), newBarCoin(10)) @@ -607,28 +608,29 @@ func (suite *IntegrationTestSuite) TestMsgMultiSendEvents() { app.AccountKeeper.SetAccount(ctx, acc) app.AccountKeeper.SetAccount(ctx, acc2) + coins := sdk.NewCoins(sdk.NewInt64Coin(fooDenom, 50), sdk.NewInt64Coin(barDenom, 100)) newCoins := sdk.NewCoins(sdk.NewInt64Coin(fooDenom, 50)) newCoins2 := sdk.NewCoins(sdk.NewInt64Coin(barDenom, 100)) - inputs := []types.Input{ - {Address: addr.String(), Coins: newCoins}, - {Address: addr2.String(), Coins: newCoins2}, + input := types.Input{ + Address: addr.String(), + Coins: coins, } outputs := []types.Output{ {Address: addr3.String(), Coins: newCoins}, {Address: addr4.String(), Coins: newCoins2}, } - suite.Require().Error(app.BankKeeper.InputOutputCoins(ctx, inputs, outputs)) + suite.Require().Error(app.BankKeeper.InputOutputCoins(ctx, input, outputs)) events := ctx.EventManager().ABCIEvents() suite.Require().Equal(0, len(events)) // Set addr's coins but not addr2's coins - suite.Require().NoError(testutil.FundAccount(app.BankKeeper, ctx, addr, sdk.NewCoins(sdk.NewInt64Coin(fooDenom, 50)))) - suite.Require().Error(app.BankKeeper.InputOutputCoins(ctx, inputs, outputs)) + suite.Require().NoError(testutil.FundAccount(app.BankKeeper, ctx, addr, sdk.NewCoins(sdk.NewInt64Coin(fooDenom, 50), sdk.NewInt64Coin(barDenom, 100)))) + suite.Require().NoError(app.BankKeeper.InputOutputCoins(ctx, input, outputs)) events = ctx.EventManager().ABCIEvents() - suite.Require().Equal(8, len(events)) // 7 events because account funding causes extra minting + coin_spent + coin_recv events + suite.Require().Equal(12, len(events)) // 9 events because account funding causes extra minting + coin_spent + coin_recv events event1 := sdk.Event{ Type: sdk.EventTypeMessage, @@ -644,50 +646,41 @@ func (suite *IntegrationTestSuite) TestMsgMultiSendEvents() { suite.Require().NoError(testutil.FundAccount(app.BankKeeper, ctx, addr, sdk.NewCoins(sdk.NewInt64Coin(fooDenom, 50)))) newCoins = sdk.NewCoins(sdk.NewInt64Coin(fooDenom, 50)) - suite.Require().NoError(testutil.FundAccount(app.BankKeeper, ctx, addr2, sdk.NewCoins(sdk.NewInt64Coin(barDenom, 100)))) + suite.Require().NoError(testutil.FundAccount(app.BankKeeper, ctx, addr, sdk.NewCoins(sdk.NewInt64Coin(barDenom, 100)))) newCoins2 = sdk.NewCoins(sdk.NewInt64Coin(barDenom, 100)) - suite.Require().NoError(app.BankKeeper.InputOutputCoins(ctx, inputs, outputs)) + suite.Require().NoError(app.BankKeeper.InputOutputCoins(ctx, input, outputs)) events = ctx.EventManager().ABCIEvents() - suite.Require().Equal(28, len(events)) // 25 due to account funding + coin_spent + coin_recv events + suite.Require().Equal(30, len(events)) // 27 due to account funding + coin_spent + coin_recv events event2 := sdk.Event{ - Type: sdk.EventTypeMessage, + Type: types.EventTypeTransfer, Attributes: []abci.EventAttribute{}, } event2.Attributes = append( event2.Attributes, - abci.EventAttribute{Key: types.AttributeKeySender, Value: addr2.String()}, + abci.EventAttribute{Key: types.AttributeKeyRecipient, Value: addr3.String()}, ) + event2.Attributes = append( + event2.Attributes, + abci.EventAttribute{Key: sdk.AttributeKeyAmount, Value: newCoins.String()}) event3 := sdk.Event{ Type: types.EventTypeTransfer, Attributes: []abci.EventAttribute{}, } event3.Attributes = append( event3.Attributes, - abci.EventAttribute{Key: types.AttributeKeyRecipient, Value: addr3.String()}, + abci.EventAttribute{Key: types.AttributeKeyRecipient, Value: addr4.String()}, ) event3.Attributes = append( event3.Attributes, - abci.EventAttribute{Key: sdk.AttributeKeyAmount, Value: newCoins.String()}) - event4 := sdk.Event{ - Type: types.EventTypeTransfer, - Attributes: []abci.EventAttribute{}, - } - event4.Attributes = append( - event4.Attributes, - abci.EventAttribute{Key: types.AttributeKeyRecipient, Value: addr4.String()}, - ) - event4.Attributes = append( - event4.Attributes, abci.EventAttribute{Key: sdk.AttributeKeyAmount, Value: newCoins2.String()}, ) // events are shifted due to the funding account events - suite.Require().Equal(abci.Event(event1), events[21]) - suite.Require().Equal(abci.Event(event2), events[23]) - suite.Require().Equal(abci.Event(event3), events[25]) - suite.Require().Equal(abci.Event(event4), events[27]) + suite.Require().Equal(abci.Event(event1), events[25]) + suite.Require().Equal(abci.Event(event2), events[27]) + suite.Require().Equal(abci.Event(event3), events[29]) } func (suite *IntegrationTestSuite) TestSpendableCoins() { diff --git a/x/bank/keeper/msg_server.go b/x/bank/keeper/msg_server.go index 4e9237631d54..b21559c2f3f1 100644 --- a/x/bank/keeper/msg_server.go +++ b/x/bank/keeper/msg_server.go @@ -74,10 +74,8 @@ func (k msgServer) MultiSend(goCtx context.Context, msg *types.MsgMultiSend) (*t ctx := sdk.UnwrapSDKContext(goCtx) // NOTE: totalIn == totalOut should already have been checked - for _, in := range msg.Inputs { - if err := k.IsSendEnabledCoins(ctx, in.Coins...); err != nil { - return nil, err - } + if err := k.IsSendEnabledCoins(ctx, msg.Input.Coins...); err != nil { + return nil, err } for _, out := range msg.Outputs { @@ -88,7 +86,7 @@ func (k msgServer) MultiSend(goCtx context.Context, msg *types.MsgMultiSend) (*t } } - err := k.InputOutputCoins(ctx, msg.Inputs, msg.Outputs) + err := k.InputOutputCoins(ctx, msg.Input, msg.Outputs) if err != nil { return nil, err } diff --git a/x/bank/keeper/send.go b/x/bank/keeper/send.go index e439b49c7ffc..aff745fd1888 100644 --- a/x/bank/keeper/send.go +++ b/x/bank/keeper/send.go @@ -17,7 +17,7 @@ import ( type SendKeeper interface { ViewKeeper - InputOutputCoins(ctx sdk.Context, inputs []types.Input, outputs []types.Output) error + InputOutputCoins(ctx sdk.Context, inputs types.Input, outputs []types.Output) error SendCoins(ctx sdk.Context, fromAddr sdk.AccAddress, toAddr sdk.AccAddress, amt sdk.Coins) error GetParams(ctx sdk.Context) types.Params @@ -88,32 +88,30 @@ func (k BaseSendKeeper) SetParams(ctx sdk.Context, params types.Params) { // InputOutputCoins performs multi-send functionality. It accepts a series of // inputs that correspond to a series of outputs. It returns an error if the // inputs and outputs don't line up or if any single transfer of tokens fails. -func (k BaseSendKeeper) InputOutputCoins(ctx sdk.Context, inputs []types.Input, outputs []types.Output) error { +func (k BaseSendKeeper) InputOutputCoins(ctx sdk.Context, input types.Input, outputs []types.Output) error { // Safety check ensuring that when sending coins the keeper must maintain the // Check supply invariant and validity of Coins. - if err := types.ValidateInputsOutputs(inputs, outputs); err != nil { + if err := types.ValidateInputsOutputs(input, outputs); err != nil { return err } - for _, in := range inputs { - inAddress, err := sdk.AccAddressFromBech32(in.Address) - if err != nil { - return err - } - - err = k.subUnlockedCoins(ctx, inAddress, in.Coins) - if err != nil { - return err - } + inAddress, err := sdk.AccAddressFromBech32(input.Address) + if err != nil { + return err + } - ctx.EventManager().EmitEvent( - sdk.NewEvent( - sdk.EventTypeMessage, - sdk.NewAttribute(types.AttributeKeySender, in.Address), - ), - ) + err = k.subUnlockedCoins(ctx, inAddress, input.Coins) + if err != nil { + return err } + ctx.EventManager().EmitEvent( + sdk.NewEvent( + sdk.EventTypeMessage, + sdk.NewAttribute(types.AttributeKeySender, input.Address), + ), + ) + for _, out := range outputs { outAddress, err := sdk.AccAddressFromBech32(out.Address) if err != nil { diff --git a/x/bank/simulation/operations.go b/x/bank/simulation/operations.go index b1456b7c6d90..76dbdd7297de 100644 --- a/x/bank/simulation/operations.go +++ b/x/bank/simulation/operations.go @@ -176,41 +176,26 @@ func SimulateMsgMultiSend(ak types.AccountKeeper, bk keeper.Keeper) simtypes.Ope r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, accs []simtypes.Account, chainID string, ) (simtypes.OperationMsg, []simtypes.FutureOperation, error) { - // random number of inputs/outputs between [1, 3] - inputs := make([]types.Input, r.Intn(3)+1) + // random number of outputs between [1, 3] outputs := make([]types.Output, r.Intn(3)+1) - // collect signer privKeys - privs := make([]cryptotypes.PrivKey, len(inputs)) - - // use map to check if address already exists as input - usedAddrs := make(map[string]bool) - var totalSentCoins sdk.Coins - for i := range inputs { - // generate random input fields, ignore to address - from, _, coins, skip := randomSendFields(r, ctx, accs, bk, ak) + // generate random input fields, ignore to address + from, _, coins, skip := randomSendFields(r, ctx, accs, bk, ak) - // make sure account is fresh and not used in previous input - for usedAddrs[from.Address.String()] { - from, _, coins, skip = randomSendFields(r, ctx, accs, bk, ak) - } - - if skip { - return simtypes.NoOpMsg(types.ModuleName, types.TypeMsgMultiSend, "skip all transfers"), nil, nil - } - - // set input address in used address map - usedAddrs[from.Address.String()] = true - - // set signer privkey - privs[i] = from.PrivKey + // if coins slice is empty, we can not create valid types.MsgMultiSend + if len(coins) == 0 { + return simtypes.NoOpMsg(types.ModuleName, types.TypeMsgMultiSend, "empty coins slice"), nil, nil + } - // set next input and accumulate total sent coins - inputs[i] = types.NewInput(from.Address, coins) - totalSentCoins = totalSentCoins.Add(coins...) + if skip { + return simtypes.NoOpMsg(types.ModuleName, types.TypeMsgMultiSend, "skip all transfers"), nil, nil } + // set next input and accumulate total sent coins + input := types.NewInput(from.Address, coins) + totalSentCoins = totalSentCoins.Add(coins...) + // Check send_enabled status of each sent coin denom if err := bk.IsSendEnabledCoins(ctx, totalSentCoins...); err != nil { return simtypes.NoOpMsg(types.ModuleName, types.TypeMsgMultiSend, err.Error()), nil, nil @@ -246,10 +231,10 @@ func SimulateMsgMultiSend(ak types.AccountKeeper, bk keeper.Keeper) simtypes.Ope } msg := &types.MsgMultiSend{ - Inputs: inputs, + Input: input, Outputs: outputs, } - err := sendMsgMultiSend(r, app, bk, ak, msg, ctx, chainID, privs) + err := sendMsgMultiSend(r, app, bk, ak, msg, ctx, chainID, []cryptotypes.PrivKey{from.PrivKey}) if err != nil { return simtypes.NoOpMsg(types.ModuleName, msg.Type(), "invalid transfers"), nil, err } @@ -264,20 +249,15 @@ func SimulateMsgMultiSendToModuleAccount(ak types.AccountKeeper, bk keeper.Keepe r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, accs []simtypes.Account, chainID string, ) (simtypes.OperationMsg, []simtypes.FutureOperation, error) { - inputs := make([]types.Input, 2) outputs := make([]types.Output, moduleAccCount) - // collect signer privKeys - privs := make([]cryptotypes.PrivKey, len(inputs)) var totalSentCoins sdk.Coins - for i := range inputs { - sender := accs[i] - privs[i] = sender.PrivKey - spendable := bk.SpendableCoins(ctx, sender.Address) - coins := simtypes.RandSubsetCoins(r, spendable) - inputs[i] = types.NewInput(sender.Address, coins) - totalSentCoins = totalSentCoins.Add(coins...) - } + + sender := accs[0] + spendable := bk.SpendableCoins(ctx, sender.Address) + coins := simtypes.RandSubsetCoins(r, spendable) + input := types.NewInput(sender.Address, coins) + totalSentCoins = totalSentCoins.Add(coins...) if err := bk.IsSendEnabledCoins(ctx, totalSentCoins...); err != nil { return simtypes.NoOpMsg(types.ModuleName, types.TypeMsgMultiSend, err.Error()), nil, nil @@ -312,10 +292,10 @@ func SimulateMsgMultiSendToModuleAccount(ak types.AccountKeeper, bk keeper.Keepe } msg := &types.MsgMultiSend{ - Inputs: inputs, + Input: input, Outputs: outputs, } - err := sendMsgMultiSend(r, app, bk, ak, msg, ctx, chainID, privs) + err := sendMsgMultiSend(r, app, bk, ak, msg, ctx, chainID, []cryptotypes.PrivKey{sender.PrivKey}) if err != nil { return simtypes.NoOpMsg(types.ModuleName, msg.Type(), "invalid transfers"), nil, err } @@ -330,28 +310,20 @@ func sendMsgMultiSend( r *rand.Rand, app *baseapp.BaseApp, bk keeper.Keeper, ak types.AccountKeeper, msg *types.MsgMultiSend, ctx sdk.Context, chainID string, privkeys []cryptotypes.PrivKey, ) error { - accountNumbers := make([]uint64, len(msg.Inputs)) - sequenceNumbers := make([]uint64, len(msg.Inputs)) - for i := 0; i < len(msg.Inputs); i++ { - addr := sdk.MustAccAddressFromBech32(msg.Inputs[i].Address) - acc := ak.GetAccount(ctx, addr) - accountNumbers[i] = acc.GetAccountNumber() - sequenceNumbers[i] = acc.GetSequence() - } + addr := sdk.MustAccAddressFromBech32(msg.Input.Address) + acc := ak.GetAccount(ctx, addr) var ( fees sdk.Coins err error ) - addr := sdk.MustAccAddressFromBech32(msg.Inputs[0].Address) - // feePayer is the first signer, i.e. first input address feePayer := ak.GetAccount(ctx, addr) spendable := bk.SpendableCoins(ctx, feePayer.GetAddress()) - coins, hasNeg := spendable.SafeSub(msg.Inputs[0].Coins...) + coins, hasNeg := spendable.SafeSub(msg.Input.Coins...) if !hasNeg { fees, err = simtypes.RandomFees(r, ctx, coins) if err != nil { @@ -367,8 +339,8 @@ func sendMsgMultiSend( fees, simtestutil.DefaultGenTxGas, chainID, - accountNumbers, - sequenceNumbers, + []uint64{acc.GetAccountNumber()}, + []uint64{acc.GetSequence()}, privkeys..., ) if err != nil { diff --git a/x/bank/simulation/operations_test.go b/x/bank/simulation/operations_test.go index f20a5c1e0a62..a75f2563c809 100644 --- a/x/bank/simulation/operations_test.go +++ b/x/bank/simulation/operations_test.go @@ -114,12 +114,11 @@ func (suite *SimTestSuite) TestSimulateMsgMultiSend() { types.ModuleCdc.UnmarshalJSON(operationMsg.Msg, &msg) require.True(operationMsg.OK) - require.Len(msg.Inputs, 3) - require.Equal("cosmos1p8wcgrjr4pjju90xg6u9cgq55dxwq8j7u4x9a0", msg.Inputs[1].Address) - require.Equal("185121068stake", msg.Inputs[1].Coins.String()) - require.Len(msg.Outputs, 2) + require.Equal("cosmos1p8wcgrjr4pjju90xg6u9cgq55dxwq8j7u4x9a0", msg.Input.Address) + require.Equal("4896096stake", msg.Input.Coins.String()) + require.Len(msg.Outputs, 3) require.Equal("cosmos1ghekyjucln7y67ntx7cf27m9dpuxxemn4c8g4r", msg.Outputs[1].Address) - require.Equal("260469617stake", msg.Outputs[1].Coins.String()) + require.Equal("891479stake", msg.Outputs[1].Coins.String()) require.Equal(types.TypeMsgMultiSend, msg.Type()) require.Equal(types.ModuleName, msg.Route()) require.Len(futureOperations, 0) diff --git a/x/bank/types/errors.go b/x/bank/types/errors.go index 8446d957b678..00851d165f80 100644 --- a/x/bank/types/errors.go +++ b/x/bank/types/errors.go @@ -6,7 +6,6 @@ import ( // x/bank module sentinel errors var ( - ErrNoInputs = sdkerrors.Register(ModuleName, 2, "no inputs to send transaction") ErrNoOutputs = sdkerrors.Register(ModuleName, 3, "no outputs to send transaction") ErrInputOutputMismatch = sdkerrors.Register(ModuleName, 4, "sum inputs != sum outputs") ErrSendDisabled = sdkerrors.Register(ModuleName, 5, "send transactions are disabled") diff --git a/x/bank/types/msgs.go b/x/bank/types/msgs.go index b2b0d21e48ad..584001d08c5e 100644 --- a/x/bank/types/msgs.go +++ b/x/bank/types/msgs.go @@ -61,8 +61,8 @@ func (msg MsgSend) GetSigners() []sdk.AccAddress { var _ sdk.Msg = &MsgMultiSend{} // NewMsgMultiSend - construct arbitrary multi-in, multi-out send msg. -func NewMsgMultiSend(in []Input, out []Output) *MsgMultiSend { - return &MsgMultiSend{Inputs: in, Outputs: out} +func NewMsgMultiSend(in Input, out []Output) *MsgMultiSend { + return &MsgMultiSend{Input: in, Outputs: out} } // Route Implements Msg @@ -75,15 +75,16 @@ func (msg MsgMultiSend) Type() string { return TypeMsgMultiSend } func (msg MsgMultiSend) ValidateBasic() error { // this just makes sure all the inputs and outputs are properly formatted, // not that they actually have the money inside - if len(msg.Inputs) == 0 { - return ErrNoInputs + + if err := msg.Input.ValidateBasic(); err != nil { + return err } if len(msg.Outputs) == 0 { return ErrNoOutputs } - return ValidateInputsOutputs(msg.Inputs, msg.Outputs) + return ValidateInputsOutputs(msg.Input, msg.Outputs) } // GetSignBytes Implements Msg. @@ -93,13 +94,8 @@ func (msg MsgMultiSend) GetSignBytes() []byte { // GetSigners Implements Msg. func (msg MsgMultiSend) GetSigners() []sdk.AccAddress { - addrs := make([]sdk.AccAddress, len(msg.Inputs)) - for i, in := range msg.Inputs { - inAddr, _ := sdk.AccAddressFromBech32(in.Address) - addrs[i] = inAddr - } - - return addrs + addrs, _ := sdk.AccAddressFromBech32(msg.Input.Address) + return []sdk.AccAddress{addrs} } // ValidateBasic - validate transaction input @@ -156,17 +152,15 @@ func NewOutput(addr sdk.AccAddress, coins sdk.Coins) Output { // ValidateInputsOutputs validates that each respective input and output is // valid and that the sum of inputs is equal to the sum of outputs. -func ValidateInputsOutputs(inputs []Input, outputs []Output) error { +func ValidateInputsOutputs(input Input, outputs []Output) error { var totalIn, totalOut sdk.Coins - for _, in := range inputs { - if err := in.ValidateBasic(); err != nil { - return err - } - - totalIn = totalIn.Add(in.Coins...) + if err := input.ValidateBasic(); err != nil { + return err } + totalIn = totalIn.Add(input.Coins...) + for _, out := range outputs { if err := out.ValidateBasic(); err != nil { return err diff --git a/x/bank/types/msgs_test.go b/x/bank/types/msgs_test.go index 6223db054f8e..27054fc06cb8 100644 --- a/x/bank/types/msgs_test.go +++ b/x/bank/types/msgs_test.go @@ -70,7 +70,7 @@ func TestMsgMultiSendRoute(t *testing.T) { addr2 := sdk.AccAddress([]byte("output")) coins := sdk.NewCoins(sdk.NewInt64Coin("atom", 10)) msg := MsgMultiSend{ - Inputs: []Input{NewInput(addr1, coins)}, + Input: NewInput(addr1, coins), Outputs: []Output{NewOutput(addr2, coins)}, } @@ -164,67 +164,75 @@ func TestOutputValidation(t *testing.T) { func TestMsgMultiSendValidation(t *testing.T) { addr1 := sdk.AccAddress([]byte("_______alice________")) addr2 := sdk.AccAddress([]byte("________bob_________")) + addr3 := sdk.AccAddress([]byte("_______addr3________")) atom123 := sdk.NewCoins(sdk.NewInt64Coin("atom", 123)) atom124 := sdk.NewCoins(sdk.NewInt64Coin("atom", 124)) - eth123 := sdk.NewCoins(sdk.NewInt64Coin("eth", 123)) - atom123eth123 := sdk.NewCoins(sdk.NewInt64Coin("atom", 123), sdk.NewInt64Coin("eth", 123)) + atom246 := sdk.NewCoins(sdk.NewInt64Coin("atom", 246)) input1 := NewInput(addr1, atom123) - input2 := NewInput(addr1, eth123) + input2 := NewInput(addr1, atom246) output1 := NewOutput(addr2, atom123) output2 := NewOutput(addr2, atom124) - outputMulti := NewOutput(addr2, atom123eth123) + output3 := NewOutput(addr2, atom123) + output4 := NewOutput(addr3, atom123) var emptyAddr sdk.AccAddress cases := []struct { - valid bool - tx MsgMultiSend + valid bool + tx MsgMultiSend + expErrMsg string }{ - {false, MsgMultiSend{}}, // no input or output - {false, MsgMultiSend{Inputs: []Input{input1}}}, // just input - {false, MsgMultiSend{Outputs: []Output{output1}}}, // just output + {false, MsgMultiSend{}, "invalid input address"}, // no input or output + {false, MsgMultiSend{Input: input1}, "no outputs to send transaction"}, // just input + {false, MsgMultiSend{Outputs: []Output{output1}}, "invalid input address"}, // just output { false, MsgMultiSend{ - Inputs: []Input{NewInput(emptyAddr, atom123)}, // invalid input + Input: NewInput(emptyAddr, atom123), // invalid input Outputs: []Output{output1}, }, + "invalid input address", }, { false, MsgMultiSend{ - Inputs: []Input{input1}, + Input: input1, Outputs: []Output{{emptyAddr.String(), atom123}}, // invalid output }, + "invalid output address", }, { false, MsgMultiSend{ - Inputs: []Input{input1}, - Outputs: []Output{output2}, // amounts dont match + Input: input1, + Outputs: []Output{output2}, // amounts don't match }, + "sum inputs != sum outputs", }, { true, MsgMultiSend{ - Inputs: []Input{input1}, + Input: input1, Outputs: []Output{output1}, }, + "", }, { true, MsgMultiSend{ - Inputs: []Input{input1, input2}, - Outputs: []Output{outputMulti}, + Input: input2, + Outputs: []Output{output3, output4}, }, + "", }, { true, MsgMultiSend{ - Inputs: []Input{NewInput(addr2, atom123.MulInt(sdk.NewInt(2)))}, + Input: NewInput(addr2, atom123.MulInt(sdk.NewInt(2))), Outputs: []Output{output1, output1}, }, + "", }, } @@ -232,8 +240,10 @@ func TestMsgMultiSendValidation(t *testing.T) { err := tc.tx.ValidateBasic() if tc.valid { require.Nil(t, err, "%d: %+v", i, err) + require.Nil(t, err) } else { require.NotNil(t, err, "%d", i) + require.Contains(t, err.Error(), tc.expErrMsg) } } } @@ -243,29 +253,22 @@ func TestMsgMultiSendGetSignBytes(t *testing.T) { addr2 := sdk.AccAddress([]byte("output")) coins := sdk.NewCoins(sdk.NewInt64Coin("atom", 10)) msg := MsgMultiSend{ - Inputs: []Input{NewInput(addr1, coins)}, + Input: NewInput(addr1, coins), Outputs: []Output{NewOutput(addr2, coins)}, } res := msg.GetSignBytes() - expected := `{"type":"cosmos-sdk/MsgMultiSend","value":{"inputs":[{"address":"cosmos1d9h8qat57ljhcm","coins":[{"amount":"10","denom":"atom"}]}],"outputs":[{"address":"cosmos1da6hgur4wsmpnjyg","coins":[{"amount":"10","denom":"atom"}]}]}}` + expected := `{"type":"cosmos-sdk/MsgMultiSend","value":{"input":{"address":"cosmos1d9h8qat57ljhcm","coins":[{"amount":"10","denom":"atom"}]},"outputs":[{"address":"cosmos1da6hgur4wsmpnjyg","coins":[{"amount":"10","denom":"atom"}]}]}}` require.Equal(t, expected, string(res)) } func TestMsgMultiSendGetSigners(t *testing.T) { - addrs := make([]string, 3) - inputs := make([]Input, 3) - for i, v := range []string{"input111111111111111", "input222222222222222", "input333333333333333"} { - addr := sdk.AccAddress([]byte(v)) - inputs[i] = NewInput(addr, nil) - addrs[i] = addr.String() - } - msg := NewMsgMultiSend(inputs, nil) - + addr := sdk.AccAddress([]byte("input111111111111111")) + input := NewInput(addr, nil) + msg := NewMsgMultiSend(input, nil) res := msg.GetSigners() - for i, signer := range res { - require.Equal(t, signer.String(), addrs[i]) - } + require.Equal(t, 1, len(res)) + require.True(t, addr.Equals(res[0])) } func TestMsgSendGetSigners(t *testing.T) { diff --git a/x/bank/types/tx.pb.go b/x/bank/types/tx.pb.go index 874c3dd8d862..dddc40586b00 100644 --- a/x/bank/types/tx.pb.go +++ b/x/bank/types/tx.pb.go @@ -109,9 +109,9 @@ func (m *MsgSendResponse) XXX_DiscardUnknown() { var xxx_messageInfo_MsgSendResponse proto.InternalMessageInfo -// MsgMultiSend represents an arbitrary multi-in, multi-out send message. +// MsgMultiSend represents a single input, multi-out send message. type MsgMultiSend struct { - Inputs []Input `protobuf:"bytes,1,rep,name=inputs,proto3" json:"inputs"` + Input Input `protobuf:"bytes,1,opt,name=input,proto3" json:"input"` Outputs []Output `protobuf:"bytes,2,rep,name=outputs,proto3" json:"outputs"` } @@ -148,11 +148,11 @@ func (m *MsgMultiSend) XXX_DiscardUnknown() { var xxx_messageInfo_MsgMultiSend proto.InternalMessageInfo -func (m *MsgMultiSend) GetInputs() []Input { +func (m *MsgMultiSend) GetInput() Input { if m != nil { - return m.Inputs + return m.Input } - return nil + return Input{} } func (m *MsgMultiSend) GetOutputs() []Output { @@ -209,36 +209,36 @@ func init() { func init() { proto.RegisterFile("cosmos/bank/v1beta1/tx.proto", fileDescriptor_1d8cb1613481f5b7) } var fileDescriptor_1d8cb1613481f5b7 = []byte{ - // 460 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x52, 0x3d, 0x6f, 0xd3, 0x40, - 0x18, 0xf6, 0x35, 0x55, 0xaa, 0x5c, 0x2b, 0x55, 0x98, 0x08, 0x12, 0x53, 0x39, 0xc5, 0x62, 0x48, - 0x91, 0x7a, 0x26, 0x65, 0x00, 0xb5, 0x13, 0xee, 0x04, 0x92, 0x85, 0xe4, 0x4e, 0xb0, 0x54, 0xfe, - 0x38, 0x0e, 0xab, 0xf8, 0xce, 0xf2, 0x9d, 0xab, 0xb2, 0x32, 0x31, 0x32, 0x31, 0x77, 0x46, 0x0c, - 0x0c, 0xfc, 0x88, 0x8e, 0x15, 0x13, 0x13, 0xa0, 0x64, 0x80, 0x7f, 0x01, 0xba, 0x0f, 0x9b, 0x22, - 0xd2, 0x66, 0x3a, 0xcb, 0xcf, 0xc7, 0x3d, 0xef, 0xf3, 0x1e, 0xdc, 0x48, 0x19, 0x2f, 0x18, 0xf7, - 0x93, 0x98, 0x1e, 0xf9, 0xc7, 0x93, 0x04, 0x8b, 0x78, 0xe2, 0x8b, 0x13, 0x54, 0x56, 0x4c, 0x30, - 0xfb, 0xba, 0x46, 0x91, 0x44, 0x91, 0x41, 0x9d, 0x3e, 0x61, 0x84, 0x29, 0xdc, 0x97, 0x5f, 0x9a, - 0xea, 0xb8, 0xad, 0x11, 0xc7, 0xad, 0x51, 0xca, 0x72, 0xfa, 0x1f, 0x7e, 0xe1, 0x22, 0xe5, 0xab, - 0xf1, 0xa1, 0xc6, 0x0f, 0xb5, 0xb1, 0xb9, 0x57, 0x43, 0x37, 0x8d, 0xb4, 0xe0, 0xc4, 0x3f, 0x9e, - 0xc8, 0x43, 0x03, 0xde, 0x6f, 0x00, 0x57, 0x42, 0x4e, 0x0e, 0x30, 0xcd, 0xec, 0x3d, 0xb8, 0xf6, - 0xa2, 0x62, 0xc5, 0x61, 0x9c, 0x65, 0x15, 0xe6, 0x7c, 0x00, 0x36, 0xc1, 0xb8, 0x17, 0x0c, 0xbe, - 0x7c, 0xde, 0xee, 0x1b, 0xb3, 0x47, 0x1a, 0x39, 0x10, 0x55, 0x4e, 0x49, 0xb4, 0x2a, 0xd9, 0xe6, - 0x97, 0xfd, 0x00, 0x42, 0xc1, 0x5a, 0xe9, 0xd2, 0x02, 0x69, 0x4f, 0xb0, 0x46, 0x98, 0xc2, 0x6e, - 0x5c, 0xb0, 0x9a, 0x8a, 0x41, 0x67, 0xb3, 0x33, 0x5e, 0xdd, 0x19, 0xa2, 0xb6, 0x31, 0x8e, 0x9b, - 0xc6, 0xd0, 0x3e, 0xcb, 0x69, 0x70, 0xef, 0xec, 0xdb, 0xc8, 0xfa, 0xf0, 0x7d, 0x34, 0x26, 0xb9, - 0x78, 0x59, 0x27, 0x28, 0x65, 0x85, 0x19, 0xd3, 0x1c, 0xdb, 0x3c, 0x3b, 0xf2, 0xc5, 0xeb, 0x12, - 0x73, 0x25, 0xe0, 0x91, 0xb1, 0xde, 0x1d, 0xbe, 0x3d, 0x1d, 0x59, 0xbf, 0x4e, 0x47, 0xd6, 0x9b, - 0x9f, 0x9f, 0xee, 0xfe, 0x33, 0xa5, 0x77, 0x0d, 0xae, 0x9b, 0x02, 0x22, 0xcc, 0x4b, 0x46, 0x39, - 0xf6, 0xde, 0x03, 0xb8, 0x16, 0x72, 0x12, 0xd6, 0xaf, 0x44, 0xae, 0x9a, 0x79, 0x08, 0xbb, 0x39, - 0x2d, 0x6b, 0x21, 0x3b, 0x91, 0x19, 0x1d, 0x34, 0x67, 0xab, 0xe8, 0xb1, 0xa4, 0x04, 0xcb, 0x32, - 0x64, 0x64, 0xf8, 0xf6, 0x1e, 0x5c, 0x61, 0xb5, 0x50, 0xd2, 0x25, 0x25, 0xbd, 0x35, 0x57, 0xfa, - 0x54, 0x71, 0x8c, 0xb6, 0x51, 0xec, 0xae, 0x37, 0x89, 0x8d, 0x9b, 0x77, 0x03, 0xf6, 0x2f, 0xe6, - 0x6a, 0x02, 0xef, 0x7c, 0x04, 0xb0, 0x13, 0x72, 0x62, 0x3f, 0x81, 0xcb, 0x2a, 0xef, 0xc6, 0xdc, - 0x4b, 0xcc, 0x98, 0xce, 0x9d, 0xab, 0xd0, 0xc6, 0xd3, 0x7e, 0x06, 0x7b, 0x7f, 0x0b, 0xb8, 0x7d, - 0x99, 0xa4, 0xa5, 0x38, 0x5b, 0x0b, 0x29, 0x8d, 0x75, 0xb0, 0x7f, 0x36, 0x75, 0xc1, 0xf9, 0xd4, - 0x05, 0x3f, 0xa6, 0x2e, 0x78, 0x37, 0x73, 0xad, 0xf3, 0x99, 0x6b, 0x7d, 0x9d, 0xb9, 0xd6, 0xf3, - 0xad, 0x2b, 0x37, 0x7b, 0xa2, 0x9f, 0xbe, 0x5a, 0x70, 0xd2, 0x55, 0x0f, 0xf8, 0xfe, 0x9f, 0x00, - 0x00, 0x00, 0xff, 0xff, 0xa7, 0xd3, 0x87, 0x2b, 0x7f, 0x03, 0x00, 0x00, + // 464 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x92, 0x4d, 0x6b, 0xd4, 0x40, + 0x1c, 0xc6, 0x33, 0x6e, 0x6d, 0xd9, 0xd9, 0xa2, 0x18, 0x17, 0xdd, 0x8d, 0x25, 0x5b, 0x83, 0x87, + 0xad, 0xd0, 0x89, 0xbb, 0x82, 0x42, 0x7b, 0x32, 0x3d, 0x29, 0x04, 0x21, 0x3d, 0xe9, 0xa5, 0xe4, + 0x65, 0x1c, 0x43, 0xcd, 0x4c, 0xc8, 0x4c, 0x4a, 0xbd, 0x7a, 0xf2, 0x28, 0xf8, 0x05, 0x7a, 0x16, + 0x0f, 0x1e, 0xfc, 0x10, 0x3d, 0x16, 0x4f, 0x9e, 0x54, 0x76, 0x0f, 0xfa, 0x2d, 0x94, 0x79, 0x49, + 0xac, 0xb8, 0x6d, 0x4f, 0x13, 0xf2, 0x7b, 0x9e, 0x67, 0xfe, 0x2f, 0x03, 0xd7, 0x52, 0xc6, 0x0b, + 0xc6, 0xfd, 0x24, 0xa6, 0xfb, 0xfe, 0xc1, 0x24, 0xc1, 0x22, 0x9e, 0xf8, 0xe2, 0x10, 0x95, 0x15, + 0x13, 0xcc, 0xbe, 0xae, 0x29, 0x92, 0x14, 0x19, 0xea, 0xf4, 0x09, 0x23, 0x4c, 0x71, 0x5f, 0x7e, + 0x69, 0xa9, 0xe3, 0xb6, 0x41, 0x1c, 0xb7, 0x41, 0x29, 0xcb, 0xe9, 0x7f, 0xfc, 0xd4, 0x45, 0x2a, + 0x57, 0xf3, 0xa1, 0xe6, 0x7b, 0x3a, 0xd8, 0xdc, 0xab, 0xd1, 0x4d, 0x63, 0x2d, 0x38, 0xf1, 0x0f, + 0x26, 0xf2, 0xd0, 0xc0, 0xfb, 0x0d, 0xe0, 0x4a, 0xc8, 0xc9, 0x2e, 0xa6, 0x99, 0xbd, 0x0d, 0x57, + 0x5f, 0x54, 0xac, 0xd8, 0x8b, 0xb3, 0xac, 0xc2, 0x9c, 0x0f, 0xc0, 0x3a, 0x18, 0x77, 0x83, 0xc1, + 0x97, 0xcf, 0x9b, 0x7d, 0x13, 0xf6, 0x48, 0x93, 0x5d, 0x51, 0xe5, 0x94, 0x44, 0x3d, 0xa9, 0x36, + 0xbf, 0xec, 0x87, 0x10, 0x0a, 0xd6, 0x5a, 0x2f, 0x5d, 0x60, 0xed, 0x0a, 0xd6, 0x18, 0x53, 0xb8, + 0x1c, 0x17, 0xac, 0xa6, 0x62, 0xd0, 0x59, 0xef, 0x8c, 0x7b, 0xd3, 0x21, 0x6a, 0x27, 0xc6, 0x71, + 0x33, 0x31, 0xb4, 0xc3, 0x72, 0x1a, 0xdc, 0x3b, 0xfe, 0x36, 0xb2, 0x3e, 0x7c, 0x1f, 0x8d, 0x49, + 0x2e, 0x5e, 0xd6, 0x09, 0x4a, 0x59, 0x61, 0xda, 0x34, 0xc7, 0x26, 0xcf, 0xf6, 0x7d, 0xf1, 0xba, + 0xc4, 0x5c, 0x19, 0x78, 0x64, 0xa2, 0xb7, 0x86, 0x6f, 0x8f, 0x46, 0xd6, 0xaf, 0xa3, 0x91, 0xf5, + 0xe6, 0xe7, 0xa7, 0xbb, 0xff, 0x74, 0xe9, 0x5d, 0x83, 0x57, 0xcd, 0x00, 0x22, 0xcc, 0x4b, 0x46, + 0x39, 0xf6, 0xde, 0x03, 0xb8, 0x1a, 0x72, 0x12, 0xd6, 0xaf, 0x44, 0xae, 0x26, 0xf3, 0x00, 0x5e, + 0xce, 0x69, 0x59, 0x0b, 0x35, 0x92, 0xde, 0xd4, 0x41, 0x0b, 0x96, 0x8a, 0x1e, 0x4b, 0x45, 0xb0, + 0x24, 0x6b, 0x8c, 0xb4, 0xdc, 0xde, 0x86, 0x2b, 0xac, 0x16, 0x65, 0x2d, 0xe4, 0x44, 0x64, 0x73, + 0xb7, 0x16, 0x3a, 0x9f, 0x2a, 0x8d, 0xb1, 0x36, 0x8e, 0xad, 0x2b, 0x4d, 0xbd, 0x3a, 0xcc, 0xbb, + 0x01, 0xfb, 0xa7, 0x8b, 0x6a, 0xaa, 0x9d, 0x7e, 0x04, 0xb0, 0x13, 0x72, 0x62, 0x3f, 0x81, 0x4b, + 0xaa, 0xd8, 0xb5, 0x85, 0x77, 0x98, 0x1e, 0x9d, 0x3b, 0xe7, 0xd1, 0x26, 0xd3, 0x7e, 0x06, 0xbb, + 0x7f, 0xbb, 0xbf, 0x7d, 0x96, 0xa5, 0x95, 0x38, 0x1b, 0x17, 0x4a, 0x9a, 0xe8, 0x60, 0xe7, 0x78, + 0xe6, 0x82, 0x93, 0x99, 0x0b, 0x7e, 0xcc, 0x5c, 0xf0, 0x6e, 0xee, 0x5a, 0x27, 0x73, 0xd7, 0xfa, + 0x3a, 0x77, 0xad, 0xe7, 0x1b, 0xe7, 0xae, 0xf5, 0x50, 0xbf, 0x7b, 0xb5, 0xdd, 0x64, 0x59, 0xbd, + 0xde, 0xfb, 0x7f, 0x02, 0x00, 0x00, 0xff, 0xff, 0x51, 0xb7, 0xdd, 0x56, 0x7c, 0x03, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -469,20 +469,16 @@ func (m *MsgMultiSend) MarshalToSizedBuffer(dAtA []byte) (int, error) { dAtA[i] = 0x12 } } - if len(m.Inputs) > 0 { - for iNdEx := len(m.Inputs) - 1; iNdEx >= 0; iNdEx-- { - { - size, err := m.Inputs[iNdEx].MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintTx(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0xa + { + size, err := m.Input.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err } + i -= size + i = encodeVarintTx(dAtA, i, uint64(size)) } + i-- + dAtA[i] = 0xa return len(dAtA) - i, nil } @@ -558,12 +554,8 @@ func (m *MsgMultiSend) Size() (n int) { } var l int _ = l - if len(m.Inputs) > 0 { - for _, e := range m.Inputs { - l = e.Size() - n += 1 + l + sovTx(uint64(l)) - } - } + l = m.Input.Size() + n += 1 + l + sovTx(uint64(l)) if len(m.Outputs) > 0 { for _, e := range m.Outputs { l = e.Size() @@ -817,7 +809,7 @@ func (m *MsgMultiSend) Unmarshal(dAtA []byte) error { switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Inputs", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Input", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -844,8 +836,7 @@ func (m *MsgMultiSend) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Inputs = append(m.Inputs, Input{}) - if err := m.Inputs[len(m.Inputs)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.Input.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex