From dd9711ecf19dced64c30bb9f8769f0d6d36c1574 Mon Sep 17 00:00:00 2001 From: Elle Mouton Date: Mon, 7 Aug 2023 12:00:22 +0200 Subject: [PATCH] terminal: dont block indefinitely on macaroon channel In this commit, we ensure that when we wait on the macaroon channel for the macaroon from the integrated LND, that we also listen to other exit signals such as the interceptor, lndQuit chanel and the error channel. This is to prevent shutdown from blocking forever in the case where there was an issue preventing LND from sending the initial macaroon. --- terminal.go | 49 +++++++++++++++++++++++++++++++++++++------------ 1 file changed, 37 insertions(+), 12 deletions(-) diff --git a/terminal.go b/terminal.go index 2f26e2c7a..66f5c35f4 100644 --- a/terminal.go +++ b/terminal.go @@ -536,31 +536,56 @@ func (g *LightningTerminal) start() error { return fmt.Errorf("error displaying startup info: %v", err) } - // Wait for lnd to be unlocked, then start all clients. - select { - case <-readyChan: + // waitForSignal is a helper closure that can be used to wait on the + // given channel for a signal while also being responsive to an error + // from the error Queue, LND quiting or the interceptor receiving a + // shutdown signal. + waitForSignal := func(c chan struct{}) error { + select { + case <-c: + return nil - case err := <-g.errQueue.ChanOut(): - return err + case err := <-g.errQueue.ChanOut(): + return err - case <-lndQuit: - return nil + case <-lndQuit: + return nil - case <-interceptor.ShutdownChannel(): - return fmt.Errorf("received the shutdown signal") + case <-interceptor.ShutdownChannel(): + return fmt.Errorf("received the shutdown signal") + } + } + + // Wait for lnd to be unlocked, then start all clients. + if err = waitForSignal(readyChan); err != nil { + return err } // If we're in integrated mode, we'll need to wait for lnd to send the // macaroon after unlock before going any further. if g.cfg.LndMode == ModeIntegrated { - <-bufReadyChan - g.cfg.lndAdminMacaroon = <-macChan + if err = waitForSignal(bufReadyChan); err != nil { + return err + } + + // Create a new macReady channel that will serve to signal that + // the LND macaroon is ready. Spin off a goroutine that will + // close this channel when the macaroon has been received. + macReady := make(chan struct{}) + go func() { + g.cfg.lndAdminMacaroon = <-macChan + close(macReady) + }() + + if err = waitForSignal(macReady); err != nil { + return err + } } // Set up all the LND clients required by LiT. err = g.setUpLNDClients() if err != nil { - log.Errorf("Could not set up LND clients: %w", err) + log.Errorf("Could not set up LND clients: %v", err) return err }