ICS 03/04: Some questions about handshake
michwqy opened this issue · 3 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!