From 450d78ad67dc6fd1aed48ec7c5b140d0ff54ef77 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Sun, 11 Feb 2024 21:02:41 +1030 Subject: [PATCH] gossipd: set dying flag on node_announcement when all channels are dying. This avoids us gossiping about nodes which don't have live channels. Interstingly, we previously tested that we *did* gossip such node announcements, and now we fix that test. Signed-off-by: Rusty Russell --- gossipd/gossmap_manage.c | 31 +++++++++++++++++++++++++++++++ tests/test_gossip.py | 4 ++-- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/gossipd/gossmap_manage.c b/gossipd/gossmap_manage.c index e540eb009..309fbb8b3 100644 --- a/gossipd/gossmap_manage.c +++ b/gossipd/gossmap_manage.c @@ -220,6 +220,17 @@ static bool any_cannounce_preceeds_offset(struct gossmap *gossmap, return false; } +/* Are all channels associated with this node dying? */ +static bool all_node_channels_dying(struct gossmap *gossmap, const struct gossmap_node *n) +{ + for (size_t i = 0; i < n->num_chans; i++) { + const struct gossmap_chan *c = gossmap_nth_chan(gossmap, n, i, NULL); + if (!gossmap_chan_is_dying(gossmap, c)) + return false; + } + return true; +} + /* To actually remove a channel: * - Suppress future lookups in case we receive another channel_update. * - Put deleted tombstone in gossip_store. @@ -1161,6 +1172,26 @@ void gossmap_manage_channel_spent(struct gossmap_manage *gm, GOSSIP_STORE_DYING_BIT, WIRE_CHANNEL_UPDATE); } + + /* If all channels associated with either node are dying, node_announcement is dying + too (so we don't broadcast) */ + for (int dir = 0; dir < 2; dir++) { + struct gossmap_node *n = gossmap_nth_node(gossmap, chan, dir); + + if (!gossmap_node_announced(n)) + continue; + + /* Don't get confused if a node has a channel with self! */ + if (dir == 1 && n == gossmap_nth_node(gossmap, chan, 0)) + continue; + + if (all_node_channels_dying(gossmap, n)) { + gossip_store_set_flag(gm->daemon->gs, + n->nann_off, + GOSSIP_STORE_DYING_BIT, + WIRE_NODE_ANNOUNCEMENT); + } + } } struct gossmap *gossmap_manage_get_gossmap(struct gossmap_manage *gm) diff --git a/tests/test_gossip.py b/tests/test_gossip.py index 5c61bfa77..1d1e6d2c3 100644 --- a/tests/test_gossip.py +++ b/tests/test_gossip.py @@ -1960,9 +1960,9 @@ def test_gossip_not_dying(node_factory, bitcoind): l1.daemon.wait_for_log("closing soon due to the funding outpoint being spent") - # We won't gossip the dead channel any more (but we still propagate node_announcement). But connectd is not explicitly synced, so wait for "a bit". + # We won't gossip the dead channel any more, nor the node_announcements. But connectd is not explicitly synced, so wait for "a bit". time.sleep(1) - assert len(get_gossip(l1)) == 2 + assert get_gossip(l1) == [] def test_dump_own_gossip(node_factory):