gossiper: retransmit self NodeAnnouncement
This commit is contained in:
parent
24004fcb37
commit
92123c603d
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user