ICS4: question on channel close
Summary
What is the reason a channel cannot be closed if its connection is not in open state?
For Admin Use
- [ ] Not duplicate issue
- [ ] Appropriate labels applied
- [ ] Appropriate contributors tagged
- [ ] Contributor assigned/self-assigned
This seems like a question for the specification cc @cwgoes
Connections can never be closed, so if a connection is not in OPEN state the connection handshake has not completed and the channel handshake should not have been completed either. It's kinda an edge case I suppose but I don't think it's a problem, unless you have a particular scenario in mind?
(the other reason is that state verification is required to close a channel in the "polite" way which is what we're referring to)
The scenario I had in mind was with the optimistic channel handshake and packet sends. Assume the connection and channel are in Init state and the application sends some packets. Before the connection and channel are open, the application wants to close the connection. In this case the channel close will be rejected. Not sure what is supposed to happen to those packets in this case.
The application wants to close the connection, or the application wants to close the channel?
If the connection has never been opened, the packets can never be received, either way, right?
Yes sorry, I meant application wants to close the channel. The packets have not been received but they have been sent. Their commitments are stored on the chain. A relayer will neither send nor timeout those.
Good question, I normally would think they could be timed out, but the counterparty channel could probably never close and the timeout verification requires an open channel. I believe we have discussed this previously and the conclusion was that optimistic sends comes with risk of unrecoverable packets. Though now I think I'm discussing something unrelated to your original question
Optimistic sends come with the risk of unrecoverable packets, but this is true regardless of whether a channel close is attempted.
True, here is another scenario and question for normal case:
- channel is
Openon both A and B - a send_packet is written on A
- relayer sends the recv_packet to B which is acknowledged on B
- A initiates channel close
- relayer sends packet
ackto A which is rejected
So if an application has meaningful actions in OnAcknowledgementPacket (either for positive or regative acks) it should not close a channel with unreceived acks. Sorry if I'm trying to state the obvious here.
Also want to make sure it's ok for the relayer to not send the acks to a closed channel (we currently do and retrying many times)
Yes, that scenario is possible. Applications may wish to deny or block channel closure for this reason. Perhaps we should consider implementing a "graceful" closure process which is multi-step and e.g. starts closing the channel, waits for all pending packets or acknowledgements to be processed, and finally closes it completely only when they are, but we haven't thought through this in depth yet.
It's fine for the relayer not to send acknowledgements to a closed channel, as least at the moment, since they will fail.
Generally, we need to think more about what the semantics of channel closure ought to be. Without motivating application examples, which we don't have yet (e.g. ICS 20 never closes channels), it's a bit difficult to reason purely in the abstract I think.
should we close this issue?
@ancazamfir Would you like any changes to be made, or any points to be clarified in the spec?
It's still not clear to me why a channel cannot be closed if the connection is not opened. We can start the handshake with the connection not opened but we cannot "stop" it by closing the channel. We have to monitor/wait for the connection to be opened and only then close the channel.
Small inconsistency in ICS04, the state diagram and transition table for channel close mention that a channel can be closed only if in OPEN state. The pseudocode just asserts !CLOSED.
Then in the description Any in-flight packets can be timed-out as soon as a channel is closed. Maybe mention something about in-flight acknowledgments and timeouts.
Transferring to the cosmos/ibc repo as this discussion is not ibc-go specific