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 <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell 2018-06-04 13:45:25 +09:30
parent c2189229ca
commit c2cc3823db
3 changed files with 49 additions and 19 deletions

View File

@ -623,6 +623,17 @@ static void send_node_announcement(struct daemon *daemon)
tal_hex(tmpctx, err)); 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 * 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); err = handle_channel_update(rstate, msg, source);
if (err) if (err)
return err; return err;
/* In case we just announced a new local channel. */
consider_own_node_announce(daemon);
break; 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 */ /* We always tell peer, even if it's not public yet */
if (!is_chan_public(chan)) if (!is_chan_public(chan))
queue_peer_msg(peer, take(cupdate)); 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 else
binding = NULL; 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! */ /* OK, we're ready! */
daemon_conn_send(&daemon->master, daemon_conn_send(&daemon->master,
take(towire_gossipctl_activate_reply(NULL, 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)) if (!fromwire_gossip_get_txout_reply(msg, msg, &scid, &satoshis, &outscript))
master_badmsg(WIRE_GOSSIP_GET_TXOUT_REPLY, msg); master_badmsg(WIRE_GOSSIP_GET_TXOUT_REPLY, msg);
if (handle_pending_cannouncement(daemon->rstate, &scid, satoshis, outscript)) handle_pending_cannouncement(daemon->rstate, &scid, satoshis, outscript);
send_node_announcement(daemon); consider_own_node_announce(daemon);
return daemon_conn_read_next(conn, &daemon->master); return daemon_conn_read_next(conn, &daemon->master);
} }

View File

@ -98,6 +98,7 @@ struct routing_state *new_routing_state(const tal_t *ctx,
rstate->prune_timeout = prune_timeout; rstate->prune_timeout = prune_timeout;
rstate->store = gossip_store_new(rstate); rstate->store = gossip_store_new(rstate);
rstate->dev_allow_localhost = dev_allow_localhost; rstate->dev_allow_localhost = dev_allow_localhost;
rstate->local_channel_announced = false;
list_head_init(&rstate->pending_cannouncement); list_head_init(&rstate->pending_cannouncement);
uintmap_init(&rstate->chanmap); 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); 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, bool routing_add_channel_announcement(struct routing_state *rstate,
const u8 *msg TAKES, u64 satoshis) 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 struct short_channel_id *scid,
const u64 satoshis, const u64 satoshis,
const u8 *outscript) const u8 *outscript)
{ {
bool local;
const u8 *s; const u8 *s;
struct pending_cannouncement *pending; struct pending_cannouncement *pending;
pending = find_pending_cannouncement(rstate, scid); pending = find_pending_cannouncement(rstate, scid);
if (!pending) if (!pending)
return false; return;
/* BOLT #7: /* BOLT #7:
* *
@ -819,7 +833,7 @@ bool handle_pending_cannouncement(struct routing_state *rstate,
type_to_string(pending, struct short_channel_id, type_to_string(pending, struct short_channel_id,
scid)); scid));
tal_free(pending); tal_free(pending);
return false; return;
} }
/* BOLT #7: /* BOLT #7:
@ -841,7 +855,7 @@ bool handle_pending_cannouncement(struct routing_state *rstate,
scid), scid),
tal_hex(tmpctx, s), tal_hex(tmpctx, outscript)); tal_hex(tmpctx, s), tal_hex(tmpctx, outscript));
tal_free(pending); tal_free(pending);
return false; return;
} }
if (!routing_add_channel_announcement(rstate, pending->announce, satoshis)) 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"); "Could not add channel_announcement");
gossip_store_add_channel_announcement(rstate->store, pending->announce, satoshis); 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. */ /* 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[0]);
process_pending_channel_update(rstate, scid, pending->updates[1]); 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); process_pending_node_announcement(rstate, &pending->node_id_2);
tal_free(pending); tal_free(pending);
return local;
} }
static void update_pending(struct pending_cannouncement *pending, 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`. * receiving the first corresponding `channel_update`.
*/ */
if (!have_broadcast_announce) if (!have_broadcast_announce)
insert_broadcast(rstate->broadcasts, chan->channel_announce); add_channel_announce_to_broadcast(rstate, chan);
insert_broadcast(rstate->broadcasts, insert_broadcast(rstate->broadcasts,
chan->half[direction].channel_update); chan->half[direction].channel_update);
@ -1077,11 +1087,12 @@ u8 *handle_channel_update(struct routing_state *rstate, const u8 *update,
return err; 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, type_to_string(tmpctx, struct short_channel_id,
&short_channel_id), &short_channel_id),
flags & 0x01, flags & 0x01,
flags & ROUTING_FLAGS_DISABLED ? "DISABLED" : "ACTIVE"); flags & ROUTING_FLAGS_DISABLED ? "DISABLED" : "ACTIVE",
source);
if (!routing_add_channel_update(rstate, serialized)) if (!routing_add_channel_update(rstate, serialized))
status_failed(STATUS_FAIL_INTERNAL_ERROR, status_failed(STATUS_FAIL_INTERNAL_ERROR,

View File

@ -175,6 +175,9 @@ struct routing_state {
/* A map of channels indexed by short_channel_ids */ /* A map of channels indexed by short_channel_ids */
UINTMAP(struct chan *) chanmap; UINTMAP(struct chan *) chanmap;
/* Has one of our own channels been announced? */
bool local_channel_announced;
}; };
static inline struct chan * 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 * handle_pending_cannouncement -- handle channel_announce once we've
* completed short_channel_id lookup. * 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 struct short_channel_id *scid,
const u64 satoshis, const u64 satoshis,
const u8 *txscript); const u8 *txscript);