Skip to content

Commit 2f54cd8

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 0d169af commit 2f54cd8

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

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

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

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

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

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

805845
var (
806846
err error
807-
insecure bool
808847
clientOptions []lndclient.BasicClientOption
809848
)
810849

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

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

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

873-
err = checkRunning()
889+
err = g.checkRunning(ctx, lndQuit)
874890
if err != nil {
875891
return err
876892
}
@@ -893,12 +909,34 @@ func (g *LightningTerminal) setUpLNDClients(ctx context.Context,
893909
g.cfg.statelessInitMode = macService.StatelessInit
894910
}
895911

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

934-
err = checkRunning()
972+
err = g.checkRunning(ctx, lndQuit)
935973
if err != nil {
936974
return err
937975
}

0 commit comments

Comments
 (0)