gossiper: retransmit self NodeAnnouncement

This commit is contained in:
Johan T. Halseth 2019-09-10 14:37:18 +02:00
parent 24004fcb37
commit 92123c603d
No known key found for this signature in database
GPG Key ID: 15BAADA29DA20D26
2 changed files with 69 additions and 20 deletions

@ -901,10 +901,10 @@ func (d *AuthenticatedGossiper) networkHandler() {
trickleTimer := time.NewTicker(d.cfg.TrickleDelay) trickleTimer := time.NewTicker(d.cfg.TrickleDelay)
defer trickleTimer.Stop() defer trickleTimer.Stop()
// To start, we'll first check to see if there are any stale channels // To start, we'll first check to see if there are any stale channel or
// that we need to re-transmit. // node announcements that we need to re-transmit.
if err := d.retransmitStaleChannels(time.Now()); err != nil { if err := d.retransmitStaleAnns(time.Now()); err != nil {
log.Errorf("Unable to rebroadcast stale channels: %v", err) log.Errorf("Unable to rebroadcast stale announcements: %v", err)
} }
// We'll use this validation to ensure that we process jobs in their // We'll use this validation to ensure that we process jobs in their
@ -1115,13 +1115,14 @@ func (d *AuthenticatedGossiper) networkHandler() {
// The retransmission timer has ticked which indicates that we // The retransmission timer has ticked which indicates that we
// should check if we need to prune or re-broadcast any of our // should check if we need to prune or re-broadcast any of our
// personal channels. This addresses the case of "zombie" // personal channels or node announcement. This addresses the
// channels and channel advertisements that have been dropped, // case of "zombie" channels and channel advertisements that
// or not properly propagated through the network. // have been dropped, or not properly propagated through the
// network.
case tick := <-d.cfg.RetransmitTicker.Ticks(): case tick := <-d.cfg.RetransmitTicker.Ticks():
if err := d.retransmitStaleChannels(tick); err != nil { if err := d.retransmitStaleAnns(tick); err != nil {
log.Errorf("unable to rebroadcast stale "+ log.Errorf("unable to rebroadcast stale "+
"channels: %v", err) "announcements: %v", err)
} }
// The gossiper has been signalled to exit, to we exit our // The gossiper has been signalled to exit, to we exit our
@ -1169,18 +1170,23 @@ func (d *AuthenticatedGossiper) isRecentlyRejectedMsg(msg lnwire.Message) bool {
} }
} }
// retransmitStaleChannels examines all outgoing channels that the source node // retransmitStaleAnns examines all outgoing channels that the source node is
// is known to maintain to check to see if any of them are "stale". A channel // known to maintain to check to see if any of them are "stale". A channel is
// is stale iff, the last timestamp of its rebroadcast is older then // stale iff, the last timestamp of its rebroadcast is older than the
// broadcastInterval. // RebroadcastInterval. We also check if a refreshed node announcement should
func (d *AuthenticatedGossiper) retransmitStaleChannels(now time.Time) error { // be resent.
func (d *AuthenticatedGossiper) retransmitStaleAnns(now time.Time) error {
// Iterate over all of our channels and check if any of them fall // Iterate over all of our channels and check if any of them fall
// within the prune interval or re-broadcast interval. // within the prune interval or re-broadcast interval.
type updateTuple struct { type updateTuple struct {
info *channeldb.ChannelEdgeInfo info *channeldb.ChannelEdgeInfo
edge *channeldb.ChannelEdgePolicy edge *channeldb.ChannelEdgePolicy
} }
var edgesToUpdate []updateTuple
var (
havePublicChannels bool
edgesToUpdate []updateTuple
)
err := d.cfg.Router.ForAllOutgoingChannels(func( err := d.cfg.Router.ForAllOutgoingChannels(func(
info *channeldb.ChannelEdgeInfo, info *channeldb.ChannelEdgeInfo,
edge *channeldb.ChannelEdgePolicy) error { edge *channeldb.ChannelEdgePolicy) error {
@ -1196,6 +1202,11 @@ func (d *AuthenticatedGossiper) retransmitStaleChannels(now time.Time) error {
return nil return nil
} }
// We make a note that we have at least one public channel. We
// use this to determine whether we should send a node
// announcement below.
havePublicChannels = true
// If this edge has a ChannelUpdate that was created before the // If this edge has a ChannelUpdate that was created before the
// introduction of the MaxHTLC field, then we'll update this // introduction of the MaxHTLC field, then we'll update this
// edge to propagate this information in the network. // edge to propagate this information in the network.
@ -1246,13 +1257,51 @@ func (d *AuthenticatedGossiper) retransmitStaleChannels(now time.Time) error {
signedUpdates = append(signedUpdates, chanUpdate) signedUpdates = append(signedUpdates, chanUpdate)
} }
// If we don't have any channels to re-broadcast, then we'll exit // If we don't have any public channels, we return as we don't want to
// broadcast anything that would reveal our existence.
if !havePublicChannels {
return nil
}
// We'll also check that our NodeAnnouncement is not too old.
currentNodeAnn, err := d.cfg.SelfNodeAnnouncement(false)
if err != nil {
return fmt.Errorf("unable to get current node announment: %v",
err)
}
timestamp := time.Unix(int64(currentNodeAnn.Timestamp), 0)
timeElapsed := now.Sub(timestamp)
// If it's been a full day since we've re-broadcasted the
// node announcement, refresh it and resend it.
nodeAnnStr := ""
if timeElapsed >= d.cfg.RebroadcastInterval {
newNodeAnn, err := d.cfg.SelfNodeAnnouncement(true)
if err != nil {
return fmt.Errorf("unable to get refreshed node "+
"announcement: %v", err)
}
signedUpdates = append(signedUpdates, &newNodeAnn)
nodeAnnStr = " and our refreshed node announcement"
// Before broadcasting the refreshed node announcement, add it
// to our own graph.
if err := d.addNode(&newNodeAnn); err != nil {
log.Errorf("Unable to add refreshed node announcement "+
"to graph: %v", err)
}
}
// If we don't have any updates to re-broadcast, then we'll exit
// early. // early.
if len(signedUpdates) == 0 { if len(signedUpdates) == 0 {
return nil return nil
} }
log.Infof("Retransmitting %v outgoing channels", len(edgesToUpdate)) log.Infof("Retransmitting %v outgoing channels%v",
len(edgesToUpdate), nodeAnnStr)
// With all the wire announcements properly crafted, we'll broadcast // With all the wire announcements properly crafted, we'll broadcast
// our known outgoing channels to all our immediate peers. // our known outgoing channels to all our immediate peers.

@ -2932,9 +2932,9 @@ func TestRetransmit(t *testing.T) {
t.Fatalf("unable to force tick") t.Fatalf("unable to force tick")
} }
// The channel announcement + local channel update should be // The channel announcement + local channel update + node announcement
// re-broadcast. // should be re-broadcast.
checkAnnouncements(t, 1, 1, 0) checkAnnouncements(t, 1, 1, 1)
} }
// TestNodeAnnouncementNoChannels tests that NodeAnnouncements for nodes with // TestNodeAnnouncementNoChannels tests that NodeAnnouncements for nodes with