Skip to content

Commit af4ea49

Browse files
terminal: separate basic and full LND client setup
In the upcoming actions migration, we will need to fetch LND's macaroons prior creating litd's stores, and therefore we need to connect to LND prior to creating the stores. To avoid having to wait for LND to fully sync before creating the stores (and, by extension, Litd's RPC servers), we separate the basic LND client setup from the full LND client setup. Only the full setup requires a fully synced LND.
1 parent 2e26430 commit af4ea49

File tree

1 file changed

+80
-42
lines changed

1 file changed

+80
-42
lines changed

terminal.go

Lines changed: 80 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -705,20 +705,21 @@ func (g *LightningTerminal) start(ctx context.Context) error {
705705
}
706706
}
707707

708-
// Set up all the LND clients required by LiT.
709-
err = g.setUpLNDClients(ctx, lndQuit)
708+
// Since we are now connected to LND, we can now set up a basic LND
709+
// client. Note this doesn't require LND to be synced, but can still be
710+
// used to fetch info from LND such as its macaroons. Therefore, it's ok
711+
// set it up prior to setting up the stores and starting the other RPC
712+
// servers, as the setup will be fast.
713+
err = g.setupBasicLNDClient(ctx, lndQuit)
710714
if err != nil {
711715
g.statusMgr.SetErrored(
712-
subservers.LND, "could not set up LND clients: %v", err,
716+
subservers.LND,
717+
"could not to set up a basic LND client: %v", err,
713718
)
714719

715720
return fmt.Errorf("could not start LND")
716721
}
717722

718-
// Mark that lnd is now completely running after connecting the
719-
// lnd clients.
720-
g.statusMgr.SetRunning(subservers.LND)
721-
722723
g.stores, err = NewStores(g.cfg, clock.NewDefaultClock())
723724
if err != nil {
724725
return fmt.Errorf("could not create stores: %v", err)
@@ -740,6 +741,22 @@ func (g *LightningTerminal) start(ctx context.Context) error {
740741
"server: %v", err)
741742
}
742743

744+
// Set up a full LND client. With this, we now have all LND clients
745+
// needed for LiT to be fully started.
746+
err = g.setupFullNDClient(ctx, lndQuit)
747+
if err != nil {
748+
g.statusMgr.SetErrored(
749+
subservers.LND,
750+
"could not to set up a full LND client: %v", err,
751+
)
752+
753+
return fmt.Errorf("could not start LND")
754+
}
755+
756+
// Mark that lnd is now completely running after connecting the
757+
// lnd clients.
758+
g.statusMgr.SetRunning(subservers.LND)
759+
743760
// Both connection types are ready now, let's start our sub-servers if
744761
// they should be started locally as an integrated service.
745762
createDefaultMacaroons := !g.cfg.statelessInitMode
@@ -786,13 +803,35 @@ func (g *LightningTerminal) basicLNDClient() (lnrpc.LightningClient, error) {
786803
return g.basicClient, nil
787804
}
788805

789-
// setUpLNDClients sets up the various LND clients required by LiT.
790-
func (g *LightningTerminal) setUpLNDClients(ctx context.Context,
806+
// checkRunning checks if we should continue running for the duration of the
807+
// defaultStartupTimeout, or else returns an error indicating why a shut-down is
808+
// needed.
809+
func (g *LightningTerminal) checkRunning(ctx context.Context,
810+
lndQuit chan struct{}) error {
811+
812+
select {
813+
case err := <-g.errQueue.ChanOut():
814+
return fmt.Errorf("error from subsystem: %v", err)
815+
816+
case <-lndQuit:
817+
return fmt.Errorf("LND has stopped")
818+
819+
case <-ctx.Done():
820+
return ctx.Err()
821+
822+
case <-time.After(g.cfg.LndConnectInterval):
823+
return nil
824+
}
825+
}
826+
827+
// setupBasicLNDClient sets up a basic LND client that can be used to connect to
828+
// LND without requiring LND to be fully synced. Since this client is only a
829+
// basic client, not all of LNDs functionality is available through it.
830+
func (g *LightningTerminal) setupBasicLNDClient(ctx context.Context,
791831
lndQuit chan struct{}) error {
792832

793833
var (
794834
err error
795-
insecure bool
796835
clientOptions []lndclient.BasicClientOption
797836
)
798837

@@ -807,36 +846,13 @@ func (g *LightningTerminal) setUpLNDClients(ctx context.Context,
807846
// If we're in integrated mode, we can retrieve the macaroon string
808847
// from lnd directly, rather than grabbing it from disk.
809848
if g.cfg.LndMode == ModeIntegrated {
810-
// Set to true in integrated mode, since we will not require tls
811-
// when communicating with lnd via a bufconn.
812-
insecure = true
813849
clientOptions = append(clientOptions, lndclient.Insecure())
814850
}
815851

816-
// checkRunning checks if we should continue running for the duration of
817-
// the defaultStartupTimeout, or else returns an error indicating why
818-
// a shut-down is needed.
819-
checkRunning := func() error {
820-
select {
821-
case err := <-g.errQueue.ChanOut():
822-
return fmt.Errorf("error from subsystem: %v", err)
823-
824-
case <-lndQuit:
825-
return fmt.Errorf("LND has stopped")
826-
827-
case <-ctx.Done():
828-
return ctx.Err()
829-
830-
case <-time.After(g.cfg.LndConnectInterval):
831-
return nil
832-
}
833-
}
834-
835852
// The main RPC listener of lnd might need some time to start, it could
836853
// be that we run into a connection refused a few times. We use the
837854
// basic client connection to find out if the RPC server is started yet
838-
// because that doesn't do anything else than just connect. We'll check
839-
// if lnd is also ready to be used in the next step.
855+
// because that doesn't do anything else than just connect.
840856
log.Infof("Connecting basic lnd client")
841857

842858
for {
@@ -858,7 +874,7 @@ func (g *LightningTerminal) setUpLNDClients(ctx context.Context,
858874
"Error when setting up basic LND Client: %v", err,
859875
)
860876

861-
err = checkRunning()
877+
err = g.checkRunning(ctx, lndQuit)
862878
if err != nil {
863879
return err
864880
}
@@ -881,12 +897,34 @@ func (g *LightningTerminal) setUpLNDClients(ctx context.Context,
881897
g.cfg.statelessInitMode = macService.StatelessInit
882898
}
883899

884-
// Now we know that the connection itself is ready. But we also need to
885-
// wait for two things: The chain notifier to be ready and the lnd
886-
// wallet being fully synced to its chain backend. The chain notifier
887-
// will always be ready first so if we instruct the lndclient to wait
888-
// for the wallet sync, we should be fully ready to start all our
889-
// subservers. This will just block until lnd signals readiness.
900+
return nil
901+
}
902+
903+
// setupFullNDClient connects a up a full LND client to LND. Note that the setup
904+
// of this client will block until LND is fully synced and unlocked.
905+
func (g *LightningTerminal) setupFullNDClient(ctx context.Context,
906+
lndQuit chan struct{}) error {
907+
908+
var (
909+
err error
910+
insecure bool
911+
)
912+
913+
host, network, tlsPath, macPath, macData := g.cfg.lndConnectParams()
914+
915+
if g.cfg.LndMode == ModeIntegrated {
916+
// Ssince we will not require tls when communicating with lnd
917+
// via a bufconn in integrated mode, we set the insecure flag
918+
// to true.
919+
insecure = true
920+
}
921+
922+
// When setting up a full LND client, we we need to wait for two things:
923+
// The chain notifier to be ready and the lnd wallet being fully synced
924+
// to its chain backend. The chain notifier will always be ready first
925+
// so if we instruct the lndclient to wait for the wallet sync, we
926+
// should be fully ready to start all our subservers. This will just
927+
// block until lnd signals readiness.
890928
log.Infof("Connecting full lnd client")
891929
for {
892930
g.lndClient, err = lndclient.NewLndServices(
@@ -919,7 +957,7 @@ func (g *LightningTerminal) setUpLNDClients(ctx context.Context,
919957
err,
920958
)
921959

922-
err = checkRunning()
960+
err = g.checkRunning(ctx, lndQuit)
923961
if err != nil {
924962
return err
925963
}

0 commit comments

Comments
 (0)