# ADR 025: IBC Passive Channels
# Changelog
- 2021-04-23: Change status to "deprecated"
- 2020-05-23: Provide sample Go code and more details
- 2020-05-18: Initial Draft
# Status
deprecated
# Context
The current "naive" IBC Relayer strategy currently establishes a single predetermined IBC channel atop a single connection between two clients (each potentially of a different chain). This strategy then detects packets to be relayed by watching for send_packet
and recv_packet
events matching that channel, and sends the necessary transactions to relay those packets.
We wish to expand this "naive" strategy to a "passive" one which detects and relays both channel handshake messages and packets on a given connection, without the need to know each channel in advance of relaying it.
In order to accomplish this, we propose adding more comprehensive events to expose channel metadata for each transaction sent from the x/ibc/core/04-channel/keeper/handshake.go
and x/ibc/core/04-channel/keeper/packet.go
modules.
Here is an example of what would be in ChanOpenInit
:
These metadata events capture all the "header" information needed to route IBC channel handshake transactions without requiring the client to query any data except that of the connection ID that it is willing to relay. It is intended that channel_meta.src_connection
is the only event key that needs to be indexed for a passive relayer to function.
# Handling Channel Open Attempts
In the case of the passive relayer, when one chain sends a ChanOpenInit
, the relayer should inform the other chain of this open attempt and allow that chain to decide how (and if) it continues the handshake. Once both chains have actively approved the channel opening, then the rest of the handshake can happen as it does with the current "naive" relayer.
To implement this behavior, we propose replacing the cbs.OnChanOpenTry
callback with a new cbs.OnAttemptChanOpenTry
callback which explicitly handles the MsgChannelOpenTry
, usually by resulting in a call to keeper.ChanOpenTry
. The typical implementation, in x/ibc-transfer/module.go
would be compatible with the current "naive" relayer, as follows:
Here is how this callback would be used, in the implementation of x/ibc/handler.go
:
The reason we do not have a more structured interaction between x/ibc/handler.go
and the port's module (to explicitly negotiate versions, etc) is that we do not wish to constrain the app module to have to finish handling the MsgChannelOpenTry
during this transaction or even this block.
# Decision
- Expose events to allow "passive" connection relayers.
- Enable application-initiated channels via such passive relayers.
- Allow port modules to control how to handle open-try messages.
# Consequences
# Positive
Makes channels into a complete application-level abstraction.
Applications have full control over initiating and accepting channels, rather than expecting a relayer to tell them when to do so.
A passive relayer does not have to know what kind of channel (version string, ordering constraints, firewalling logic) the application supports. These are negotiated directly between applications.
# Negative
Increased event size for IBC messages.
# Neutral
More IBC events are exposed.
# References
- The Agoric VM's IBC handler currently accomodates
attemptChanOpenTry
(opens new window)