From 803e4f8895241e9bb457eec7f162fa225f7cec6f Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Mon, 4 Jun 2018 13:46:25 +0930 Subject: [PATCH] gossipd: announce nodes after channel announcement. In general, we need to only publish node announcements after publishing channel announcements, though we can accept node announcements as soon as we see channel announcements. So we keep a flag for those node_announcement which haven't been broadcast yet. Signed-off-by: Rusty Russell --- gossipd/routing.c | 39 ++++++++++++++++++++++++++++++--------- gossipd/routing.h | 1 + 2 files changed, 31 insertions(+), 9 deletions(-) diff --git a/gossipd/routing.c b/gossipd/routing.c index 1b844869a..168dcf746 100644 --- a/gossipd/routing.c +++ b/gossipd/routing.c @@ -150,6 +150,7 @@ static struct node *new_node(struct routing_state *rstate, n->chans = tal_arr(n, struct chan *, 0); n->alias = NULL; n->node_announcement = NULL; + n->node_announcement_public = false; n->last_timestamp = -1; n->addresses = tal_arr(n, struct wireaddr, 0); node_map_add(rstate->nodes, n); @@ -617,6 +618,18 @@ static void add_channel_announce_to_broadcast(struct routing_state *rstate, { insert_broadcast(rstate->broadcasts, chan->channel_announce); rstate->local_channel_announced |= is_local_channel(rstate, chan); + + /* If we've been waiting for this, now we can announce node */ + for (size_t i = 0; i < ARRAY_SIZE(chan->nodes); i++) { + struct node *node = chan->nodes[i]; + if (!node->node_announcement) + continue; + if (!node->node_announcement_public) { + node->node_announcement_public = true; + insert_broadcast(rstate->broadcasts, + node->node_announcement); + } + } } bool routing_add_channel_announcement(struct routing_state *rstate, @@ -1140,6 +1153,14 @@ static struct wireaddr *read_addresses(const tal_t *ctx, const u8 *ser) return wireaddrs; } +static bool node_has_public_channels(struct node *node) +{ + for (size_t i = 0; i < tal_count(node->chans); i++) + if (is_chan_public(node->chans[i])) + return true; + return false; +} + bool routing_add_node_announcement(struct routing_state *rstate, const u8 *msg TAKES) { struct node *node; @@ -1175,16 +1196,16 @@ bool routing_add_node_announcement(struct routing_state *rstate, const u8 *msg T tal_free(node->node_announcement); node->node_announcement = tal_dup_arr(node, u8, msg, tal_len(msg), 0); - insert_broadcast(rstate->broadcasts, node->node_announcement); - return true; -} -static bool node_has_public_channels(struct node *node) -{ - for (size_t i = 0; i < tal_count(node->chans); i++) - if (is_chan_public(node->chans[i])) - return true; - return false; + /* FIXME: + * When a channel is closed, the node announce may now be out of + * order. It's not vital, but would be nice to fix. + */ + /* We might be waiting for channel_announce to be released. */ + node->node_announcement_public = node_has_public_channels(node); + if (node->node_announcement_public) + insert_broadcast(rstate->broadcasts, node->node_announcement); + return true; } u8 *handle_node_announcement(struct routing_state *rstate, const u8 *node_ann) diff --git a/gossipd/routing.h b/gossipd/routing.h index b557b0339..46be560ab 100644 --- a/gossipd/routing.h +++ b/gossipd/routing.h @@ -101,6 +101,7 @@ struct node { /* Cached `node_announcement` we might forward to new peers (or NULL). */ const u8 *node_announcement; + bool node_announcement_public; }; const secp256k1_pubkey *node_map_keyof_node(const struct node *n);