routing: rebroadcast our outgoing channels with a long period

This commit adds new behavior to the ChannelRouter struct: we know
rebroadcast our outgoing channels every 30 minutes. This new behavior
should ensure that both directions of an advertised channel edge are
always propagated though the network, fixing the issue of “ghost” edges
which exist but aren’t advertised.
This commit is contained in:
Olaoluwa Osuntokun 2017-01-22 14:39:18 -08:00
parent 97bb8744c4
commit db40b4322e
No known key found for this signature in database
GPG Key ID: 9CC5B105D03521A2

@ -1,6 +1,7 @@
package routing package routing
import ( import (
"bytes"
"encoding/hex" "encoding/hex"
"sync" "sync"
"sync/atomic" "sync/atomic"
@ -92,7 +93,7 @@ type ChannelRouter struct {
cfg *Config cfg *Config
self *channeldb.LightningNode selfNode *channeldb.LightningNode
// TODO(roasbeef): make LRU, invalidate upon new block connect // TODO(roasbeef): make LRU, invalidate upon new block connect
shortestPathCache map[[33]byte][]*Route shortestPathCache map[[33]byte][]*Route
@ -133,14 +134,14 @@ func New(cfg Config) (*ChannelRouter, error) {
return nil, err return nil, err
} }
self, err := cfg.Graph.SourceNode() selfNode, err := cfg.Graph.SourceNode()
if err != nil { if err != nil {
return nil, err return nil, err
} }
return &ChannelRouter{ return &ChannelRouter{
cfg: &cfg, cfg: &cfg,
self: self, selfNode: selfNode,
fakeSig: fakeSig, fakeSig: fakeSig,
networkMsgs: make(chan *routingMsg), networkMsgs: make(chan *routingMsg),
syncRequests: make(chan *syncRequest), syncRequests: make(chan *syncRequest),
@ -301,6 +302,9 @@ func (r *ChannelRouter) networkHandler() {
trickleTimer := time.NewTicker(time.Millisecond * 300) trickleTimer := time.NewTicker(time.Millisecond * 300)
defer trickleTimer.Stop() defer trickleTimer.Stop()
retransmitTimer := time.NewTicker(time.Minute * 30)
defer retransmitTimer.Stop()
for { for {
select { select {
// A new fully validated network message has just arrived. As a // A new fully validated network message has just arrived. As a
@ -371,6 +375,55 @@ func (r *ChannelRouter) networkHandler() {
log.Infof("Block %v (height=%v) closed %v channels", log.Infof("Block %v (height=%v) closed %v channels",
newBlock.Hash, newBlock.Height, numClosed) newBlock.Hash, newBlock.Height, numClosed)
// The retransmission timer has ticked which indicates that we
// should broadcast our personal channel sot the network. This
// addresses the case of channel advertisements whether being
// dropped, or not properly propagated through the network.
case <-retransmitTimer.C:
var selfChans []lnwire.Message
selfPub := r.selfNode.PubKey.SerializeCompressed()
err := r.selfNode.ForEachChannel(nil, func(c *channeldb.ChannelEdge) error {
chanNodePub := c.Node.PubKey.SerializeCompressed()
// Compare our public key with that of the
// channel peer. If our key is "less" than
// theirs, then we're the "first" node in the
// advertisement, otherwise we're the second.
flags := uint16(1)
if bytes.Compare(selfPub, chanNodePub) == -1 {
flags = 0
}
selfChans = append(selfChans, &lnwire.ChannelUpdateAnnouncement{
Signature: r.fakeSig,
ChannelID: lnwire.NewChanIDFromInt(c.ChannelID),
Timestamp: uint32(c.LastUpdate.Unix()),
Flags: flags,
Expiry: c.Expiry,
HtlcMinimumMstat: uint32(c.MinHTLC),
FeeBaseMstat: uint32(c.FeeBaseMSat),
FeeProportionalMillionths: uint32(c.FeeProportionalMillionths),
})
return nil
})
if err != nil {
log.Errorf("unable to retransmit "+
"channels: %v", err)
continue
}
log.Infof("Retransmitting %v outgoing channels",
len(selfChans))
// With all the wire messages properly crafted, we'll
// broadcast our known outgoing channel to all our
// immediate peers.
if err := r.cfg.Broadcast(nil, selfChans...); err != nil {
log.Errorf("unable to re-broadcast "+
"channels: %v", err)
}
// The trickle timer has ticked, which indicates we should // The trickle timer has ticked, which indicates we should
// flush to the network the pending batch of new announcements // flush to the network the pending batch of new announcements
// we've received since the last trickle tick. // we've received since the last trickle tick.