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 <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell 2023-02-15 15:03:57 +10:30 committed by Alex Myers
parent 4fc3c26671
commit 2e7c08824a
5 changed files with 16 additions and 57 deletions

View file

@ -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)

View file

@ -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.
*

View file

@ -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;
}
}

View file

@ -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)

View file

@ -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 *)){ }