cosmos / ibc

Interchain Standards (ICS) for the Cosmos network & interchain ecosystem.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

ICS 03/04: Some questions about handshake

michwqy opened this issue · comments

These questions may seem a bit silly, but I need some help to better understand the handshake process. Connections and channels have a similar handshake process, and I will use connections as an example.

Question 1

Both connOpenInit and connOpenTry need to create a connection end with a new identifier. If both Chain A and Chain B want to establish a connection with the other party, both parties will create an INIT state connection end, and then each party will create a TRYOPEN state connection end to complete the handshake with the other party. Finally, there will be two connections. I think this is a bit strange, why can't we directly use the two connection ends of INIT state to complete the handshake. Besides, it seems that the connection ends of INIT and TRYOPEN states will share the identifier count. Is there a problem with this? Like connOpenInit ran out of identifiers, resulting in the inability to execute connOpenTry.

Question 2

A INIT state connection end of the counterparty chain can be used to create multiple TRYOPEN state connection ends, because connOpenTry only verifies the counterparty connection end's state and does not check if it already has a corresponding TRYOPEN state connection end. However, only one of these TRYOPEN state connection ends will match the INIT state connection end in the connOpenAck because the connOpenAck will change connection end's state. The remaining connection ends will freeze in their previous states. I think these frozen connection ends will interfere with the normal use of users. Why can't we close these connection/channel ends that can't complete the handshake, or check if there is already a corresponding end in connOpenTry?

Hi @michwqy.

Question 1

The flow that usually happens is that the relayer will send ConnOpenInit datagram to chain A, and once chain A is in INIT state, then the relayer will send ConnOpenTry datagram to chain B. I don't think it happens very often that one or multiple relayers will send ConnOpenInit datagram simultaneously to chain A and B. But if it does happen, then the relayer only needs to send ConnOpenTry to one of the chains, not both. In this situation the chain that executed both ConnOpenInit and ConnOpenTry will have two connection identifiers, but only one of them will be used for the connection being establish. The protocol used to support this scenario (called crossing hello) so that the connection identifier generated in init would also be re-used in try, but this was removed to simplify the protocol.

Besides, it seems that the connection ends of INIT and TRYOPEN states will share the identifier count. Is there a problem with this? Like connOpenInit ran out of identifiers, resulting in the inability to execute connOpenTry.

The connection identifiers on both sides don't necessarily need to be the same. And for the identifiers we used uint64 so we will not run out of them anytime soon. :)

Question 2

I think these frozen connection ends will interfere with the normal use of users. Why can't we close these connection/channel ends that can't complete the handshake, or check if there is already a corresponding end in connOpenTry?

Those extra connection ends might be a problem for relayers, but other than that it should be fine. There's an issue in ibc-go that encountered this problem as well. There are ways to handle with this problem, but I don't think they need to be part of the handshake protocol. Each implementation can decide on their own how to (if they want to) handle it.

@michwqy Did you my comments above help with the questions you had? If they did, can I then please close the issue?

@michwqy I will assume your questions have been answered and close the issue now. Thanks!