-
Notifications
You must be signed in to change notification settings - Fork 383
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ICS 04: fix timeout conditions for ordered (without/with allow timeout) channels #977
ICS 04: fix timeout conditions for ordered (without/with allow timeout) channels #977
Conversation
@@ -964,7 +964,7 @@ function timeoutPacket( | |||
// ordered channel: check that packet has not been received | |||
// only allow timeout on next sequence so all sequences before the timed out packet are processed (received/timed out) | |||
// before this packet times out | |||
abortTransactionUnless(nextSequenceRecv == packet.sequence) | |||
abortTransactionUnless(nextSequenceRecv <= packet.sequence) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See ibc-go.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think its clearer to write
abortTransactionUnless(packet.Sequence >= nextSequenceRecv)
switch channel.order { | ||
case ORDERED: | ||
// ordered channel: check that packet has not been received | ||
abortTransactionUnless(nextSequenceRecv <= packet.sequence) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I changed the ordered to match what the implementation does and what the spec also does for regular packet timeouts.
|
||
// NOTE: For ORDERED_ALLOW_TIMEOUT, the relayer must first attempt the receive on the destination chain | ||
// before the timeout receipt can be written and subsequently proven on the sender chain in timeoutPacket | ||
case ORDERED_ALLOW_TIMEOUT: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I split ORDERED
and ORDERED_ALLOW_TIMEOUT
because conditions are different.
// only allow timeout on next sequence so all sequences before the timed out packet are processed (received/timed out) | ||
// before this packet times out | ||
abortTransactionUnless(nextSequenceRecv == packet.sequence) | ||
abortTransactionUnless(nextSequenceRecv > packet.sequence) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For both packet timeouts and for timeout on close the nextSequenceRecv
on the counterparty would have been incremented by one before the timeout receipt is written.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe this was correct as it was
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The reason for changing it is that in line 709 inside recvPacket
the nextSequenceRecv
is incremented by 1 before the timeout receipt is written:
nextSequenceRecv = nextSequenceRecv + 1
provableStore.set(nextSequenceRecvPath(packet.destPort, packet.destChannel), nextSequenceRecv)
So if I relayer tries to timeout the packet, the nextSequenceRecv
in the timeout message will be > than packet.sequence
, won't it?
Same thing for the condition checked in timeoutOnClose
.
Is this reasoning correct, @AdityaSripal?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@AdityaSripal for timing out a packet if the channel is open, should the condition still be that the relayer must attempt to receive the packet (as the comment above this line says)? If that's the case, then I guess it's ok to not support the situation where packet.sequence
is >= nextSequenceRecv
.
@@ -964,7 +964,7 @@ function timeoutPacket( | |||
// ordered channel: check that packet has not been received | |||
// only allow timeout on next sequence so all sequences before the timed out packet are processed (received/timed out) | |||
// before this packet times out | |||
abortTransactionUnless(nextSequenceRecv == packet.sequence) | |||
abortTransactionUnless(nextSequenceRecv <= packet.sequence) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think its clearer to write
abortTransactionUnless(packet.Sequence >= nextSequenceRecv)
// only allow timeout on next sequence so all sequences before the timed out packet are processed (received/timed out) | ||
// before this packet times out | ||
abortTransactionUnless(nextSequenceRecv == packet.sequence) | ||
abortTransactionUnless(nextSequenceRecv > packet.sequence) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe this was correct as it was
// NOTE: For ORDERED_ALLOW_TIMEOUT, the relayer must first attempt the receive on the destination chain | ||
// before the timeout receipt can be written and subsequently proven on the sender chain in timeoutPacket | ||
case ORDERED_ALLOW_TIMEOUT: | ||
abortTransactionUnless(nextSequenceRecv > packet.sequence) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be an equals
…annot attempt receive
// only allow timeout on next sequence so all sequences before the timed out packet are processed (received/timed out) | ||
// before this packet times out | ||
abortTransactionUnless(nextSequenceRecv == packet.sequence) | ||
abortTransactionUnless(nextSequenceRecv > packet.sequence) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@AdityaSripal for timing out a packet if the channel is open, should the condition still be that the relayer must attempt to receive the packet (as the comment above this line says)? If that's the case, then I guess it's ok to not support the situation where packet.sequence
is >= nextSequenceRecv
.
// Otherwise, if packet.sequence < nextSequenceRecv, then the relayer has attempted | ||
// to receive the packet on the destination chain, and nextSequenceRecv has been incremented. | ||
// In this situation, verify the presence of timeout receipt. | ||
if packet.sequence < nextSequenceRecv { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If packet.sequence >= nextSequenceRecv
, then timeout, otherwise verify there is a timeout receipt.
…unction-timeoutpacket-and-timeoutonclose
// only allow timeout on next sequence so all sequences before the timed out packet are processed (received/timed out) | ||
// before this packet times out | ||
abortTransactionUnless(nextSequenceRecv == packet.sequence) | ||
abortTransactionUnless(packet.sequence < nextSequenceRecv) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@AdityaSripal if a channel is open and the relayer must first attempt to receive the packet on destination chain, I guess it is ok to assume that nextSequenceRecv
will have been incremented and therefore is > packet.sequence
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No we will actually want the equals here because I think it makes sense to enforce that timeout happens in order as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should the condition be then abortTransactionUnless(packet.sequence == nextSequenceRecv - 1)
since nextSequenceRecv
will have been incremented when attempting to receive packet with packet.sequence
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks Carlos, I think its still important to ensure ordering in the timeout logic. Perhaps we should even add this to timeoutOnClose. Also I believe the else clause in the ordered_allow_timeout case is missing.
// only allow timeout on next sequence so all sequences before the timed out packet are processed (received/timed out) | ||
// before this packet times out | ||
abortTransactionUnless(nextSequenceRecv == packet.sequence) | ||
abortTransactionUnless(packet.sequence < nextSequenceRecv) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No we will actually want the equals here because I think it makes sense to enforce that timeout happens in order as well.
@@ -1190,8 +1190,7 @@ function timeoutPacket( | |||
// ordered channel: check that packet has not been received | |||
// only allow timeout on next sequence so all sequences before the timed out packet are processed (received/timed out) | |||
// before this packet times out | |||
abortTransactionUnless(nextSequenceRecv == packet.sequence) | |||
|
|||
abortTransactionUnless(packet.sequence >= nextSequenceRecv) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Again I think this should remain as is. It would enforce that the only packet that gets timed out is the first in line
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you @crodriguezvega !
closes: #965