@@ -257,7 +257,10 @@ func (g *LightningTerminal) startSubservers(network string) error {
257257 var basicClient lnrpc.LightningClient
258258
259259 // The main RPC listener of lnd might need some time to start, it could
260- // be that we run into a connection refused a few times.
260+ // be that we run into a connection refused a few times. We use the
261+ // basic client connection to find out if the RPC server is started yet
262+ // because that doesn't do anything else than just connect. We'll check
263+ // if lnd is also ready to be used in the next step.
261264 err := wait .NoError (func () error {
262265 // Create an lnd client now that we have the full configuration.
263266 // We'll need a basic client and a full client because not all
@@ -270,61 +273,52 @@ func (g *LightningTerminal) startSubservers(network string) error {
270273 g .cfg .Lnd .AdminMacPath ,
271274 )),
272275 )
273- if err != nil {
274- return err
275- }
276- g .lndClient , err = lndclient .NewLndServices (
277- & lndclient.LndServicesConfig {
278- LndAddress : g .lndAddr ,
279- Network : lndclient .Network (network ),
280- MacaroonDir : filepath .Dir (g .cfg .Lnd .AdminMacPath ),
281- TLSPath : g .cfg .Lnd .TLSCertPath ,
282- },
283- )
284276 return err
285-
286277 }, defaultStartupTimeout )
287278 if err != nil {
288279 return err
289280 }
290281
291- // The chain notifier also needs some time to start. Loop will subscribe
292- // to the notifier and crash if it isn't ready yet, so we need to wait
293- // here as a workaround.
294- //
295- // TODO(guggero): Remove once loop can retry itself.
296- err = wait . NoError ( func () error {
297- ctxt , cancel := context . WithTimeout (
298- context . Background (), defaultStartupTimeout ,
299- )
300- defer cancel ()
282+ // Now we know that the connection itself is ready. But we also need to
283+ // wait for two things: The chain notifier to be ready and the lnd
284+ // wallet being fully synced to its chain backend. The chain notifier
285+ // will always be ready first so if we instruct the lndclient to wait
286+ // for the wallet sync, we should be fully ready to start all our
287+ // subservers. This will just block until lnd signals readiness. But we
288+ // still want to react to shutdown requests, so we need to listen for
289+ // those.
290+ ctxc , cancel := context . WithCancel ( context . Background () )
291+ defer cancel ()
301292
302- notifier := g .lndClient .ChainNotifier
303- resChan , errChan , err := notifier .RegisterBlockEpochNtfn (
304- ctxt ,
305- )
306- if err != nil {
307- return err
308- }
309-
310- // Block until we get a positive/negative answer or the timeout
311- // is reached.
293+ // Make sure the context is canceled if the user requests shutdown.
294+ go func () {
312295 select {
313- case <- resChan :
314- return nil
296+ // Client requests shutdown, cancel the wait.
297+ case <- signal .ShutdownChannel ():
298+ cancel ()
315299
316- case err := <- errChan :
317- return err
318-
319- case <- ctxt .Done ():
320- return fmt .Errorf ("wait for chain notifier to be " +
321- "ready timed out" )
300+ // The check was completed and the above defer canceled the
301+ // context. We can just exit the goroutine, nothing more to do.
302+ case <- ctxc .Done ():
322303 }
323- }, defaultStartupTimeout )
304+ }()
305+ g .lndClient , err = lndclient .NewLndServices (
306+ & lndclient.LndServicesConfig {
307+ LndAddress : g .lndAddr ,
308+ Network : lndclient .Network (network ),
309+ MacaroonDir : filepath .Dir (
310+ g .cfg .Lnd .AdminMacPath ,
311+ ),
312+ TLSPath : g .cfg .Lnd .TLSCertPath ,
313+ BlockUntilChainSynced : true ,
314+ ChainSyncCtx : ctxc ,
315+ },
316+ )
324317 if err != nil {
325318 return err
326319 }
327320
321+ // Both connection types are ready now, let's start our subservers.
328322 err = g .faradayServer .StartAsSubserver (g .lndClient .LndServices )
329323 if err != nil {
330324 return err
0 commit comments