Implement version negotiation as per spec & test dynamic protocol support with CosmWASM (ideally).
Happy to work on this.
@ethanfrey If https://www.mintscan.io/proposals/25 passes, do you plan to work on this?
The cosmos hub proposal is focused on governance gating and migrations, and not related to any ibc work.
This ibc work is awaiting final approval and a contract from the icf. When that is finalized (and we release 0.8 in a week or so), IBC becomes high priority for me and happy to work on this or other related tasks
@ethanfrey Does CosmWASM have a particular set of requirements for channel-level versioning?
We are also happy to work on this at IG but want to make sure we understand the dynamic-contract use-case.
In particular, should this be different than https://github.com/cosmos/cosmos-sdk/pull/6534?
Okay, I will write up my thoughts here on the what and why (not the how) of channel level-versioning.
It is different from connection-level versioning - #6534 - in that negotiation ensures compatible IBC packets, where here I am interested in compatible payloads. The channel-level versioning could be implemented by each app (and maybe should??) but at least having a clear definition and process that all apps follow will make compatibility much easier.
Example use case:
I have a CW20 (CosmWasm fungible token) contract on Zone A that issues FUN tokens. It supports ICS20 - you can send and receive FUN tokens to other chains once they are minted. Any chains supporting ICS20 - eg. over a channel to remote/transfer.
This contract also has a mintable interface that allows the creation of new tokens (or setting up a new bonding curve / uniswap), but that is controlled by a DAO on Zone B. For this we have a new protocol, say "ICS77" that allows this "mint" message to come through.
When opening a channel with the contract, we must see if the remote contract wants to speak ICS20 or ICS77. If it is ICS20, we allow (almost) anyone to open a channel, but we only handle our token and returning our same token. If it is ICS77, we do some more checks as to who is trying to connect (we only allow one client/port that corresponds to our "admin").
I see the following options:
Do not channel handshake and allow any ICS20 or ICS77 messages on the same channel, enforcing the constraints on the packets. This can cause issues when our token contract tries to send an ICS20 packet to the DAO (which connected to run ICS77 and doesn't support ICS20). I guess these packets would just error, but it is a confusing UX
Provide some channel handshake where we find the set of protocols that both the initiator and the receiver support and if it is not the empty set, we create the channel. This channel then has some meta-data as to what protocols will run over it. And if there is incompatibility, it fails early rather than later during packets
There is intention on the part of the initiator of the channel, which requests certain protocol(s). The recipient can accept this or reject it. If accepted, we store the metadata of those protocols (which may be fewer than the intersection above).
Other ideas?
Even if we define this protocol handshake as the first packets to run over the channel and not as part of a channel handshake, it would be good to specify it well, so all apps could use the same handshake mechanism.
@cwgoes does that use case make sense?
I'd love to hear some better ideas on how to support it.
Provide some channel handshake where we find the set of protocols that both the initiator and the receiver support and if it is not the empty set, we create the channel. This channel then has some meta-data as to what protocols will run over it. And if there is incompatibility, it fails early rather than later during packets
There is intention on the part of the initiator of the channel, which requests certain protocol(s). The recipient can accept this or reject it. If accepted, we store the metadata of those protocols (which may be fewer than the intersection above).
Right, these make sense, this was the use-case we were thinking about, and we should be able to do this with the current versioning protocol without any issues, since both sides of the handshake can agree on the version string (opaque to IBC, but it can be treated as a set of protocols from which a subset is picked, for example) - it would just be good to have tests for this (cc @colin-axner).
Most helpful comment
Okay, I will write up my thoughts here on the what and why (not the how) of channel level-versioning.
It is different from connection-level versioning - #6534 - in that negotiation ensures compatible IBC packets, where here I am interested in compatible payloads. The channel-level versioning could be implemented by each app (and maybe should??) but at least having a clear definition and process that all apps follow will make compatibility much easier.