@@ -56,6 +56,10 @@ const (
5656 // updates that we'll hold onto.
5757 maxPrematureUpdates = 100
5858
59+ // maxPrematureNodeAnnouncements tracks the max amount of premature node
60+ // announcements that we'll hold onto.
61+ maxPrematureNodeAnnouncements = 100
62+
5963 // maxFutureMessages tracks the max amount of future messages that
6064 // we'll hold onto.
6165 maxFutureMessages = 1000
@@ -502,6 +506,11 @@ type AuthenticatedGossiper struct {
502506 // ChannelAnnouncement for the channel is received.
503507 prematureChannelUpdates * lru.Cache [uint64 , * cachedNetworkMsg ]
504508
509+ // prematureNodeAnnouncements stores NodeAnnouncements for which we
510+ // don't yet know any associated channel. They'll be replayed once
511+ // one of the node's channels is added to the graph.
512+ prematureNodeAnnouncements * lru.Cache [route.Vertex , * cachedNetworkMsg ]
513+
505514 // banman tracks our peer's ban status.
506515 banman * banman
507516
@@ -585,6 +594,9 @@ func New(cfg Config, selfKeyDesc *keychain.KeyDescriptor) *AuthenticatedGossiper
585594 prematureChannelUpdates : lru.NewCache [uint64 , * cachedNetworkMsg ]( //nolint: ll
586595 maxPrematureUpdates ,
587596 ),
597+ prematureNodeAnnouncements : lru.NewCache [route.Vertex , * cachedNetworkMsg ]( //nolint: ll
598+ maxPrematureNodeAnnouncements ,
599+ ),
588600 channelMtx : multimutex .NewMutex [uint64 ](),
589601 recentRejects : lru.NewCache [rejectCacheKey , * cachedReject ](
590602 maxRejectedUpdates ,
@@ -2132,6 +2144,78 @@ func (d *AuthenticatedGossiper) isPremature(chanID lnwire.ShortChannelID,
21322144 return true
21332145}
21342146
2147+ // cachePrematureNodeAnnouncement stores the passed node announcement for later
2148+ // processing. We do this when we haven't yet seen any channels for the node and
2149+ // therefore can't verify whether the announcement should be accepted.
2150+ func (d * AuthenticatedGossiper ) cachePrematureNodeAnnouncement (
2151+ nodeID route.Vertex , nMsg * networkMsg ) {
2152+
2153+ pMsg := & processedNetworkMsg {msg : nMsg }
2154+
2155+ earlyMsgs , err := d .prematureNodeAnnouncements .Get (nodeID )
2156+ switch {
2157+ case err == cache .ErrElementNotFound :
2158+ _ , _ = d .prematureNodeAnnouncements .Put (
2159+ nodeID , & cachedNetworkMsg {
2160+ msgs : []* processedNetworkMsg {pMsg },
2161+ },
2162+ )
2163+
2164+ default :
2165+ msgs := earlyMsgs .msgs
2166+ msgs = append (msgs , pMsg )
2167+ _ , _ = d .prematureNodeAnnouncements .Put (
2168+ nodeID , & cachedNetworkMsg {
2169+ msgs : msgs ,
2170+ },
2171+ )
2172+ }
2173+
2174+ log .Debugf ("Caching NodeAnnouncement for node=%x until a channel " +
2175+ "is known" , nodeID )
2176+ }
2177+
2178+ // replayPrematureNodeAnnouncements re-queues any cached node announcements for
2179+ // the provided vertices so they can be processed now that a channel exists.
2180+ func (d * AuthenticatedGossiper ) replayPrematureNodeAnnouncements (
2181+ vertices ... route.Vertex ) {
2182+
2183+ for _ , vertex := range vertices {
2184+ earlyMsgs , err := d .prematureNodeAnnouncements .Get (vertex )
2185+ if err == cache .ErrElementNotFound {
2186+ continue
2187+ }
2188+ if err != nil {
2189+ log .Warnf ("Unable to load cached node announcement " +
2190+ "for %x: %v" , vertex , err )
2191+ continue
2192+ }
2193+
2194+ for _ , cached := range earlyMsgs .msgs {
2195+ if cached .processed {
2196+ continue
2197+ }
2198+
2199+ cached .processed = true
2200+
2201+ nMsg := cached .msg
2202+ d .wg .Add (1 )
2203+ go func (vertex route.Vertex , replay * networkMsg ) {
2204+ defer d .wg .Done ()
2205+
2206+ log .Debugf ("Replaying cached NodeAnnouncement " +
2207+ "for node=%x" , vertex )
2208+
2209+ select {
2210+ case d .networkMsgs <- replay :
2211+ case <- d .quit :
2212+ replay .err <- ErrGossiperShuttingDown
2213+ }
2214+ }(vertex , nMsg )
2215+ }
2216+ }
2217+ }
2218+
21352219// processNetworkAnnouncement processes a new network relate authenticated
21362220// channel or node announcement or announcements proofs. If the announcement
21372221// didn't affect the internal state due to either being out of date, invalid,
@@ -2490,6 +2574,24 @@ func (d *AuthenticatedGossiper) handleNodeAnnouncement(ctx context.Context,
24902574 // We'll quickly ask the router if it already has a newer update for
24912575 // this node so we can skip validating signatures if not required.
24922576 if d .cfg .Graph .IsStaleNode (ctx , nodeAnn .NodeID , timestamp ) {
2577+ if nMsg .isRemote {
2578+ _ , err := d .cfg .Graph .FetchNode (ctx , nodeAnn .NodeID )
2579+ switch {
2580+ case errors .Is (err , graphdb .ErrGraphNodeNotFound ):
2581+ vertex := route .Vertex (nodeAnn .NodeID )
2582+ d .cachePrematureNodeAnnouncement (vertex , nMsg )
2583+
2584+ return nil , false
2585+
2586+ case err != nil :
2587+ log .Errorf ("Unable to fetch node %x: %v" ,
2588+ nodeAnn .NodeID , err )
2589+
2590+ nMsg .err <- err
2591+ return nil , false
2592+ }
2593+ }
2594+
24932595 log .Debugf ("Skipped processing stale node: %x" , nodeAnn .NodeID )
24942596 nMsg .err <- nil
24952597 return nil , true
@@ -2499,12 +2601,19 @@ func (d *AuthenticatedGossiper) handleNodeAnnouncement(ctx context.Context,
24992601 log .Debugf ("Adding node: %x got error: %v" , nodeAnn .NodeID ,
25002602 err )
25012603
2502- if ! graph . IsError (
2503- err ,
2504- graph . ErrOutdated ,
2505- graph . ErrIgnored ,
2506- ) {
2604+ switch {
2605+ case graph . IsError ( err , graph . ErrIgnored ):
2606+ if nMsg . isRemote {
2607+ vertex := route . Vertex ( nodeAnn . NodeID )
2608+ d . cachePrematureNodeAnnouncement ( vertex , nMsg )
25072609
2610+ return nil , false
2611+ }
2612+
2613+ case graph .IsError (err , graph .ErrOutdated ):
2614+ // No need to log, we'll just return the error below.
2615+
2616+ default :
25082617 log .Error (err )
25092618 }
25102619
@@ -2914,6 +3023,11 @@ func (d *AuthenticatedGossiper) handleChanAnnouncement(ctx context.Context,
29143023 channelUpdates = append (channelUpdates , chanMsgs .msgs ... )
29153024 }
29163025
3026+ d .replayPrematureNodeAnnouncements (
3027+ route .Vertex (edge .NodeKey1Bytes ),
3028+ route .Vertex (edge .NodeKey2Bytes ),
3029+ )
3030+
29173031 // Launch a new goroutine to handle each ChannelUpdate, this is to
29183032 // ensure we don't block here, as we can handle only one announcement
29193033 // at a time.
0 commit comments