discovery: fix race access to syncer's state

This commit fixes the following race,
1. syncer(state=syncingChans) sends QueryChannelRange
2. remote peer replies ReplyChannelRange
3. ProcessQueryMsg fails to process the remote peer's msg as its state
   is neither waitingQueryChanReply nor waitingQueryRangeReply.
4. syncer marks its new state waitingQueryChanReply, but too late.

The historical sync will now fail, and the syncer will be stuck at this
state. What's worse is it cannot forward channel announcements to other
connected peers now as it will skip the broadcasting during initial
graph sync.

This is now fixed to make sure the following two steps are atomic,
1. syncer(state=syncingChans) sends QueryChannelRange
2. syncer marks its new state waitingQueryChanReply.
This commit is contained in:
yyforyongyu
2025-01-16 22:49:25 +08:00
parent 4b30b09d1c
commit 9fecfed3b5
2 changed files with 20 additions and 4 deletions

View File

@@ -832,9 +832,13 @@ func (d *AuthenticatedGossiper) ProcessRemoteAnnouncement(msg lnwire.Message,
// If we've found the message target, then we'll dispatch the
// message directly to it.
syncer.ProcessQueryMsg(m, peer.QuitSignal())
err := syncer.ProcessQueryMsg(m, peer.QuitSignal())
if err != nil {
log.Errorf("Process query msg from peer %x got %v",
peer.PubKey(), err)
}
errChan <- nil
errChan <- err
return errChan
// If a peer is updating its current update horizon, then we'll dispatch