From bfcdbe22043553f346e31f752914faf86d7a3520 Mon Sep 17 00:00:00 2001 From: Olaoluwa Osuntokun Date: Fri, 25 May 2018 19:08:59 -0700 Subject: [PATCH] peer: when failing link, depend on server wg, not peer In this commit, we fix a recently introduced bug. The issue is that while we're failing the link, the peer we're attempting to force close on may disconnect. As a result, if the peerTerminationWatcher exits before we can add to the wait group (it's waiting on that), then we'll run into a panic as we're attempting to increment the wait group while another goroutine is calling wait. The fix is to first check that the server isn't shutting down, and then use the server's wait group rather than the peer to synchronize goroutines. Fixes #1285. --- peer.go | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/peer.go b/peer.go index 9d8e7d5d..3606f3de 100644 --- a/peer.go +++ b/peer.go @@ -438,14 +438,23 @@ func (p *peer) addLink(chanPoint *wire.OutPoint, shortChanID lnwire.ShortChannelID, linkErr htlcswitch.LinkFailureError) { + select { + // If the server is already exiting, then none of the actions + // below can finish exiting, so we'll exit early as well. + case <-p.server.quit: + return + + default: + } + // The link has notified us about a failure. We launch a go // routine to stop the link, disconnect the peer and optionally // force close the channel. We must launch a goroutine since we // must let OnChannelFailure return in order for the link to // completely stop in the call to RemoveLink. - p.wg.Add(1) + p.server.wg.Add(1) go func() { - defer p.wg.Done() + defer p.server.wg.Done() // We begin by removing the link from the switch, such // that it won't be attempted used for any more