From 2e7c08824a2bbeb4b8ef5529d3582712c21170a7 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 15 Feb 2023 15:03:57 +1030 Subject: [PATCH] gossipd: don't zombify node_announcements, just forget them. This simplifies things (we'll get node_announcement if they ever rebroadcast), since we clearly have an issue with node_announcement for zombie nodes. Changes: 1. Remove now-unused gossip_store_mark_nannounce_zombie and resurrect_nannouncements. 2. Don't consider zombie channels to count when deciding whether to move node_announcement (node_announcement must be preceded by at least one broadcastable channel_announcement). 3. Treat incoming node_announcement where we have all-zombie channels the same as if we had no channels. 4. Remove node_announcement whenever we have no announcable channels (not just zombies). Signed-off-by: Rusty Russell --- gossipd/gossip_store.c | 7 --- gossipd/gossip_store.h | 3 - gossipd/routing.c | 55 ++++++------------- gossipd/test/run-check_channel_announcement.c | 4 -- gossipd/test/run-txout_failure.c | 4 -- 5 files changed, 16 insertions(+), 57 deletions(-) diff --git a/gossipd/gossip_store.c b/gossipd/gossip_store.c index 1d4d67093..4ad0d5b2c 100644 --- a/gossipd/gossip_store.c +++ b/gossipd/gossip_store.c @@ -696,13 +696,6 @@ void gossip_store_mark_cupdate_zombie(struct gossip_store *gs, mark_zombie(gs, bcast, WIRE_CHANNEL_UPDATE); } -/* Marks the length field of a node_announcement with the zombie flag bit */ -void gossip_store_mark_nannounce_zombie(struct gossip_store *gs, - struct broadcastable *bcast) -{ - mark_zombie(gs, bcast, WIRE_NODE_ANNOUNCEMENT); -} - const u8 *gossip_store_get(const tal_t *ctx, struct gossip_store *gs, u64 offset) diff --git a/gossipd/gossip_store.h b/gossipd/gossip_store.h index e3847e9bc..d6f76e176 100644 --- a/gossipd/gossip_store.h +++ b/gossipd/gossip_store.h @@ -77,9 +77,6 @@ void gossip_store_mark_channel_zombie(struct gossip_store *gs, void gossip_store_mark_cupdate_zombie(struct gossip_store *gs, struct broadcastable *bcast); -void gossip_store_mark_nannounce_zombie(struct gossip_store *gs, - struct broadcastable *bcast); - /** * Direct store accessor: loads gossip msg back from store. * diff --git a/gossipd/routing.c b/gossipd/routing.c index 0dfee78b6..62f2d26fc 100644 --- a/gossipd/routing.c +++ b/gossipd/routing.c @@ -442,6 +442,10 @@ static bool node_announce_predates_channels(const struct node *node) if (!is_chan_public(c)) continue; + /* Zombies don't count! */ + if (is_chan_zombie(c)) + continue; + if (c->bcast.index < node->bcast.index) return false; } @@ -517,6 +521,7 @@ static void remove_chan_from_node(struct routing_state *rstate, return; } + /* Don't bother if there's no node_announcement */ if (!node->bcast.index) return; @@ -1317,31 +1322,6 @@ static void delete_spam_update(struct routing_state *rstate, hc->rgraph.timestamp = hc->bcast.timestamp; } -static void resurrect_nannouncements(struct routing_state *rstate, - struct chan *chan) -{ - const u8 *zombie_nann = NULL; - for (int i = 0; i < 2; i++) { - struct node *node = chan->nodes[i]; - /* Use the most recent announcement (could be spam.) */ - zombie_nann = gossip_store_get(tmpctx, rstate->gs, - node->rgraph.index); - /* If there was a spam entry, delete them both. */ - if (node->bcast.index != node->rgraph.index) - gossip_store_delete(rstate->gs, &node->bcast, - WIRE_NODE_ANNOUNCEMENT); - gossip_store_delete(rstate->gs, &node->rgraph, - WIRE_NODE_ANNOUNCEMENT); - node->bcast.index = gossip_store_add(rstate->gs, zombie_nann, - node->rgraph.timestamp, - local_direction(rstate, - chan, NULL), - false, false, NULL); - node->bcast.timestamp = node->rgraph.timestamp; - node->rgraph.index = node->bcast.index; - } -} - bool routing_add_channel_update(struct routing_state *rstate, const u8 *update TAKES, u32 index, @@ -1583,10 +1563,6 @@ bool routing_add_channel_update(struct routing_state *rstate, else chan->half[!direction].rgraph.index = chan->half[!direction].bcast.index; - /* If we caught any node_announcements for fully zombie nodes - * (no remaining active channels) handle those as well. */ - resurrect_nannouncements(rstate, chan); - /* It's a miracle! */ chan->half[0].zombie = false; chan->half[1].zombie = false; @@ -1798,8 +1774,9 @@ bool routing_add_node_announcement(struct routing_state *rstate, node = get_node(rstate, &node_id); - if (node == NULL || (!node_has_broadcastable_channels(node) && - !is_node_zombie(node))) { + if (node == NULL + || !node_has_broadcastable_channels(node) + || is_node_zombie(node)) { struct pending_node_announce *pna; /* BOLT #7: * @@ -2054,18 +2031,18 @@ static void zombify_channel(struct gossip_store *gs, struct chan *channel) type_to_string(tmpctx, struct short_channel_id, &channel->scid)); - /* If one of the nodes has no remaining active channels, the - * node_announcement should also be stashed. */ + /* If one of the nodes has no remaining active channels, forget + * the node_announcement. */ for (int i = 0; i < 2; i++) { struct node *node = channel->nodes[i]; - if (!is_node_zombie(node) || !node->bcast.index) + if (node_has_broadcastable_channels(node)) continue; if (node->rgraph.index != node->bcast.index) - gossip_store_mark_nannounce_zombie(gs, &node->rgraph); - gossip_store_mark_nannounce_zombie(gs, &node->bcast); - status_debug("Node %s zombified", - type_to_string(tmpctx, struct node_id, - &node->id)); + gossip_store_delete(gs, &node->rgraph, + WIRE_NODE_ANNOUNCEMENT); + gossip_store_delete(gs, &node->bcast, + WIRE_NODE_ANNOUNCEMENT); + node->rgraph.index = node->bcast.index = 0; } } diff --git a/gossipd/test/run-check_channel_announcement.c b/gossipd/test/run-check_channel_announcement.c index 887569305..5b25af4b0 100644 --- a/gossipd/test/run-check_channel_announcement.c +++ b/gossipd/test/run-check_channel_announcement.c @@ -94,10 +94,6 @@ void gossip_store_mark_channel_zombie(struct gossip_store *gs UNNEEDED, void gossip_store_mark_cupdate_zombie(struct gossip_store *gs UNNEEDED, struct broadcastable *bcast UNNEEDED) { fprintf(stderr, "gossip_store_mark_cupdate_zombie called!\n"); abort(); } -/* Generated stub for gossip_store_mark_nannounce_zombie */ -void gossip_store_mark_nannounce_zombie(struct gossip_store *gs UNNEEDED, - struct broadcastable *bcast UNNEEDED) -{ fprintf(stderr, "gossip_store_mark_nannounce_zombie called!\n"); abort(); } /* Generated stub for gossip_store_new */ struct gossip_store *gossip_store_new(struct routing_state *rstate UNNEEDED, struct list_head *peers UNNEEDED) diff --git a/gossipd/test/run-txout_failure.c b/gossipd/test/run-txout_failure.c index 049e7e0ed..90e01bd4c 100644 --- a/gossipd/test/run-txout_failure.c +++ b/gossipd/test/run-txout_failure.c @@ -65,10 +65,6 @@ void gossip_store_mark_channel_zombie(struct gossip_store *gs UNNEEDED, void gossip_store_mark_cupdate_zombie(struct gossip_store *gs UNNEEDED, struct broadcastable *bcast UNNEEDED) { fprintf(stderr, "gossip_store_mark_cupdate_zombie called!\n"); abort(); } -/* Generated stub for gossip_store_mark_nannounce_zombie */ -void gossip_store_mark_nannounce_zombie(struct gossip_store *gs UNNEEDED, - struct broadcastable *bcast UNNEEDED) -{ fprintf(stderr, "gossip_store_mark_nannounce_zombie called!\n"); abort(); } /* Generated stub for memleak_add_helper_ */ void memleak_add_helper_(const tal_t *p UNNEEDED, void (*cb)(struct htable *memtable UNNEEDED, const tal_t *)){ }