Skip to content

Commit d163247

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 f9a606d commit d163247

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
@@ -720,20 +720,21 @@ func (g *LightningTerminal) start(ctx context.Context) error {
720720
}
721721
}
722722

723-
// Set up all the LND clients required by LiT.
724-
err = g.setUpLNDClients(ctx, lndQuit)
723+
// Since we are now connected to LND, we can now set up a basic LND
724+
// client. Note this doesn't require LND to be synced, but can still be
725+
// used to fetch info from LND such as its macaroons. Therefore, it's ok
726+
// set it up prior to setting up the stores and starting the other RPC
727+
// servers, as the setup will be fast.
728+
err = g.setupBasicLNDClient(ctx, lndQuit)
725729
if err != nil {
726730
g.statusMgr.SetErrored(
727-
subservers.LND, "could not set up LND clients: %v", err,
731+
subservers.LND,
732+
"could not to set up a basic LND client: %v", err,
728733
)
729734

730735
return fmt.Errorf("could not start LND")
731736
}
732737

733-
// Mark that lnd is now completely running after connecting the
734-
// lnd clients.
735-
g.statusMgr.SetRunning(subservers.LND)
736-
737738
g.stores, err = NewStores(g.cfg, clock.NewDefaultClock())
738739
if err != nil {
739740
return fmt.Errorf("could not create stores: %v", err)
@@ -755,6 +756,22 @@ func (g *LightningTerminal) start(ctx context.Context) error {
755756
"server: %v", err)
756757
}
757758

759+
// Set up a full LND client. With this, we now have all LND clients
760+
// needed for LiT to be fully started.
761+
err = g.setupFullLNDClient(ctx, lndQuit)
762+
if err != nil {
763+
g.statusMgr.SetErrored(
764+
subservers.LND,
765+
"could not to set up a full LND client: %v", err,
766+
)
767+
768+
return fmt.Errorf("could not start LND")
769+
}
770+
771+
// Mark that lnd is now completely running after connecting the
772+
// lnd clients.
773+
g.statusMgr.SetRunning(subservers.LND)
774+
758775
// Both connection types are ready now, let's start our sub-servers if
759776
// they should be started locally as an integrated service.
760777
createDefaultMacaroons := !g.cfg.statelessInitMode
@@ -801,13 +818,35 @@ func (g *LightningTerminal) basicLNDClient() (lnrpc.LightningClient, error) {
801818
return g.basicClient, nil
802819
}
803820

804-
// setUpLNDClients sets up the various LND clients required by LiT.
805-
func (g *LightningTerminal) setUpLNDClients(ctx context.Context,
821+
// checkRunning checks if we should continue running for the duration of the
822+
// defaultStartupTimeout, or else returns an error indicating why a shut-down is
823+
// needed.
824+
func (g *LightningTerminal) checkRunning(ctx context.Context,
825+
lndQuit chan struct{}) error {
826+
827+
select {
828+
case err := <-g.errQueue.ChanOut():
829+
return fmt.Errorf("error from subsystem: %v", err)
830+
831+
case <-lndQuit:
832+
return fmt.Errorf("LND has stopped")
833+
834+
case <-ctx.Done():
835+
return ctx.Err()
836+
837+
case <-time.After(g.cfg.LndConnectInterval):
838+
return nil
839+
}
840+
}
841+
842+
// setupBasicLNDClient sets up a basic LND client that can be used to connect to
843+
// LND without requiring LND to be fully synced. Since this client is only a
844+
// basic client, not all of LNDs functionality is available through it.
845+
func (g *LightningTerminal) setupBasicLNDClient(ctx context.Context,
806846
lndQuit chan struct{}) error {
807847

808848
var (
809849
err error
810-
insecure bool
811850
clientOptions []lndclient.BasicClientOption
812851
)
813852

@@ -822,36 +861,13 @@ func (g *LightningTerminal) setUpLNDClients(ctx context.Context,
822861
// If we're in integrated mode, we can retrieve the macaroon string
823862
// from lnd directly, rather than grabbing it from disk.
824863
if g.cfg.LndMode == ModeIntegrated {
825-
// Set to true in integrated mode, since we will not require tls
826-
// when communicating with lnd via a bufconn.
827-
insecure = true
828864
clientOptions = append(clientOptions, lndclient.Insecure())
829865
}
830866

831-
// checkRunning checks if we should continue running for the duration of
832-
// the defaultStartupTimeout, or else returns an error indicating why
833-
// a shut-down is needed.
834-
checkRunning := func() error {
835-
select {
836-
case err := <-g.errQueue.ChanOut():
837-
return fmt.Errorf("error from subsystem: %v", err)
838-
839-
case <-lndQuit:
840-
return fmt.Errorf("LND has stopped")
841-
842-
case <-ctx.Done():
843-
return ctx.Err()
844-
845-
case <-time.After(g.cfg.LndConnectInterval):
846-
return nil
847-
}
848-
}
849-
850867
// The main RPC listener of lnd might need some time to start, it could
851868
// be that we run into a connection refused a few times. We use the
852869
// basic client connection to find out if the RPC server is started yet
853-
// because that doesn't do anything else than just connect. We'll check
854-
// if lnd is also ready to be used in the next step.
870+
// because that doesn't do anything else than just connect.
855871
log.Infof("Connecting basic lnd client")
856872

857873
for {
@@ -873,7 +889,7 @@ func (g *LightningTerminal) setUpLNDClients(ctx context.Context,
873889
"Error when setting up basic LND Client: %v", err,
874890
)
875891

876-
err = checkRunning()
892+
err = g.checkRunning(ctx, lndQuit)
877893
if err != nil {
878894
return err
879895
}
@@ -896,12 +912,34 @@ func (g *LightningTerminal) setUpLNDClients(ctx context.Context,
896912
g.cfg.statelessInitMode = macService.StatelessInit
897913
}
898914

899-
// Now we know that the connection itself is ready. But we also need to
900-
// wait for two things: The chain notifier to be ready and the lnd
901-
// wallet being fully synced to its chain backend. The chain notifier
902-
// will always be ready first so if we instruct the lndclient to wait
903-
// for the wallet sync, we should be fully ready to start all our
904-
// subservers. This will just block until lnd signals readiness.
915+
return nil
916+
}
917+
918+
// setupFullLNDClient connects a up a full LND client to LND. Note that the
919+
// setup of this client will block until LND is fully synced and unlocked.
920+
func (g *LightningTerminal) setupFullLNDClient(ctx context.Context,
921+
lndQuit chan struct{}) error {
922+
923+
var (
924+
err error
925+
insecure bool
926+
)
927+
928+
host, network, tlsPath, macPath, macData := g.cfg.lndConnectParams()
929+
930+
if g.cfg.LndMode == ModeIntegrated {
931+
// Ssince we will not require tls when communicating with lnd
932+
// via a bufconn in integrated mode, we set the insecure flag
933+
// to true.
934+
insecure = true
935+
}
936+
937+
// When setting up a full LND client, we we need to wait for two things:
938+
// The chain notifier to be ready and the lnd wallet being fully synced
939+
// to its chain backend. The chain notifier will always be ready first
940+
// so if we instruct the lndclient to wait for the wallet sync, we
941+
// should be fully ready to start all our subservers. This will just
942+
// block until lnd signals readiness.
905943
log.Infof("Connecting full lnd client")
906944
for {
907945
g.lndClient, err = lndclient.NewLndServices(
@@ -934,7 +972,7 @@ func (g *LightningTerminal) setUpLNDClients(ctx context.Context,
934972
err,
935973
)
936974

937-
err = checkRunning()
975+
err = g.checkRunning(ctx, lndQuit)
938976
if err != nil {
939977
return err
940978
}

0 commit comments

Comments
 (0)