From ca0358f978971a4e65e67e7a0ac368330a0369db Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Tue, 15 Jun 2021 14:37:15 +0930 Subject: [PATCH] channeld: send shutdown_complete even if reestablish_only. 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 Changelog-Added: Protocol: We will now reestablish and negotiate mutual close on channels we've already closed (great if peer has lost their database). --- channeld/channeld.c | 27 +++++++++++++++++---------- lightningd/channel_control.c | 3 ++- lightningd/closing_control.c | 2 +- tests/test_closing.py | 1 - 4 files changed, 20 insertions(+), 13 deletions(-) diff --git a/channeld/channeld.c b/channeld/channeld.c index cee12432d..d37cd96b7 100644 --- a/channeld/channeld.c +++ b/channeld/channeld.c @@ -918,6 +918,15 @@ static void maybe_send_shutdown(struct peer *peer) billboard_update(peer); } +static void send_shutdown_complete(struct peer *peer) +{ + /* Now we can tell master shutdown is complete. */ + wire_sync_write(MASTER_FD, + take(towire_channeld_shutdown_complete(NULL, peer->pps))); + per_peer_state_fdpass_send(MASTER_FD, peer->pps); + close(MASTER_FD); +} + /* This queues other traffic from the fd until we get reply. */ static u8 *master_wait_sync_reply(const tal_t *ctx, struct peer *peer, @@ -2929,10 +2938,17 @@ got_reestablish: #endif /* EXPERIMENTAL_FEATURES */ /* Now stop, we've been polite long enough. */ - if (reestablish_only) + if (reestablish_only) { + /* If we were successfully closing, we still go to closingd. */ + if (shutdown_complete(peer)) { + send_shutdown_complete(peer); + daemon_shutdown(); + exit(0); + } peer_failed_err(peer->pps, &peer->channel_id, "Channel is already closed"); + } /* Corner case: we didn't send shutdown before because update_add_htlc * pending, but now they're cleared by restart, and we're actually @@ -3594,15 +3610,6 @@ static void init_channel(struct peer *peer) billboard_update(peer); } -static void send_shutdown_complete(struct peer *peer) -{ - /* Now we can tell master shutdown is complete. */ - wire_sync_write(MASTER_FD, - take(towire_channeld_shutdown_complete(NULL, peer->pps))); - per_peer_state_fdpass_send(MASTER_FD, peer->pps); - close(MASTER_FD); -} - static void try_read_gossip_store(struct peer *peer) { u8 *msg = gossip_store_next(tmpctx, peer->pps); diff --git a/lightningd/channel_control.c b/lightningd/channel_control.c index 011c5754a..e1585e0d7 100644 --- a/lightningd/channel_control.c +++ b/lightningd/channel_control.c @@ -318,7 +318,8 @@ static void peer_start_closingd_after_shutdown(struct channel *channel, peer_start_closingd(channel, pps); /* We might have reconnected, so already be here. */ - if (channel->state != CLOSINGD_SIGEXCHANGE) + if (!channel_closed(channel) + && channel->state != CLOSINGD_SIGEXCHANGE) channel_set_state(channel, CHANNELD_SHUTTING_DOWN, CLOSINGD_SIGEXCHANGE, diff --git a/lightningd/closing_control.c b/lightningd/closing_control.c index 0729ee76d..d20708757 100644 --- a/lightningd/closing_control.c +++ b/lightningd/closing_control.c @@ -145,7 +145,7 @@ static void peer_closing_complete(struct channel *channel, const u8 *msg) channel_set_billboard(channel, false, NULL); /* Retransmission only, ignore closing. */ - if (channel->state == CLOSINGD_COMPLETE) + if (channel_closed(channel)) return; /* Channel gets dropped to chain cooperatively. */ diff --git a/tests/test_closing.py b/tests/test_closing.py index 3404bf885..3efbdcd10 100644 --- a/tests/test_closing.py +++ b/tests/test_closing.py @@ -2786,7 +2786,6 @@ def test_htlc_rexmit_while_closing(node_factory, executor): fut2.result(TIMEOUT) -@pytest.mark.xfail(strict=True) @pytest.mark.openchannel('v1') @pytest.mark.developer("needs dev_disconnect") def test_you_forgot_closed_channel(node_factory, executor):