mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-11-09 21:56:47 +01:00
lnd.go: sync headers before chain notifier startup to prevent premature rescan
This commit addresses a regression where Neutrino rescanning starts from an outdated height (~100k blocks behind) instead of using the current synced height. Root Cause: In commit16a8b623b, the initialization order was changed so that Chain Notifier starts before wallet syncing completes. This means the rescan begins using the stale height from BuildChainControl rather than the fully synced height. Old behavior (commit1dfb5a0c2): 1. RPC server starts 2. Headers sync as part of daemon server 3. Chain Notifier starts after sync completes 4. Rescan begins from current (synced) height Current behavior (regression): 1. Chain Notifier starts in newServer (before RPC) 2. Wallet sync happens after RPC server starts 3. Rescan uses outdated height from BuildChainControl Solution: - Ensure headers are fully synced before starting the chain notifier, and after starting the RPC server. - Move chain notifier startup to its correct location after headers are fully synced. - Make sure the starting beat is lazily called after chain notifier started and before that starting beat result is used.
This commit is contained in:
52
server.go
52
server.go
@@ -733,17 +733,6 @@ func newServer(ctx context.Context, cfg *Config, listenAddrs []net.Addr,
|
||||
quit: make(chan struct{}),
|
||||
}
|
||||
|
||||
// Start the low-level services once they are initialized.
|
||||
//
|
||||
// TODO(yy): break the server startup into four steps,
|
||||
// 1. init the low-level services.
|
||||
// 2. start the low-level services.
|
||||
// 3. init the high-level services.
|
||||
// 4. start the high-level services.
|
||||
if err := s.startLowLevelServices(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
currentHash, currentHeight, err := s.cc.ChainIO.GetBestBlock()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -2125,41 +2114,12 @@ func (c cleaner) run() {
|
||||
}
|
||||
}
|
||||
|
||||
// startLowLevelServices starts the low-level services of the server. These
|
||||
// services must be started successfully before running the main server. The
|
||||
// services are,
|
||||
// 1. the chain notifier.
|
||||
//
|
||||
// TODO(yy): identify and add more low-level services here.
|
||||
func (s *server) startLowLevelServices() error {
|
||||
var startErr error
|
||||
|
||||
cleanup := cleaner{}
|
||||
|
||||
cleanup = cleanup.add(s.cc.ChainNotifier.Stop)
|
||||
if err := s.cc.ChainNotifier.Start(); err != nil {
|
||||
startErr = err
|
||||
}
|
||||
|
||||
if startErr != nil {
|
||||
cleanup.run()
|
||||
}
|
||||
|
||||
return startErr
|
||||
}
|
||||
|
||||
// Start starts the main daemon server, all requested listeners, and any helper
|
||||
// goroutines.
|
||||
// NOTE: This function is safe for concurrent access.
|
||||
//
|
||||
//nolint:funlen
|
||||
func (s *server) Start(ctx context.Context) error {
|
||||
// Get the current blockbeat.
|
||||
beat, err := s.getStartingBeat()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var startErr error
|
||||
|
||||
// If one sub system fails to start, the following code ensures that the
|
||||
@@ -2213,6 +2173,12 @@ func (s *server) Start(ctx context.Context) error {
|
||||
return
|
||||
}
|
||||
|
||||
cleanup = cleanup.add(s.cc.ChainNotifier.Stop)
|
||||
if err := s.cc.ChainNotifier.Start(); err != nil {
|
||||
startErr = err
|
||||
return
|
||||
}
|
||||
|
||||
cleanup = cleanup.add(s.cc.BestBlockTracker.Stop)
|
||||
if err := s.cc.BestBlockTracker.Start(); err != nil {
|
||||
startErr = err
|
||||
@@ -2247,6 +2213,12 @@ func (s *server) Start(ctx context.Context) error {
|
||||
}
|
||||
}
|
||||
|
||||
beat, err := s.getStartingBeat()
|
||||
if err != nil {
|
||||
startErr = err
|
||||
return
|
||||
}
|
||||
|
||||
cleanup = cleanup.add(s.txPublisher.Stop)
|
||||
if err := s.txPublisher.Start(beat); err != nil {
|
||||
startErr = err
|
||||
|
||||
Reference in New Issue
Block a user