Skip to content

Commit

Permalink
feat(ica): allow unordered ica channels (#5633)
Browse files Browse the repository at this point in the history
* Remove order check for ICA host and controller upgrade callbacks (#5561)

* imp: remove the channel type = ordered checks from both host and controller (#5578)

* rm checks and tests, amend docustring

* rm unnecessary test

* When a channel reopens the ordering and metadata must not change (#5562)

* chore: require active channel be CLOSED before re-opening. (#5601)

* docs: Update ICA documentation with support for unordered channels (#5607)

* Allow specifying order when registering ICA account (#5608)

* proto: Add Order to MsgRegisterInterchainAccount.

* chore: apply proto changes to go files.

* Add ordering to cli tx for Register.

* Add documentation line for tx now accepting ordering.

* Address feedback review.

Co-authored-by: Carlos Rodriguez <carlos@interchain.io>

* Address Cian's feedback; spacing.

---------

Co-authored-by: Carlos Rodriguez <carlos@interchain.io>

* docs: ICA register CLI (#5625)

* imp(ica/host): removed previous version validation check (#5613)

* imp: removed validation check

* test: updated icahost test

* docs: added godocs

* docs: added godocs

* chore(ica/host): require active channel be CLOSED before re-opening (#5630)

* chore(ica/host): require active channel be CLOSED before re-opening

* Update modules/apps/27-interchain-accounts/host/keeper/handshake_test.go

Co-authored-by: DimitrisJim <d.f.hilliard@gmail.com>

---------

Co-authored-by: DimitrisJim <d.f.hilliard@gmail.com>

* e2e: ordered ica channel is upgraded to unordered (#5616)

* E2E test where unordered channel is used with ICA (#5566)

* test: add test to use an unordered ICA channel

* chore: add hard coded UNORDERED channel Order

* proto: Add Order to MsgRegisterInterchainAccount.

* chore: apply proto changes to go files.

* chore: apply proto changes to go files.

* chore: e2e test passing with hard coded ordered value

* Add ordering to cli tx for Register.

* Add documentation line for tx now accepting ordering.

* Address feedback review.

Co-authored-by: Carlos Rodriguez <carlos@interchain.io>

* Address Cian's feedback; spacing.

* Update e2e/tests/interchain_accounts/base_test.go

Co-authored-by: Charly <charly@interchain.io>

---------

Co-authored-by: DimitrisJim <d.f.hilliard@gmail.com>
Co-authored-by: Carlos Rodriguez <carlos@interchain.io>
Co-authored-by: Charly <charly@interchain.io>

* fix: host chan open try test (#5632)

* chore: fix linter and merge main

* chore: doc lint issue fix

* docs: add extra information about ICA channel reopening (#5631)

* docs: add extra information about ICA channel reopening

* add link to active channels section

* Apply suggestions from code review

Co-authored-by: Damian Nolan <damiannolan@gmail.com>
Co-authored-by: srdtrk <59252793+srdtrk@users.noreply.github.com>

* Update 01-overview.md

---------

Co-authored-by: Damian Nolan <damiannolan@gmail.com>
Co-authored-by: srdtrk <59252793+srdtrk@users.noreply.github.com>

* chore: rm order checks reintroduced after merge conflict.

* e2e: comment out failing e2e

* chore: lintertroubles

---------

Co-authored-by: Cian Hatton <cian@interchain.io>
Co-authored-by: Charly <charly@interchain.io>
Co-authored-by: DimitrisJim <d.f.hilliard@gmail.com>
Co-authored-by: Carlos Rodriguez <carlos@interchain.io>
Co-authored-by: Damian Nolan <damiannolan@gmail.com>
Co-authored-by: chatton <github.qpeyb@simplelogin.fr>
Co-authored-by: Colin Axnér <25233464+colin-axner@users.noreply.github.com>
(cherry picked from commit 6174822)

# Conflicts:
#	docs/docs/02-apps/02-interchain-accounts/01-overview.md
#	docs/docs/02-apps/02-interchain-accounts/05-messages.md
#	docs/docs/02-apps/02-interchain-accounts/08-client.md
#	docs/docs/02-apps/02-interchain-accounts/09-active-channels.md
#	e2e/tests/core/04-channel/upgrades_test.go
#	e2e/tests/interchain_accounts/base_test.go
#	e2e/tests/interchain_accounts/gov_test.go
#	e2e/tests/interchain_accounts/groups_test.go
#	e2e/tests/interchain_accounts/incentivized_test.go
#	e2e/tests/interchain_accounts/localhost_test.go
#	e2e/tests/interchain_accounts/params_test.go
#	e2e/tests/upgrades/genesis_test.go
#	e2e/testsuite/testconfig.go
#	modules/apps/27-interchain-accounts/controller/types/msgs_test.go
  • Loading branch information
srdtrk authored and mergify[bot] committed Jan 17, 2024
1 parent 73ddc6d commit 709cf8a
Show file tree
Hide file tree
Showing 28 changed files with 3,856 additions and 184 deletions.
48 changes: 48 additions & 0 deletions docs/docs/02-apps/02-interchain-accounts/01-overview.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
---
title: Overview
sidebar_label: Overview
sidebar_position: 1
slug: /apps/interchain-accounts/overview
---


# Overview

:::note Synopsis
Learn about what the Interchain Accounts module is
:::

## What is the Interchain Accounts module?

Interchain Accounts is the Cosmos SDK implementation of the ICS-27 protocol, which enables cross-chain account management built upon IBC.

- How does an interchain account differ from a regular account?

Regular accounts use a private key to sign transactions. Interchain Accounts are instead controlled programmatically by counterparty chains via IBC packets.

## Concepts

`Host Chain`: The chain where the interchain account is registered. The host chain listens for IBC packets from a controller chain which should contain instructions (e.g. Cosmos SDK messages) for which the interchain account will execute.

`Controller Chain`: The chain registering and controlling an account on a host chain. The controller chain sends IBC packets to the host chain to control the account.

`Interchain Account`: An account on a host chain created using the ICS-27 protocol. An interchain account has all the capabilities of a normal account. However, rather than signing transactions with a private key, a controller chain will send IBC packets to the host chain which signals what transactions the interchain account should execute.

`Authentication Module`: A custom application module on the controller chain that uses the Interchain Accounts module to build custom logic for the creation & management of interchain accounts. It can be either an IBC application module using the [legacy API](10-legacy/03-keeper-api.md), or a regular Cosmos SDK application module sending messages to the controller submodule's `MsgServer` (this is the recommended approach from ibc-go v6 if access to packet callbacks is not needed). Please note that the legacy API will eventually be removed and IBC applications will not be able to use them in later releases.

## SDK security model

SDK modules on a chain are assumed to be trustworthy. For example, there are no checks to prevent an untrustworthy module from accessing the bank keeper.

The implementation of ICS-27 in ibc-go uses this assumption in its security considerations.

The implementation assumes other IBC application modules will not bind to ports within the ICS-27 namespace.

## Channel Closure

The provided interchain account host and controller implementations do not support `ChanCloseInit`. However, they do support `ChanCloseConfirm`.
This means that the host and controller modules cannot close channels, but they will confirm channel closures initiated by other implementations of ICS-27.

In the event of a channel closing (due to a packet timeout in an ordered channel, for example), the interchain account associated with that channel can become accessible again if a new channel is created with a (JSON-formatted) version string that encodes the exact same `Metadata` information of the previous channel. The channel can be reopened using either [`MsgRegisterInterchainAccount`](./05-messages.md#msgregisterinterchainaccount) or `MsgChannelOpenInit`. If `MsgRegisterInterchainAccount` is used, then it is possible to leave the `version` field of the message empty, since it will be filled in by the controller submodule. If `MsgChannelOpenInit` is used, then the `version` field must be provided with the correct JSON-encoded `Metadata` string. See section [Understanding Active Channels](./09-active-channels.md#understanding-active-channels) for more information.

When reopening a channel with the default controller submodule, the ordering of the channel cannot be changed. In order to change the ordering of the channel, the channel has to go through a [channel upgrade handshake](../../01-ibc/06-channel-upgrades.md) or reopen the channel with a custom controller implementation.
79 changes: 79 additions & 0 deletions docs/docs/02-apps/02-interchain-accounts/05-messages.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
---
title: Messages
sidebar_label: Messages
sidebar_position: 5
slug: /apps/interchain-accounts/messages
---


# Messages

## `MsgRegisterInterchainAccount`

An Interchain Accounts channel handshake can be initiated using `MsgRegisterInterchainAccount`:

```go
type MsgRegisterInterchainAccount struct {
Owner string
ConnectionID string
Version string
Order channeltypes.Order
}
```

This message is expected to fail if:

- `Owner` is an empty string.
- `ConnectionID` is invalid (see [24-host naming requirements](https://github.com/cosmos/ibc/blob/master/spec/core/ics-024-host-requirements/README.md#paths-identifiers-separators)).

This message will construct a new `MsgChannelOpenInit` on chain and route it to the core IBC message server to initiate the opening step of the channel handshake.

The controller submodule will generate a new port identifier and claim the associated port capability. The caller is expected to provide an appropriate application version string. For example, this may be an ICS-27 JSON encoded [`Metadata`](https://github.com/cosmos/ibc-go/blob/v6.0.0/proto/ibc/applications/interchain_accounts/v1/metadata.proto#L11) type or an ICS-29 JSON encoded [`Metadata`](https://github.com/cosmos/ibc-go/blob/v6.0.0/proto/ibc/applications/fee/v1/metadata.proto#L11) type with a nested application version.
If the `Version` string is omitted, the controller submodule will construct a default version string in the `OnChanOpenInit` handshake callback.

```go
type MsgRegisterInterchainAccountResponse struct {
ChannelID string
PortId string
}
```

The `ChannelID` and `PortID` are returned in the message response.

## `MsgSendTx`

An Interchain Accounts transaction can be executed on a remote host chain by sending a `MsgSendTx` from the corresponding controller chain:

```go
type MsgSendTx struct {
Owner string
ConnectionID string
PacketData InterchainAccountPacketData
RelativeTimeout uint64
}
```

This message is expected to fail if:

- `Owner` is an empty string.
- `ConnectionID` is invalid (see [24-host naming requirements](https://github.com/cosmos/ibc/blob/master/spec/core/ics-024-host-requirements/README.md#paths-identifiers-separators)).
- `PacketData` contains an `UNSPECIFIED` type enum, the length of `Data` bytes is zero or the `Memo` field exceeds 256 characters in length.
- `RelativeTimeout` is zero.

This message will create a new IBC packet with the provided `PacketData` and send it via the channel associated with the `Owner` and `ConnectionID`.
The `PacketData` is expected to contain a list of serialized `[]sdk.Msg` in the form of `CosmosTx`. Please note the signer field of each `sdk.Msg` must be the interchain account address.
When the packet is relayed to the host chain, the `PacketData` is unmarshalled and the messages are authenticated and executed.

```go
type MsgSendTxResponse struct {
Sequence uint64
}
```

The packet `Sequence` is returned in the message response.

## Atomicity

As the Interchain Accounts module supports the execution of multiple transactions using the Cosmos SDK `Msg` interface, it provides the same atomicity guarantees as Cosmos SDK-based applications, leveraging the [`CacheMultiStore`](https://docs.cosmos.network/main/learn/advanced/store#cachemultistore) architecture provided by the [`Context`](https://docs.cosmos.network/main/learn/advanced/context.html) type.

This provides atomic execution of transactions when using Interchain Accounts, where state changes are only committed if all `Msg`s succeed.
202 changes: 202 additions & 0 deletions docs/docs/02-apps/02-interchain-accounts/08-client.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,202 @@
---
title: Client
sidebar_label: Client
sidebar_position: 8
slug: /apps/interchain-accounts/client
---

# Client

## CLI

A user can query and interact with the Interchain Accounts module using the CLI. Use the `--help` flag to discover the available commands:

```shell
simd query interchain-accounts --help
```

> Please not that this section does not document all the available commands, but only the ones that deserved extra documentation that was not possible to fit in the command line documentation.
### Controller

A user can query and interact with the controller submodule.

#### Query

The `query` commands allow users to query the controller submodule.

```shell
simd query interchain-accounts controller --help
```

#### Transactions

The `tx` commands allow users to interact with the controller submodule.

```shell
simd tx interchain-accounts controller --help
```

#### `register`

The `register` command allows users to register an interchain account on a host chain on the provided connection.

```shell
simd tx interchain-accounts controller register [connection-id] [flags]
```

During registration a new channel is set up between controller and host. There are two flags available that influence the channel that is created:

- `--version` to specify the (JSON-formatted) version string of the channel. For example: `{\"version\":\"ics27-1\",\"encoding\":\"proto3\",\"tx_type\":\"sdk_multi_msg\",\"controller_connection_id\":\"connection-0\",\"host_connection_id\":\"connection-0\"}`. Passing a custom version string is useful if you want to specify, for example, the encoding format of the interchain accounts packet data (either `proto3` or `proto3json`). If not specified the controller submodule will generate a default version string.
- `--ordering` to specify the ordering of the channel. Available options are `order_ordered` (default if not specified) and `order_unordered`.

Example:

```shell
simd tx interchain-accounts controller register connection-0 --ordering order_unordered --from cosmos1..
```

#### `send-tx`

The `send-tx` command allows users to send a transaction on the provided connection to be executed using an interchain account on the host chain.

```shell
simd tx interchain-accounts controller send-tx [connection-id] [path/to/packet_msg.json]
```

Example:

```shell
simd tx interchain-accounts controller send-tx connection-0 packet-data.json --from cosmos1..
```

See below for example contents of `packet-data.json`. The CLI handler will unmarshal the following into `InterchainAccountPacketData` appropriately.

```json
{
"type":"TYPE_EXECUTE_TX",
"data":"CqIBChwvY29zbW9zLmJhbmsudjFiZXRhMS5Nc2dTZW5kEoEBCkFjb3Ntb3MxNWNjc2hobXAwZ3N4MjlxcHFxNmc0em1sdG5udmdteXU5dWV1YWRoOXkybmM1emowc3psczVndGRkehItY29zbW9zMTBoOXN0YzV2Nm50Z2V5Z2Y1eGY5NDVuanFxNWgzMnI1M3VxdXZ3Gg0KBXN0YWtlEgQxMDAw",
"memo":""
}
```

Note the `data` field is a base64 encoded byte string as per the tx encoding agreed upon during the channel handshake.

A helper CLI is provided in the host submodule which can be used to generate the packet data JSON using the counterparty chain's binary. See the [`generate-packet-data` command](#generate-packet-data) for an example.

### Host

A user can query and interact with the host submodule.

#### Query

The `query` commands allow users to query the host submodule.

```shell
simd query interchain-accounts host --help
```

#### Transactions

The `tx` commands allow users to interact with the controller submodule.

```shell
simd tx interchain-accounts host --help
```

##### `generate-packet-data`

The `generate-packet-data` command allows users to generate protobuf or proto3 JSON encoded interchain accounts packet data for input message(s). The packet data can then be used with the controller submodule's [`send-tx` command](#send-tx). The `--encoding` flag can be used to specify the encoding format (value must be either `proto3` or `proto3json`); if not specified, the default will be `proto3`. The `--memo` flag can be used to include a memo string in the interchain accounts packet data.

```shell
simd tx interchain-accounts host generate-packet-data [message]
```

Example:

```shell
simd tx interchain-accounts host generate-packet-data '[{
"@type":"/cosmos.bank.v1beta1.MsgSend",
"from_address":"cosmos15ccshhmp0gsx29qpqq6g4zmltnnvgmyu9ueuadh9y2nc5zj0szls5gtddz",
"to_address":"cosmos10h9stc5v6ntgeygf5xf945njqq5h32r53uquvw",
"amount": [
{
"denom": "stake",
"amount": "1000"
}
]
}]' --memo memo
```

The command accepts a single `sdk.Msg` or a list of `sdk.Msg`s that will be encoded into the outputs `data` field.

Example output:

```json
{
"type":"TYPE_EXECUTE_TX",
"data":"CqIBChwvY29zbW9zLmJhbmsudjFiZXRhMS5Nc2dTZW5kEoEBCkFjb3Ntb3MxNWNjc2hobXAwZ3N4MjlxcHFxNmc0em1sdG5udmdteXU5dWV1YWRoOXkybmM1emowc3psczVndGRkehItY29zbW9zMTBoOXN0YzV2Nm50Z2V5Z2Y1eGY5NDVuanFxNWgzMnI1M3VxdXZ3Gg0KBXN0YWtlEgQxMDAw",
"memo":"memo"
}
```

## gRPC

A user can query the interchain account module using gRPC endpoints.

### Controller

A user can query the controller submodule using gRPC endpoints.

#### `InterchainAccount`

The `InterchainAccount` endpoint allows users to query the controller submodule for the interchain account address for a given owner on a particular connection.

```shell
ibc.applications.interchain_accounts.controller.v1.Query/InterchainAccount
```

Example:

```shell
grpcurl -plaintext \
-d '{"owner":"cosmos1..","connection_id":"connection-0"}' \
localhost:9090 \
ibc.applications.interchain_accounts.controller.v1.Query/InterchainAccount
```

#### `Params`

The `Params` endpoint users to query the current controller submodule parameters.

```shell
ibc.applications.interchain_accounts.controller.v1.Query/Params
```

Example:

```shell
grpcurl -plaintext \
localhost:9090 \
ibc.applications.interchain_accounts.controller.v1.Query/Params
```

### Host

A user can query the host submodule using gRPC endpoints.

#### `Params`

The `Params` endpoint users to query the current host submodule parameters.

```shell
ibc.applications.interchain_accounts.host.v1.Query/Params
```

Example:

```shell
grpcurl -plaintext \
localhost:9090 \
ibc.applications.interchain_accounts.host.v1.Query/Params
```
45 changes: 45 additions & 0 deletions docs/docs/02-apps/02-interchain-accounts/09-active-channels.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
---
title: Active Channels
sidebar_label: Active Channels
sidebar_position: 9
slug: /apps/interchain-accounts/active-channels
---

# Understanding Active Channels

The Interchain Accounts module uses either [ORDERED or UNORDERED](https://github.com/cosmos/ibc/tree/master/spec/core/ics-004-channel-and-packet-semantics#ordering) channels.

When using `ORDERED` channels, the order of transactions when sending packets from a controller to a host chain is maintained.

When using `UNORDERED` channels, there is no guarantee that the order of transactions when sending packets from the controller to the host chain is maintained.

> A limitation when using ORDERED channels is that when a packet times out the channel will be closed.
In the case of a channel closing, a controller chain needs to be able to regain access to the interchain account registered on this channel. `Active Channels` enable this functionality.

When an Interchain Account is registered using `MsgRegisterInterchainAccount`, a new channel is created on a particular port. During the `OnChanOpenAck` and `OnChanOpenConfirm` steps (on controller & host chain respectively) the `Active Channel` for this interchain account is stored in state.

It is possible to create a new channel using the same controller chain portID if the previously set `Active Channel` is now in a `CLOSED` state. This channel creation can be initialized programmatically by sending a new `MsgChannelOpenInit` message like so:

```go
msg := channeltypes.NewMsgChannelOpenInit(portID, string(versionBytes), channeltypes.ORDERED, []string{connectionID}, icatypes.HostPortID, authtypes.NewModuleAddress(icatypes.ModuleName).String())
handler := keeper.msgRouter.Handler(msg)
res, err := handler(ctx, msg)
if err != nil {
return err
}
```

Alternatively, any relayer operator may initiate a new channel handshake for this interchain account once the previously set `Active Channel` is in a `CLOSED` state. This is done by initiating the channel handshake on the controller chain using the same portID associated with the interchain account in question.

It is important to note that once a channel has been opened for a given interchain account, new channels can not be opened for this account until the currently set `Active Channel` is set to `CLOSED`.

## Future improvements

Future versions of the ICS-27 protocol and the Interchain Accounts module will likely use a new channel type that provides ordering of packets without the channel closing in the event of a packet timing out, thus removing the need for `Active Channels` entirely.
The following is a list of issues which will provide the infrastructure to make this possible:

- [IBC Channel Upgrades](https://github.com/cosmos/ibc-go/issues/1599)
- [Implement ORDERED_ALLOW_TIMEOUT logic in 04-channel](https://github.com/cosmos/ibc-go/issues/1661)
- [Add ORDERED_ALLOW_TIMEOUT as supported ordering in 03-connection](https://github.com/cosmos/ibc-go/issues/1662)
- [Allow ICA channels to be opened as ORDERED_ALLOW_TIMEOUT](https://github.com/cosmos/ibc-go/issues/1663)
Loading

0 comments on commit 709cf8a

Please sign in to comment.