@@ -257,7 +257,10 @@ func (g *LightningTerminal) startSubservers(network string) error {
257
257
var basicClient lnrpc.LightningClient
258
258
259
259
// 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.
261
264
err := wait .NoError (func () error {
262
265
// Create an lnd client now that we have the full configuration.
263
266
// We'll need a basic client and a full client because not all
@@ -270,61 +273,52 @@ func (g *LightningTerminal) startSubservers(network string) error {
270
273
g .cfg .Lnd .AdminMacPath ,
271
274
)),
272
275
)
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
- )
284
276
return err
285
-
286
277
}, defaultStartupTimeout )
287
278
if err != nil {
288
279
return err
289
280
}
290
281
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 ()
301
292
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 () {
312
295
select {
313
- case <- resChan :
314
- return nil
296
+ // Client requests shutdown, cancel the wait.
297
+ case <- signal .ShutdownChannel ():
298
+ cancel ()
315
299
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 ():
322
303
}
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
+ )
324
317
if err != nil {
325
318
return err
326
319
}
327
320
321
+ // Both connection types are ready now, let's start our subservers.
328
322
err = g .faradayServer .StartAsSubserver (g .lndClient .LndServices )
329
323
if err != nil {
330
324
return err
0 commit comments