Skip to content
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

Negotiate close even if we already consider the channel closed. #4559

Conversation

rustyrussell
Copy link
Contributor

@rustyrussell rustyrussell commented May 26, 2021

This was initially found by CI: one peer got the final signature and the other didn't, so one was closing and the other wasn't. This is generally harmless (the one who thinks it's closed broadcasts, so the peer will see it eventually), but it's painful if they lost information and were relying on the reconnection to provide it.

This adds a test for that, but also allows us to renegotiate closing even if we consider the channel completely closed (in which case, openingd will receive the REESTABLISH msg). I didn't support this for dualopend yet, since there the potential channel and the connection are quite closely tied, and it's hard to dispose of the (uncreated) channel without closing the connection.

It's a nice-to-have, but not vital.

@rustyrussell rustyrussell added this to the v0.10.1 milestone May 26, 2021
@rustyrussell rustyrussell force-pushed the guilt/htlc-leftover-while-closingd branch from e51988c to c247f9f Compare May 26, 2021 07:13
@cdecker cdecker force-pushed the guilt/htlc-leftover-while-closingd branch from c247f9f to 875d2c8 Compare May 26, 2021 11:46
@cdecker
Copy link
Member

cdecker commented May 26, 2021

Rebased on top of master to fix conflict on generated SQL files.

@cdecker cdecker force-pushed the guilt/htlc-leftover-while-closingd branch from 0caf809 to f7f6b60 Compare May 26, 2021 12:42
@rustyrussell
Copy link
Contributor Author

rustyrussell commented May 27, 2021

This opened a longstanding issue with "I consider your channel closed so I will no longer talk to you about it!". I will fix that on top of this too, since it's been a flaw for a while.

Edit: done

@rustyrussell rustyrussell marked this pull request as draft June 1, 2021 01:14
@rustyrussell rustyrussell force-pushed the guilt/htlc-leftover-while-closingd branch from f7f6b60 to 38fb12c Compare June 4, 2021 05:19
@rustyrussell rustyrussell changed the title Fix closing hang when expecting final revoke_and_ack Negotiate close even if we already consider the channel closed. Jun 4, 2021
@rustyrussell rustyrussell marked this pull request as ready for review June 4, 2021 05:24
@rustyrussell
Copy link
Contributor Author

rustyrussell commented Jun 5, 2021

OK, so some surprising tests expected the old behavior. Hmm, will look next week.

Fixed, all ready for review.

@rustyrussell rustyrussell force-pushed the guilt/htlc-leftover-while-closingd branch 3 times, most recently from b13e72b to 2e83d0e Compare June 9, 2021 04:46
This allows us to ensure a packet is read by the other end, but we
don't read anything else from them or write anything to them.

Using '+' is similar, but because it closes the connection, the peer
might notice before receiving the packet (such as if it does a write).

Signed-off-by: Rusty Russell <[email protected]>
This was turned by at random by CI:

1. Alice has sent shutdown, but it still waiting for revoke_and_ack.
2. Bob has sent and received shutdown, and sent revoke_and_ack,
   so it considers it time for signature exchange.
3. Disconnect before Alice received revoke_and_ack.
4. Reconnect, Bob is in closingd, which doesn't rexmit revoke_and_ack.
5. Timeout.

Signed-off-by: Rusty Russell <[email protected]>
It handles all the cases of retransmission, and in the normal case
retransmits shutdown and immediately returns for us to run closingd.

This is actually far simpler and reduces code duplication.

[ Includes fixup to stop warn_unused_result from Christian ]

Signed-off-by: Rusty Russell <[email protected]>
Changelog-Fixed: Protocol: We could get stuck on signature exchange if we needed to retransmit the final revoke_and_ack.
In particular, if one side sees the final CLOSING_SIGNED and the other
doesn't, we won't talk when it reconnects.

Signed-off-by: Rusty Russell <[email protected]>
Let the callers do that (only channeld needs to do this).

We temporarily send an error on unknown reestablish in openingd, as
this mimic previous behavior and avoids breaking tests (it does leave
a BROKEN message in the logs though, so
test_funding_external_wallet_corners needs to ignore that for now.

Signed-off-by: Rusty Russell <[email protected]>
This supports reestablish on a closed channel: we tell channeld to
respond to the reestablish message appropriately, then close the
channel.

Signed-off-by: Rusty Russell <[email protected]>
It simply uses connectd to send an error if it doesn't know anything
about the channel.

Signed-off-by: Rusty Russell <[email protected]>
This lets us transition (with a few supporting changes) to closingd,
which will happily let them mutual close with us.

We already handle the case where this mutual close is redundant (for
packet loss), so this is easy.

Signed-off-by: Rusty Russell <[email protected]>
Changelog-Added: Protocol: We will now reestablish and negotiate mutual close on channels we've already closed (great if peer has lost their database).
@rustyrussell rustyrussell force-pushed the guilt/htlc-leftover-while-closingd branch from 2e83d0e to 015ab60 Compare June 15, 2021 05:07
@cdecker
Copy link
Member

cdecker commented Jun 18, 2021

ACK 015ab60

@rustyrussell rustyrussell merged commit 84190af into ElementsProject:master Jun 25, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants