From 70b5016bc85ec157f02f335506a2896bdb898380 Mon Sep 17 00:00:00 2001 From: Elle Mouton Date: Wed, 6 Aug 2025 13:42:47 +0200 Subject: [PATCH] discovery+gossip: make sure we dont advertise node anns with bad DNS We may have already persisted node announcements that have multiple DNS addresses since we may have received them before updating our code to check for this. So here we just make sure not to send these on to our peers. --- discovery/chan_series.go | 30 ++++++++++++++++++++++++++---- discovery/gossiper.go | 11 +++++++++-- 2 files changed, 35 insertions(+), 6 deletions(-) diff --git a/discovery/chan_series.go b/discovery/chan_series.go index ed7140d7d..cf502694c 100644 --- a/discovery/chan_series.go +++ b/discovery/chan_series.go @@ -231,6 +231,13 @@ func (c *ChanSeries) UpdatesInHorizon(chain chainhash.Hash, return nil, err } + if err := netann.ValidateNodeAnnFields(nodeUpdate); err != nil { + log.Debugf("Skipping forwarding invalid node "+ + "announcement %x: %v", nodeAnn.PubKeyBytes, err) + + continue + } + updates = append(updates, nodeUpdate) } @@ -282,6 +289,7 @@ func (c *ChanSeries) FilterChannelRange(_ chainhash.Hash, startHeight, // to reply to a QueryShortChanIDs message sent by a remote peer. The response // will contain a unique set of ChannelAnnouncements, the latest ChannelUpdate // for each of the announcements, and a unique set of NodeAnnouncements. +// Invalid node announcements are skipped and logged for debugging purposes. // // NOTE: This is part of the ChannelGraphTimeSeries interface. func (c *ChanSeries) FetchChanAnns(chain chainhash.Hash, @@ -335,8 +343,15 @@ func (c *ChanSeries) FetchChanAnns(chain chainhash.Hash, return nil, err } - chanAnns = append(chanAnns, nodeAnn) - nodePubsSent[nodePub] = struct{}{} + err = netann.ValidateNodeAnnFields(nodeAnn) + if err != nil { + log.Debugf("Skipping forwarding "+ + "invalid node announcement "+ + "%x: %v", nodeAnn.NodeID, err) + } else { + chanAnns = append(chanAnns, nodeAnn) + nodePubsSent[nodePub] = struct{}{} + } } } if edge2 != nil { @@ -354,8 +369,15 @@ func (c *ChanSeries) FetchChanAnns(chain chainhash.Hash, return nil, err } - chanAnns = append(chanAnns, nodeAnn) - nodePubsSent[nodePub] = struct{}{} + err = netann.ValidateNodeAnnFields(nodeAnn) + if err != nil { + log.Debugf("Skipping forwarding "+ + "invalid node announcement "+ + "%x: %v", nodeAnn.NodeID, err) + } else { + chanAnns = append(chanAnns, nodeAnn) + nodePubsSent[nodePub] = struct{}{} + } } } } diff --git a/discovery/gossiper.go b/discovery/gossiper.go index c720a6129..f24286ad9 100644 --- a/discovery/gossiper.go +++ b/discovery/gossiper.go @@ -2229,7 +2229,9 @@ func (d *AuthenticatedGossiper) processZombieUpdate(_ context.Context, } // fetchNodeAnn fetches the latest signed node announcement from our point of -// view for the node with the given public key. +// view for the node with the given public key. It also validates the node +// announcement fields and returns an error if they are invalid to prevent +// forwarding invalid node announcements to our peers. func (d *AuthenticatedGossiper) fetchNodeAnn(ctx context.Context, pubKey [33]byte) (*lnwire.NodeAnnouncement, error) { @@ -2238,7 +2240,12 @@ func (d *AuthenticatedGossiper) fetchNodeAnn(ctx context.Context, return nil, err } - return node.NodeAnnouncement(true) + nodeAnn, err := node.NodeAnnouncement(true) + if err != nil { + return nil, err + } + + return nodeAnn, netann.ValidateNodeAnnFields(nodeAnn) } // isMsgStale determines whether a message retrieved from the backing