gossmap: implement gossmap_random_node(), use it in gossipd.

It's easy for gossmap, since it has access to the htable.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell 2024-11-22 14:03:38 +10:30
parent 363b721cd3
commit 69c252e06f
3 changed files with 20 additions and 26 deletions

View File

@ -1390,6 +1390,14 @@ struct gossmap_node *gossmap_next_node(const struct gossmap *map,
return node_iter(map, prev - map->node_arr + 1);
}
struct gossmap_node *gossmap_random_node(const struct gossmap *map)
{
ptrint_t *pi = nodeidx_htable_pick(map->nodes, pseudorand_u64(), NULL);
if (pi)
return ptrint2node(pi);
return NULL;
}
size_t gossmap_num_chans(const struct gossmap *map)
{
return chanidx_htable_count(map->channels);

View File

@ -279,6 +279,9 @@ struct gossmap_node *gossmap_first_node(const struct gossmap *map);
struct gossmap_node *gossmap_next_node(const struct gossmap *map,
const struct gossmap_node *prev);
/* Get me a random node */
struct gossmap_node *gossmap_random_node(const struct gossmap *map);
/* Unsorted iterate through (do not add/remove channels or nodes!) */
size_t gossmap_num_chans(const struct gossmap *map);

View File

@ -979,41 +979,24 @@ static struct node_and_addrs *get_random_node(const tal_t *ctx,
struct seeker *seeker)
{
struct gossmap *gossmap = gossmap_manage_get_gossmap(seeker->daemon->gm);
if (gossmap_num_nodes(gossmap) < 1)
return NULL;
u32 max_idx = gossmap_max_node_idx(gossmap);
if (max_idx < 1)
struct gossmap_node *node = gossmap_random_node(gossmap);
if (!node)
return NULL;
struct gossmap_node *random_node;
struct node_and_addrs *found_node = NULL;
for (int i = 0; i<20; i++) {
u32 random = pseudorand(max_idx);
random_node = gossmap_node_byidx(gossmap, random);
if (!random_node) {
continue;
}
found_node = tal(ctx, struct node_and_addrs);
struct node_and_addrs *found_node = tal(ctx, struct node_and_addrs);
found_node->id = tal(found_node, struct node_id);
gossmap_node_get_id(gossmap, random_node, found_node->id);
if (node_id_eq(found_node->id, &seeker->daemon->id)) {
found_node = tal_free(found_node);
continue;
}
gossmap_node_get_id(gossmap, node, found_node->id);
found_node->addrs =
gossmap_manage_get_node_addresses(found_node,
seeker->daemon->gm,
found_node->id);
if (!found_node->addrs || tal_count(found_node->addrs) == 0) {
found_node = tal_free(found_node);
continue;
}
break;
if (found_node->addrs && tal_count(found_node->addrs) != 0)
return found_node;
tal_free(found_node);
}
return found_node;
return NULL;
}
/* Ask lightningd for more peers if we're short on gossip streamers. */