From bea9c0b52b9b471a6d7ca3dbe447e98d88efcda8 Mon Sep 17 00:00:00 2001 From: Andrey Samokhvalov Date: Sun, 9 Jul 2017 02:20:56 +0300 Subject: [PATCH] htlcswitch: make stop of the link not in the goroutine In order to be able to properly restart switch several times we should have the sequential process of channel link stop. In other words if we stopped the switch we should be sure that all channel links have been stopped too. Addition of the goroutine during the force close was added because of the deadlock: Trace: 1. link:force_close_notification 2. link:wipe_channel 3. peer:switch_remove_link 4. switch:stop_link 5. link:wait <-- deadlock --- htlcswitch/link.go | 15 +++++++++------ htlcswitch/switch.go | 2 +- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/htlcswitch/link.go b/htlcswitch/link.go index 48c60bbf..067f3292 100644 --- a/htlcswitch/link.go +++ b/htlcswitch/link.go @@ -369,14 +369,17 @@ out: case <-l.channel.UnilateralCloseSignal: log.Warnf("Remote peer has closed ChannelPoint(%v) on-chain", l.channel.ChannelPoint()) - if err := l.cfg.Peer.WipeChannel(l.channel); err != nil { - log.Errorf("unable to wipe channel %v", err) - } - // TODO(roasbeef): need to send HTLC outputs to nursery + go func() { + if err := l.cfg.Peer.WipeChannel(l.channel); err != nil { + log.Errorf("unable to wipe channel %v", err) + } + + // TODO(roasbeef): need to send HTLC outputs to nursery + // TODO(roasbeef): or let the arb sweep? + l.cfg.SettledContracts <- l.channel.ChannelPoint() + }() - // TODO(roasbeef): or let the arb sweep? - l.cfg.SettledContracts <- l.channel.ChannelPoint() break out // A local sub-system has initiated a force close of the active diff --git a/htlcswitch/switch.go b/htlcswitch/switch.go index 683e8e8e..0e1ae2b4 100644 --- a/htlcswitch/switch.go +++ b/htlcswitch/switch.go @@ -968,7 +968,7 @@ func (s *Switch) removeLink(chanID lnwire.ChannelID) error { peerPub := link.Peer().PubKey() delete(s.interfaceIndex, peerPub) - go link.Stop() + link.Stop() return nil }