Skip to content

Commit

Permalink
gossipd: add code to check dying flags are consistent.
Browse files Browse the repository at this point in the history
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
  • Loading branch information
rustyrussell committed Feb 9, 2024
1 parent 793290a commit 1ec6143
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 0 deletions.
3 changes: 3 additions & 0 deletions gossipd/gossipd.c
Original file line number Diff line number Diff line change
Expand Up @@ -491,6 +491,9 @@ static void dev_gossip_memleak(struct daemon *daemon, const u8 *msg)
struct htable *memtable;
bool found_leak;

/* Check this while we're here! */
gossmap_check_dying(daemon->gm);

memtable = memleak_start(tmpctx);
memleak_ptr(memtable, msg);
/* Now delete daemon and those which it has pointers to. */
Expand Down
60 changes: 60 additions & 0 deletions gossipd/gossmap_manage.c
Original file line number Diff line number Diff line change
Expand Up @@ -1400,3 +1400,63 @@ struct wireaddr *gossmap_manage_get_node_addresses(const tal_t *ctx,

return wireaddrs;
}

void gossmap_check_dying(struct gossmap_manage *gm)
{
struct gossmap *gossmap;

/* We reload this every time we delete a channel: that way we can tell if it's
* time to remove a node! */
gossmap = gossmap_manage_get_gossmap(gm);

/* channel_updates should match channel. */
for (struct gossmap_chan *c = gossmap_first_chan(gossmap);
c;
c = gossmap_next_chan(gossmap, c)) {
bool dying = gossmap_chan_is_dying(gossmap, c);

for (int dir = 0; dir < 2; dir++) {
bool update_dying;
if (!gossmap_chan_set(c, dir))
continue;
update_dying = (gossip_store_get_flags(gm->daemon->gs, c->cupdate_off[dir],
WIRE_CHANNEL_UPDATE) & GOSSIP_STORE_DYING_BIT);
if (update_dying != dying) {
status_broken("Bad gossip order: "
"channel_update[%i] at %u says %s, channel is %s",
dir, c->cupdate_off[dir],
update_dying ? "dying" : "not dying",
dying ? "dying" : "not dying");
}
}
}

/* Nodes should match iff no live channels. */
for (struct gossmap_node *n = gossmap_first_node(gossmap);
n;
n = gossmap_next_node(gossmap, n)) {
bool dying, all_chans_dying = true;

if (!gossmap_node_announced(n))
continue;

dying = (gossip_store_get_flags(gm->daemon->gs, n->nann_off,
WIRE_NODE_ANNOUNCEMENT) & GOSSIP_STORE_DYING_BIT);

for (size_t i = 0; i < n->num_chans; i++) {
struct gossmap_chan *c = gossmap_nth_chan(gossmap, n, i, NULL);
bool chan_dying = gossmap_chan_is_dying(gossmap, c);

if (!chan_dying)
all_chans_dying = false;
}

if (all_chans_dying != dying) {
status_broken("Bad gossip order: "
"node_announce at %u says %s, all channels %s",
n->nann_off,
dying ? "dying" : "not dying",
all_chans_dying ? "dying" : "not dying");
}
}
}
6 changes: 6 additions & 0 deletions gossipd/gossmap_manage.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,4 +123,10 @@ struct wireaddr *gossmap_manage_get_node_addresses(const tal_t *ctx,
*/
void gossmap_manage_tell_lightningd_locals(struct daemon *daemon,
struct gossmap_manage *gm);

/**
* gossmap_check_dying: check that we have consistent dying flags.
* @gm: the gossmap_manage context.
*/
void gossmap_check_dying(struct gossmap_manage *gm);
#endif /* LIGHTNING_GOSSIPD_GOSSMAP_MANAGE_H */

0 comments on commit 1ec6143

Please sign in to comment.