renepay: add disabledmap abstraction

Define a new object called disabledmap that carries information about
the disabled channels and nodes.
This commit is contained in:
Lagrang3 2024-05-04 10:36:45 +01:00 committed by Rusty Russell
parent 96bd0e455b
commit ca2b4e54ae
5 changed files with 146 additions and 40 deletions

View file

@ -3,6 +3,7 @@ PLUGIN_RENEPAY_SRC := \
plugins/renepay/flow.c \
plugins/renepay/mcf.c \
plugins/renepay/dijkstra.c \
plugins/renepay/disabledmap.c \
plugins/renepay/payment.c \
plugins/renepay/chan_extra.c \
plugins/renepay/route.c \
@ -19,6 +20,7 @@ PLUGIN_RENEPAY_HDRS := \
plugins/renepay/flow.h \
plugins/renepay/mcf.h \
plugins/renepay/dijkstra.h \
plugins/renepay/disabledmap.h \
plugins/renepay/payment.h \
plugins/renepay/chan_extra.h \
plugins/renepay/route.h \

View file

@ -0,0 +1,86 @@
#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_scids = tal_arr(obj, struct short_channel_id, 0);
obj->warned_scids = tal_arr(obj, struct short_channel_id, 0);
obj->disabled_nodes = tal_arr(obj, struct node_id, 0);
if (!obj->disabled_scids || !obj->warned_scids || !obj->disabled_nodes)
return tal_free(obj);
return obj;
}
// FIXME: check success
void disabledmap_reset(struct disabledmap *p)
{
tal_resize(&p->disabled_scids, 0);
tal_resize(&p->warned_scids, 0);
tal_resize(&p->disabled_nodes, 0);
}
// FIXME: check success
void disabledmap_add_channel(struct disabledmap *p,
struct short_channel_id scid)
{
tal_arr_expand(&p->disabled_scids, scid);
}
// FIXME: check success
void disabledmap_warn_channel(struct disabledmap *p,
struct short_channel_id scid)
{
tal_arr_expand(&p->warned_scids, scid);
}
// 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 scid)
{
for (size_t i = 0; i < tal_count(p->warned_scids); i++) {
if (short_channel_id_eq(scid, p->warned_scids[i]))
return true;
}
return false;
}
bitmap *tal_disabledmap_get_bitmap(const tal_t *ctx, struct disabledmap *p,
const struct gossmap *gossmap)
{
bitmap *disabled =
tal_arrz(ctx, bitmap, BITMAP_NWORDS(gossmap_max_chan_idx(gossmap)));
if (!disabled)
return NULL;
/* Disable every channel in the list of disabled scids. */
for (size_t i = 0; i < tal_count(p->disabled_scids); i++) {
struct gossmap_chan *c =
gossmap_find_chan(gossmap, &p->disabled_scids[i]);
if (c)
bitmap_set_bit(disabled, gossmap_chan_idx(gossmap, c));
}
/* 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));
}
}
return disabled;
}

View file

@ -0,0 +1,37 @@
#ifndef LIGHTNING_PLUGINS_RENEPAY_DISABLEDMAP_H
#define LIGHTNING_PLUGINS_RENEPAY_DISABLEDMAP_H
#include "config.h"
#include <bitcoin/short_channel_id.h>
#include <ccan/bitmap/bitmap.h>
#include <common/gossmap.h>
#include <common/node_id.h>
struct disabledmap {
/* Channels we decided to disable for various reasons. */
/* FIXME: disabled_scids should be a set rather than an array, so that
* we don't have to worry about disabling the same channel multiple
* times. */
struct short_channel_id *disabled_scids;
/* Channels that we flagged for failures. If warned two times we will
* disable it. */
struct short_channel_id *warned_scids;
/* nodes we disable */
struct node_id *disabled_nodes;
};
void disabledmap_reset(struct disabledmap *p);
struct disabledmap *disabledmap_new(const tal_t *ctx);
void disabledmap_add_channel(struct disabledmap *p,
struct short_channel_id scid);
void disabledmap_warn_channel(struct disabledmap *p,
struct short_channel_id scid);
void disabledmap_add_node(struct disabledmap *p, struct node_id node);
bool disabledmap_channel_is_warned(struct disabledmap *p,
struct short_channel_id scid);
bitmap *tal_disabledmap_get_bitmap(const tal_t *ctx, struct disabledmap *p,
const struct gossmap *gossmap);
#endif /* LIGHTNING_PLUGINS_RENEPAY_DISABLEDMAP_H */

View file

@ -98,9 +98,7 @@ struct payment *payment_new(
p->next_partid = 1;
p->cmd_array = tal_arr(p, struct command *, 0);
p->local_gossmods = NULL;
p->disabled_scids = tal_arr(p, struct short_channel_id, 0);
p->warned_scids = tal_arr(p, struct short_channel_id, 0);
p->disabled_nodes = tal_arr(p, struct node_id, 0);
p->disabledmap = disabledmap_new(p);
p->have_results = false;
p->retry = false;
@ -117,9 +115,12 @@ static void payment_cleanup(struct payment *p)
p->exec_state = INVALID_STATE;
tal_resize(&p->cmd_array, 0);
p->local_gossmods = tal_free(p->local_gossmods);
tal_resize(&p->disabled_scids, 0);
tal_resize(&p->warned_scids, 0);
tal_resize(&p->disabled_nodes, 0);
/* FIXME: for optimization, a cleanup should prune all the data that has
* no use after a payent is completed. The entire disablemap structure
* is no longer needed, hence I guess we should free it not just reset
* it. */
disabledmap_reset(p->disabledmap);
p->waitresult_timer = tal_free(p->waitresult_timer);
p->routes_computed = tal_free(p->routes_computed);
@ -188,14 +189,8 @@ bool payment_update(
p->local_gossmods = tal_free(p->local_gossmods);
assert(p->disabled_scids);
tal_resize(&p->disabled_scids, 0);
assert(p->warned_scids);
tal_resize(&p->warned_scids, 0);
assert(p->disabled_nodes);
tal_resize(&p->disabled_nodes, 0);
assert(p->disabledmap);
disabledmap_reset(p->disabledmap);
p->have_results = false;
p->retry = false;
@ -357,13 +352,11 @@ static struct command_result *payment_finish(struct payment *p)
return my_command_finish(p, cmd);
}
/* FIXME: disabled_scids should be a set rather than an array, so that we don't
* have to worry about disabling the same channel multiple times. */
void payment_disable_chan(struct payment *p, struct short_channel_id scid,
enum log_level lvl, const char *fmt, ...)
{
assert(p);
assert(p->disabled_scids);
assert(p->disabledmap);
va_list ap;
const char *str;
@ -373,15 +366,14 @@ void payment_disable_chan(struct payment *p, struct short_channel_id scid,
payment_note(p, lvl, "disabling %s: %s",
fmt_short_channel_id(tmpctx, scid),
str);
tal_arr_expand(&p->disabled_scids, scid);
disabledmap_add_channel(p->disabledmap, scid);
}
/* FIXME use a map instead of a array here. */
void payment_warn_chan(struct payment *p, struct short_channel_id scid,
enum log_level lvl, const char *fmt, ...)
{
assert(p);
assert(p->warned_scids);
assert(p->disabledmap);
va_list ap;
const char *str;
@ -389,26 +381,23 @@ void payment_warn_chan(struct payment *p, struct short_channel_id scid,
str = tal_vfmt(tmpctx, fmt, ap);
va_end(ap);
for (size_t i = 0; i < tal_count(p->warned_scids); i++) {
if (short_channel_id_eq(scid, p->warned_scids[i])) {
payment_disable_chan(p, scid, lvl,
"%s, channel warned twice", str);
return;
}
if (disabledmap_channel_is_warned(p->disabledmap, scid)) {
payment_disable_chan(p, scid, lvl, "%s, channel warned twice",
str);
return;
}
payment_note(
p, lvl, "flagged for warning %s: %s, next time it will be disabled",
fmt_short_channel_id(tmpctx, scid), str);
tal_arr_expand(&p->warned_scids, scid);
disabledmap_warn_channel(p->disabledmap, scid);
}
/* FIXME use a map instead of a array here. */
void payment_disable_node(struct payment *p, struct node_id node,
enum log_level lvl, const char *fmt, ...)
{
assert(p);
assert(p->disabled_nodes);
assert(p->disabledmap);
va_list ap;
const char *str;
@ -418,5 +407,5 @@ void payment_disable_node(struct payment *p, struct node_id node,
payment_note(p, lvl, "disabling node %s: %s",
fmt_node_id(tmpctx, &node),
str);
tal_arr_expand(&p->disabled_nodes, node);
disabledmap_add_node(p->disabledmap, node);
}

View file

@ -3,6 +3,7 @@
#include "config.h"
#include <common/gossmap.h>
#include <plugins/libplugin.h>
#include <plugins/renepay/disabledmap.h>
enum payment_status { PAYMENT_PENDING, PAYMENT_SUCCESS, PAYMENT_FAIL };
@ -127,16 +128,7 @@ struct payment {
/* Localmods to apply to gossip_map for our own use. */
struct gossmap_localmods *local_gossmods;
/* Channels we decided to disable for various reasons. */
struct short_channel_id *disabled_scids;
/* Channels that we flagged for failures. If warned two times we will
* disable it. */
struct short_channel_id *warned_scids;
/* nodes we disable */
struct node_id *disabled_nodes;
struct disabledmap *disabledmap;
/* Flag to indicate wether we have collected enough results to make a
* decision on the payment progress. */