discovery: send channel announcements before node announcements.

According to BOLT#7, nodes will ignore node announcements
for nodes not found in any previous channel announcements.
This commit makes the discovery service send its known
channels before its known nodes when syncing the channel
graph with a peer.
This commit is contained in:
Johan T. Halseth 2017-07-14 21:41:46 +02:00 committed by Olaoluwa Osuntokun
parent ebbe6d7a10
commit 889a4eb48b

@ -439,8 +439,9 @@ func (d *AuthenticatedGossiper) processNetworkAnnouncement(nMsg *networkMsg) []l
switch msg := nMsg.msg.(type) {
// A new node announcement has arrived which either presents a new
// node, or a node updating previously advertised information.
// A new node announcement has arrived which either presents new information
// about a node in one of the channels we know about, or a updating
// previously advertised information.
case *lnwire.NodeAnnouncement:
if nMsg.isRemote {
if err := d.validateNodeAnn(msg); err != nil {
@ -453,12 +454,13 @@ func (d *AuthenticatedGossiper) processNetworkAnnouncement(nMsg *networkMsg) []l
}
node := &channeldb.LightningNode{
LastUpdate: time.Unix(int64(msg.Timestamp), 0),
Addresses: msg.Addresses,
PubKey: msg.NodeID,
Alias: msg.Alias.String(),
AuthSig: msg.Signature,
Features: msg.Features,
HaveNodeAnnouncement: true,
LastUpdate: time.Unix(int64(msg.Timestamp), 0),
Addresses: msg.Addresses,
PubKey: msg.NodeID,
Alias: msg.Alias.String(),
AuthSig: msg.Signature,
Features: msg.Features,
}
if err := d.cfg.Router.AddNode(node); err != nil {
@ -537,6 +539,11 @@ func (d *AuthenticatedGossiper) processNetworkAnnouncement(nMsg *networkMsg) []l
BitcoinKey2: msg.BitcoinKey2,
AuthProof: proof,
}
// We will add the edge to the channel router. If the nodes
// present in this channel are not present in the database, a
// partial node will be added to represent each node while we
// wait for a node announcement.
if err := d.cfg.Router.AddEdge(edge); err != nil {
if routing.IsError(err, routing.ErrOutdated,
routing.ErrIgnored) {
@ -896,30 +903,10 @@ func (d *AuthenticatedGossiper) synchronizeWithNode(syncReq *syncRequest) error
// containing all the messages to be sent to the target peer.
var announceMessages []lnwire.Message
// First run through all the vertexes in the graph, retrieving the data
// for the announcement we originally retrieved.
var numNodes uint32
if err := d.cfg.Router.ForEachNode(func(node *channeldb.LightningNode) error {
ann := &lnwire.NodeAnnouncement{
Signature: node.AuthSig,
Timestamp: uint32(node.LastUpdate.Unix()),
Addresses: node.Addresses,
NodeID: node.PubKey,
Alias: lnwire.NewAlias(node.Alias),
Features: node.Features,
}
announceMessages = append(announceMessages, ann)
numNodes++
return nil
}); err != nil {
return err
}
// With the vertexes gathered, we'll no retrieve the initial
// announcement, as well as the latest channel update announcement for
// both of the directed infos that make up the channel.
// As peers are expecting channel announcements before node
// announcements, we first retrieve the initial announcement, as well as
// the latest channel update announcement for both of the directed edges
// that make up each channel, and queue these to be sent to the peer.
var numEdges uint32
if err := d.cfg.Router.ForEachChannel(func(chanInfo *channeldb.ChannelEdgeInfo,
e1, e2 *channeldb.ChannelEdgePolicy) error {
@ -947,6 +934,32 @@ func (d *AuthenticatedGossiper) synchronizeWithNode(syncReq *syncRequest) error
return err
}
// Run through all the vertexes in the graph, retrieving the data for
// the node announcements we originally retrieved.
var numNodes uint32
if err := d.cfg.Router.ForEachNode(func(node *channeldb.LightningNode) error {
// If this is a node we never received a node announcement for,
// we skip it.
if !node.HaveNodeAnnouncement {
return nil
}
ann := &lnwire.NodeAnnouncement{
Signature: node.AuthSig,
Timestamp: uint32(node.LastUpdate.Unix()),
Addresses: node.Addresses,
NodeID: node.PubKey,
Alias: lnwire.NewAlias(node.Alias),
Features: node.Features,
}
announceMessages = append(announceMessages, ann)
numNodes++
return nil
}); err != nil {
return err
}
log.Infof("Syncing channel graph state with %x, sending %v "+
"vertexes and %v edges", targetNode.SerializeCompressed(),
numNodes, numEdges)