How Channel Upgradability Will Level Up the Interchain
Central to the transport layer of IBC (Inter-Blockchain Communication) protocol are channels. Channels act as a conduit to transfer data packets between two application modules on different chains — where each channel is associated with a single application.
Channel upgradability will soon become an important feature release as part of IBC. Why is that? What is channel upgradability? How is it important? This blog post answers these questions and more.
What is channel upgradability and why is it needed?
Channel upgradability is an IBC-level protocol that allows chains to leverage new channel features without having to create new channels or perform a network-wide upgrade.
As of today, Cosmos chains that want to upgrade an application module or add a middleware have no way of doing so while maintaining the existing channels. For example, to update the transfer module to leverage a novel feature, or to implement the fee middleware module (for on-chain incentivisation of relayers), either a coordinated network-wide upgrade is required or a new channel must be negotiated. The downside here is the loss of accumulated state/liquidity, token fungibility, and network effects on the existing channel.
With the release of channel upgradability (slated for 2023 Q1), this is no longer a concern. Applications will be able to implement features such as including a memo field in the packet data for fungible tokens, adding denom metadata to tokens, or utilize the fee middleware, while maintaining the channels on which they currently operate.
Channel upgrades will be initialized using a handshake process that is designed to be similar to the standard connection/channel opening handshake.
A successful handshake process for channel upgrades works as follows:
- The chain initiating the upgrade process (chain A) sets its channel state from OPEN to INITUPGRADE via the ChanUpgradeInit function.
- Subsequently, the counterparty (chain B) changes its channel end from OPEN to TRYUPGRADE with ChanUpgradeTry.
- Upon successful completion of the previous step, chain A sets its channel state to OPEN with ChanUpgradeAck.
- Finally, chain B sets its channel state to OPEN with ChanUpgradeConfirm.
The ChanUpgradeInit function is triggered by a relayer or the chain itself upon governance authorization (more on access control detailed below). Core IBC on chain A performs the verification and ordering checks at the transport layer. Afterwards, a callback to the application on chain A (indicated by blue arrows) allows the app to perform its custom INIT logic. Subsequently, chain B initiates ChanUpgradeTry. Similar to the callbacks on chain A, the application on chain B will do its own custom TRY logic. Finally the ChanUpgradeAck and ChanUpgradeConfirm are sent by the relayers.
Note that the upgrade process is atomic. Therefore, either both channel ends upgrade to the new version and process packets according to the upgraded logic, or the upgrade fails, in which case both ends of the channel fall back to its previous version (as shown in Figure 2). This maintains liveness guarantees in the event of one chain canceling the process mid-handshake.
This is also the primary difference between a channel opening handshake and the handshake for upgrades. In the former, if the handshake stalls at any one of the channel opening steps (INIT, TRY, etc.), then the handshake fails and a new one has to be initiated eventually. But for channel upgrades, if the counterparty does not agree to the proposed update to its channel end and cancels the upgrade mid-handshake (or if the counterparty has not enabled the upgrade feature on its end) the process is aborted and the pre-update channel version is restored.
Another key aspect to note is that the specification does not mention who should have the access control to initiate a channel upgrade (the ChanUpgradeInit). This can be done in a permissioned or permissionless manner.
Given any two chains A and B, there are at least 3 different scenarios by which the ChanUpgradeInit can be called:
- A and B pre-approves certain upgrade types: a technical committee/DAO on A, elected by chain governance, initiates a governance proposal using the groups module stating their chain pre approves all channel upgrade types of the transfer module from v1 to v2. If this proposal passes, and if chain B has also pre-approved upgrades of this type (transfer v1 to v2), the channel upgrade executes in a permissioned and pre-approved manner. In this case, any relayer can submit the ChanUpgradeInit and ChanUpgradeTry messages.
- Governance-gated upgrades on A and pre-approved upgrade type on B: chain A passes a governance proposal to approve an upgrade and executes the ChanUpgradeInit. Chain B has pre-approved all upgrades of this type (initiated on A) and so any relayer can submit the ChanUpgradeTry message on B.
- Governance-gated upgrades on A and B: chains A and B both gate the upgrade by a full chain governance or a DAO/technical committee via the groups module. Chain A calls the Init. And chain B, within the timeout window specified by A, must call the Try function.
Note that in the 3rd case where all upgrades on a counterparty are gated by governance, the channel upgrade timeout window specified on the source chain must take this information into account since governance proposals can span from days to weeks depending on the chain.
Finally, a permissionless upgrade could be one where a chain agrees or pre-approves a set list of upgrade types to which the counterparty agrees by default. In this case any relayer can send the ChanUpgradeTry to the counterparty.
Sidenote: we are currently in the process of reaching out to different chains and collecting feedback on how they would want to tailor the access control for upgrades on their chain. Specifying the access control in an optimal manner is important given that it directly impacts the end-user experience. If you have any thoughts or ideas or questions regarding this, please feel free to share them here.
Modifications to channel end parameters
It is important to note that anything within the channel end struct except the identifiers (counterparty port ID and channel ID) can be changed — such as the version, connection hops, and channel ordering. For example, the fee middleware can be added to an application module by updating the version string as shown here.
The channel ordering can only be upgraded if the new ordering is a subset of its previous one. This means that a channel can be upgraded from an ordered to an unordered channel but not the other way around.
Channel upgradability is a key component for chains to take advantage of new application features in a scalable manner. The fee middleware module — which offers an in-protocol solution to fund relayer operations — will be able to be added to existing channels using channel upgradability. And we expect many more utility-driven channel features, especially for ICS-20 (fungible token transfers) to launch in the future.
As part of our ongoing user research, we are in the process of talking to different Cosmos chains and soliciting feedback on the topic of access controls. If you as a developer/contributor to the Interchain have any thoughts on this matter that you would like to discuss with us, we encourage you or your team to proactively reach out to us here, or on the ‘developers’ channel on IBC Gang discord.