discovery: fix gossiper shutdown deadlock

When processing a remote network announcement, it is possible for two
error messages to be sent back on the errChan.  Since Brontide doesn't
actually read from errChan, and since errChan only buffered one error
message, the sending goroutine would deadlock forever.  This would only
become apparent when the gossiper attempted to shut down and got hung
up.

For now, we can fix this simply by buffering up to two error messages on
errChan.  There is an existing TODO to restructure this logic entirely
to use the actor model, and we can do a more thorough fix as part of
that work.

This bug was discovered while doing full node fuzz testing and was
triggered by sending a specific channel_announcement message and then
shutting down LND.
This commit is contained in:
Matt Morehouse committed 2026-02-03 09:14:56 -06:00
1 parent 06b175a140
commit 21588acb3d
2 files changed
+69 -1

No files matched your search

+8 -1
View File
@@ -880,7 +880,14 @@ func (d *AuthenticatedGossiper) stop() {
func (d *AuthenticatedGossiper) ProcessRemoteAnnouncement(ctx context.Context,
msg lnwire.Message, peer lnpeer.Peer) chan error {
errChan := make(chan error, 1)
// Buffer up to two messages on errChan since up to two messages may be
// written and not all callers of this function actually read from
// errChan. Without this buffer goroutines end up blocking on writes to
// errChan, which prevents the gossiper from shutting down cleanly.
//
// TODO(ziggie): Redesign this once the actor model pattern becomes
// available. See https://github.com/lightningnetwork/lnd/pull/9820.
errChan := make(chan error, 2)
// For messages in the known set of channel series queries, we'll
// dispatch the message directly to the GossipSyncer, and skip the main