@@ -120,6 +120,10 @@ func (c *ChanSeries) UpdatesInHorizon(chain chainhash.Hash,
120120 if err != nil {
121121 return nil , err
122122 }
123+
124+ // nodesFromChan records the nodes seen from the channels.
125+ nodesFromChan := make (map [[33 ]byte ]struct {}, len (chansInHorizon )* 2 )
126+
123127 for _ , channel := range chansInHorizon {
124128 // If the channel hasn't been fully advertised yet, or is a
125129 // private channel, then we'll skip it as we can't construct a
@@ -136,7 +140,21 @@ func (c *ChanSeries) UpdatesInHorizon(chain chainhash.Hash,
136140 return nil , err
137141 }
138142
139- updates = append (updates , chanAnn )
143+ // Create a slice to hold the `channel_announcement` and
144+ // potentially two `channel_update` msgs.
145+ //
146+ // NOTE: Based on BOLT7, if a channel_announcement has no
147+ // corresponding channel_updates, we must not send the
148+ // channel_announcement. Thus we use this slice to decide we
149+ // want to send this `channel_announcement` or not. By the end
150+ // of the operation, if the len of the slice is 1, we will not
151+ // send the `channel_announcement`. Otherwise, when sending the
152+ // msgs, the `channel_announcement` must be sent prior to any
153+ // corresponding `channel_update` or `node_annoucement`, that's
154+ // why we create a slice here to maintain the order.
155+ chanUpdates := make ([]lnwire.Message , 0 , 3 )
156+ chanUpdates = append (chanUpdates , chanAnn )
157+
140158 if edge1 != nil {
141159 // We don't want to send channel updates that don't
142160 // conform to the spec (anymore).
@@ -145,18 +163,32 @@ func (c *ChanSeries) UpdatesInHorizon(chain chainhash.Hash,
145163 log .Errorf ("not sending invalid channel " +
146164 "update %v: %v" , edge1 , err )
147165 } else {
148- updates = append (updates , edge1 )
166+ chanUpdates = append (chanUpdates , edge1 )
149167 }
150168 }
169+
151170 if edge2 != nil {
152171 err := netann .ValidateChannelUpdateFields (0 , edge2 )
153172 if err != nil {
154173 log .Errorf ("not sending invalid channel " +
155174 "update %v: %v" , edge2 , err )
156175 } else {
157- updates = append (updates , edge2 )
176+ chanUpdates = append (chanUpdates , edge2 )
158177 }
159178 }
179+
180+ // If there's no corresponding `channel_update` to send, skip
181+ // sending this `channel_announcement`.
182+ if len (chanUpdates ) < 2 {
183+ continue
184+ }
185+
186+ // Append the all the msgs to the slice.
187+ updates = append (updates , chanUpdates ... )
188+
189+ // Record the nodes seen.
190+ nodesFromChan [channel .Info .NodeKey1Bytes ] = struct {}{}
191+ nodesFromChan [channel .Info .NodeKey2Bytes ] = struct {}{}
160192 }
161193
162194 // Next, we'll send out all the node announcements that have an update
@@ -168,8 +200,15 @@ func (c *ChanSeries) UpdatesInHorizon(chain chainhash.Hash,
168200 if err != nil {
169201 return nil , err
170202 }
203+
171204 for _ , nodeAnn := range nodeAnnsInHorizon {
172- nodeAnn := nodeAnn
205+ // If this node has not been seen in the above channels, we can
206+ // skip sending its NodeAnnouncement.
207+ if _ , seen := nodesFromChan [nodeAnn .PubKeyBytes ]; ! seen {
208+ log .Debugf ("Skipping forwarding as node %x not found " +
209+ "in channel announcement" , nodeAnn .PubKeyBytes )
210+ continue
211+ }
173212
174213 // Ensure we only forward nodes that are publicly advertised to
175214 // prevent leaking information about nodes.
0 commit comments