diff --git a/gossipd/gossip.c b/gossipd/gossip.c index 76a647003..b3b8ae43e 100644 --- a/gossipd/gossip.c +++ b/gossipd/gossip.c @@ -771,6 +771,7 @@ static void handle_local_add_channel(struct peer *peer, u8 *msg) u32 fee_base_msat, fee_proportional_millionths; u64 htlc_minimum_msat; struct node_connection *c; + struct routing_channel *chan; if (!fromwire_gossip_local_add_channel( msg, NULL, &scid, &chain_hash, &remote_node_id, &flags, @@ -792,8 +793,13 @@ static void handle_local_add_channel(struct peer *peer, u8 *msg) return; } + chan = routing_channel_new(rstate, &scid); + chan->public = false; + uintmap_add(&rstate->channels, short_channel_id_to_uint(&scid), chan); + direction = get_channel_direction(&rstate->local_id, &remote_node_id); c = half_add_connection(rstate, &rstate->local_id, &remote_node_id, &scid, direction); + channel_add_connection(rstate, chan, c); c->active = true; c->last_timestamp = 0; diff --git a/gossipd/routing.c b/gossipd/routing.c index 25a18124b..f45ce7066 100644 --- a/gossipd/routing.c +++ b/gossipd/routing.c @@ -565,8 +565,8 @@ find_pending_cannouncement(struct routing_state *rstate, return NULL; } -static struct routing_channel * -routing_channel_new(const tal_t *ctx, struct short_channel_id *scid) +struct routing_channel *routing_channel_new(const tal_t *ctx, + struct short_channel_id *scid) { struct routing_channel *chan = tal(ctx, struct routing_channel); chan->scid = *scid; @@ -574,10 +574,34 @@ routing_channel_new(const tal_t *ctx, struct short_channel_id *scid) chan->nodes[0] = chan->nodes[1] = NULL; chan->txout_script = NULL; chan->state = TXOUT_FETCHING; + chan->public = false; memset(&chan->msg_indexes, 0, sizeof(chan->msg_indexes)); return chan; } +static void remove_connection_from_channel(struct node_connection *nc, + struct routing_state *rstate) +{ + struct routing_channel *chan = uintmap_get( + &rstate->channels, short_channel_id_to_uint(&nc->short_channel_id)); + struct node_connection *c = chan->connections[nc->flags & 0x1]; + if (c == NULL) + return; + /* If we found a channel it should be the same */ + assert(nc == c); + chan->connections[nc->flags & 0x1] = NULL; +} + +void channel_add_connection(struct routing_state *rstate, + struct routing_channel *chan, + struct node_connection *nc) +{ + int direction = get_channel_direction(&nc->src->id, &nc->dst->id); + assert(chan != NULL); + chan->connections[direction] = nc; + tal_add_destructor2(nc, remove_connection_from_channel, rstate); +} + const struct short_channel_id *handle_channel_announcement( struct routing_state *rstate, const u8 *announce TAKES) @@ -617,7 +641,7 @@ const struct short_channel_id *handle_channel_announcement( /* Check if we know the channel already (no matter in what * state, we stop here if yes). */ chan = uintmap_get(&rstate->channels, scid); - if (chan != NULL) { + if (chan != NULL && chan->public) { return tal_free(pending); } /* FIXME: Handle duplicates as per BOLT #7 */ @@ -673,6 +697,9 @@ const struct short_channel_id *handle_channel_announcement( /* So you're new in town, ey? Let's find you a room in the Inn. */ chan = routing_channel_new(chan, &pending->short_channel_id); + + /* The channel will be public if we complete the verification */ + chan->public = true; uintmap_add(&rstate->channels, scid, chan); list_add_tail(&rstate->pending_cannouncement, &pending->list); @@ -742,10 +769,13 @@ bool handle_pending_cannouncement(struct routing_state *rstate, c1 = get_connection(rstate, &pending->node_id_1, &pending->node_id_2); forward = !c0 || !c1 || !c0->channel_announcement || !c1->channel_announcement; - add_channel_direction(rstate, &pending->node_id_1, &pending->node_id_2, - &pending->short_channel_id, pending->announce); - add_channel_direction(rstate, &pending->node_id_2, &pending->node_id_1, - &pending->short_channel_id, pending->announce); + c0 = add_channel_direction(rstate, &pending->node_id_1, &pending->node_id_2, + &pending->short_channel_id, pending->announce); + c1 = add_channel_direction(rstate, &pending->node_id_2, &pending->node_id_1, + &pending->short_channel_id, pending->announce); + + channel_add_connection(rstate, chan, c0); + channel_add_connection(rstate, chan, c1); if (forward) { if (replace_broadcast(rstate->broadcasts, diff --git a/gossipd/routing.h b/gossipd/routing.h index 10f2322c6..f2fb72cb4 100644 --- a/gossipd/routing.h +++ b/gossipd/routing.h @@ -96,6 +96,9 @@ struct routing_channel { struct node *nodes[2]; u64 msg_indexes[3]; + + /* Is this a public channel, or was it only added locally? */ + bool public; }; struct routing_state { @@ -180,6 +183,15 @@ void routing_failure(struct routing_state *rstate, enum onion_type failcode, const u8 *channel_update); +/* routing_channel constructor */ +struct routing_channel *routing_channel_new(const tal_t *ctx, + struct short_channel_id *scid); + +/* Add the connection to the channel */ +void channel_add_connection(struct routing_state *rstate, + struct routing_channel *chan, + struct node_connection *nc); + /* Utility function that, given a source and a destination, gives us * the direction bit the matching channel should get */ #define get_channel_direction(from, to) (pubkey_cmp(from, to) > 0)