Skip to content

Commit 3700cb4

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 a779761 commit 3700cb4

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
@@ -716,20 +716,21 @@ func (g *LightningTerminal) start(ctx context.Context) error {
716716
}
717717
}
718718

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

726731
return fmt.Errorf("could not start LND")
727732
}
728733

729-
// Mark that lnd is now completely running after connecting the
730-
// lnd clients.
731-
g.statusMgr.SetRunning(subservers.LND)
732-
733734
g.stores, err = NewStores(g.cfg, clock.NewDefaultClock())
734735
if err != nil {
735736
return fmt.Errorf("could not create stores: %v", err)
@@ -751,6 +752,22 @@ func (g *LightningTerminal) start(ctx context.Context) error {
751752
"server: %v", err)
752753
}
753754

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

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

804844
var (
805845
err error
806-
insecure bool
807846
clientOptions []lndclient.BasicClientOption
808847
)
809848

@@ -818,36 +857,13 @@ func (g *LightningTerminal) setUpLNDClients(ctx context.Context,
818857
// If we're in integrated mode, we can retrieve the macaroon string
819858
// from lnd directly, rather than grabbing it from disk.
820859
if g.cfg.LndMode == ModeIntegrated {
821-
// Set to true in integrated mode, since we will not require tls
822-
// when communicating with lnd via a bufconn.
823-
insecure = true
824860
clientOptions = append(clientOptions, lndclient.Insecure())
825861
}
826862

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

853869
for {
@@ -869,7 +885,7 @@ func (g *LightningTerminal) setUpLNDClients(ctx context.Context,
869885
"Error when setting up basic LND Client: %v", err,
870886
)
871887

872-
err = checkRunning()
888+
err = g.checkRunning(ctx, lndQuit)
873889
if err != nil {
874890
return err
875891
}
@@ -892,12 +908,34 @@ func (g *LightningTerminal) setUpLNDClients(ctx context.Context,
892908
g.cfg.statelessInitMode = macService.StatelessInit
893909
}
894910

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

933-
err = checkRunning()
971+
err = g.checkRunning(ctx, lndQuit)
934972
if err != nil {
935973
return err
936974
}

0 commit comments

Comments
 (0)