From 8940528bdb7e7ab5d706cabbb5179bf54e392dd2 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Thu, 10 May 2018 17:20:03 +0930 Subject: [PATCH] gossipd: don't include private announcements into broadcast map. Basically, if we don't have an announcement for the channel, stash it, and once we get an announcement, replay if necessary. Fixes: #1485 Signed-off-by: Rusty Russell --- gossipd/gossip.c | 2 +- gossipd/routing.c | 21 +++++++++++++++++++++ gossipd/routing.h | 3 +++ 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/gossipd/gossip.c b/gossipd/gossip.c index 296227817..8bf53e0a4 100644 --- a/gossipd/gossip.c +++ b/gossipd/gossip.c @@ -902,7 +902,7 @@ static void handle_get_update(struct peer *peer, const u8 *msg) &scid)); update = NULL; } else { - /* We want update that comes from our end. */ + /* We want (public) update that comes from our end. */ if (pubkey_eq(&chan->nodes[0]->id, &peer->daemon->id)) update = get_broadcast(rstate->broadcasts, chan->half[0] diff --git a/gossipd/routing.c b/gossipd/routing.c index 81cc03b84..4f1edf59b 100644 --- a/gossipd/routing.c +++ b/gossipd/routing.c @@ -194,6 +194,7 @@ static void init_half_chan(struct routing_state *rstate, struct half_chan *c = &chan->half[idx]; c->channel_update_msgidx = 0; + c->private_update = NULL; c->unroutable_until = 0; c->active = false; c->flags = idx; @@ -641,6 +642,17 @@ bool routing_add_channel_announcement(struct routing_state *rstate, old_msgidx, chan->channel_announce_msgidx); return false; } + + /* If we have previously private updates for channels, process now */ + for (size_t i = 0; i < ARRAY_SIZE(chan->half); i++) { + const u8 *update = chan->half[i].private_update; + + if (update) { + chan->half[i].private_update = NULL; + routing_add_channel_update(rstate, take(update)); + } + } + return true; } @@ -948,6 +960,15 @@ bool routing_add_channel_update(struct routing_state *rstate, (flags & ROUTING_FLAGS_DISABLED) == 0, timestamp, htlc_minimum_msat); + /* For private channels, we get updates without an announce: don't + * broadcast them! */ + if (chan->channel_announce_msgidx == 0) { + tal_free(chan->half[direction].private_update); + chan->half[direction].private_update + = tal_dup_arr(chan, u8, update, tal_len(update), 0); + return true; + } + replace_broadcast(chan, rstate->broadcasts, &chan->half[direction].channel_update_msgidx, update); diff --git a/gossipd/routing.h b/gossipd/routing.h index 45867b32a..b57ce3873 100644 --- a/gossipd/routing.h +++ b/gossipd/routing.h @@ -37,6 +37,9 @@ struct half_chan { /* Cached `channel_update` we might forward to new peers (or 0) */ u64 channel_update_msgidx; + /* If it's a private update, it's not in the broadcast map. */ + const u8 *private_update; + /* If greater than current time, this connection should not * be used for routing. */ time_t unroutable_until;