From c2cc3823db7b79d097b583b422580a1b7774ff69 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Mon, 4 Jun 2018 13:45:25 +0930 Subject: [PATCH] gossipd: announce own node only after channel announcement actually broadcast. handle_pending_cannouncement might not actually add the announcment, as it could be waiting for a channel_update. We need to wait for the actual announcement before considering announcing our node. Signed-off-by: Rusty Russell --- gossipd/gossip.c | 24 ++++++++++++++++++++++-- gossipd/routing.c | 35 +++++++++++++++++++++++------------ gossipd/routing.h | 9 ++++----- 3 files changed, 49 insertions(+), 19 deletions(-) diff --git a/gossipd/gossip.c b/gossipd/gossip.c index df4f694922ea..7abc1be00c48 100644 --- a/gossipd/gossip.c +++ b/gossipd/gossip.c @@ -623,6 +623,17 @@ static void send_node_announcement(struct daemon *daemon) tal_hex(tmpctx, err)); } +/* Should we announce our own node? */ +static void consider_own_node_announce(struct daemon *daemon) +{ + if (!daemon->rstate->local_channel_announced) + return; + + /* FIXME: We may not need to retransmit here, if previous still valid. */ + send_node_announcement(daemon); + daemon->rstate->local_channel_announced = false; +} + /** * Handle an incoming gossip message * @@ -661,6 +672,8 @@ static u8 *handle_gossip_msg(struct daemon *daemon, const u8 *msg, err = handle_channel_update(rstate, msg, source); if (err) return err; + /* In case we just announced a new local channel. */ + consider_own_node_announce(daemon); break; } @@ -1042,6 +1055,9 @@ static void handle_local_channel_update(struct peer *peer, const u8 *msg) /* We always tell peer, even if it's not public yet */ if (!is_chan_public(chan)) queue_peer_msg(peer, take(cupdate)); + + /* That channel_update might trigger our first channel_announcement */ + consider_own_node_announce(peer->daemon); } /** @@ -2005,6 +2021,10 @@ static struct io_plan *gossip_activate(struct daemon_conn *master, else binding = NULL; + /* Now we know our addresses, re-announce ourselves if we have a + * channel, in case options have changed. */ + consider_own_node_announce(daemon); + /* OK, we're ready! */ daemon_conn_send(&daemon->master, take(towire_gossipctl_activate_reply(NULL, @@ -2562,8 +2582,8 @@ static struct io_plan *handle_txout_reply(struct io_conn *conn, if (!fromwire_gossip_get_txout_reply(msg, msg, &scid, &satoshis, &outscript)) master_badmsg(WIRE_GOSSIP_GET_TXOUT_REPLY, msg); - if (handle_pending_cannouncement(daemon->rstate, &scid, satoshis, outscript)) - send_node_announcement(daemon); + handle_pending_cannouncement(daemon->rstate, &scid, satoshis, outscript); + consider_own_node_announce(daemon); return daemon_conn_read_next(conn, &daemon->master); } diff --git a/gossipd/routing.c b/gossipd/routing.c index 74392bad29ce..1b844869ae8a 100644 --- a/gossipd/routing.c +++ b/gossipd/routing.c @@ -98,6 +98,7 @@ struct routing_state *new_routing_state(const tal_t *ctx, rstate->prune_timeout = prune_timeout; rstate->store = gossip_store_new(rstate); rstate->dev_allow_localhost = dev_allow_localhost; + rstate->local_channel_announced = false; list_head_init(&rstate->pending_cannouncement); uintmap_init(&rstate->chanmap); @@ -604,6 +605,20 @@ static void destroy_pending_cannouncement(struct pending_cannouncement *pending, list_del_from(&rstate->pending_cannouncement, &pending->list); } +static bool is_local_channel(const struct routing_state *rstate, + const struct chan *chan) +{ + return pubkey_eq(&chan->nodes[0]->id, &rstate->local_id) + || pubkey_eq(&chan->nodes[1]->id, &rstate->local_id); +} + +static void add_channel_announce_to_broadcast(struct routing_state *rstate, + struct chan *chan) +{ + insert_broadcast(rstate->broadcasts, chan->channel_announce); + rstate->local_channel_announced |= is_local_channel(rstate, chan); +} + bool routing_add_channel_announcement(struct routing_state *rstate, const u8 *msg TAKES, u64 satoshis) { @@ -797,18 +812,17 @@ static void process_pending_channel_update(struct routing_state *rstate, } } -bool handle_pending_cannouncement(struct routing_state *rstate, +void handle_pending_cannouncement(struct routing_state *rstate, const struct short_channel_id *scid, const u64 satoshis, const u8 *outscript) { - bool local; const u8 *s; struct pending_cannouncement *pending; pending = find_pending_cannouncement(rstate, scid); if (!pending) - return false; + return; /* BOLT #7: * @@ -819,7 +833,7 @@ bool handle_pending_cannouncement(struct routing_state *rstate, type_to_string(pending, struct short_channel_id, scid)); tal_free(pending); - return false; + return; } /* BOLT #7: @@ -841,7 +855,7 @@ bool handle_pending_cannouncement(struct routing_state *rstate, scid), tal_hex(tmpctx, s), tal_hex(tmpctx, outscript)); tal_free(pending); - return false; + return; } if (!routing_add_channel_announcement(rstate, pending->announce, satoshis)) @@ -849,9 +863,6 @@ bool handle_pending_cannouncement(struct routing_state *rstate, "Could not add channel_announcement"); gossip_store_add_channel_announcement(rstate->store, pending->announce, satoshis); - local = pubkey_eq(&pending->node_id_1, &rstate->local_id) || - pubkey_eq(&pending->node_id_2, &rstate->local_id); - /* Did we have an update waiting? If so, apply now. */ process_pending_channel_update(rstate, scid, pending->updates[0]); process_pending_channel_update(rstate, scid, pending->updates[1]); @@ -860,7 +871,6 @@ bool handle_pending_cannouncement(struct routing_state *rstate, process_pending_node_announcement(rstate, &pending->node_id_2); tal_free(pending); - return local; } static void update_pending(struct pending_cannouncement *pending, @@ -967,7 +977,7 @@ bool routing_add_channel_update(struct routing_state *rstate, * receiving the first corresponding `channel_update`. */ if (!have_broadcast_announce) - insert_broadcast(rstate->broadcasts, chan->channel_announce); + add_channel_announce_to_broadcast(rstate, chan); insert_broadcast(rstate->broadcasts, chan->half[direction].channel_update); @@ -1077,11 +1087,12 @@ u8 *handle_channel_update(struct routing_state *rstate, const u8 *update, return err; } - status_trace("Received channel_update for channel %s(%d) now %s", + status_trace("Received channel_update for channel %s(%d) now %s (from %s)", type_to_string(tmpctx, struct short_channel_id, &short_channel_id), flags & 0x01, - flags & ROUTING_FLAGS_DISABLED ? "DISABLED" : "ACTIVE"); + flags & ROUTING_FLAGS_DISABLED ? "DISABLED" : "ACTIVE", + source); if (!routing_add_channel_update(rstate, serialized)) status_failed(STATUS_FAIL_INTERNAL_ERROR, diff --git a/gossipd/routing.h b/gossipd/routing.h index 39b90d54fc42..b557b0339b36 100644 --- a/gossipd/routing.h +++ b/gossipd/routing.h @@ -175,6 +175,9 @@ struct routing_state { /* A map of channels indexed by short_channel_ids */ UINTMAP(struct chan *) chanmap; + + /* Has one of our own channels been announced? */ + bool local_channel_announced; }; static inline struct chan * @@ -217,12 +220,8 @@ u8 *handle_channel_announcement(struct routing_state *rstate, /** * handle_pending_cannouncement -- handle channel_announce once we've * completed short_channel_id lookup. - * - * Returns true if the channel was new and is local. This means that - * if we haven't sent a node_announcement just yet, now would be a - * good time. */ -bool handle_pending_cannouncement(struct routing_state *rstate, +void handle_pending_cannouncement(struct routing_state *rstate, const struct short_channel_id *scid, const u64 satoshis, const u8 *txscript);