core-lightning/plugins/renepay/disabledmap.c
Lagrang3 c0dd3cd826 renepay: disabled channels in a map
Expecting to have more than just a bunch of disabled channels if we
prune the lightning network heavily I am changing the internal data
structure of disabledmap from a simple array to a hashtable.

Have a finer control over disabled channels by targeting
short_channel_id_dir instead of short_channel_id,
ie. we can disable a single direction of a channel.

Signed-off-by: Lagrang3 <lagrang3@protonmail.com>
2024-08-12 22:44:58 -07:00

125 lines
3.4 KiB
C

#include "config.h"
#include <plugins/renepay/disabledmap.h>
struct disabledmap *disabledmap_new(const tal_t *ctx)
{
struct disabledmap *obj = tal(ctx, struct disabledmap);
if (!obj)
return NULL;
obj->disabled_map = tal(obj, struct scidd_map);
obj->warned_map = tal(obj, struct scidd_map);
obj->disabled_ctx = tal(obj, tal_t);
obj->warned_ctx = tal(obj, tal_t);
obj->disabled_nodes = tal_arr(obj, struct node_id, 0);
if (!obj->disabled_map || !obj->warned_map || !obj->disabled_nodes ||
!obj->disabled_ctx || !obj->warned_ctx)
return tal_free(obj);
scidd_map_init(obj->disabled_map);
scidd_map_init(obj->warned_map);
return obj;
}
// FIXME: check success
void disabledmap_reset(struct disabledmap *p)
{
/* This will remove and free every element in the maps. */
p->warned_ctx = tal_free(p->warned_ctx);
p->disabled_ctx = tal_free(p->disabled_ctx);
tal_resize(&p->disabled_nodes, 0);
p->disabled_ctx = tal(p, tal_t);
p->warned_ctx = tal(p, tal_t);
}
static void remove_scidd(struct short_channel_id_dir *scidd,
struct scidd_map *map)
{
scidd_map_del(map, scidd);
}
// FIXME: check success
void disabledmap_add_channel(struct disabledmap *p,
struct short_channel_id_dir scidd)
{
struct short_channel_id_dir *ptr_scidd =
scidd_map_get(p->disabled_map, scidd);
if (ptr_scidd) {
/* htable allows for duplicates, but we don't want duplicates.
*/
return;
}
ptr_scidd =
tal_dup(p->disabled_ctx, struct short_channel_id_dir, &scidd);
scidd_map_add(p->disabled_map, ptr_scidd);
tal_add_destructor2(ptr_scidd, remove_scidd, p->disabled_map);
}
// FIXME: check success
void disabledmap_warn_channel(struct disabledmap *p,
struct short_channel_id_dir scidd)
{
struct short_channel_id_dir *ptr_scidd =
scidd_map_get(p->warned_map, scidd);
if (ptr_scidd) {
/* htable allows for duplicates, but we don't want duplicates.
*/
return;
}
ptr_scidd = tal_dup(p->warned_ctx, struct short_channel_id_dir, &scidd);
scidd_map_add(p->warned_map, ptr_scidd);
tal_add_destructor2(ptr_scidd, remove_scidd, p->warned_map);
}
// FIXME: check success
void disabledmap_add_node(struct disabledmap *p, struct node_id node)
{
tal_arr_expand(&p->disabled_nodes, node);
}
bool disabledmap_channel_is_warned(struct disabledmap *p,
struct short_channel_id_dir scidd)
{
return scidd_map_get(p->warned_map, scidd) != NULL;
}
bitmap *tal_disabledmap_get_bitmap(const tal_t *ctx, struct disabledmap *p,
const struct gossmap *gossmap)
{
bitmap *disabled = tal_arrz(
ctx, bitmap, 2 * BITMAP_NWORDS(gossmap_max_chan_idx(gossmap)));
if (!disabled)
return NULL;
/* Disable every channel in the list of disabled scids. */
struct scidd_map_iter it;
for(struct short_channel_id_dir *scidd = scidd_map_first(p->disabled_map,&it);
scidd;
scidd = scidd_map_next(p->disabled_map, &it)){
struct gossmap_chan *c =
gossmap_find_chan(gossmap, &scidd->scid);
if (c)
bitmap_set_bit(disabled,
gossmap_chan_idx(gossmap, c) * 2 +
scidd->dir);
}
/* Disable all channels that lead to a disabled node. */
for (size_t i = 0; i < tal_count(p->disabled_nodes); i++) {
const struct gossmap_node *node =
gossmap_find_node(gossmap, &p->disabled_nodes[i]);
for (size_t j = 0; j < node->num_chans; j++) {
int half;
const struct gossmap_chan *c =
gossmap_nth_chan(gossmap, node, j, &half);
bitmap_set_bit(disabled,
gossmap_chan_idx(gossmap, c) * 2 + half);
}
}
return disabled;
}