terminal: don't wait for chain sync when tapd is integrated

Before starting the sub-servers, we wait for lnd to be fully synced to
its chain backend. lnd only reports itself as synced once its blockbeat
dispatcher caught up, and block processing can be blocked on tapd's aux
components: if a channel is being resolved on chain, the sweeper calls
into tapd's aux sweeper, which blocks until tapd is started. Since tapd
is only started after the full lnd client is created, litd deadlocks in
that situation. And because the client creation is retried in a loop, we
don't even fail, we just log "Retrying to create LND Services client"
forever while tapd never comes up.

We therefore skip the chain sync wait when tapd runs in-process, which
is the only mode where the aux components are wired into lnd. We still
wait for the chain notifier to be ready, which is what the sub-servers
need to subscribe to blocks.
This commit is contained in:
George Tsagkarelis 2026-08-10 16:01:17 +00:00
parent 23433a05ed
commit a5bf9999b8

View file

@ -1003,6 +1003,23 @@ func (g *LightningTerminal) setupFullLNDClient(ctx context.Context,
// so if we instruct the lndclient to wait for the wallet sync, we
// should be fully ready to start all our subservers. This will just
// block until lnd signals readiness.
//
// There is one exception to that: with both lnd and tapd running
// in-process, we must not wait for lnd to be synced to chain here. lnd
// only reports itself as synced once its blockbeat caught up, and block
// processing can be blocked on tapd's aux components. If for example a
// channel is being resolved on chain, the sweeper calls into tapd's aux
// sweeper, which blocks until tapd is started. As tapd is only started
// once we have the client below, waiting here would deadlock the
// startup and we'd retry forever without ever starting tapd.
integratedTapd := g.cfg.LndMode == ModeIntegrated &&
g.cfg.TaprootAssetsMode == ModeIntegrated
blockUntilChainSynced := !integratedTapd
if integratedTapd {
log.Infof("Not waiting for lnd to be synced to chain, as " +
"tapd is running in integrated mode")
}
log.Infof("Connecting full lnd client")
for {
g.lndClient, err = lndclient.NewLndServices(
@ -1020,7 +1037,7 @@ func (g *LightningTerminal) setupFullLNDClient(ctx context.Context,
RPCTimeout: g.cfg.LndRPCTimeout,
ChainSyncPollInterval: g.cfg.LndConnectInterval,
BlockUntilChainSynced: true,
BlockUntilChainSynced: blockUntilChainSynced,
BlockUntilUnlocked: true,
BlockUntilChainNotifier: true,
},