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):