diff --git a/docs/ibc/proto-docs.md b/docs/ibc/proto-docs.md index 986ffd334f8..fe109584bba 100644 --- a/docs/ibc/proto-docs.md +++ b/docs/ibc/proto-docs.md @@ -17,7 +17,7 @@ - [Query](#ibc.applications.interchain_accounts.v1.Query) - [ibc/applications/interchain_accounts/v1/types.proto](#ibc/applications/interchain_accounts/v1/types.proto) - - [IBCTxBody](#ibc.applications.interchain_accounts.v1.IBCTxBody) + - [CosmosTx](#ibc.applications.interchain_accounts.v1.CosmosTx) - [InterchainAccountPacketData](#ibc.applications.interchain_accounts.v1.InterchainAccountPacketData) - [Type](#ibc.applications.interchain_accounts.v1.Type) @@ -398,10 +398,10 @@ Query defines the gRPC querier service. - + -### IBCTxBody -Body of a tx for an ics27 IBC packet +### CosmosTx +CosmosTx contains a list of sdk.Msg's. It should be used when sending transactions to an SDK host chain. | Field | Type | Label | Description | @@ -416,7 +416,7 @@ Body of a tx for an ics27 IBC packet ### InterchainAccountPacketData -InterchainAccountPacketData is comprised of araw transaction,type of transaction and optional memo field. +InterchainAccountPacketData is comprised of a raw transaction, type of transaction and optional memo field. | Field | Type | Label | Description | diff --git a/modules/apps/27-interchain-accounts/keeper/keeper.go b/modules/apps/27-interchain-accounts/keeper/keeper.go index d66026c7a6d..2c685ade7d9 100644 --- a/modules/apps/27-interchain-accounts/keeper/keeper.go +++ b/modules/apps/27-interchain-accounts/keeper/keeper.go @@ -55,23 +55,24 @@ func NewKeeper( } } -// SerializeCosmosTx marshals data to bytes using the provided codec -func (k Keeper) SerializeCosmosTx(cdc codec.BinaryCodec, msgs []sdk.Msg) ([]byte, error) { +// SerializeCosmosTx serializes a slice of sdk.Msg's using the CosmosTx type. The sdk.Msg's are +// packed into Any's and inserted into the Messages field of a CosmosTx. The proto marshaled CosmosTx +// bytes are returned. +func (k Keeper) SerializeCosmosTx(cdc codec.BinaryCodec, msgs []sdk.Msg) (bz []byte, err error) { msgAnys := make([]*codectypes.Any, len(msgs)) for i, msg := range msgs { - var err error msgAnys[i], err = codectypes.NewAnyWithValue(msg) if err != nil { return nil, err } } - txBody := &types.IBCTxBody{ + cosmosTx := &types.CosmosTx{ Messages: msgAnys, } - bz, err := cdc.Marshal(txBody) + bz, err = cdc.Marshal(cosmosTx) if err != nil { return nil, err } diff --git a/modules/apps/27-interchain-accounts/keeper/relay.go b/modules/apps/27-interchain-accounts/keeper/relay.go index f01bb02aba2..446f1521837 100644 --- a/modules/apps/27-interchain-accounts/keeper/relay.go +++ b/modules/apps/27-interchain-accounts/keeper/relay.go @@ -12,7 +12,7 @@ import ( // TODO: implement middleware functionality, this will allow us to use capabilities to // manage helper module access to owner addresses they do not have capabilities for -func (k Keeper) TrySendTx(ctx sdk.Context, portID string, data interface{}, memo string) (uint64, error) { +func (k Keeper) TrySendTx(ctx sdk.Context, portID string, icaPacketData types.InterchainAccountPacketData) (uint64, error) { // Check for the active channel activeChannelId, found := k.GetActiveChannel(ctx, portID) if !found { @@ -27,7 +27,7 @@ func (k Keeper) TrySendTx(ctx sdk.Context, portID string, data interface{}, memo destinationPort := sourceChannelEnd.GetCounterparty().GetPortID() destinationChannel := sourceChannelEnd.GetCounterparty().GetChannelID() - return k.createOutgoingPacket(ctx, portID, activeChannelId, destinationPort, destinationChannel, data, memo) + return k.createOutgoingPacket(ctx, portID, activeChannelId, destinationPort, destinationChannel, icaPacketData) } func (k Keeper) createOutgoingPacket( @@ -36,27 +36,10 @@ func (k Keeper) createOutgoingPacket( sourceChannel, destinationPort, destinationChannel string, - data interface{}, - memo string, + icaPacketData types.InterchainAccountPacketData, ) (uint64, error) { - if data == nil { - return 0, types.ErrInvalidOutgoingData - } - - var ( - txBytes []byte - err error - ) - - switch data := data.(type) { - case []sdk.Msg: - txBytes, err = k.SerializeCosmosTx(k.cdc, data) - default: - return 0, sdkerrors.Wrapf(types.ErrInvalidOutgoingData, "message type %T is not supported", data) - } - - if err != nil { - return 0, sdkerrors.Wrap(err, "serialization of transaction data failed") + if err := icaPacketData.ValidateBasic(); err != nil { + return 0, sdkerrors.Wrap(err, "invalid interchain account packet data") } channelCap, ok := k.scopedKeeper.GetCapability(ctx, host.ChannelCapabilityPath(sourcePort, sourceChannel)) @@ -70,18 +53,12 @@ func (k Keeper) createOutgoingPacket( return 0, channeltypes.ErrSequenceSendNotFound } - packetData := types.InterchainAccountPacketData{ - Type: types.EXECUTE_TX, - Data: txBytes, - Memo: memo, - } - // timeoutTimestamp is set to be a max number here so that we never recieve a timeout // ics-27-1 uses ordered channels which can close upon recieving a timeout, which is an undesired effect const timeoutTimestamp = ^uint64(0) >> 1 // Shift the unsigned bit to satisfy hermes relayer timestamp conversion packet := channeltypes.NewPacket( - packetData.GetBytes(), + icaPacketData.GetBytes(), sequence, sourcePort, sourceChannel, @@ -100,25 +77,26 @@ func (k Keeper) createOutgoingPacket( // DeserializeCosmosTx unmarshals and unpacks a slice of transaction bytes // into a slice of sdk.Msg's. -func (k Keeper) DeserializeCosmosTx(_ sdk.Context, txBytes []byte) ([]sdk.Msg, error) { - var txBody types.IBCTxBody - - if err := k.cdc.Unmarshal(txBytes, &txBody); err != nil { +func (k Keeper) DeserializeCosmosTx(_ sdk.Context, data []byte) ([]sdk.Msg, error) { + var cosmosTx types.CosmosTx + if err := k.cdc.Unmarshal(data, &cosmosTx); err != nil { return nil, err } - anys := txBody.Messages - res := make([]sdk.Msg, len(anys)) - for i, any := range anys { + msgs := make([]sdk.Msg, len(cosmosTx.Messages)) + + for i, any := range cosmosTx.Messages { var msg sdk.Msg + err := k.cdc.UnpackAny(any, &msg) if err != nil { return nil, err } - res[i] = msg + + msgs[i] = msg } - return res, nil + return msgs, nil } func (k Keeper) AuthenticateTx(ctx sdk.Context, msgs []sdk.Msg, portId string) error { diff --git a/modules/apps/27-interchain-accounts/keeper/relay_test.go b/modules/apps/27-interchain-accounts/keeper/relay_test.go index d3c7aadc2d5..f5d02b2ec6a 100644 --- a/modules/apps/27-interchain-accounts/keeper/relay_test.go +++ b/modules/apps/27-interchain-accounts/keeper/relay_test.go @@ -15,9 +15,9 @@ import ( func (suite *KeeperTestSuite) TestTrySendTx() { var ( - path *ibctesting.Path - msg interface{} - portID string + path *ibctesting.Path + icaPacketData types.InterchainAccountPacketData + portID string ) testCases := []struct { @@ -27,9 +27,6 @@ func (suite *KeeperTestSuite) TestTrySendTx() { }{ { "success", func() { - amount, _ := sdk.ParseCoinsNormalized("100stake") - interchainAccountAddr, _ := suite.chainB.GetSimApp().ICAKeeper.GetInterchainAccountAddress(suite.chainB.GetContext(), path.EndpointA.ChannelConfig.PortID) - msg = []sdk.Msg{&banktypes.MsgSend{FromAddress: interchainAccountAddr, ToAddress: suite.chainB.SenderAccount.GetAddress().String(), Amount: amount}} }, true, }, { @@ -38,45 +35,30 @@ func (suite *KeeperTestSuite) TestTrySendTx() { interchainAccountAddr, _ := suite.chainB.GetSimApp().ICAKeeper.GetInterchainAccountAddress(suite.chainB.GetContext(), path.EndpointA.ChannelConfig.PortID) msg1 := &banktypes.MsgSend{FromAddress: interchainAccountAddr, ToAddress: suite.chainB.SenderAccount.GetAddress().String(), Amount: amount} msg2 := &banktypes.MsgSend{FromAddress: interchainAccountAddr, ToAddress: suite.chainB.SenderAccount.GetAddress().String(), Amount: amount} - msg = []sdk.Msg{msg1, msg2} + data, err := suite.chainB.GetSimApp().ICAKeeper.SerializeCosmosTx(suite.chainB.GetSimApp().AppCodec(), []sdk.Msg{msg1, msg2}) + suite.Require().NoError(err) + icaPacketData.Data = data }, true, }, { - "incorrect outgoing data", func() { - msg = []byte{} - }, false, - }, - { - "incorrect outgoing data - []sdk.Msg is not used", func() { - amount, _ := sdk.ParseCoinsNormalized("100stake") - interchainAccountAddr, _ := suite.chainB.GetSimApp().ICAKeeper.GetInterchainAccountAddress(suite.chainB.GetContext(), path.EndpointA.ChannelConfig.PortID) - msg = &banktypes.MsgSend{FromAddress: interchainAccountAddr, ToAddress: suite.chainB.SenderAccount.GetAddress().String(), Amount: amount} + "data is nil", func() { + icaPacketData.Data = nil }, false, }, { "active channel not found", func() { - amount, _ := sdk.ParseCoinsNormalized("100stake") - interchainAccountAddr, _ := suite.chainB.GetSimApp().ICAKeeper.GetInterchainAccountAddress(suite.chainB.GetContext(), path.EndpointA.ChannelConfig.PortID) - msg = &banktypes.MsgSend{FromAddress: interchainAccountAddr, ToAddress: suite.chainB.SenderAccount.GetAddress().String(), Amount: amount} portID = "incorrect portID" }, false, }, { "channel does not exist", func() { - amount, _ := sdk.ParseCoinsNormalized("100stake") - interchainAccountAddr, _ := suite.chainB.GetSimApp().ICAKeeper.GetInterchainAccountAddress(suite.chainB.GetContext(), path.EndpointA.ChannelConfig.PortID) - msg = &banktypes.MsgSend{FromAddress: interchainAccountAddr, ToAddress: suite.chainB.SenderAccount.GetAddress().String(), Amount: amount} suite.chainA.GetSimApp().ICAKeeper.SetActiveChannel(suite.chainA.GetContext(), portID, "channel-100") }, false, }, { - "data is nil", func() { - msg = nil - }, false, - }, - { - "data is not an SDK message", func() { - msg = "not an sdk message" + "SendPacket fails - channel closed", func() { + err := path.EndpointA.SetChannelClosed() + suite.Require().NoError(err) }, false, }, } @@ -88,16 +70,28 @@ func (suite *KeeperTestSuite) TestTrySendTx() { suite.SetupTest() // reset path = NewICAPath(suite.chainA, suite.chainB) suite.coordinator.SetupConnections(path) - memo := "memo" err := suite.SetupICAPath(path, TestOwnerAddress) suite.Require().NoError(err) portID = path.EndpointA.ChannelConfig.PortID + amount, _ := sdk.ParseCoinsNormalized("100stake") + interchainAccountAddr, _ := suite.chainB.GetSimApp().ICAKeeper.GetInterchainAccountAddress(suite.chainB.GetContext(), path.EndpointA.ChannelConfig.PortID) + msg := &banktypes.MsgSend{FromAddress: interchainAccountAddr, ToAddress: suite.chainB.SenderAccount.GetAddress().String(), Amount: amount} + data, err := suite.chainB.GetSimApp().ICAKeeper.SerializeCosmosTx(suite.chainB.GetSimApp().AppCodec(), []sdk.Msg{msg}) + suite.Require().NoError(err) + + // default packet data, must be modified in malleate for test cases expected to fail + icaPacketData = types.InterchainAccountPacketData{ + Type: types.EXECUTE_TX, + Data: data, + Memo: "memo", + } + tc.malleate() - _, err = suite.chainA.GetSimApp().ICAKeeper.TrySendTx(suite.chainA.GetContext(), portID, msg, memo) + _, err = suite.chainA.GetSimApp().ICAKeeper.TrySendTx(suite.chainA.GetContext(), portID, icaPacketData) if tc.expPass { suite.Require().NoError(err) @@ -112,7 +106,6 @@ func (suite *KeeperTestSuite) TestOnRecvPacket() { var ( path *ibctesting.Path msg sdk.Msg - txBytes []byte packetData []byte sourcePort string ) @@ -129,30 +122,40 @@ func (suite *KeeperTestSuite) TestOnRecvPacket() { interchainAccountAddr, _ := suite.chainB.GetSimApp().ICAKeeper.GetInterchainAccountAddress(suite.chainB.GetContext(), path.EndpointA.ChannelConfig.PortID) msg = &banktypes.MsgSend{FromAddress: interchainAccountAddr, ToAddress: suite.chainB.SenderAccount.GetAddress().String(), Amount: amount} // build packet data - txBytes, err := suite.chainA.GetSimApp().ICAKeeper.SerializeCosmosTx(suite.chainA.Codec, []sdk.Msg{msg}) + data, err := suite.chainA.GetSimApp().ICAKeeper.SerializeCosmosTx(suite.chainA.Codec, []sdk.Msg{msg}) suite.Require().NoError(err) - data := types.InterchainAccountPacketData{Type: types.EXECUTE_TX, - Data: txBytes} - packetData = data.GetBytes() + icaPacketData := types.InterchainAccountPacketData{ + Type: types.EXECUTE_TX, + Data: data, + } + packetData = icaPacketData.GetBytes() }, true, }, { - "Cannot deserialize txBytes", func() { - txBytes = []byte("invalid tx bytes") - data := types.InterchainAccountPacketData{Type: types.EXECUTE_TX, - Data: txBytes} - packetData = data.GetBytes() + "Cannot deserialize packet data messages", func() { + data := []byte("invalid packet data") + + icaPacketData := types.InterchainAccountPacketData{ + Type: types.EXECUTE_TX, + Data: data, + } + packetData = icaPacketData.GetBytes() }, false, }, { "Invalid packet type", func() { - txBytes = []byte{} + // build packet data + data, err := suite.chainA.GetSimApp().ICAKeeper.SerializeCosmosTx(suite.chainA.Codec, []sdk.Msg{&banktypes.MsgSend{}}) + suite.Require().NoError(err) + // Type here is an ENUM // Valid type is types.EXECUTE_TX - data := types.InterchainAccountPacketData{Type: 100, - Data: txBytes} - packetData = data.GetBytes() + icaPacketData := types.InterchainAccountPacketData{ + Type: 100, + Data: data, + } + packetData = icaPacketData.GetBytes() }, false, }, { @@ -172,11 +175,13 @@ func (suite *KeeperTestSuite) TestOnRecvPacket() { // Incorrect FromAddress msg = &banktypes.MsgSend{FromAddress: suite.chainB.SenderAccount.GetAddress().String(), ToAddress: suite.chainB.SenderAccount.GetAddress().String(), Amount: amount} // build packet data - txBytes, err := suite.chainA.GetSimApp().ICAKeeper.SerializeCosmosTx(suite.chainA.Codec, []sdk.Msg{msg}) + data, err := suite.chainA.GetSimApp().ICAKeeper.SerializeCosmosTx(suite.chainA.Codec, []sdk.Msg{msg}) suite.Require().NoError(err) - data := types.InterchainAccountPacketData{Type: types.EXECUTE_TX, - Data: txBytes} - packetData = data.GetBytes() + icaPacketData := types.InterchainAccountPacketData{ + Type: types.EXECUTE_TX, + Data: data, + } + packetData = icaPacketData.GetBytes() }, false, }, } diff --git a/modules/apps/27-interchain-accounts/types/packet.go b/modules/apps/27-interchain-accounts/types/packet.go index 1c64054b3ee..d69dfebd30a 100644 --- a/modules/apps/27-interchain-accounts/types/packet.go +++ b/modules/apps/27-interchain-accounts/types/packet.go @@ -1,9 +1,46 @@ package types import ( + codectypes "github.com/cosmos/cosmos-sdk/codec/types" sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) -func (packet InterchainAccountPacketData) GetBytes() []byte { - return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(&packet)) +const MaxMemoCharLength = 256 + +// ValidateBasic performs basic validation of the interchain account packet data. +// The memo may be empty. +func (iapd InterchainAccountPacketData) ValidateBasic() error { + if iapd.Data == nil { + return sdkerrors.Wrap(ErrInvalidOutgoingData, "packet data cannot be empty") + } + + if len(iapd.Memo) > MaxMemoCharLength { + return sdkerrors.Wrapf(ErrInvalidOutgoingData, "packet data memo cannot be greater than %d characters", MaxMemoCharLength) + } + // TODO: add type validation when data type enum supports unspecified type + + return nil +} + +// GetBytes returns the JSON marshalled interchain account packet data. +func (iapd InterchainAccountPacketData) GetBytes() []byte { + return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(&iapd)) +} + +// GetBytes returns the JSON marshalled interchain account CosmosTx. +func (ct CosmosTx) GetBytes() []byte { + return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(&ct)) +} + +// UnpackInterfaces implements UnpackInterfacesMessage.UnpackInterfaces +func (ct CosmosTx) UnpackInterfaces(unpacker codectypes.AnyUnpacker) error { + for _, any := range ct.Messages { + err := unpacker.UnpackAny(any, new(sdk.Msg)) + if err != nil { + return err + } + } + + return nil } diff --git a/modules/apps/27-interchain-accounts/types/packet_test.go b/modules/apps/27-interchain-accounts/types/packet_test.go new file mode 100644 index 00000000000..ce2fab2f5ca --- /dev/null +++ b/modules/apps/27-interchain-accounts/types/packet_test.go @@ -0,0 +1,66 @@ +package types_test + +import ( + "github.com/cosmos/ibc-go/v2/modules/apps/27-interchain-accounts/types" +) + +var largeMemo = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum" + +func (suite *TypesTestSuite) TestValidateBasic() { + testCases := []struct { + name string + packetData types.InterchainAccountPacketData + expPass bool + }{ + { + "success", + types.InterchainAccountPacketData{ + Type: types.EXECUTE_TX, + Data: []byte("data"), + Memo: "memo", + }, + true, + }, + { + "success, empty memo", + types.InterchainAccountPacketData{ + Type: types.EXECUTE_TX, + Data: []byte("data"), + }, + true, + }, + { + "empty data", + types.InterchainAccountPacketData{ + Type: types.EXECUTE_TX, + Data: nil, + Memo: "memo", + }, + false, + }, + { + "memo too large", + types.InterchainAccountPacketData{ + Type: types.EXECUTE_TX, + Data: []byte("data"), + Memo: largeMemo, + }, + false, + }, + } + + for _, tc := range testCases { + tc := tc + suite.Run(tc.name, func() { + suite.SetupTest() // reset + + err := tc.packetData.ValidateBasic() + + if tc.expPass { + suite.Require().NoError(err) + } else { + suite.Require().Error(err) + } + }) + } +} diff --git a/modules/apps/27-interchain-accounts/types/types.pb.go b/modules/apps/27-interchain-accounts/types/types.pb.go index 38aa8249c28..a4fad957f7f 100644 --- a/modules/apps/27-interchain-accounts/types/types.pb.go +++ b/modules/apps/27-interchain-accounts/types/types.pb.go @@ -50,52 +50,7 @@ func (Type) EnumDescriptor() ([]byte, []int) { return fileDescriptor_39bab93e18d89799, []int{0} } -// Body of a tx for an ics27 IBC packet -type IBCTxBody struct { - Messages []*types.Any `protobuf:"bytes,1,rep,name=messages,proto3" json:"messages,omitempty"` -} - -func (m *IBCTxBody) Reset() { *m = IBCTxBody{} } -func (m *IBCTxBody) String() string { return proto.CompactTextString(m) } -func (*IBCTxBody) ProtoMessage() {} -func (*IBCTxBody) Descriptor() ([]byte, []int) { - return fileDescriptor_39bab93e18d89799, []int{0} -} -func (m *IBCTxBody) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *IBCTxBody) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_IBCTxBody.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 *IBCTxBody) XXX_Merge(src proto.Message) { - xxx_messageInfo_IBCTxBody.Merge(m, src) -} -func (m *IBCTxBody) XXX_Size() int { - return m.Size() -} -func (m *IBCTxBody) XXX_DiscardUnknown() { - xxx_messageInfo_IBCTxBody.DiscardUnknown(m) -} - -var xxx_messageInfo_IBCTxBody proto.InternalMessageInfo - -func (m *IBCTxBody) GetMessages() []*types.Any { - if m != nil { - return m.Messages - } - return nil -} - -// InterchainAccountPacketData is comprised of araw transaction,type of transaction and optional memo field. +// InterchainAccountPacketData is comprised of a raw transaction, type of transaction and optional memo field. type InterchainAccountPacketData struct { Type Type `protobuf:"varint,1,opt,name=type,proto3,enum=ibc.applications.interchain_accounts.v1.Type" json:"type,omitempty"` Data []byte `protobuf:"bytes,2,opt,name=data,proto3" json:"data,omitempty"` @@ -106,7 +61,7 @@ func (m *InterchainAccountPacketData) Reset() { *m = InterchainAccountPa func (m *InterchainAccountPacketData) String() string { return proto.CompactTextString(m) } func (*InterchainAccountPacketData) ProtoMessage() {} func (*InterchainAccountPacketData) Descriptor() ([]byte, []int) { - return fileDescriptor_39bab93e18d89799, []int{1} + return fileDescriptor_39bab93e18d89799, []int{0} } func (m *InterchainAccountPacketData) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -156,10 +111,55 @@ func (m *InterchainAccountPacketData) GetMemo() string { return "" } +// CosmosTx contains a list of sdk.Msg's. It should be used when sending transactions to an SDK host chain. +type CosmosTx struct { + Messages []*types.Any `protobuf:"bytes,1,rep,name=messages,proto3" json:"messages,omitempty"` +} + +func (m *CosmosTx) Reset() { *m = CosmosTx{} } +func (m *CosmosTx) String() string { return proto.CompactTextString(m) } +func (*CosmosTx) ProtoMessage() {} +func (*CosmosTx) Descriptor() ([]byte, []int) { + return fileDescriptor_39bab93e18d89799, []int{1} +} +func (m *CosmosTx) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *CosmosTx) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_CosmosTx.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 *CosmosTx) XXX_Merge(src proto.Message) { + xxx_messageInfo_CosmosTx.Merge(m, src) +} +func (m *CosmosTx) XXX_Size() int { + return m.Size() +} +func (m *CosmosTx) XXX_DiscardUnknown() { + xxx_messageInfo_CosmosTx.DiscardUnknown(m) +} + +var xxx_messageInfo_CosmosTx proto.InternalMessageInfo + +func (m *CosmosTx) GetMessages() []*types.Any { + if m != nil { + return m.Messages + } + return nil +} + func init() { proto.RegisterEnum("ibc.applications.interchain_accounts.v1.Type", Type_name, Type_value) - proto.RegisterType((*IBCTxBody)(nil), "ibc.applications.interchain_accounts.v1.IBCTxBody") proto.RegisterType((*InterchainAccountPacketData)(nil), "ibc.applications.interchain_accounts.v1.InterchainAccountPacketData") + proto.RegisterType((*CosmosTx)(nil), "ibc.applications.interchain_accounts.v1.CosmosTx") } func init() { @@ -167,68 +167,31 @@ func init() { } var fileDescriptor_39bab93e18d89799 = []byte{ - // 380 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x91, 0xcf, 0xaa, 0xd3, 0x40, - 0x18, 0xc5, 0x33, 0xde, 0x20, 0xde, 0x51, 0x8a, 0x84, 0x2e, 0x62, 0x0a, 0x21, 0x74, 0x63, 0x10, - 0x32, 0x63, 0xd3, 0x85, 0xab, 0x2e, 0xfa, 0x27, 0x42, 0x36, 0x52, 0x62, 0x0a, 0xd5, 0x4d, 0x98, - 0x4c, 0xc7, 0x74, 0xb0, 0xc9, 0x84, 0xce, 0xa4, 0x98, 0x37, 0x28, 0xae, 0x7c, 0x01, 0x57, 0xbe, - 0x8c, 0xcb, 0x2e, 0x5d, 0x4a, 0xfb, 0x22, 0x92, 0x04, 0x5b, 0x17, 0x2e, 0xee, 0xee, 0xf0, 0xcd, - 0xfc, 0x0e, 0xdf, 0xf9, 0x0e, 0x1c, 0xf3, 0x94, 0x62, 0x52, 0x96, 0x3b, 0x4e, 0x89, 0xe2, 0xa2, - 0x90, 0x98, 0x17, 0x8a, 0xed, 0xe9, 0x96, 0xf0, 0x22, 0x21, 0x94, 0x8a, 0xaa, 0x50, 0x12, 0x1f, - 0x46, 0x58, 0xd5, 0x25, 0x93, 0xa8, 0xdc, 0x0b, 0x25, 0x8c, 0x97, 0x3c, 0xa5, 0xe8, 0x5f, 0x08, - 0xfd, 0x07, 0x42, 0x87, 0x91, 0xf5, 0x22, 0x13, 0x22, 0xdb, 0x31, 0xdc, 0x62, 0x69, 0xf5, 0x09, - 0x93, 0xa2, 0xee, 0x3c, 0xac, 0x7e, 0x26, 0x32, 0xd1, 0x4a, 0xdc, 0xa8, 0x6e, 0x3a, 0x9c, 0xc0, - 0xfb, 0x70, 0x36, 0x8f, 0xbf, 0xcc, 0xc4, 0xa6, 0x36, 0x5e, 0xc3, 0x27, 0x39, 0x93, 0x92, 0x64, - 0x4c, 0x9a, 0xc0, 0xb9, 0x73, 0x9f, 0xfa, 0x7d, 0xd4, 0x19, 0xa2, 0xbf, 0x86, 0x68, 0x5a, 0xd4, - 0xd1, 0xf5, 0xd7, 0xf0, 0x08, 0xe0, 0x20, 0xbc, 0xae, 0x32, 0xed, 0x36, 0x59, 0x12, 0xfa, 0x99, - 0xa9, 0x05, 0x51, 0xc4, 0x98, 0x42, 0xbd, 0xc9, 0x61, 0x02, 0x07, 0xb8, 0x3d, 0xdf, 0x43, 0x0f, - 0xcc, 0x81, 0xe2, 0xba, 0x64, 0x51, 0x8b, 0x1a, 0x06, 0xd4, 0x37, 0x44, 0x11, 0xf3, 0x91, 0x03, - 0xdc, 0x67, 0x51, 0xab, 0x9b, 0x59, 0xce, 0x72, 0x61, 0xde, 0x39, 0xc0, 0xbd, 0x8f, 0x5a, 0xfd, - 0x6a, 0x02, 0xf5, 0x86, 0x32, 0x30, 0x1c, 0xc4, 0x1f, 0x96, 0x41, 0x12, 0xac, 0x83, 0xf9, 0x2a, - 0x0e, 0x92, 0x78, 0x9d, 0xac, 0xde, 0xbd, 0x5f, 0x06, 0xf3, 0xf0, 0x6d, 0x18, 0x2c, 0x9e, 0x6b, - 0x56, 0xef, 0xeb, 0x77, 0x07, 0xde, 0x5e, 0x2d, 0xfd, 0xf8, 0xc3, 0xd6, 0x66, 0xc9, 0xcf, 0xb3, - 0x0d, 0x4e, 0x67, 0x1b, 0xfc, 0x3e, 0xdb, 0xe0, 0xdb, 0xc5, 0xd6, 0x4e, 0x17, 0x5b, 0xfb, 0x75, - 0xb1, 0xb5, 0x8f, 0x41, 0xc6, 0xd5, 0xb6, 0x4a, 0x11, 0x15, 0x39, 0xa6, 0x42, 0xe6, 0x42, 0x62, - 0x9e, 0x52, 0x2f, 0x13, 0xf8, 0xe0, 0xe3, 0x5c, 0x6c, 0xaa, 0x1d, 0x93, 0x4d, 0xa3, 0x12, 0xfb, - 0x6f, 0xbc, 0x5b, 0x1e, 0xef, 0x5a, 0x66, 0xdb, 0x64, 0xfa, 0xb8, 0x3d, 0xe1, 0xf8, 0x4f, 0x00, - 0x00, 0x00, 0xff, 0xff, 0x69, 0x0c, 0xd9, 0x88, 0x01, 0x02, 0x00, 0x00, -} - -func (m *IBCTxBody) 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 *IBCTxBody) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *IBCTxBody) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.Messages) > 0 { - for iNdEx := len(m.Messages) - 1; iNdEx >= 0; iNdEx-- { - { - size, err := m.Messages[iNdEx].MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintTypes(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0xa - } - } - return len(dAtA) - i, nil + // 376 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x91, 0x41, 0xeb, 0xd3, 0x30, + 0x18, 0xc6, 0x1b, 0xff, 0x45, 0x66, 0x94, 0x21, 0x65, 0x87, 0xda, 0x41, 0x29, 0xbb, 0x58, 0x84, + 0x26, 0xae, 0x3b, 0x78, 0xd1, 0xc3, 0xdc, 0x2a, 0xec, 0x22, 0xa3, 0x76, 0x30, 0xbd, 0x94, 0x34, + 0x8b, 0x5d, 0x70, 0x6d, 0xca, 0x92, 0x0e, 0xfb, 0x0d, 0x86, 0x27, 0xbf, 0x80, 0x27, 0xbf, 0x8c, + 0xc7, 0x1d, 0x3d, 0xca, 0xf6, 0x45, 0xa4, 0x29, 0x6e, 0x1e, 0x3c, 0x78, 0x7b, 0x78, 0x93, 0xe7, + 0xc9, 0xef, 0xcd, 0x03, 0x27, 0x3c, 0xa3, 0x98, 0x54, 0xd5, 0x8e, 0x53, 0xa2, 0xb8, 0x28, 0x25, + 0xe6, 0xa5, 0x62, 0x7b, 0xba, 0x25, 0xbc, 0x4c, 0x09, 0xa5, 0xa2, 0x2e, 0x95, 0xc4, 0x87, 0x31, + 0x56, 0x4d, 0xc5, 0x24, 0xaa, 0xf6, 0x42, 0x09, 0xeb, 0x29, 0xcf, 0x28, 0xfa, 0xdb, 0x84, 0xfe, + 0x61, 0x42, 0x87, 0xb1, 0xf3, 0x24, 0x17, 0x22, 0xdf, 0x31, 0xac, 0x6d, 0x59, 0xfd, 0x11, 0x93, + 0xb2, 0xe9, 0x32, 0x9c, 0x41, 0x2e, 0x72, 0xa1, 0x25, 0x6e, 0x55, 0x37, 0x1d, 0x1d, 0x01, 0x1c, + 0x2e, 0xae, 0x59, 0xd3, 0x2e, 0x6a, 0x49, 0xe8, 0x27, 0xa6, 0xe6, 0x44, 0x11, 0x6b, 0x0a, 0xcd, + 0x16, 0xc4, 0x06, 0x1e, 0xf0, 0xfb, 0x61, 0x80, 0xfe, 0x13, 0x04, 0x25, 0x4d, 0xc5, 0x62, 0x6d, + 0xb5, 0x2c, 0x68, 0x6e, 0x88, 0x22, 0xf6, 0x3d, 0x0f, 0xf8, 0x8f, 0x62, 0xad, 0xdb, 0x59, 0xc1, + 0x0a, 0x61, 0xdf, 0x79, 0xc0, 0x7f, 0x10, 0x6b, 0x3d, 0x7a, 0x09, 0x7b, 0x33, 0x21, 0x0b, 0x21, + 0x93, 0xcf, 0xd6, 0x73, 0xd8, 0x2b, 0x98, 0x94, 0x24, 0x67, 0xd2, 0x06, 0xde, 0x9d, 0xff, 0x30, + 0x1c, 0xa0, 0x6e, 0x35, 0xf4, 0x67, 0x35, 0x34, 0x2d, 0x9b, 0xf8, 0x7a, 0xeb, 0xd9, 0x2b, 0x68, + 0xb6, 0x6f, 0x5a, 0x18, 0x0e, 0x93, 0xf7, 0xcb, 0x28, 0x8d, 0xd6, 0xd1, 0x6c, 0x95, 0x44, 0x69, + 0xb2, 0x4e, 0x57, 0x6f, 0xdf, 0x2d, 0xa3, 0xd9, 0xe2, 0xcd, 0x22, 0x9a, 0x3f, 0x36, 0x9c, 0xfe, + 0x97, 0x6f, 0x1e, 0xbc, 0x9d, 0x3a, 0xe6, 0xf1, 0xbb, 0x6b, 0xbc, 0x4e, 0x7f, 0x9c, 0x5d, 0x70, + 0x3a, 0xbb, 0xe0, 0xd7, 0xd9, 0x05, 0x5f, 0x2f, 0xae, 0x71, 0xba, 0xb8, 0xc6, 0xcf, 0x8b, 0x6b, + 0x7c, 0x88, 0x72, 0xae, 0xb6, 0x75, 0x86, 0xa8, 0x28, 0x30, 0xd5, 0x7c, 0x98, 0x67, 0x34, 0xc8, + 0x05, 0x3e, 0x84, 0xb8, 0x10, 0x9b, 0x7a, 0xc7, 0x64, 0x5b, 0xa8, 0xc4, 0xe1, 0x8b, 0xe0, 0xf6, + 0x1b, 0xc1, 0xb5, 0x4b, 0x5d, 0x64, 0x76, 0x5f, 0x73, 0x4f, 0x7e, 0x07, 0x00, 0x00, 0xff, 0xff, + 0x09, 0xbd, 0x2f, 0x2f, 0x00, 0x02, 0x00, 0x00, } func (m *InterchainAccountPacketData) Marshal() (dAtA []byte, err error) { @@ -273,6 +236,43 @@ func (m *InterchainAccountPacketData) MarshalToSizedBuffer(dAtA []byte) (int, er return len(dAtA) - i, nil } +func (m *CosmosTx) 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 *CosmosTx) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *CosmosTx) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Messages) > 0 { + for iNdEx := len(m.Messages) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Messages[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTypes(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + func encodeVarintTypes(dAtA []byte, offset int, v uint64) int { offset -= sovTypes(v) base := offset @@ -284,21 +284,6 @@ func encodeVarintTypes(dAtA []byte, offset int, v uint64) int { dAtA[offset] = uint8(v) return base } -func (m *IBCTxBody) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if len(m.Messages) > 0 { - for _, e := range m.Messages { - l = e.Size() - n += 1 + l + sovTypes(uint64(l)) - } - } - return n -} - func (m *InterchainAccountPacketData) Size() (n int) { if m == nil { return 0 @@ -319,13 +304,28 @@ func (m *InterchainAccountPacketData) Size() (n int) { return n } +func (m *CosmosTx) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Messages) > 0 { + for _, e := range m.Messages { + l = e.Size() + n += 1 + l + sovTypes(uint64(l)) + } + } + return n +} + func sovTypes(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } func sozTypes(x uint64) (n int) { return sovTypes(uint64((x << 1) ^ uint64((int64(x) >> 63)))) } -func (m *IBCTxBody) Unmarshal(dAtA []byte) error { +func (m *InterchainAccountPacketData) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -348,17 +348,36 @@ func (m *IBCTxBody) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: IBCTxBody: wiretype end group for non-group") + return fmt.Errorf("proto: InterchainAccountPacketData: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: IBCTxBody: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: InterchainAccountPacketData: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) + } + m.Type = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Type |= Type(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Messages", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Data", wireType) } - var msglen int + var byteLen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowTypes @@ -368,26 +387,58 @@ func (m *IBCTxBody) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + byteLen |= int(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + if byteLen < 0 { return ErrInvalidLengthTypes } - postIndex := iNdEx + msglen + postIndex := iNdEx + byteLen if postIndex < 0 { return ErrInvalidLengthTypes } if postIndex > l { return io.ErrUnexpectedEOF } - m.Messages = append(m.Messages, &types.Any{}) - if err := m.Messages[len(m.Messages)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err + m.Data = append(m.Data[:0], dAtA[iNdEx:postIndex]...) + if m.Data == nil { + m.Data = []byte{} } iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Memo", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Memo = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipTypes(dAtA[iNdEx:]) @@ -409,7 +460,7 @@ func (m *IBCTxBody) Unmarshal(dAtA []byte) error { } return nil } -func (m *InterchainAccountPacketData) Unmarshal(dAtA []byte) error { +func (m *CosmosTx) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -432,36 +483,17 @@ func (m *InterchainAccountPacketData) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: InterchainAccountPacketData: wiretype end group for non-group") + return fmt.Errorf("proto: CosmosTx: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: InterchainAccountPacketData: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: CosmosTx: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) - } - m.Type = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTypes - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.Type |= Type(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Data", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Messages", wireType) } - var byteLen int + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowTypes @@ -471,57 +503,25 @@ func (m *InterchainAccountPacketData) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - byteLen |= int(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - if byteLen < 0 { + if msglen < 0 { return ErrInvalidLengthTypes } - postIndex := iNdEx + byteLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthTypes } if postIndex > l { return io.ErrUnexpectedEOF } - m.Data = append(m.Data[:0], dAtA[iNdEx:postIndex]...) - if m.Data == nil { - m.Data = []byte{} - } - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Memo", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTypes - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthTypes - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthTypes - } - if postIndex > l { - return io.ErrUnexpectedEOF + m.Messages = append(m.Messages, &types.Any{}) + if err := m.Messages[len(m.Messages)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err } - m.Memo = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex diff --git a/proto/ibc/applications/interchain_accounts/v1/types.proto b/proto/ibc/applications/interchain_accounts/v1/types.proto index 758c2539072..b8f3683ba44 100644 --- a/proto/ibc/applications/interchain_accounts/v1/types.proto +++ b/proto/ibc/applications/interchain_accounts/v1/types.proto @@ -5,11 +5,6 @@ import "google/protobuf/any.proto"; import "gogoproto/gogo.proto"; option go_package = "github.com/cosmos/ibc-go/v2/modules/apps/27-interchain-accounts/types"; -// Body of a tx for an ics27 IBC packet -message IBCTxBody { - repeated google.protobuf.Any messages = 1; -} - // The different types of interchain account transactions // EXECUTE_TX is used when sending a TX from the controller side to the host side. The host side will execute the tx on // behalf of the interchain account. @@ -25,3 +20,9 @@ message InterchainAccountPacketData { bytes data = 2; string memo = 3; } + +// CosmosTx contains a list of sdk.Msg's. It should be used when sending transactions to an SDK host chain. +message CosmosTx { + repeated google.protobuf.Any messages = 1; +} +