From d0677078c3542152be8f04e4eebc82d177e85b7c Mon Sep 17 00:00:00 2001 From: Damian Nolan Date: Wed, 26 Oct 2022 15:19:26 +0200 Subject: [PATCH] refactor: adapting transfer metadata bytes field to memo string (#2595) * adapting transfer metadata bytes field to memo string * updating changelog (cherry picked from commit 05685b3f1bb4241ec04c4768dbb7152273f83a96) # Conflicts: # CHANGELOG.md # docs/ibc/proto-docs.md # go.mod # go.sum # modules/apps/29-fee/transfer_test.go # modules/apps/transfer/client/cli/tx.go # modules/apps/transfer/ibc_module.go # modules/apps/transfer/keeper/mbt_relay_test.go # modules/apps/transfer/keeper/msg_server_test.go # modules/apps/transfer/keeper/relay.go # modules/apps/transfer/keeper/relay_test.go # modules/apps/transfer/transfer_test.go # modules/apps/transfer/types/msgs.go # modules/apps/transfer/types/msgs_test.go # modules/apps/transfer/types/packet.go # modules/apps/transfer/types/packet.pb.go # modules/apps/transfer/types/packet_test.go # modules/apps/transfer/types/tx.pb.go --- CHANGELOG.md | 6 + docs/ibc/proto-docs.md | 1269 +++++++++++++++++ go.mod | 4 + go.sum | 5 + modules/apps/29-fee/transfer_test.go | 70 + modules/apps/transfer/client/cli/tx.go | 10 +- modules/apps/transfer/ibc_module.go | 296 ++++ .../apps/transfer/keeper/mbt_relay_test.go | 14 + modules/apps/transfer/keeper/msg_server.go | 2 +- .../apps/transfer/keeper/msg_server_test.go | 11 + modules/apps/transfer/keeper/relay.go | 6 +- modules/apps/transfer/keeper/relay_test.go | 92 +- modules/apps/transfer/transfer_test.go | 21 + modules/apps/transfer/types/events.go | 2 +- modules/apps/transfer/types/msgs.go | 8 + modules/apps/transfer/types/msgs_test.go | 29 + modules/apps/transfer/types/packet.go | 8 + modules/apps/transfer/types/packet.pb.go | 56 +- modules/apps/transfer/types/packet_test.go | 13 + modules/apps/transfer/types/tx.pb.go | 67 +- proto/ibc/applications/transfer/v1/tx.proto | 4 +- .../ibc/applications/transfer/v2/packet.proto | 4 +- 22 files changed, 1946 insertions(+), 51 deletions(-) create mode 100644 modules/apps/29-fee/transfer_test.go create mode 100644 modules/apps/transfer/ibc_module.go diff --git a/CHANGELOG.md b/CHANGELOG.md index 2da253f0bed..ea43d29bae5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -48,7 +48,13 @@ Ref: https://keepachangelog.com/en/1.0.0/ ### Features +<<<<<<< HEAD * (apps/transfer) [\#2305](https://github.com/cosmos/ibc-go/pull/2305) Added optional metadata field to `FungibleTokenPacketData` and `MsgTransfer`. +======= +* (apps/27-interchain-accounts) [\#2147](https://github.com/cosmos/ibc-go/pull/2147) Adding a `SubmitTx` gRPC endpoint for the ICS27 Controller module which allows owners of interchain accounts to submit transactions. This replaces the previously existing need for authentication modules to implement this standard functionality. +* (testing/simapp) [\#2190](https://github.com/cosmos/ibc-go/pull/2190) Adding the new `x/group` cosmos-sdk module to simapp. +* (apps/transfer) [\#2595](https://github.com/cosmos/ibc-go/pull/2595) Adding optional memo field to `FungibleTokenPacketData` and `MsgTransfer`. +>>>>>>> 05685b3 (refactor: adapting transfer metadata bytes field to memo string (#2595)) ### Bug Fixes diff --git a/docs/ibc/proto-docs.md b/docs/ibc/proto-docs.md index 881a5e4bc07..2fe2261204d 100644 --- a/docs/ibc/proto-docs.md +++ b/docs/ibc/proto-docs.md @@ -889,11 +889,1270 @@ Packet defines a type that carries data across different chains through IBC +<<<<<<< HEAD ### PacketState PacketState defines the generic type necessary to retrieve and store packet commitments, acknowledgements, and receipts. Caller is responsible for knowing the context necessary to interpret this state as a commitment, acknowledgement, or a receipt. +======= +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `fee_enabled` | [bool](#bool) | | boolean flag representing the fee enabled channel status | + + + + + + + + +### QueryFeeEnabledChannelsRequest +QueryFeeEnabledChannelsRequest defines the request type for the FeeEnabledChannels rpc + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `pagination` | [cosmos.base.query.v1beta1.PageRequest](#cosmos.base.query.v1beta1.PageRequest) | | pagination defines an optional pagination for the request. | +| `query_height` | [uint64](#uint64) | | block height at which to query | + + + + + + + + +### QueryFeeEnabledChannelsResponse +QueryFeeEnabledChannelsResponse defines the response type for the FeeEnabledChannels rpc + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `fee_enabled_channels` | [FeeEnabledChannel](#ibc.applications.fee.v1.FeeEnabledChannel) | repeated | list of fee enabled channels | + + + + + + + + +### QueryIncentivizedPacketRequest +QueryIncentivizedPacketRequest defines the request type for the IncentivizedPacket rpc + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `packet_id` | [ibc.core.channel.v1.PacketId](#ibc.core.channel.v1.PacketId) | | unique packet identifier comprised of channel ID, port ID and sequence | +| `query_height` | [uint64](#uint64) | | block height at which to query | + + + + + + + + +### QueryIncentivizedPacketResponse +QueryIncentivizedPacketsResponse defines the response type for the IncentivizedPacket rpc + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `incentivized_packet` | [IdentifiedPacketFees](#ibc.applications.fee.v1.IdentifiedPacketFees) | | the identified fees for the incentivized packet | + + + + + + + + +### QueryIncentivizedPacketsForChannelRequest +QueryIncentivizedPacketsForChannelRequest defines the request type for querying for all incentivized packets +for a specific channel + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `pagination` | [cosmos.base.query.v1beta1.PageRequest](#cosmos.base.query.v1beta1.PageRequest) | | pagination defines an optional pagination for the request. | +| `port_id` | [string](#string) | | | +| `channel_id` | [string](#string) | | | +| `query_height` | [uint64](#uint64) | | Height to query at | + + + + + + + + +### QueryIncentivizedPacketsForChannelResponse +QueryIncentivizedPacketsResponse defines the response type for the incentivized packets RPC + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `incentivized_packets` | [IdentifiedPacketFees](#ibc.applications.fee.v1.IdentifiedPacketFees) | repeated | Map of all incentivized_packets | + + + + + + + + +### QueryIncentivizedPacketsRequest +QueryIncentivizedPacketsRequest defines the request type for the IncentivizedPackets rpc + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `pagination` | [cosmos.base.query.v1beta1.PageRequest](#cosmos.base.query.v1beta1.PageRequest) | | pagination defines an optional pagination for the request. | +| `query_height` | [uint64](#uint64) | | block height at which to query | + + + + + + + + +### QueryIncentivizedPacketsResponse +QueryIncentivizedPacketsResponse defines the response type for the IncentivizedPackets rpc + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `incentivized_packets` | [IdentifiedPacketFees](#ibc.applications.fee.v1.IdentifiedPacketFees) | repeated | list of identified fees for incentivized packets | + + + + + + + + +### QueryPayeeRequest +QueryPayeeRequest defines the request type for the Payee rpc + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `channel_id` | [string](#string) | | unique channel identifier | +| `relayer` | [string](#string) | | the relayer address to which the distribution address is registered | + + + + + + + + +### QueryPayeeResponse +QueryPayeeResponse defines the response type for the Payee rpc + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `payee_address` | [string](#string) | | the payee address to which packet fees are paid out | + + + + + + + + +### QueryTotalAckFeesRequest +QueryTotalAckFeesRequest defines the request type for the TotalAckFees rpc + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `packet_id` | [ibc.core.channel.v1.PacketId](#ibc.core.channel.v1.PacketId) | | the packet identifier for the associated fees | + + + + + + + + +### QueryTotalAckFeesResponse +QueryTotalAckFeesResponse defines the response type for the TotalAckFees rpc + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `ack_fees` | [cosmos.base.v1beta1.Coin](#cosmos.base.v1beta1.Coin) | repeated | the total packet acknowledgement fees | + + + + + + + + +### QueryTotalRecvFeesRequest +QueryTotalRecvFeesRequest defines the request type for the TotalRecvFees rpc + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `packet_id` | [ibc.core.channel.v1.PacketId](#ibc.core.channel.v1.PacketId) | | the packet identifier for the associated fees | + + + + + + + + +### QueryTotalRecvFeesResponse +QueryTotalRecvFeesResponse defines the response type for the TotalRecvFees rpc + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `recv_fees` | [cosmos.base.v1beta1.Coin](#cosmos.base.v1beta1.Coin) | repeated | the total packet receive fees | + + + + + + + + +### QueryTotalTimeoutFeesRequest +QueryTotalTimeoutFeesRequest defines the request type for the TotalTimeoutFees rpc + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `packet_id` | [ibc.core.channel.v1.PacketId](#ibc.core.channel.v1.PacketId) | | the packet identifier for the associated fees | + + + + + + + + +### QueryTotalTimeoutFeesResponse +QueryTotalTimeoutFeesResponse defines the response type for the TotalTimeoutFees rpc + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `timeout_fees` | [cosmos.base.v1beta1.Coin](#cosmos.base.v1beta1.Coin) | repeated | the total packet timeout fees | + + + + + + + + + + + + + + +### Query +Query defines the ICS29 gRPC querier service. + +| Method Name | Request Type | Response Type | Description | HTTP Verb | Endpoint | +| ----------- | ------------ | ------------- | ------------| ------- | -------- | +| `IncentivizedPackets` | [QueryIncentivizedPacketsRequest](#ibc.applications.fee.v1.QueryIncentivizedPacketsRequest) | [QueryIncentivizedPacketsResponse](#ibc.applications.fee.v1.QueryIncentivizedPacketsResponse) | IncentivizedPackets returns all incentivized packets and their associated fees | GET|/ibc/apps/fee/v1/incentivized_packets| +| `IncentivizedPacket` | [QueryIncentivizedPacketRequest](#ibc.applications.fee.v1.QueryIncentivizedPacketRequest) | [QueryIncentivizedPacketResponse](#ibc.applications.fee.v1.QueryIncentivizedPacketResponse) | IncentivizedPacket returns all packet fees for a packet given its identifier | GET|/ibc/apps/fee/v1/channels/{packet_id.channel_id}/ports/{packet_id.port_id}/sequences/{packet_id.sequence}/incentivized_packet| +| `IncentivizedPacketsForChannel` | [QueryIncentivizedPacketsForChannelRequest](#ibc.applications.fee.v1.QueryIncentivizedPacketsForChannelRequest) | [QueryIncentivizedPacketsForChannelResponse](#ibc.applications.fee.v1.QueryIncentivizedPacketsForChannelResponse) | Gets all incentivized packets for a specific channel | GET|/ibc/apps/fee/v1/channels/{channel_id}/ports/{port_id}/incentivized_packets| +| `TotalRecvFees` | [QueryTotalRecvFeesRequest](#ibc.applications.fee.v1.QueryTotalRecvFeesRequest) | [QueryTotalRecvFeesResponse](#ibc.applications.fee.v1.QueryTotalRecvFeesResponse) | TotalRecvFees returns the total receive fees for a packet given its identifier | GET|/ibc/apps/fee/v1/channels/{packet_id.channel_id}/ports/{packet_id.port_id}/sequences/{packet_id.sequence}/total_recv_fees| +| `TotalAckFees` | [QueryTotalAckFeesRequest](#ibc.applications.fee.v1.QueryTotalAckFeesRequest) | [QueryTotalAckFeesResponse](#ibc.applications.fee.v1.QueryTotalAckFeesResponse) | TotalAckFees returns the total acknowledgement fees for a packet given its identifier | GET|/ibc/apps/fee/v1/channels/{packet_id.channel_id}/ports/{packet_id.port_id}/sequences/{packet_id.sequence}/total_ack_fees| +| `TotalTimeoutFees` | [QueryTotalTimeoutFeesRequest](#ibc.applications.fee.v1.QueryTotalTimeoutFeesRequest) | [QueryTotalTimeoutFeesResponse](#ibc.applications.fee.v1.QueryTotalTimeoutFeesResponse) | TotalTimeoutFees returns the total timeout fees for a packet given its identifier | GET|/ibc/apps/fee/v1/channels/{packet_id.channel_id}/ports/{packet_id.port_id}/sequences/{packet_id.sequence}/total_timeout_fees| +| `Payee` | [QueryPayeeRequest](#ibc.applications.fee.v1.QueryPayeeRequest) | [QueryPayeeResponse](#ibc.applications.fee.v1.QueryPayeeResponse) | Payee returns the registered payee address for a specific channel given the relayer address | GET|/ibc/apps/fee/v1/channels/{channel_id}/relayers/{relayer}/payee| +| `CounterpartyPayee` | [QueryCounterpartyPayeeRequest](#ibc.applications.fee.v1.QueryCounterpartyPayeeRequest) | [QueryCounterpartyPayeeResponse](#ibc.applications.fee.v1.QueryCounterpartyPayeeResponse) | CounterpartyPayee returns the registered counterparty payee for forward relaying | GET|/ibc/apps/fee/v1/channels/{channel_id}/relayers/{relayer}/counterparty_payee| +| `FeeEnabledChannels` | [QueryFeeEnabledChannelsRequest](#ibc.applications.fee.v1.QueryFeeEnabledChannelsRequest) | [QueryFeeEnabledChannelsResponse](#ibc.applications.fee.v1.QueryFeeEnabledChannelsResponse) | FeeEnabledChannels returns a list of all fee enabled channels | GET|/ibc/apps/fee/v1/fee_enabled| +| `FeeEnabledChannel` | [QueryFeeEnabledChannelRequest](#ibc.applications.fee.v1.QueryFeeEnabledChannelRequest) | [QueryFeeEnabledChannelResponse](#ibc.applications.fee.v1.QueryFeeEnabledChannelResponse) | FeeEnabledChannel returns true if the provided port and channel identifiers belong to a fee enabled channel | GET|/ibc/apps/fee/v1/channels/{channel_id}/ports/{port_id}/fee_enabled| + + + + + + +

Top

+ +## ibc/applications/fee/v1/tx.proto + + + + + +### MsgPayPacketFee +MsgPayPacketFee defines the request type for the PayPacketFee rpc +This Msg can be used to pay for a packet at the next sequence send & should be combined with the Msg that will be +paid for + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `fee` | [Fee](#ibc.applications.fee.v1.Fee) | | fee encapsulates the recv, ack and timeout fees associated with an IBC packet | +| `source_port_id` | [string](#string) | | the source port unique identifier | +| `source_channel_id` | [string](#string) | | the source channel unique identifer | +| `signer` | [string](#string) | | account address to refund fee if necessary | +| `relayers` | [string](#string) | repeated | optional list of relayers permitted to the receive packet fees | + + + + + + + + +### MsgPayPacketFeeAsync +MsgPayPacketFeeAsync defines the request type for the PayPacketFeeAsync rpc +This Msg can be used to pay for a packet at a specified sequence (instead of the next sequence send) + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `packet_id` | [ibc.core.channel.v1.PacketId](#ibc.core.channel.v1.PacketId) | | unique packet identifier comprised of the channel ID, port ID and sequence | +| `packet_fee` | [PacketFee](#ibc.applications.fee.v1.PacketFee) | | the packet fee associated with a particular IBC packet | + + + + + + + + +### MsgPayPacketFeeAsyncResponse +MsgPayPacketFeeAsyncResponse defines the response type for the PayPacketFeeAsync rpc + + + + + + + + +### MsgPayPacketFeeResponse +MsgPayPacketFeeResponse defines the response type for the PayPacketFee rpc + + + + + + + + +### MsgRegisterCounterpartyPayee +MsgRegisterCounterpartyPayee defines the request type for the RegisterCounterpartyPayee rpc + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `port_id` | [string](#string) | | unique port identifier | +| `channel_id` | [string](#string) | | unique channel identifier | +| `relayer` | [string](#string) | | the relayer address | +| `counterparty_payee` | [string](#string) | | the counterparty payee address | + + + + + + + + +### MsgRegisterCounterpartyPayeeResponse +MsgRegisterCounterpartyPayeeResponse defines the response type for the RegisterCounterpartyPayee rpc + + + + + + + + +### MsgRegisterPayee +MsgRegisterPayee defines the request type for the RegisterPayee rpc + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `port_id` | [string](#string) | | unique port identifier | +| `channel_id` | [string](#string) | | unique channel identifier | +| `relayer` | [string](#string) | | the relayer address | +| `payee` | [string](#string) | | the payee address | + + + + + + + + +### MsgRegisterPayeeResponse +MsgRegisterPayeeResponse defines the response type for the RegisterPayee rpc + + + + + + + + + + + + + + +### Msg +Msg defines the ICS29 Msg service. + +| Method Name | Request Type | Response Type | Description | HTTP Verb | Endpoint | +| ----------- | ------------ | ------------- | ------------| ------- | -------- | +| `RegisterPayee` | [MsgRegisterPayee](#ibc.applications.fee.v1.MsgRegisterPayee) | [MsgRegisterPayeeResponse](#ibc.applications.fee.v1.MsgRegisterPayeeResponse) | RegisterPayee defines a rpc handler method for MsgRegisterPayee RegisterPayee is called by the relayer on each channelEnd and allows them to set an optional payee to which reverse and timeout relayer packet fees will be paid out. The payee should be registered on the source chain from which packets originate as this is where fee distribution takes place. This function may be called more than once by a relayer, in which case, the latest payee is always used. | | +| `RegisterCounterpartyPayee` | [MsgRegisterCounterpartyPayee](#ibc.applications.fee.v1.MsgRegisterCounterpartyPayee) | [MsgRegisterCounterpartyPayeeResponse](#ibc.applications.fee.v1.MsgRegisterCounterpartyPayeeResponse) | RegisterCounterpartyPayee defines a rpc handler method for MsgRegisterCounterpartyPayee RegisterCounterpartyPayee is called by the relayer on each channelEnd and allows them to specify the counterparty payee address before relaying. This ensures they will be properly compensated for forward relaying since the destination chain must include the registered counterparty payee address in the acknowledgement. This function may be called more than once by a relayer, in which case, the latest counterparty payee address is always used. | | +| `PayPacketFee` | [MsgPayPacketFee](#ibc.applications.fee.v1.MsgPayPacketFee) | [MsgPayPacketFeeResponse](#ibc.applications.fee.v1.MsgPayPacketFeeResponse) | PayPacketFee defines a rpc handler method for MsgPayPacketFee PayPacketFee is an open callback that may be called by any module/user that wishes to escrow funds in order to incentivize the relaying of the packet at the next sequence NOTE: This method is intended to be used within a multi msg transaction, where the subsequent msg that follows initiates the lifecycle of the incentivized packet | | +| `PayPacketFeeAsync` | [MsgPayPacketFeeAsync](#ibc.applications.fee.v1.MsgPayPacketFeeAsync) | [MsgPayPacketFeeAsyncResponse](#ibc.applications.fee.v1.MsgPayPacketFeeAsyncResponse) | PayPacketFeeAsync defines a rpc handler method for MsgPayPacketFeeAsync PayPacketFeeAsync is an open callback that may be called by any module/user that wishes to escrow funds in order to incentivize the relaying of a known packet (i.e. at a particular sequence) | | + + + + + + +

Top

+ +## ibc/applications/interchain_accounts/controller/v1/controller.proto + + + + + +### Params +Params defines the set of on-chain interchain accounts parameters. +The following parameters may be used to disable the controller submodule. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `controller_enabled` | [bool](#bool) | | controller_enabled enables or disables the controller submodule. | + + + + + + + + + + + + + + + + +

Top

+ +## ibc/applications/interchain_accounts/controller/v1/query.proto + + + + + +### QueryInterchainAccountRequest +QueryInterchainAccountRequest is the request type for the Query/InterchainAccount RPC method. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `owner` | [string](#string) | | | +| `connection_id` | [string](#string) | | | + + + + + + + + +### QueryInterchainAccountResponse +QueryInterchainAccountResponse the response type for the Query/InterchainAccount RPC method. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `address` | [string](#string) | | | + + + + + + + + +### QueryParamsRequest +QueryParamsRequest is the request type for the Query/Params RPC method. + + + + + + + + +### QueryParamsResponse +QueryParamsResponse is the response type for the Query/Params RPC method. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `params` | [Params](#ibc.applications.interchain_accounts.controller.v1.Params) | | params defines the parameters of the module. | + + + + + + + + + + + + + + +### Query +Query provides defines the gRPC querier service. + +| Method Name | Request Type | Response Type | Description | HTTP Verb | Endpoint | +| ----------- | ------------ | ------------- | ------------| ------- | -------- | +| `InterchainAccount` | [QueryInterchainAccountRequest](#ibc.applications.interchain_accounts.controller.v1.QueryInterchainAccountRequest) | [QueryInterchainAccountResponse](#ibc.applications.interchain_accounts.controller.v1.QueryInterchainAccountResponse) | InterchainAccount returns the interchain account address for a given owner address on a given connection | GET|/ibc/apps/interchain_accounts/controller/v1/owners/{owner}/connections/{connection_id}| +| `Params` | [QueryParamsRequest](#ibc.applications.interchain_accounts.controller.v1.QueryParamsRequest) | [QueryParamsResponse](#ibc.applications.interchain_accounts.controller.v1.QueryParamsResponse) | Params queries all parameters of the ICA controller submodule. | GET|/ibc/apps/interchain_accounts/controller/v1/params| + + + + + + +

Top

+ +## ibc/applications/interchain_accounts/v1/packet.proto + + + + + +### 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 | +| ----- | ---- | ----- | ----------- | +| `messages` | [google.protobuf.Any](#google.protobuf.Any) | repeated | | + + + + + + + + +### InterchainAccountPacketData +InterchainAccountPacketData is comprised of a raw transaction, type of transaction and optional memo field. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `type` | [Type](#ibc.applications.interchain_accounts.v1.Type) | | | +| `data` | [bytes](#bytes) | | | +| `memo` | [string](#string) | | | + + + + + + + + + + +### Type +Type defines a classification of message issued from a controller chain to its associated interchain accounts +host + +| Name | Number | Description | +| ---- | ------ | ----------- | +| TYPE_UNSPECIFIED | 0 | Default zero value enumeration | +| TYPE_EXECUTE_TX | 1 | Execute a transaction on an interchain accounts host chain | + + + + + + + + + + + +

Top

+ +## ibc/applications/interchain_accounts/controller/v1/tx.proto + + + + + +### MsgRegisterInterchainAccount +MsgRegisterInterchainAccount defines the payload for Msg/RegisterAccount + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `owner` | [string](#string) | | | +| `connection_id` | [string](#string) | | | +| `version` | [string](#string) | | | + + + + + + + + +### MsgRegisterInterchainAccountResponse +MsgRegisterInterchainAccountResponse defines the response for Msg/RegisterAccount + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `channel_id` | [string](#string) | | | + + + + + + + + +### MsgSendTx +MsgSendTx defines the payload for Msg/SendTx + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `owner` | [string](#string) | | | +| `connection_id` | [string](#string) | | | +| `packet_data` | [ibc.applications.interchain_accounts.v1.InterchainAccountPacketData](#ibc.applications.interchain_accounts.v1.InterchainAccountPacketData) | | | +| `relative_timeout` | [uint64](#uint64) | | Relative timeout timestamp provided will be added to the current block time during transaction execution. The timeout timestamp must be non-zero. | + + + + + + + + +### MsgSendTxResponse +MsgSendTxResponse defines the response for MsgSendTx + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `sequence` | [uint64](#uint64) | | | + + + + + + + + + + + + + + +### Msg +Msg defines the 27-interchain-accounts/controller Msg service. + +| Method Name | Request Type | Response Type | Description | HTTP Verb | Endpoint | +| ----------- | ------------ | ------------- | ------------| ------- | -------- | +| `RegisterInterchainAccount` | [MsgRegisterInterchainAccount](#ibc.applications.interchain_accounts.controller.v1.MsgRegisterInterchainAccount) | [MsgRegisterInterchainAccountResponse](#ibc.applications.interchain_accounts.controller.v1.MsgRegisterInterchainAccountResponse) | RegisterInterchainAccount defines a rpc handler for MsgRegisterInterchainAccount. | | +| `SendTx` | [MsgSendTx](#ibc.applications.interchain_accounts.controller.v1.MsgSendTx) | [MsgSendTxResponse](#ibc.applications.interchain_accounts.controller.v1.MsgSendTxResponse) | SendTx defines a rpc handler for MsgSendTx. | | + + + + + + +

Top

+ +## ibc/applications/interchain_accounts/host/v1/host.proto + + + + + +### Params +Params defines the set of on-chain interchain accounts parameters. +The following parameters may be used to disable the host submodule. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `host_enabled` | [bool](#bool) | | host_enabled enables or disables the host submodule. | +| `allow_messages` | [string](#string) | repeated | allow_messages defines a list of sdk message typeURLs allowed to be executed on a host chain. | + + + + + + + + + + + + + + + + +

Top

+ +## ibc/applications/interchain_accounts/genesis/v1/genesis.proto + + + + + +### ActiveChannel +ActiveChannel contains a connection ID, port ID and associated active channel ID, as well as a boolean flag to +indicate if the channel is middleware enabled + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `connection_id` | [string](#string) | | | +| `port_id` | [string](#string) | | | +| `channel_id` | [string](#string) | | | +| `is_middleware_enabled` | [bool](#bool) | | | + + + + + + + + +### ControllerGenesisState +ControllerGenesisState defines the interchain accounts controller genesis state + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `active_channels` | [ActiveChannel](#ibc.applications.interchain_accounts.genesis.v1.ActiveChannel) | repeated | | +| `interchain_accounts` | [RegisteredInterchainAccount](#ibc.applications.interchain_accounts.genesis.v1.RegisteredInterchainAccount) | repeated | | +| `ports` | [string](#string) | repeated | | +| `params` | [ibc.applications.interchain_accounts.controller.v1.Params](#ibc.applications.interchain_accounts.controller.v1.Params) | | | + + + + + + + + +### GenesisState +GenesisState defines the interchain accounts genesis state + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `controller_genesis_state` | [ControllerGenesisState](#ibc.applications.interchain_accounts.genesis.v1.ControllerGenesisState) | | | +| `host_genesis_state` | [HostGenesisState](#ibc.applications.interchain_accounts.genesis.v1.HostGenesisState) | | | + + + + + + + + +### HostGenesisState +HostGenesisState defines the interchain accounts host genesis state + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `active_channels` | [ActiveChannel](#ibc.applications.interchain_accounts.genesis.v1.ActiveChannel) | repeated | | +| `interchain_accounts` | [RegisteredInterchainAccount](#ibc.applications.interchain_accounts.genesis.v1.RegisteredInterchainAccount) | repeated | | +| `port` | [string](#string) | | | +| `params` | [ibc.applications.interchain_accounts.host.v1.Params](#ibc.applications.interchain_accounts.host.v1.Params) | | | + + + + + + + + +### RegisteredInterchainAccount +RegisteredInterchainAccount contains a connection ID, port ID and associated interchain account address + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `connection_id` | [string](#string) | | | +| `port_id` | [string](#string) | | | +| `account_address` | [string](#string) | | | + + + + + + + + + + + + + + + + +

Top

+ +## ibc/applications/interchain_accounts/host/v1/query.proto + + + + + +### QueryParamsRequest +QueryParamsRequest is the request type for the Query/Params RPC method. + + + + + + + + +### QueryParamsResponse +QueryParamsResponse is the response type for the Query/Params RPC method. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `params` | [Params](#ibc.applications.interchain_accounts.host.v1.Params) | | params defines the parameters of the module. | + + + + + + + + + + + + + + +### Query +Query provides defines the gRPC querier service. + +| Method Name | Request Type | Response Type | Description | HTTP Verb | Endpoint | +| ----------- | ------------ | ------------- | ------------| ------- | -------- | +| `Params` | [QueryParamsRequest](#ibc.applications.interchain_accounts.host.v1.QueryParamsRequest) | [QueryParamsResponse](#ibc.applications.interchain_accounts.host.v1.QueryParamsResponse) | Params queries all parameters of the ICA host submodule. | GET|/ibc/apps/interchain_accounts/host/v1/params| + + + + + + +

Top

+ +## ibc/applications/interchain_accounts/v1/account.proto + + + + + +### InterchainAccount +An InterchainAccount is defined as a BaseAccount & the address of the account owner on the controller chain + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `base_account` | [cosmos.auth.v1beta1.BaseAccount](#cosmos.auth.v1beta1.BaseAccount) | | | +| `account_owner` | [string](#string) | | | + + + + + + + + + + + + + + + + +

Top

+ +## ibc/applications/interchain_accounts/v1/metadata.proto + + + + + +### Metadata +Metadata defines a set of protocol specific data encoded into the ICS27 channel version bytestring +See ICS004: https://github.com/cosmos/ibc/tree/master/spec/core/ics-004-channel-and-packet-semantics#Versioning + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `version` | [string](#string) | | version defines the ICS27 protocol version | +| `controller_connection_id` | [string](#string) | | controller_connection_id is the connection identifier associated with the controller chain | +| `host_connection_id` | [string](#string) | | host_connection_id is the connection identifier associated with the host chain | +| `address` | [string](#string) | | address defines the interchain account address to be fulfilled upon the OnChanOpenTry handshake step NOTE: the address field is empty on the OnChanOpenInit handshake step | +| `encoding` | [string](#string) | | encoding defines the supported codec format | +| `tx_type` | [string](#string) | | tx_type defines the type of transactions the interchain account can execute | + + + + + + + + + + + + + + + + +

Top

+ +## ibc/applications/transfer/v1/transfer.proto + + + + + +### DenomTrace +DenomTrace contains the base denomination for ICS20 fungible tokens and the +source tracing information path. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `path` | [string](#string) | | path defines the chain of port/channel identifiers used for tracing the source of the fungible token. | +| `base_denom` | [string](#string) | | base denomination of the relayed fungible token. | + + + + + + + + +### Params +Params defines the set of IBC transfer parameters. +NOTE: To prevent a single token from being transferred, set the +TransfersEnabled parameter to true and then set the bank module's SendEnabled +parameter for the denomination to false. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `send_enabled` | [bool](#bool) | | send_enabled enables or disables all cross-chain token transfers from this chain. | +| `receive_enabled` | [bool](#bool) | | receive_enabled enables or disables all cross-chain token transfers to this chain. | + + + + + + + + + + + + + + + + +

Top

+ +## ibc/applications/transfer/v1/genesis.proto + + + + + +### GenesisState +GenesisState defines the ibc-transfer genesis state + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `port_id` | [string](#string) | | | +| `denom_traces` | [DenomTrace](#ibc.applications.transfer.v1.DenomTrace) | repeated | | +| `params` | [Params](#ibc.applications.transfer.v1.Params) | | | + + + + + + + + + + + + + + + + +

Top

+ +## ibc/applications/transfer/v1/query.proto + + + + + +### QueryDenomHashRequest +QueryDenomHashRequest is the request type for the Query/DenomHash RPC +method + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `trace` | [string](#string) | | The denomination trace ([port_id]/[channel_id])+/[denom] | + + + + + + + + +### QueryDenomHashResponse +QueryDenomHashResponse is the response type for the Query/DenomHash RPC +method. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `hash` | [string](#string) | | hash (in hex format) of the denomination trace information. | + + + + + + + + +### QueryDenomTraceRequest +QueryDenomTraceRequest is the request type for the Query/DenomTrace RPC +method + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `hash` | [string](#string) | | hash (in hex format) or denom (full denom with ibc prefix) of the denomination trace information. | + + + + + + + + +### QueryDenomTraceResponse +QueryDenomTraceResponse is the response type for the Query/DenomTrace RPC +method. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `denom_trace` | [DenomTrace](#ibc.applications.transfer.v1.DenomTrace) | | denom_trace returns the requested denomination trace information. | + + + + + + + + +### QueryDenomTracesRequest +QueryConnectionsRequest is the request type for the Query/DenomTraces RPC +method + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `pagination` | [cosmos.base.query.v1beta1.PageRequest](#cosmos.base.query.v1beta1.PageRequest) | | pagination defines an optional pagination for the request. | + + + + + + + + +### QueryDenomTracesResponse +QueryConnectionsResponse is the response type for the Query/DenomTraces RPC +method. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `denom_traces` | [DenomTrace](#ibc.applications.transfer.v1.DenomTrace) | repeated | denom_traces returns all denominations trace information. | +| `pagination` | [cosmos.base.query.v1beta1.PageResponse](#cosmos.base.query.v1beta1.PageResponse) | | pagination defines the pagination in the response. | + + + + + + + + +### QueryEscrowAddressRequest +QueryEscrowAddressRequest is the request type for the EscrowAddress RPC method. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `port_id` | [string](#string) | | unique port identifier | +| `channel_id` | [string](#string) | | unique channel identifier | + + + + + + + + +### QueryEscrowAddressResponse +QueryEscrowAddressResponse is the response type of the EscrowAddress RPC method. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `escrow_address` | [string](#string) | | the escrow account address | + + + + + + + + +### QueryParamsRequest +QueryParamsRequest is the request type for the Query/Params RPC method. + + + + + + + + +### QueryParamsResponse +QueryParamsResponse is the response type for the Query/Params RPC method. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `params` | [Params](#ibc.applications.transfer.v1.Params) | | params defines the parameters of the module. | + + + + + + + + + + + + + + +### Query +Query provides defines the gRPC querier service. + +| Method Name | Request Type | Response Type | Description | HTTP Verb | Endpoint | +| ----------- | ------------ | ------------- | ------------| ------- | -------- | +| `DenomTrace` | [QueryDenomTraceRequest](#ibc.applications.transfer.v1.QueryDenomTraceRequest) | [QueryDenomTraceResponse](#ibc.applications.transfer.v1.QueryDenomTraceResponse) | DenomTrace queries a denomination trace information. | GET|/ibc/apps/transfer/v1/denom_traces/{hash}| +| `DenomTraces` | [QueryDenomTracesRequest](#ibc.applications.transfer.v1.QueryDenomTracesRequest) | [QueryDenomTracesResponse](#ibc.applications.transfer.v1.QueryDenomTracesResponse) | DenomTraces queries all denomination traces. | GET|/ibc/apps/transfer/v1/denom_traces| +| `Params` | [QueryParamsRequest](#ibc.applications.transfer.v1.QueryParamsRequest) | [QueryParamsResponse](#ibc.applications.transfer.v1.QueryParamsResponse) | Params queries all parameters of the ibc-transfer module. | GET|/ibc/apps/transfer/v1/params| +| `DenomHash` | [QueryDenomHashRequest](#ibc.applications.transfer.v1.QueryDenomHashRequest) | [QueryDenomHashResponse](#ibc.applications.transfer.v1.QueryDenomHashResponse) | DenomHash queries a denomination hash information. | GET|/ibc/apps/transfer/v1/denom_hashes/{trace}| +| `EscrowAddress` | [QueryEscrowAddressRequest](#ibc.applications.transfer.v1.QueryEscrowAddressRequest) | [QueryEscrowAddressResponse](#ibc.applications.transfer.v1.QueryEscrowAddressResponse) | EscrowAddress returns the escrow address for a particular port and channel id. | GET|/ibc/apps/transfer/v1/channels/{channel_id}/ports/{port_id}/escrow_address| + + + + + + +

Top

+ +## ibc/applications/transfer/v1/tx.proto + + + + + +### MsgTransfer +MsgTransfer defines a msg to transfer fungible tokens (i.e Coins) between +ICS20 enabled chains. See ICS Spec here: +https://github.com/cosmos/ibc/tree/master/spec/app/ics-020-fungible-token-transfer#data-structures + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `source_port` | [string](#string) | | the port on which the packet will be sent | +| `source_channel` | [string](#string) | | the channel by which the packet will be sent | +| `token` | [cosmos.base.v1beta1.Coin](#cosmos.base.v1beta1.Coin) | | the tokens to be transferred | +| `sender` | [string](#string) | | the sender address | +| `receiver` | [string](#string) | | the recipient address on the destination chain | +| `timeout_height` | [ibc.core.client.v1.Height](#ibc.core.client.v1.Height) | | Timeout height relative to the current block height. The timeout is disabled when set to 0. | +| `timeout_timestamp` | [uint64](#uint64) | | Timeout timestamp in absolute nanoseconds since unix epoch. The timeout is disabled when set to 0. | +| `memo` | [string](#string) | | optional memo | + + + + + + + + +### MsgTransferResponse +MsgTransferResponse defines the Msg/Transfer response type. +>>>>>>> 05685b3 (refactor: adapting transfer metadata bytes field to memo string (#2595)) | Field | Type | Label | Description | @@ -921,6 +2180,16 @@ Order defines if a channel is ORDERED or UNORDERED | ORDER_UNORDERED | 1 | packets can be delivered in any order, which may differ from the order in which they were sent. | | ORDER_ORDERED | 2 | packets are delivered exactly in the order which they were sent | +<<<<<<< HEAD +======= +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `denom` | [string](#string) | | the token denomination to be transferred | +| `amount` | [string](#string) | | the token amount to be transferred | +| `sender` | [string](#string) | | the sender address | +| `receiver` | [string](#string) | | the recipient address on the destination chain | +| `memo` | [string](#string) | | optional memo | +>>>>>>> 05685b3 (refactor: adapting transfer metadata bytes field to memo string (#2595)) diff --git a/go.mod b/go.mod index fe4df203c6a..a17ed71df4f 100644 --- a/go.mod +++ b/go.mod @@ -35,6 +35,10 @@ require ( github.com/beorn7/perks v1.0.1 // indirect github.com/bgentry/speakeasy v0.1.0 // indirect github.com/btcsuite/btcd v0.22.1 // indirect +<<<<<<< HEAD +======= + github.com/cenkalti/backoff/v4 v4.1.1 // indirect +>>>>>>> 05685b3 (refactor: adapting transfer metadata bytes field to memo string (#2595)) github.com/cespare/xxhash v1.1.0 // indirect github.com/cespare/xxhash/v2 v2.1.2 // indirect github.com/coinbase/rosetta-sdk-go v0.7.0 // indirect diff --git a/go.sum b/go.sum index 656c31132ab..cd36d826bbe 100644 --- a/go.sum +++ b/go.sum @@ -130,6 +130,11 @@ github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46f github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4= github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= +<<<<<<< HEAD +======= +github.com/cenkalti/backoff/v4 v4.1.1 h1:G2HAfAmvm/GcKan2oOQpBXOd2tT2G57ZnZGWa1PxPBQ= +github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= +>>>>>>> 05685b3 (refactor: adapting transfer metadata bytes field to memo string (#2595)) github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/cp v0.1.0/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s= github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= diff --git a/modules/apps/29-fee/transfer_test.go b/modules/apps/29-fee/transfer_test.go new file mode 100644 index 00000000000..8bbe01abcb1 --- /dev/null +++ b/modules/apps/29-fee/transfer_test.go @@ -0,0 +1,70 @@ +package fee_test + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/cosmos/ibc-go/v6/modules/apps/29-fee/types" + transfertypes "github.com/cosmos/ibc-go/v6/modules/apps/transfer/types" + clienttypes "github.com/cosmos/ibc-go/v6/modules/core/02-client/types" + ibctesting "github.com/cosmos/ibc-go/v6/testing" +) + +// Integration test to ensure ics29 works with ics20 +func (suite *FeeTestSuite) TestFeeTransfer() { + path := ibctesting.NewPath(suite.chainA, suite.chainB) + feeTransferVersion := string(types.ModuleCdc.MustMarshalJSON(&types.Metadata{FeeVersion: types.Version, AppVersion: transfertypes.Version})) + path.EndpointA.ChannelConfig.Version = feeTransferVersion + path.EndpointB.ChannelConfig.Version = feeTransferVersion + path.EndpointA.ChannelConfig.PortID = transfertypes.PortID + path.EndpointB.ChannelConfig.PortID = transfertypes.PortID + + suite.coordinator.Setup(path) + + // set up coin & ics20 packet + coin := ibctesting.TestCoin + fee := types.Fee{ + RecvFee: defaultRecvFee, + AckFee: defaultAckFee, + TimeoutFee: defaultTimeoutFee, + } + + msgs := []sdk.Msg{ + types.NewMsgPayPacketFee(fee, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, suite.chainA.SenderAccount.GetAddress().String(), nil), + transfertypes.NewMsgTransfer(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, coin, suite.chainA.SenderAccount.GetAddress().String(), suite.chainB.SenderAccount.GetAddress().String(), clienttypes.NewHeight(1, 100), 0, ""), + } + res, err := suite.chainA.SendMsgs(msgs...) + suite.Require().NoError(err) // message committed + + // after incentivizing the packets + originalChainASenderAccountBalance := sdk.NewCoins(suite.chainA.GetSimApp().BankKeeper.GetBalance(suite.chainA.GetContext(), suite.chainA.SenderAccount.GetAddress(), ibctesting.TestCoin.Denom)) + + packet, err := ibctesting.ParsePacketFromEvents(res.GetEvents()) + suite.Require().NoError(err) + + // register counterparty address on chainB + // relayerAddress is address of sender account on chainB, but we will use it on chainA + // to differentiate from the chainA.SenderAccount for checking successful relay payouts + relayerAddress := suite.chainB.SenderAccount.GetAddress() + + msgRegister := types.NewMsgRegisterCounterpartyPayee(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, suite.chainB.SenderAccount.GetAddress().String(), relayerAddress.String()) + _, err = suite.chainB.SendMsgs(msgRegister) + suite.Require().NoError(err) // message committed + + // relay packet + err = path.RelayPacket(packet) + suite.Require().NoError(err) // relay committed + + // ensure relayers got paid + // relayer for forward relay: chainB.SenderAccount + // relayer for reverse relay: chainA.SenderAccount + + // check forward relay balance + suite.Require().Equal( + fee.RecvFee, + sdk.NewCoins(suite.chainA.GetSimApp().BankKeeper.GetBalance(suite.chainA.GetContext(), suite.chainB.SenderAccount.GetAddress(), ibctesting.TestCoin.Denom)), + ) + + suite.Require().Equal( + fee.AckFee.Add(fee.TimeoutFee...), // ack fee paid, timeout fee refunded + sdk.NewCoins(suite.chainA.GetSimApp().BankKeeper.GetBalance(suite.chainA.GetContext(), suite.chainA.SenderAccount.GetAddress(), ibctesting.TestCoin.Denom)).Sub(originalChainASenderAccountBalance[0])) +} diff --git a/modules/apps/transfer/client/cli/tx.go b/modules/apps/transfer/client/cli/tx.go index 85c012da865..5fb2fc1662f 100644 --- a/modules/apps/transfer/client/cli/tx.go +++ b/modules/apps/transfer/client/cli/tx.go @@ -22,7 +22,7 @@ const ( flagPacketTimeoutHeight = "packet-timeout-height" flagPacketTimeoutTimestamp = "packet-timeout-timestamp" flagAbsoluteTimeouts = "absolute-timeouts" - flagMetadata = "metadata" + flagMemo = "memo" ) // NewTransferTxCmd returns the command to create a NewMsgTransfer transaction @@ -77,7 +77,7 @@ corresponding to the counterparty channel. Any timeout set to 0 is disabled.`), return err } - metadataStr, err := cmd.Flags().GetString(flagMetadata) + memo, err := cmd.Flags().GetString(flagMemo) if err != nil { return err } @@ -117,7 +117,11 @@ corresponding to the counterparty channel. Any timeout set to 0 is disabled.`), } msg := types.NewMsgTransfer( +<<<<<<< HEAD srcPort, srcChannel, coin, sender, receiver, timeoutHeight, timeoutTimestamp, +======= + srcPort, srcChannel, coin, sender, receiver, timeoutHeight, timeoutTimestamp, memo, +>>>>>>> 05685b3 (refactor: adapting transfer metadata bytes field to memo string (#2595)) ) msg.Metadata = []byte(metadataStr) @@ -128,7 +132,7 @@ corresponding to the counterparty channel. Any timeout set to 0 is disabled.`), cmd.Flags().String(flagPacketTimeoutHeight, types.DefaultRelativePacketTimeoutHeight, "Packet timeout block height. The timeout is disabled when set to 0-0.") cmd.Flags().Uint64(flagPacketTimeoutTimestamp, types.DefaultRelativePacketTimeoutTimestamp, "Packet timeout timestamp in nanoseconds. Default is 10 minutes. The timeout is disabled when set to 0.") cmd.Flags().Bool(flagAbsoluteTimeouts, false, "Timeout flags are used as absolute timeouts.") - cmd.Flags().String(flagMetadata, "", "Metadata to be sent along with the packet. The CLI accepts only strings here but you can construct a packet with arbitrary bytes via code.") + cmd.Flags().String(flagMemo, "", "Memo to be sent along with the packet.") flags.AddTxFlagsToCmd(cmd) return cmd diff --git a/modules/apps/transfer/ibc_module.go b/modules/apps/transfer/ibc_module.go new file mode 100644 index 00000000000..b730a46f164 --- /dev/null +++ b/modules/apps/transfer/ibc_module.go @@ -0,0 +1,296 @@ +package transfer + +import ( + "fmt" + "math" + "strings" + + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" + + "github.com/cosmos/ibc-go/v6/modules/apps/transfer/keeper" + "github.com/cosmos/ibc-go/v6/modules/apps/transfer/types" + channeltypes "github.com/cosmos/ibc-go/v6/modules/core/04-channel/types" + porttypes "github.com/cosmos/ibc-go/v6/modules/core/05-port/types" + host "github.com/cosmos/ibc-go/v6/modules/core/24-host" + ibcexported "github.com/cosmos/ibc-go/v6/modules/core/exported" +) + +// IBCModule implements the ICS26 interface for transfer given the transfer keeper. +type IBCModule struct { + keeper keeper.Keeper +} + +// NewIBCModule creates a new IBCModule given the keeper +func NewIBCModule(k keeper.Keeper) IBCModule { + return IBCModule{ + keeper: k, + } +} + +// ValidateTransferChannelParams does validation of a newly created transfer channel. A transfer +// channel must be UNORDERED, use the correct port (by default 'transfer'), and use the current +// supported version. Only 2^32 channels are allowed to be created. +func ValidateTransferChannelParams( + ctx sdk.Context, + keeper keeper.Keeper, + order channeltypes.Order, + portID string, + channelID string, +) error { + // NOTE: for escrow address security only 2^32 channels are allowed to be created + // Issue: https://github.com/cosmos/cosmos-sdk/issues/7737 + channelSequence, err := channeltypes.ParseChannelSequence(channelID) + if err != nil { + return err + } + if channelSequence > uint64(math.MaxUint32) { + return sdkerrors.Wrapf(types.ErrMaxTransferChannels, "channel sequence %d is greater than max allowed transfer channels %d", channelSequence, uint64(math.MaxUint32)) + } + if order != channeltypes.UNORDERED { + return sdkerrors.Wrapf(channeltypes.ErrInvalidChannelOrdering, "expected %s channel, got %s ", channeltypes.UNORDERED, order) + } + + // Require portID is the portID transfer module is bound to + boundPort := keeper.GetPort(ctx) + if boundPort != portID { + return sdkerrors.Wrapf(porttypes.ErrInvalidPort, "invalid port: %s, expected %s", portID, boundPort) + } + + return nil +} + +// OnChanOpenInit implements the IBCModule interface +func (im IBCModule) OnChanOpenInit( + ctx sdk.Context, + order channeltypes.Order, + connectionHops []string, + portID string, + channelID string, + chanCap *capabilitytypes.Capability, + counterparty channeltypes.Counterparty, + version string, +) (string, error) { + if err := ValidateTransferChannelParams(ctx, im.keeper, order, portID, channelID); err != nil { + return "", err + } + + if strings.TrimSpace(version) == "" { + version = types.Version + } + + if version != types.Version { + return "", sdkerrors.Wrapf(types.ErrInvalidVersion, "got %s, expected %s", version, types.Version) + } + + // Claim channel capability passed back by IBC module + if err := im.keeper.ClaimCapability(ctx, chanCap, host.ChannelCapabilityPath(portID, channelID)); err != nil { + return "", err + } + + return version, nil +} + +// OnChanOpenTry implements the IBCModule interface. +func (im IBCModule) OnChanOpenTry( + ctx sdk.Context, + order channeltypes.Order, + connectionHops []string, + portID, + channelID string, + chanCap *capabilitytypes.Capability, + counterparty channeltypes.Counterparty, + counterpartyVersion string, +) (string, error) { + if err := ValidateTransferChannelParams(ctx, im.keeper, order, portID, channelID); err != nil { + return "", err + } + + if counterpartyVersion != types.Version { + return "", sdkerrors.Wrapf(types.ErrInvalidVersion, "invalid counterparty version: got: %s, expected %s", counterpartyVersion, types.Version) + } + + // OpenTry must claim the channelCapability that IBC passes into the callback + if err := im.keeper.ClaimCapability(ctx, chanCap, host.ChannelCapabilityPath(portID, channelID)); err != nil { + return "", err + } + + return types.Version, nil +} + +// OnChanOpenAck implements the IBCModule interface +func (im IBCModule) OnChanOpenAck( + ctx sdk.Context, + portID, + channelID string, + _ string, + counterpartyVersion string, +) error { + if counterpartyVersion != types.Version { + return sdkerrors.Wrapf(types.ErrInvalidVersion, "invalid counterparty version: %s, expected %s", counterpartyVersion, types.Version) + } + return nil +} + +// OnChanOpenConfirm implements the IBCModule interface +func (im IBCModule) OnChanOpenConfirm( + ctx sdk.Context, + portID, + channelID string, +) error { + return nil +} + +// OnChanCloseInit implements the IBCModule interface +func (im IBCModule) OnChanCloseInit( + ctx sdk.Context, + portID, + channelID string, +) error { + // Disallow user-initiated channel closing for transfer channels + return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "user cannot close channel") +} + +// OnChanCloseConfirm implements the IBCModule interface +func (im IBCModule) OnChanCloseConfirm( + ctx sdk.Context, + portID, + channelID string, +) error { + return nil +} + +// OnRecvPacket implements the IBCModule interface. A successful acknowledgement +// is returned if the packet data is successfully decoded and the receive application +// logic returns without error. +func (im IBCModule) OnRecvPacket( + ctx sdk.Context, + packet channeltypes.Packet, + relayer sdk.AccAddress, +) ibcexported.Acknowledgement { + ack := channeltypes.NewResultAcknowledgement([]byte{byte(1)}) + + var data types.FungibleTokenPacketData + var ackErr error + if err := types.ModuleCdc.UnmarshalJSON(packet.GetData(), &data); err != nil { + ackErr = sdkerrors.Wrapf(sdkerrors.ErrInvalidType, "cannot unmarshal ICS-20 transfer packet data") + ack = channeltypes.NewErrorAcknowledgement(ackErr) + } + + // only attempt the application logic if the packet data + // was successfully decoded + if ack.Success() { + err := im.keeper.OnRecvPacket(ctx, packet, data) + if err != nil { + ack = channeltypes.NewErrorAcknowledgement(err) + ackErr = err + } + } + + eventAttributes := []sdk.Attribute{ + sdk.NewAttribute(sdk.AttributeKeyModule, types.ModuleName), + sdk.NewAttribute(sdk.AttributeKeySender, data.Sender), + sdk.NewAttribute(types.AttributeKeyReceiver, data.Receiver), + sdk.NewAttribute(types.AttributeKeyDenom, data.Denom), + sdk.NewAttribute(types.AttributeKeyAmount, data.Amount), + sdk.NewAttribute(types.AttributeKeyMemo, data.Memo), + sdk.NewAttribute(types.AttributeKeyAckSuccess, fmt.Sprintf("%t", ack.Success())), + } + + if ackErr != nil { + eventAttributes = append(eventAttributes, sdk.NewAttribute(types.AttributeKeyAckError, ackErr.Error())) + } + + ctx.EventManager().EmitEvent( + sdk.NewEvent( + types.EventTypePacket, + eventAttributes..., + ), + ) + + // NOTE: acknowledgement will be written synchronously during IBC handler execution. + return ack +} + +// OnAcknowledgementPacket implements the IBCModule interface +func (im IBCModule) OnAcknowledgementPacket( + ctx sdk.Context, + packet channeltypes.Packet, + acknowledgement []byte, + relayer sdk.AccAddress, +) error { + var ack channeltypes.Acknowledgement + if err := types.ModuleCdc.UnmarshalJSON(acknowledgement, &ack); err != nil { + return sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "cannot unmarshal ICS-20 transfer packet acknowledgement: %v", err) + } + var data types.FungibleTokenPacketData + if err := types.ModuleCdc.UnmarshalJSON(packet.GetData(), &data); err != nil { + return sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "cannot unmarshal ICS-20 transfer packet data: %s", err.Error()) + } + + if err := im.keeper.OnAcknowledgementPacket(ctx, packet, data, ack); err != nil { + return err + } + + ctx.EventManager().EmitEvent( + sdk.NewEvent( + types.EventTypePacket, + sdk.NewAttribute(sdk.AttributeKeyModule, types.ModuleName), + sdk.NewAttribute(sdk.AttributeKeySender, data.Sender), + sdk.NewAttribute(types.AttributeKeyReceiver, data.Receiver), + sdk.NewAttribute(types.AttributeKeyDenom, data.Denom), + sdk.NewAttribute(types.AttributeKeyAmount, data.Amount), + sdk.NewAttribute(types.AttributeKeyMemo, data.Memo), + sdk.NewAttribute(types.AttributeKeyAck, ack.String()), + ), + ) + + switch resp := ack.Response.(type) { + case *channeltypes.Acknowledgement_Result: + ctx.EventManager().EmitEvent( + sdk.NewEvent( + types.EventTypePacket, + sdk.NewAttribute(types.AttributeKeyAckSuccess, string(resp.Result)), + ), + ) + case *channeltypes.Acknowledgement_Error: + ctx.EventManager().EmitEvent( + sdk.NewEvent( + types.EventTypePacket, + sdk.NewAttribute(types.AttributeKeyAckError, resp.Error), + ), + ) + } + + return nil +} + +// OnTimeoutPacket implements the IBCModule interface +func (im IBCModule) OnTimeoutPacket( + ctx sdk.Context, + packet channeltypes.Packet, + relayer sdk.AccAddress, +) error { + var data types.FungibleTokenPacketData + if err := types.ModuleCdc.UnmarshalJSON(packet.GetData(), &data); err != nil { + return sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "cannot unmarshal ICS-20 transfer packet data: %s", err.Error()) + } + // refund tokens + if err := im.keeper.OnTimeoutPacket(ctx, packet, data); err != nil { + return err + } + + ctx.EventManager().EmitEvent( + sdk.NewEvent( + types.EventTypeTimeout, + sdk.NewAttribute(sdk.AttributeKeyModule, types.ModuleName), + sdk.NewAttribute(types.AttributeKeyRefundReceiver, data.Sender), + sdk.NewAttribute(types.AttributeKeyRefundDenom, data.Denom), + sdk.NewAttribute(types.AttributeKeyRefundAmount, data.Amount), + sdk.NewAttribute(types.AttributeKeyMemo, data.Memo), + ), + ) + + return nil +} diff --git a/modules/apps/transfer/keeper/mbt_relay_test.go b/modules/apps/transfer/keeper/mbt_relay_test.go index fb22f29dfc4..52c3d14ed43 100644 --- a/modules/apps/transfer/keeper/mbt_relay_test.go +++ b/modules/apps/transfer/keeper/mbt_relay_test.go @@ -145,7 +145,12 @@ func FungibleTokenPacketFromTla(packet TlaFungibleTokenPacket) FungibleTokenPack DenomFromTla(packet.Data.Denom), packet.Data.Amount, AddressFromString(packet.Data.Sender), +<<<<<<< HEAD AddressFromString(packet.Data.Receiver)), +======= + AddressFromString(packet.Data.Receiver), + ""), +>>>>>>> 05685b3 (refactor: adapting transfer metadata bytes field to memo string (#2595)) } } @@ -344,8 +349,17 @@ func (suite *KeeperTestSuite) TestModelBasedRelay() { sdk.NewCoin(denom, amount), sender, tc.packet.Data.Receiver, +<<<<<<< HEAD clienttypes.NewHeight(0, 110), 0) +======= + suite.chainA.GetTimeoutHeight(), 0, // only use timeout height + "", + ) + + _, err = suite.chainB.GetSimApp().TransferKeeper.Transfer(sdk.WrapSDKContext(suite.chainB.GetContext()), msg) + +>>>>>>> 05685b3 (refactor: adapting transfer metadata bytes field to memo string (#2595)) } case "OnRecvPacket": err = suite.chainB.GetSimApp().TransferKeeper.OnRecvPacket(suite.chainB.GetContext(), packet, tc.packet.Data) diff --git a/modules/apps/transfer/keeper/msg_server.go b/modules/apps/transfer/keeper/msg_server.go index 77c83a2f3e5..7b720146c7a 100644 --- a/modules/apps/transfer/keeper/msg_server.go +++ b/modules/apps/transfer/keeper/msg_server.go @@ -20,7 +20,7 @@ func (k Keeper) Transfer(goCtx context.Context, msg *types.MsgTransfer) (*types. sequence, err := k.sendTransfer( ctx, msg.SourcePort, msg.SourceChannel, msg.Token, sender, msg.Receiver, msg.TimeoutHeight, msg.TimeoutTimestamp, - msg.Metadata) + msg.Memo) if err != nil { return nil, err } diff --git a/modules/apps/transfer/keeper/msg_server_test.go b/modules/apps/transfer/keeper/msg_server_test.go index e09d326aa84..97101e91bff 100644 --- a/modules/apps/transfer/keeper/msg_server_test.go +++ b/modules/apps/transfer/keeper/msg_server_test.go @@ -48,6 +48,7 @@ func (suite *KeeperTestSuite) TestMsgTransfer() { path := NewTransferPath(suite.chainA, suite.chainB) suite.coordinator.Setup(path) +<<<<<<< HEAD coin := sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100)) msg = types.NewMsgTransfer( path.EndpointA.ChannelConfig.PortID, @@ -56,6 +57,16 @@ func (suite *KeeperTestSuite) TestMsgTransfer() { suite.chainB.GetTimeoutHeight(), 0, // only use timeout height ) msg.Metadata = []byte("custom metadata") +======= + coin := sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100)) + msg = types.NewMsgTransfer( + path.EndpointA.ChannelConfig.PortID, + path.EndpointA.ChannelID, + coin, suite.chainA.SenderAccount.GetAddress().String(), suite.chainB.SenderAccount.GetAddress().String(), + suite.chainB.GetTimeoutHeight(), 0, // only use timeout height + "memo", + ) +>>>>>>> 05685b3 (refactor: adapting transfer metadata bytes field to memo string (#2595)) tc.malleate() diff --git a/modules/apps/transfer/keeper/relay.go b/modules/apps/transfer/keeper/relay.go index 96527af63dc..83edab14480 100644 --- a/modules/apps/transfer/keeper/relay.go +++ b/modules/apps/transfer/keeper/relay.go @@ -84,7 +84,7 @@ func (k Keeper) sendTransfer( receiver string, timeoutHeight clienttypes.Height, timeoutTimestamp uint64, - metadata []byte, + memo string, ) (uint64, error) { if !k.GetSendEnabled(ctx) { return 0, types.ErrSendDisabled @@ -175,6 +175,7 @@ func (k Keeper) sendTransfer( } packetData := types.NewFungibleTokenPacketData( +<<<<<<< HEAD fullDenomPath, token.Amount.String(), sender.String(), receiver, ) packetData.Metadata = metadata @@ -188,6 +189,9 @@ func (k Keeper) sendTransfer( destinationChannel, timeoutHeight, timeoutTimestamp, +======= + fullDenomPath, token.Amount.String(), sender.String(), receiver, memo, +>>>>>>> 05685b3 (refactor: adapting transfer metadata bytes field to memo string (#2595)) ) if err := k.channelKeeper.SendPacket(ctx, channelCap, packet); err != nil { diff --git a/modules/apps/transfer/keeper/relay_test.go b/modules/apps/transfer/keeper/relay_test.go index 1bac750a713..c438b341b94 100644 --- a/modules/apps/transfer/keeper/relay_test.go +++ b/modules/apps/transfer/keeper/relay_test.go @@ -17,10 +17,18 @@ import ( // chainA and coin that orignate on chainB func (suite *KeeperTestSuite) TestSendTransfer() { var ( +<<<<<<< HEAD amount sdk.Coin path *ibctesting.Path sender sdk.AccAddress err error +======= + coin sdk.Coin + path *ibctesting.Path + sender sdk.AccAddress + timeoutHeight clienttypes.Height + memo string +>>>>>>> 05685b3 (refactor: adapting transfer metadata bytes field to memo string (#2595)) ) testCases := []struct { @@ -29,18 +37,46 @@ func (suite *KeeperTestSuite) TestSendTransfer() { sendFromSource bool expPass bool }{ +<<<<<<< HEAD {"successful transfer from source chain", func() { suite.coordinator.CreateTransferChannels(path) amount = sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100)) }, true, true}, +======= + { + "successful transfer with native token", + func() {}, true, + }, + { + "successful transfer from source chain with memo", + func() { + memo = "memo" + }, true, + }, +>>>>>>> 05685b3 (refactor: adapting transfer metadata bytes field to memo string (#2595)) { "successful transfer with coin from counterparty chain", func() { +<<<<<<< HEAD // send coin from chainA back to chainB suite.coordinator.CreateTransferChannels(path) amount = types.GetTransferCoin(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, sdk.DefaultBondDenom, sdk.NewInt(100)) }, false, true}, +======= + // send IBC token back to chainB + coin = types.GetTransferCoin(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, coin.Denom, coin.Amount) + }, true, + }, + { + "successful transfer with IBC token and memo", + func() { + // send IBC token back to chainB + coin = types.GetTransferCoin(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, coin.Denom, coin.Amount) + memo = "memo" + }, true, + }, +>>>>>>> 05685b3 (refactor: adapting transfer metadata bytes field to memo string (#2595)) { "source channel not found", func() { @@ -101,8 +137,18 @@ func (suite *KeeperTestSuite) TestSendTransfer() { path = NewTransferPath(suite.chainA, suite.chainB) suite.coordinator.SetupConnections(path) sender = suite.chainA.SenderAccount.GetAddress() +<<<<<<< HEAD tc.malleate() +======= + memo = "" + timeoutHeight = suite.chainB.GetTimeoutHeight() + + // create IBC token on chainA + transferMsg := types.NewMsgTransfer(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, coin, suite.chainB.SenderAccount.GetAddress().String(), suite.chainA.SenderAccount.GetAddress().String(), suite.chainA.GetTimeoutHeight(), 0, "") + result, err := suite.chainB.SendMsgs(transferMsg) + suite.Require().NoError(err) // message committed +>>>>>>> 05685b3 (refactor: adapting transfer metadata bytes field to memo string (#2595)) if !tc.sendFromSource { // send coin from chainB to chainA @@ -121,10 +167,20 @@ func (suite *KeeperTestSuite) TestSendTransfer() { packetKey := host.PacketCommitmentKey(packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()) proof, proofHeight := path.EndpointB.QueryProof(packetKey) +<<<<<<< HEAD recvMsg := channeltypes.NewMsgRecvPacket(packet, proof, proofHeight, suite.chainA.SenderAccount.GetAddress().String()) _, err = suite.chainA.SendMsgs(recvMsg) suite.Require().NoError(err) // message committed } +======= + msg := types.NewMsgTransfer( + path.EndpointA.ChannelConfig.PortID, + path.EndpointA.ChannelID, + coin, sender.String(), suite.chainB.SenderAccount.GetAddress().String(), + timeoutHeight, 0, // only use timeout height + memo, + ) +>>>>>>> 05685b3 (refactor: adapting transfer metadata bytes field to memo string (#2595)) err = suite.chainA.GetSimApp().TransferKeeper.SendTransfer( suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, amount, @@ -149,7 +205,7 @@ func (suite *KeeperTestSuite) TestOnRecvPacket() { trace types.DenomTrace amount sdk.Int receiver string - metadata []byte + memo string ) testCases := []struct { @@ -159,12 +215,12 @@ func (suite *KeeperTestSuite) TestOnRecvPacket() { expPass bool }{ {"success receive on source chain", func() {}, true, true}, - {"success receive on source chain with metadata", func() { - metadata = []byte("metadata") + {"success receive on source chain with memo", func() { + memo = "memo" }, true, true}, {"success receive with coin from another chain as source", func() {}, false, true}, - {"success receive with coin from another chain as source with metadata", func() { - metadata = []byte("metadata") + {"success receive with coin from another chain as source with memo", func() { + memo = "memo" }, false, true}, {"empty coin", func() { trace = types.DenomTrace{} @@ -206,15 +262,20 @@ func (suite *KeeperTestSuite) TestOnRecvPacket() { suite.coordinator.Setup(path) receiver = suite.chainB.SenderAccount.GetAddress().String() // must be explicitly changed in malleate - metadata = []byte{} // can be explicitly changed in malleate + memo = "" // can be explicitly changed in malleate amount = sdk.NewInt(100) // must be explicitly changed in malleate seq := uint64(1) if tc.recvIsSource { // send coin from chainB to chainA, receive them, acknowledge them, and send back to chainB coinFromBToA := sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100)) +<<<<<<< HEAD transferMsg := types.NewMsgTransfer(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, coinFromBToA, suite.chainB.SenderAccount.GetAddress().String(), suite.chainA.SenderAccount.GetAddress().String(), clienttypes.NewHeight(0, 110), 0) _, err := suite.chainB.SendMsgs(transferMsg) +======= + transferMsg := types.NewMsgTransfer(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, coinFromBToA, suite.chainB.SenderAccount.GetAddress().String(), suite.chainA.SenderAccount.GetAddress().String(), clienttypes.NewHeight(1, 110), 0, memo) + res, err := suite.chainB.SendMsgs(transferMsg) +>>>>>>> 05685b3 (refactor: adapting transfer metadata bytes field to memo string (#2595)) suite.Require().NoError(err) // message committed // relay send packet @@ -233,16 +294,25 @@ func (suite *KeeperTestSuite) TestOnRecvPacket() { } // send coin from chainA to chainB +<<<<<<< HEAD transferMsg := types.NewMsgTransfer(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, sdk.NewCoin(trace.IBCDenom(), amount), suite.chainA.SenderAccount.GetAddress().String(), receiver, clienttypes.NewHeight(0, 110), 0) transferMsg.Metadata = metadata +======= + transferMsg := types.NewMsgTransfer(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, sdk.NewCoin(trace.IBCDenom(), amount), suite.chainA.SenderAccount.GetAddress().String(), receiver, clienttypes.NewHeight(1, 110), 0, memo) +>>>>>>> 05685b3 (refactor: adapting transfer metadata bytes field to memo string (#2595)) _, err := suite.chainA.SendMsgs(transferMsg) suite.Require().NoError(err) // message committed tc.malleate() +<<<<<<< HEAD data := types.NewFungibleTokenPacketData(trace.GetFullDenomPath(), amount.String(), suite.chainA.SenderAccount.GetAddress().String(), receiver) data.Metadata = metadata packet := channeltypes.NewPacket(data.GetBytes(), seq, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, clienttypes.NewHeight(0, 100), 0) +======= + data := types.NewFungibleTokenPacketData(trace.GetFullDenomPath(), amount.String(), suite.chainA.SenderAccount.GetAddress().String(), receiver, memo) + packet := channeltypes.NewPacket(data.GetBytes(), seq, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, clienttypes.NewHeight(1, 100), 0) +>>>>>>> 05685b3 (refactor: adapting transfer metadata bytes field to memo string (#2595)) err = suite.chainB.GetSimApp().TransferKeeper.OnRecvPacket(suite.chainB.GetContext(), packet, data) @@ -310,8 +380,13 @@ func (suite *KeeperTestSuite) TestOnAcknowledgementPacket() { tc.malleate() +<<<<<<< HEAD data := types.NewFungibleTokenPacketData(trace.GetFullDenomPath(), amount.String(), suite.chainA.SenderAccount.GetAddress().String(), suite.chainB.SenderAccount.GetAddress().String()) packet := channeltypes.NewPacket(data.GetBytes(), 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, clienttypes.NewHeight(0, 100), 0) +======= + data := types.NewFungibleTokenPacketData(trace.GetFullDenomPath(), amount.String(), suite.chainA.SenderAccount.GetAddress().String(), suite.chainB.SenderAccount.GetAddress().String(), "") + packet := channeltypes.NewPacket(data.GetBytes(), 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, clienttypes.NewHeight(1, 100), 0) +>>>>>>> 05685b3 (refactor: adapting transfer metadata bytes field to memo string (#2595)) preCoin := suite.chainA.GetSimApp().BankKeeper.GetBalance(suite.chainA.GetContext(), suite.chainA.SenderAccount.GetAddress(), trace.IBCDenom()) @@ -396,8 +471,13 @@ func (suite *KeeperTestSuite) TestOnTimeoutPacket() { tc.malleate() +<<<<<<< HEAD data := types.NewFungibleTokenPacketData(trace.GetFullDenomPath(), amount.String(), sender, suite.chainB.SenderAccount.GetAddress().String()) packet := channeltypes.NewPacket(data.GetBytes(), 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, clienttypes.NewHeight(0, 100), 0) +======= + data := types.NewFungibleTokenPacketData(trace.GetFullDenomPath(), amount.String(), sender, suite.chainB.SenderAccount.GetAddress().String(), "") + packet := channeltypes.NewPacket(data.GetBytes(), 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, clienttypes.NewHeight(1, 100), 0) +>>>>>>> 05685b3 (refactor: adapting transfer metadata bytes field to memo string (#2595)) preCoin := suite.chainA.GetSimApp().BankKeeper.GetBalance(suite.chainA.GetContext(), suite.chainA.SenderAccount.GetAddress(), trace.IBCDenom()) diff --git a/modules/apps/transfer/transfer_test.go b/modules/apps/transfer/transfer_test.go index 58b33cbe647..7f405a8eb12 100644 --- a/modules/apps/transfer/transfer_test.go +++ b/modules/apps/transfer/transfer_test.go @@ -53,7 +53,13 @@ func (suite *TransferTestSuite) TestHandleMsgTransfer() { coinToSendToB := sdk.NewCoin(sdk.DefaultBondDenom, amount) // send from chainA to chainB +<<<<<<< HEAD msg := types.NewMsgTransfer(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, coinToSendToB, suite.chainA.SenderAccount.GetAddress().String(), suite.chainB.SenderAccount.GetAddress().String(), timeoutHeight, 0) +======= + msg := types.NewMsgTransfer(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, coinToSendToB, suite.chainA.SenderAccount.GetAddress().String(), suite.chainB.SenderAccount.GetAddress().String(), timeoutHeight, 0, "") + res, err := suite.chainA.SendMsgs(msg) + suite.Require().NoError(err) // message committed +>>>>>>> 05685b3 (refactor: adapting transfer metadata bytes field to memo string (#2595)) _, err := suite.chainA.SendMsgs(msg) suite.Require().NoError(err) // message committed @@ -80,7 +86,16 @@ func (suite *TransferTestSuite) TestHandleMsgTransfer() { suite.coordinator.Setup(pathBtoC) // send from chainB to chainC +<<<<<<< HEAD msg = types.NewMsgTransfer(pathBtoC.EndpointA.ChannelConfig.PortID, pathBtoC.EndpointA.ChannelID, coinSentFromAToB, suite.chainB.SenderAccount.GetAddress().String(), suite.chainC.SenderAccount.GetAddress().String(), timeoutHeight, 0) +======= + msg = types.NewMsgTransfer(pathBtoC.EndpointA.ChannelConfig.PortID, pathBtoC.EndpointA.ChannelID, coinSentFromAToB, suite.chainB.SenderAccount.GetAddress().String(), suite.chainC.SenderAccount.GetAddress().String(), timeoutHeight, 0, "") + res, err = suite.chainB.SendMsgs(msg) + suite.Require().NoError(err) // message committed + + packet, err = ibctesting.ParsePacketFromEvents(res.GetEvents()) + suite.Require().NoError(err) +>>>>>>> 05685b3 (refactor: adapting transfer metadata bytes field to memo string (#2595)) _, err = suite.chainB.SendMsgs(msg) suite.Require().NoError(err) // message committed @@ -104,7 +119,13 @@ func (suite *TransferTestSuite) TestHandleMsgTransfer() { suite.Require().Zero(balance.Amount.Int64()) // send from chainC back to chainB +<<<<<<< HEAD msg = types.NewMsgTransfer(pathBtoC.EndpointB.ChannelConfig.PortID, pathBtoC.EndpointB.ChannelID, coinSentFromBToC, suite.chainC.SenderAccount.GetAddress().String(), suite.chainB.SenderAccount.GetAddress().String(), timeoutHeight, 0) +======= + msg = types.NewMsgTransfer(pathBtoC.EndpointB.ChannelConfig.PortID, pathBtoC.EndpointB.ChannelID, coinSentFromBToC, suite.chainC.SenderAccount.GetAddress().String(), suite.chainB.SenderAccount.GetAddress().String(), timeoutHeight, 0, "") + res, err = suite.chainC.SendMsgs(msg) + suite.Require().NoError(err) // message committed +>>>>>>> 05685b3 (refactor: adapting transfer metadata bytes field to memo string (#2595)) _, err = suite.chainC.SendMsgs(msg) suite.Require().NoError(err) // message committed diff --git a/modules/apps/transfer/types/events.go b/modules/apps/transfer/types/events.go index 5cc87f11797..89964a8a9a4 100644 --- a/modules/apps/transfer/types/events.go +++ b/modules/apps/transfer/types/events.go @@ -18,5 +18,5 @@ const ( AttributeKeyAck = "acknowledgement" AttributeKeyAckError = "error" AttributeKeyTraceHash = "trace_hash" - AttributeKeyMetadata = "metadata" + AttributeKeyMemo = "memo" ) diff --git a/modules/apps/transfer/types/msgs.go b/modules/apps/transfer/types/msgs.go index 169ffe9ca36..4b6ba38ac7f 100644 --- a/modules/apps/transfer/types/msgs.go +++ b/modules/apps/transfer/types/msgs.go @@ -21,6 +21,10 @@ func NewMsgTransfer( sourcePort, sourceChannel string, token sdk.Coin, sender, receiver string, timeoutHeight clienttypes.Height, timeoutTimestamp uint64, +<<<<<<< HEAD +======= + memo string, +>>>>>>> 05685b3 (refactor: adapting transfer metadata bytes field to memo string (#2595)) ) *MsgTransfer { return &MsgTransfer{ SourcePort: sourcePort, @@ -30,6 +34,10 @@ func NewMsgTransfer( Receiver: receiver, TimeoutHeight: timeoutHeight, TimeoutTimestamp: timeoutTimestamp, +<<<<<<< HEAD +======= + Memo: memo, +>>>>>>> 05685b3 (refactor: adapting transfer metadata bytes field to memo string (#2595)) } } diff --git a/modules/apps/transfer/types/msgs_test.go b/modules/apps/transfer/types/msgs_test.go index 27057d6de4c..62851ee6806 100644 --- a/modules/apps/transfer/types/msgs_test.go +++ b/modules/apps/transfer/types/msgs_test.go @@ -41,7 +41,11 @@ var ( // TestMsgTransferRoute tests Route for MsgTransfer func TestMsgTransferRoute(t *testing.T) { +<<<<<<< HEAD msg := NewMsgTransfer(validPort, validChannel, coin, addr1, addr2, timeoutHeight, 0) +======= + msg := NewMsgTransfer(validPort, validChannel, coin, addr1, addr2, timeoutHeight, 0, "") +>>>>>>> 05685b3 (refactor: adapting transfer metadata bytes field to memo string (#2595)) require.Equal(t, RouterKey, msg.Route()) } @@ -54,7 +58,11 @@ func TestMsgTransferType(t *testing.T) { } func TestMsgTransferGetSignBytes(t *testing.T) { +<<<<<<< HEAD msg := NewMsgTransfer(validPort, validChannel, coin, addr1, addr2, timeoutHeight, 0) +======= + msg := NewMsgTransfer(validPort, validChannel, coin, addr1, addr2, timeoutHeight, 0, "") +>>>>>>> 05685b3 (refactor: adapting transfer metadata bytes field to memo string (#2595)) expected := fmt.Sprintf(`{"type":"cosmos-sdk/MsgTransfer","value":{"receiver":"%s","sender":"%s","source_channel":"testchannel","source_port":"testportid","timeout_height":{"revision_height":"10"},"token":{"amount":"100","denom":"atom"}}}`, addr2, addr1) require.NotPanics(t, func() { res := msg.GetSignBytes() @@ -69,6 +77,7 @@ func TestMsgTransferValidation(t *testing.T) { msg *MsgTransfer expPass bool }{ +<<<<<<< HEAD {"valid msg with base denom", NewMsgTransfer(validPort, validChannel, coin, addr1, addr2, timeoutHeight, 0), true}, {"valid msg with trace hash", NewMsgTransfer(validPort, validChannel, ibcCoin, addr1, addr2, timeoutHeight, 0), true}, {"invalid ibc denom", NewMsgTransfer(validPort, validChannel, invalidIBCCoin, addr1, addr2, timeoutHeight, 0), false}, @@ -83,6 +92,22 @@ func TestMsgTransferValidation(t *testing.T) { {"missing sender address", NewMsgTransfer(validPort, validChannel, coin, emptyAddr, addr2, timeoutHeight, 0), false}, {"missing recipient address", NewMsgTransfer(validPort, validChannel, coin, addr1, "", timeoutHeight, 0), false}, {"empty coin", NewMsgTransfer(validPort, validChannel, sdk.Coin{}, addr1, addr2, timeoutHeight, 0), false}, +======= + {"valid msg with base denom", NewMsgTransfer(validPort, validChannel, coin, addr1, addr2, timeoutHeight, 0, ""), true}, + {"valid msg with trace hash", NewMsgTransfer(validPort, validChannel, ibcCoin, addr1, addr2, timeoutHeight, 0, ""), true}, + {"invalid ibc denom", NewMsgTransfer(validPort, validChannel, invalidIBCCoin, addr1, addr2, timeoutHeight, 0, ""), false}, + {"too short port id", NewMsgTransfer(invalidShortPort, validChannel, coin, addr1, addr2, timeoutHeight, 0, ""), false}, + {"too long port id", NewMsgTransfer(invalidLongPort, validChannel, coin, addr1, addr2, timeoutHeight, 0, ""), false}, + {"port id contains non-alpha", NewMsgTransfer(invalidPort, validChannel, coin, addr1, addr2, timeoutHeight, 0, ""), false}, + {"too short channel id", NewMsgTransfer(validPort, invalidShortChannel, coin, addr1, addr2, timeoutHeight, 0, ""), false}, + {"too long channel id", NewMsgTransfer(validPort, invalidLongChannel, coin, addr1, addr2, timeoutHeight, 0, ""), false}, + {"channel id contains non-alpha", NewMsgTransfer(validPort, invalidChannel, coin, addr1, addr2, timeoutHeight, 0, ""), false}, + {"invalid denom", NewMsgTransfer(validPort, validChannel, invalidDenomCoin, addr1, addr2, timeoutHeight, 0, ""), false}, + {"zero coin", NewMsgTransfer(validPort, validChannel, zeroCoin, addr1, addr2, timeoutHeight, 0, ""), false}, + {"missing sender address", NewMsgTransfer(validPort, validChannel, coin, emptyAddr, addr2, timeoutHeight, 0, ""), false}, + {"missing recipient address", NewMsgTransfer(validPort, validChannel, coin, addr1, "", timeoutHeight, 0, ""), false}, + {"empty coin", NewMsgTransfer(validPort, validChannel, sdk.Coin{}, addr1, addr2, timeoutHeight, 0, ""), false}, +>>>>>>> 05685b3 (refactor: adapting transfer metadata bytes field to memo string (#2595)) } for i, tc := range testCases { @@ -99,7 +124,11 @@ func TestMsgTransferValidation(t *testing.T) { func TestMsgTransferGetSigners(t *testing.T) { addr := sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()) +<<<<<<< HEAD msg := NewMsgTransfer(validPort, validChannel, coin, addr.String(), addr2, timeoutHeight, 0) +======= + msg := NewMsgTransfer(validPort, validChannel, coin, addr.String(), addr2, timeoutHeight, 0, "") +>>>>>>> 05685b3 (refactor: adapting transfer metadata bytes field to memo string (#2595)) res := msg.GetSigners() require.Equal(t, []sdk.AccAddress{addr}, res) diff --git a/modules/apps/transfer/types/packet.go b/modules/apps/transfer/types/packet.go index a7384c47486..74427499550 100644 --- a/modules/apps/transfer/types/packet.go +++ b/modules/apps/transfer/types/packet.go @@ -25,12 +25,20 @@ var ( func NewFungibleTokenPacketData( denom string, amount string, sender, receiver string, +<<<<<<< HEAD +======= + memo string, +>>>>>>> 05685b3 (refactor: adapting transfer metadata bytes field to memo string (#2595)) ) FungibleTokenPacketData { return FungibleTokenPacketData{ Denom: denom, Amount: amount, Sender: sender, Receiver: receiver, +<<<<<<< HEAD +======= + Memo: memo, +>>>>>>> 05685b3 (refactor: adapting transfer metadata bytes field to memo string (#2595)) } } diff --git a/modules/apps/transfer/types/packet.pb.go b/modules/apps/transfer/types/packet.pb.go index 8ff01154f9c..a1645f8231f 100644 --- a/modules/apps/transfer/types/packet.pb.go +++ b/modules/apps/transfer/types/packet.pb.go @@ -34,8 +34,8 @@ type FungibleTokenPacketData struct { Sender string `protobuf:"bytes,3,opt,name=sender,proto3" json:"sender,omitempty"` // the recipient address on the destination chain Receiver string `protobuf:"bytes,4,opt,name=receiver,proto3" json:"receiver,omitempty"` - // optional metadata - Metadata []byte `protobuf:"bytes,5,opt,name=metadata,proto3" json:"metadata,omitempty"` + // optional memo + Memo string `protobuf:"bytes,5,opt,name=memo,proto3" json:"memo,omitempty"` } func (m *FungibleTokenPacketData) Reset() { *m = FungibleTokenPacketData{} } @@ -99,11 +99,11 @@ func (m *FungibleTokenPacketData) GetReceiver() string { return "" } -func (m *FungibleTokenPacketData) GetMetadata() []byte { +func (m *FungibleTokenPacketData) GetMemo() string { if m != nil { - return m.Metadata + return m.Memo } - return nil + return "" } func init() { @@ -115,6 +115,7 @@ func init() { } var fileDescriptor_653ca2ce9a5ca313 = []byte{ +<<<<<<< HEAD // 258 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x4c, 0x90, 0xb1, 0x4e, 0xc3, 0x30, 0x10, 0x86, 0x6b, 0xa0, 0x15, 0x44, 0x4c, 0x11, 0x82, 0x08, 0x21, 0xab, 0x62, 0x2a, 0x03, 0xb1, @@ -133,6 +134,25 @@ var fileDescriptor_653ca2ce9a5ca313 = []byte{ 0x5f, 0x97, 0xd8, 0xff, 0x6e, 0xb1, 0xa8, 0x2b, 0x88, 0xbd, 0x9c, 0x1d, 0x29, 0xf4, 0xee, 0x21, 0xaa, 0xd9, 0x60, 0xe4, 0xe6, 0x37, 0x00, 0x00, 0xff, 0xff, 0x5d, 0x3d, 0x15, 0x2a, 0x3e, 0x01, 0x00, 0x00, +======= + // 254 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x4c, 0x90, 0xb1, 0x4a, 0x34, 0x31, + 0x14, 0x46, 0x27, 0xff, 0xbf, 0xbb, 0x68, 0xca, 0x20, 0x3a, 0x88, 0x04, 0xb1, 0xd2, 0xc2, 0x09, + 0xac, 0xa0, 0xbd, 0x88, 0xb5, 0x8a, 0x95, 0x5d, 0x92, 0xb9, 0x8e, 0x61, 0x27, 0xb9, 0x21, 0xc9, + 0x0c, 0xf8, 0x14, 0xfa, 0x58, 0x96, 0x5b, 0x5a, 0xca, 0xcc, 0x8b, 0xc8, 0x66, 0x54, 0xb6, 0xcb, + 0x39, 0xf9, 0x6e, 0x73, 0xe8, 0x99, 0x51, 0x5a, 0x48, 0xef, 0x5b, 0xa3, 0x65, 0x32, 0xe8, 0xa2, + 0x48, 0x41, 0xba, 0xf8, 0x0c, 0x41, 0xf4, 0x4b, 0xe1, 0xa5, 0x5e, 0x41, 0xaa, 0x7c, 0xc0, 0x84, + 0xec, 0xc8, 0x28, 0x5d, 0x6d, 0x4f, 0xab, 0xdf, 0x69, 0xd5, 0x2f, 0x4f, 0xde, 0x08, 0x3d, 0xb8, + 0xed, 0x5c, 0x63, 0x54, 0x0b, 0x8f, 0xb8, 0x02, 0x77, 0x97, 0x6f, 0x6f, 0x64, 0x92, 0x6c, 0x8f, + 0xce, 0x6b, 0x70, 0x68, 0x4b, 0x72, 0x4c, 0x4e, 0x77, 0x1f, 0x26, 0x60, 0xfb, 0x74, 0x21, 0x2d, + 0x76, 0x2e, 0x95, 0xff, 0xb2, 0xfe, 0xa1, 0x8d, 0x8f, 0xe0, 0x6a, 0x08, 0xe5, 0xff, 0xc9, 0x4f, + 0xc4, 0x0e, 0xe9, 0x4e, 0x00, 0x0d, 0xa6, 0x87, 0x50, 0xce, 0xf2, 0xcf, 0x1f, 0x33, 0x46, 0x67, + 0x16, 0x2c, 0x96, 0xf3, 0xec, 0xf3, 0xfb, 0xfa, 0xfe, 0x63, 0xe0, 0x64, 0x3d, 0x70, 0xf2, 0x35, + 0x70, 0xf2, 0x3e, 0xf2, 0x62, 0x3d, 0xf2, 0xe2, 0x73, 0xe4, 0xc5, 0xd3, 0x55, 0x63, 0xd2, 0x4b, + 0xa7, 0x2a, 0x8d, 0x56, 0x68, 0x8c, 0x16, 0xa3, 0x30, 0x4a, 0x9f, 0x37, 0x28, 0xfa, 0x4b, 0x61, + 0xb1, 0xee, 0x5a, 0x88, 0x9b, 0x28, 0x5b, 0x31, 0xd2, 0xab, 0x87, 0xa8, 0x16, 0xb9, 0xc4, 0xc5, + 0x77, 0x00, 0x00, 0x00, 0xff, 0xff, 0x2d, 0xee, 0xa2, 0x5e, 0x36, 0x01, 0x00, 0x00, +>>>>>>> 05685b3 (refactor: adapting transfer metadata bytes field to memo string (#2595)) } func (m *FungibleTokenPacketData) Marshal() (dAtA []byte, err error) { @@ -155,10 +175,10 @@ func (m *FungibleTokenPacketData) MarshalToSizedBuffer(dAtA []byte) (int, error) _ = i var l int _ = l - if len(m.Metadata) > 0 { - i -= len(m.Metadata) - copy(dAtA[i:], m.Metadata) - i = encodeVarintPacket(dAtA, i, uint64(len(m.Metadata))) + if len(m.Memo) > 0 { + i -= len(m.Memo) + copy(dAtA[i:], m.Memo) + i = encodeVarintPacket(dAtA, i, uint64(len(m.Memo))) i-- dAtA[i] = 0x2a } @@ -226,7 +246,7 @@ func (m *FungibleTokenPacketData) Size() (n int) { if l > 0 { n += 1 + l + sovPacket(uint64(l)) } - l = len(m.Metadata) + l = len(m.Memo) if l > 0 { n += 1 + l + sovPacket(uint64(l)) } @@ -398,9 +418,9 @@ func (m *FungibleTokenPacketData) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 5: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Metadata", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Memo", wireType) } - var byteLen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowPacket @@ -410,25 +430,23 @@ func (m *FungibleTokenPacketData) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - byteLen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if byteLen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthPacket } - postIndex := iNdEx + byteLen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthPacket } if postIndex > l { return io.ErrUnexpectedEOF } - m.Metadata = append(m.Metadata[:0], dAtA[iNdEx:postIndex]...) - if m.Metadata == nil { - m.Metadata = []byte{} - } + m.Memo = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex diff --git a/modules/apps/transfer/types/packet_test.go b/modules/apps/transfer/types/packet_test.go index e5d21d648d2..9ddfaf3c9de 100644 --- a/modules/apps/transfer/types/packet_test.go +++ b/modules/apps/transfer/types/packet_test.go @@ -20,6 +20,7 @@ func TestFungibleTokenPacketDataValidateBasic(t *testing.T) { packetData FungibleTokenPacketData expPass bool }{ +<<<<<<< HEAD {"valid packet", NewFungibleTokenPacketData(denom, amount, addr1, addr2), true}, {"valid packet with large amount", NewFungibleTokenPacketData(denom, largeAmount, addr1, addr2), true}, {"invalid denom", NewFungibleTokenPacketData("", amount, addr1, addr2), false}, @@ -29,6 +30,18 @@ func TestFungibleTokenPacketDataValidateBasic(t *testing.T) { {"invalid large amount", NewFungibleTokenPacketData(denom, invalidLargeAmount, addr1, addr2), false}, {"missing sender address", NewFungibleTokenPacketData(denom, amount, emptyAddr, addr2), false}, {"missing recipient address", NewFungibleTokenPacketData(denom, amount, addr1, emptyAddr), false}, +======= + {"valid packet", NewFungibleTokenPacketData(denom, amount, addr1, addr2, ""), true}, + {"valid packet with memo", NewFungibleTokenPacketData(denom, amount, addr1, addr2, "memo"), true}, + {"valid packet with large amount", NewFungibleTokenPacketData(denom, largeAmount, addr1, addr2, ""), true}, + {"invalid denom", NewFungibleTokenPacketData("", amount, addr1, addr2, ""), false}, + {"invalid empty amount", NewFungibleTokenPacketData(denom, "", addr1, addr2, ""), false}, + {"invalid zero amount", NewFungibleTokenPacketData(denom, "0", addr1, addr2, ""), false}, + {"invalid negative amount", NewFungibleTokenPacketData(denom, "-1", addr1, addr2, ""), false}, + {"invalid large amount", NewFungibleTokenPacketData(denom, invalidLargeAmount, addr1, addr2, ""), false}, + {"missing sender address", NewFungibleTokenPacketData(denom, amount, emptyAddr, addr2, ""), false}, + {"missing recipient address", NewFungibleTokenPacketData(denom, amount, addr1, emptyAddr, ""), false}, +>>>>>>> 05685b3 (refactor: adapting transfer metadata bytes field to memo string (#2595)) } for i, tc := range testCases { diff --git a/modules/apps/transfer/types/tx.pb.go b/modules/apps/transfer/types/tx.pb.go index b2cacf0fab6..83f51b85a6a 100644 --- a/modules/apps/transfer/types/tx.pb.go +++ b/modules/apps/transfer/types/tx.pb.go @@ -50,8 +50,8 @@ type MsgTransfer struct { // Timeout timestamp (in nanoseconds) relative to the current block timestamp. // The timeout is disabled when set to 0. TimeoutTimestamp uint64 `protobuf:"varint,7,opt,name=timeout_timestamp,json=timeoutTimestamp,proto3" json:"timeout_timestamp,omitempty" yaml:"timeout_timestamp"` - // optional metadata - Metadata []byte `protobuf:"bytes,8,opt,name=metadata,proto3" json:"metadata,omitempty"` + // optional memo + Memo string `protobuf:"bytes,8,opt,name=memo,proto3" json:"memo,omitempty"` } func (m *MsgTransfer) Reset() { *m = MsgTransfer{} } @@ -143,6 +143,7 @@ func init() { } var fileDescriptor_7401ed9bed2f8e09 = []byte{ +<<<<<<< HEAD // 520 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x93, 0x31, 0x6f, 0xd3, 0x40, 0x14, 0xc7, 0x6d, 0x92, 0x86, 0x70, 0xa1, 0x15, 0x18, 0xa8, 0xdc, 0xa8, 0xd8, 0x91, 0x25, 0xa4, @@ -177,6 +178,42 @@ var fileDescriptor_7401ed9bed2f8e09 = []byte{ 0x34, 0x8f, 0xd9, 0x8b, 0x44, 0x92, 0x62, 0x44, 0x52, 0x39, 0x99, 0xcf, 0x40, 0x99, 0x27, 0xd4, 0x78, 0x3a, 0xfa, 0x2a, 0x03, 0x15, 0x77, 0xca, 0x35, 0x7e, 0xf9, 0x27, 0x00, 0x00, 0xff, 0xff, 0x7f, 0x1a, 0xac, 0x9b, 0x64, 0x03, 0x00, 0x00, +======= + // 516 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x53, 0xc1, 0x6e, 0xd3, 0x40, + 0x10, 0xb5, 0x49, 0x1a, 0xc2, 0x46, 0xad, 0x60, 0x81, 0xca, 0x8d, 0x8a, 0x1d, 0x59, 0x42, 0x0a, + 0x07, 0x76, 0xe5, 0x22, 0xa8, 0xd4, 0x13, 0x4a, 0x2f, 0x70, 0xa8, 0x04, 0x56, 0x4f, 0x5c, 0x8a, + 0xbd, 0x1d, 0x9c, 0x15, 0xb1, 0xc7, 0x78, 0x37, 0x16, 0xfd, 0x03, 0x8e, 0x7c, 0x42, 0xbf, 0x84, + 0x73, 0x8f, 0x3d, 0x72, 0x8a, 0x50, 0x72, 0xe1, 0x9c, 0x2f, 0x40, 0x6b, 0x3b, 0x21, 0xb9, 0x20, + 0x4e, 0x9e, 0x99, 0xf7, 0xc6, 0x6f, 0xdf, 0xce, 0x2c, 0x79, 0x2a, 0x63, 0xc1, 0xa3, 0x3c, 0x9f, + 0x48, 0x11, 0x69, 0x89, 0x99, 0xe2, 0xba, 0x88, 0x32, 0xf5, 0x09, 0x0a, 0x5e, 0x06, 0x5c, 0x7f, + 0x65, 0x79, 0x81, 0x1a, 0xe9, 0xa1, 0x8c, 0x05, 0xdb, 0xa4, 0xb1, 0x15, 0x8d, 0x95, 0x41, 0xff, + 0x51, 0x82, 0x09, 0x56, 0x44, 0x6e, 0xa2, 0xba, 0xa7, 0xef, 0x0a, 0x54, 0x29, 0x2a, 0x1e, 0x47, + 0x0a, 0x78, 0x19, 0xc4, 0xa0, 0xa3, 0x80, 0x0b, 0x94, 0x59, 0x83, 0x7b, 0x46, 0x5a, 0x60, 0x01, + 0x5c, 0x4c, 0x24, 0x64, 0xda, 0x08, 0xd6, 0x51, 0x4d, 0xf0, 0x7f, 0xb4, 0x48, 0xef, 0x4c, 0x25, + 0xe7, 0x8d, 0x12, 0x3d, 0x26, 0x3d, 0x85, 0xd3, 0x42, 0xc0, 0x45, 0x8e, 0x85, 0x76, 0xec, 0x81, + 0x3d, 0xbc, 0x37, 0xda, 0x5f, 0xce, 0x3c, 0x7a, 0x15, 0xa5, 0x93, 0x13, 0x7f, 0x03, 0xf4, 0x43, + 0x52, 0x67, 0xef, 0xb0, 0xd0, 0xf4, 0x35, 0xd9, 0x6b, 0x30, 0x31, 0x8e, 0xb2, 0x0c, 0x26, 0xce, + 0x9d, 0xaa, 0xf7, 0x60, 0x39, 0xf3, 0x1e, 0x6f, 0xf5, 0x36, 0xb8, 0x1f, 0xee, 0xd6, 0x85, 0xd3, + 0x3a, 0xa7, 0x2f, 0xc9, 0x8e, 0xc6, 0xcf, 0x90, 0x39, 0xad, 0x81, 0x3d, 0xec, 0x1d, 0x1d, 0xb0, + 0xda, 0x1b, 0x33, 0xde, 0x58, 0xe3, 0x8d, 0x9d, 0xa2, 0xcc, 0x46, 0xed, 0x9b, 0x99, 0x67, 0x85, + 0x35, 0x9b, 0xee, 0x93, 0x8e, 0x82, 0xec, 0x12, 0x0a, 0xa7, 0x6d, 0x04, 0xc3, 0x26, 0xa3, 0x7d, + 0xd2, 0x2d, 0x40, 0x80, 0x2c, 0xa1, 0x70, 0x76, 0x2a, 0x64, 0x9d, 0xd3, 0x8f, 0x64, 0x4f, 0xcb, + 0x14, 0x70, 0xaa, 0x2f, 0xc6, 0x20, 0x93, 0xb1, 0x76, 0x3a, 0x95, 0x66, 0x9f, 0x99, 0x19, 0x98, + 0xfb, 0x62, 0xcd, 0x2d, 0x95, 0x01, 0x7b, 0x53, 0x31, 0x46, 0x4f, 0x8c, 0xe8, 0x5f, 0x33, 0xdb, + 0xfd, 0x7e, 0xb8, 0xdb, 0x14, 0x6a, 0x36, 0x7d, 0x4b, 0x1e, 0xac, 0x18, 0xe6, 0xab, 0x74, 0x94, + 0xe6, 0xce, 0xdd, 0x81, 0x3d, 0x6c, 0x8f, 0x0e, 0x97, 0x33, 0xcf, 0xd9, 0xfe, 0xc9, 0x9a, 0xe2, + 0x87, 0xf7, 0x9b, 0xda, 0xf9, 0xaa, 0x44, 0x29, 0x69, 0xa7, 0x90, 0xa2, 0xd3, 0xad, 0x4c, 0x54, + 0xf1, 0x49, 0xf7, 0xdb, 0xb5, 0x67, 0xfd, 0xbe, 0xf6, 0x2c, 0x3f, 0x20, 0x0f, 0x37, 0xe6, 0x17, + 0x82, 0xca, 0x31, 0x53, 0x60, 0xdc, 0x2b, 0xf8, 0x32, 0x85, 0x4c, 0x40, 0x35, 0xc4, 0x76, 0xb8, + 0xce, 0x8f, 0x90, 0xb4, 0xce, 0x54, 0x42, 0xc7, 0xa4, 0xbb, 0x1e, 0xfb, 0x33, 0xf6, 0xaf, 0xe5, + 0x63, 0x1b, 0x0a, 0xfd, 0xe0, 0xbf, 0xa9, 0xab, 0xc3, 0x8c, 0xde, 0xdf, 0xcc, 0x5d, 0xfb, 0x76, + 0xee, 0xda, 0xbf, 0xe6, 0xae, 0xfd, 0x7d, 0xe1, 0x5a, 0xb7, 0x0b, 0xd7, 0xfa, 0xb9, 0x70, 0xad, + 0x0f, 0xc7, 0x89, 0xd4, 0xe3, 0x69, 0xcc, 0x04, 0xa6, 0xbc, 0x59, 0x65, 0x19, 0x8b, 0xe7, 0x09, + 0xf2, 0xf2, 0x15, 0x4f, 0xf1, 0x72, 0x3a, 0x01, 0x65, 0x9e, 0xce, 0xc6, 0x93, 0xd1, 0x57, 0x39, + 0xa8, 0xb8, 0x53, 0xad, 0xef, 0x8b, 0x3f, 0x01, 0x00, 0x00, 0xff, 0xff, 0xc1, 0x2a, 0x32, 0x96, + 0x5c, 0x03, 0x00, 0x00, +>>>>>>> 05685b3 (refactor: adapting transfer metadata bytes field to memo string (#2595)) } // Reference imports to suppress errors if they are not otherwise used. @@ -281,10 +318,10 @@ func (m *MsgTransfer) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l - if len(m.Metadata) > 0 { - i -= len(m.Metadata) - copy(dAtA[i:], m.Metadata) - i = encodeVarintTx(dAtA, i, uint64(len(m.Metadata))) + if len(m.Memo) > 0 { + i -= len(m.Memo) + copy(dAtA[i:], m.Memo) + i = encodeVarintTx(dAtA, i, uint64(len(m.Memo))) i-- dAtA[i] = 0x42 } @@ -412,7 +449,7 @@ func (m *MsgTransfer) Size() (n int) { if m.TimeoutTimestamp != 0 { n += 1 + sovTx(uint64(m.TimeoutTimestamp)) } - l = len(m.Metadata) + l = len(m.Memo) if l > 0 { n += 1 + l + sovTx(uint64(l)) } @@ -681,9 +718,9 @@ func (m *MsgTransfer) Unmarshal(dAtA []byte) error { } case 8: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Metadata", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Memo", wireType) } - var byteLen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowTx @@ -693,25 +730,23 @@ func (m *MsgTransfer) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - byteLen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if byteLen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthTx } - postIndex := iNdEx + byteLen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthTx } if postIndex > l { return io.ErrUnexpectedEOF } - m.Metadata = append(m.Metadata[:0], dAtA[iNdEx:postIndex]...) - if m.Metadata == nil { - m.Metadata = []byte{} - } + m.Memo = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex diff --git a/proto/ibc/applications/transfer/v1/tx.proto b/proto/ibc/applications/transfer/v1/tx.proto index d7396fa4bd5..31a23f6834f 100644 --- a/proto/ibc/applications/transfer/v1/tx.proto +++ b/proto/ibc/applications/transfer/v1/tx.proto @@ -38,8 +38,8 @@ message MsgTransfer { // Timeout timestamp (in nanoseconds) relative to the current block timestamp. // The timeout is disabled when set to 0. uint64 timeout_timestamp = 7 [(gogoproto.moretags) = "yaml:\"timeout_timestamp\""]; - // optional metadata - bytes metadata = 8; + // optional memo + string memo = 8; } // MsgTransferResponse defines the Msg/Transfer response type. diff --git a/proto/ibc/applications/transfer/v2/packet.proto b/proto/ibc/applications/transfer/v2/packet.proto index 953f67128a2..d2626d36798 100644 --- a/proto/ibc/applications/transfer/v2/packet.proto +++ b/proto/ibc/applications/transfer/v2/packet.proto @@ -16,6 +16,6 @@ message FungibleTokenPacketData { string sender = 3; // the recipient address on the destination chain string receiver = 4; - // optional metadata - bytes metadata = 5; + // optional memo + string memo = 5; }