renepay: uncertainty network update revisited

- Update the uncertainty network with the gossmap+local_gossmods,
- ignore channels that fail to give their capacity.
This commit is contained in:
Lagrang3 2024-04-10 20:02:34 +01:00 committed by Rusty Russell
parent 9f13621de9
commit 761c295199
5 changed files with 78 additions and 16 deletions

View file

@ -76,7 +76,13 @@ static const char *init(struct plugin *p,
"gossmap ignored %zu channel updates",
num_channel_updates_rejected);
pay_plugin->uncertainty = uncertainty_new(pay_plugin);
uncertainty_update(pay_plugin->uncertainty, pay_plugin->gossmap);
int skipped_count =
uncertainty_update(pay_plugin->uncertainty, pay_plugin->gossmap);
if (skipped_count)
plugin_log(pay_plugin->plugin, LOG_UNUSUAL,
"%s: uncertainty was updated but %d channels have "
"been ignored.",
__PRETTY_FUNCTION__, skipped_count);
plugin_set_memleak_handler(p, memleak_mark);
return NULL;

View file

@ -519,6 +519,8 @@ refreshgossmap_done(struct command *cmd UNUSED, const char *buf UNUSED,
const jsmntok_t *result UNUSED, struct payment *payment)
{
assert(pay_plugin->gossmap); // gossmap must be already initialized
assert(payment);
assert(payment->local_gossmods);
size_t num_channel_updates_rejected;
bool gossmap_changed =
@ -529,8 +531,20 @@ refreshgossmap_done(struct command *cmd UNUSED, const char *buf UNUSED,
"gossmap ignored %zu channel updates",
num_channel_updates_rejected);
if (gossmap_changed)
uncertainty_update(pay_plugin->uncertainty, pay_plugin->gossmap);
if (gossmap_changed) {
gossmap_apply_localmods(pay_plugin->gossmap,
payment->local_gossmods);
int skipped_count = uncertainty_update(pay_plugin->uncertainty,
pay_plugin->gossmap);
gossmap_remove_localmods(pay_plugin->gossmap,
payment->local_gossmods);
if (skipped_count)
plugin_log(
pay_plugin->plugin, LOG_UNUSUAL,
"%s: uncertainty was updated but %d channels have "
"been ignored.",
__PRETTY_FUNCTION__, skipped_count);
}
return payment_continue(payment);
}
@ -560,6 +574,9 @@ static void add_hintchan(struct payment *payment, const struct node_id *src,
const struct short_channel_id scid, u32 fee_base_msat,
u32 fee_proportional_millionths)
{
assert(payment);
assert(payment->local_gossmods);
// TODO test this, simply make a payment through a private channel, this
// statement is either right or wrong.
int dir = node_id_cmp(src, dst) < 0 ? 0 : 1;
@ -623,8 +640,11 @@ static struct command_result *routehints_done(struct command *cmd UNUSED,
struct payment *payment)
{
// FIXME are there route hints for B12?
assert(payment);
assert(payment->local_gossmods);
assert(payment->routehints);
const size_t nhints = tal_count(payment->routehints);
/* Hints are added to the local_gossmods. */
for (size_t i = 0; i < nhints; i++) {
/* Each one, presumably, leads to the destination */
const struct route_info *r = payment->routehints[i];
@ -638,6 +658,18 @@ static struct command_result *routehints_done(struct command *cmd UNUSED,
end = &r[j].pubkey;
}
}
/* Add hints to the uncertainty network. */
gossmap_apply_localmods(pay_plugin->gossmap, payment->local_gossmods);
int skipped_count =
uncertainty_update(pay_plugin->uncertainty, pay_plugin->gossmap);
gossmap_remove_localmods(pay_plugin->gossmap, payment->local_gossmods);
if (skipped_count)
plugin_log(pay_plugin->plugin, LOG_UNUSUAL,
"%s: uncertainty was updated but %d channels have "
"been ignored.",
__PRETTY_FUNCTION__, skipped_count);
return payment_continue(payment);
}

View file

@ -361,7 +361,8 @@ int main(int argc, char *argv[])
assert(short_channel_id_from_str("103x1x0", 7, &scid23));
struct uncertainty *uncertainty = uncertainty_new(tmpctx);
uncertainty_update(uncertainty, gossmap);
int skipped_count = uncertainty_update(uncertainty, gossmap);
assert(skipped_count == 0);
printf("All set, now let's call minflow ...\n");

View file

@ -78,33 +78,56 @@ void uncertainty_channel_cannot_send(struct uncertainty *uncertainty,
chan_extra_cannot_send(uncertainty->chan_extra_map, &scidd);
}
void uncertainty_update(struct uncertainty *uncertainty,
struct gossmap *gossmap)
int uncertainty_update(struct uncertainty *uncertainty, struct gossmap *gossmap)
{
// FIXME: after running for some time we might find some channels in
// chan_extra_map that are not needed and do not exist in the gossmap
// for being private or closed.
/* Each channel in chan_extra_map should be either in gossmap or in
* local_gossmods. */
assert(uncertainty);
struct chan_extra_map *chan_extra_map = uncertainty->chan_extra_map;
assert(chan_extra_map);
struct chan_extra **del_list = tal_arr(NULL, struct chan_extra*, 0);
struct chan_extra_map_iter it;
for (struct chan_extra *ch = chan_extra_map_first(chan_extra_map, &it);
ch; ch = chan_extra_map_next(chan_extra_map, &it)) {
/* If we cannot find that channel in the gossmap, add it to the
* delete list. */
if (!gossmap_find_chan(gossmap, &ch->scid))
tal_arr_expand(&del_list, ch);
}
for(size_t i=0;i<tal_count(del_list);i++) {
chan_extra_map_del(chan_extra_map, del_list[i]);
}
del_list = tal_free(del_list);
/* For each channel in the gossmap, create a extra data in
* chan_extra_map */
int skipped_count = 0;
for (struct gossmap_chan *chan = gossmap_first_chan(gossmap); chan;
chan = gossmap_next_chan(gossmap, chan)) {
struct short_channel_id scid = gossmap_chan_scid(gossmap, chan);
struct chan_extra *ce =
chan_extra_map_get(uncertainty->chan_extra_map,
chan_extra_map_get(chan_extra_map,
gossmap_chan_scid(gossmap, chan));
if (!ce) {
struct amount_sat cap;
struct amount_msat cap_msat;
// FIXME: check errors
if (!gossmap_chan_get_capacity(gossmap, chan, &cap) ||
!amount_sat_to_msat(&cap_msat, cap) ||
!new_chan_extra(uncertainty->chan_extra_map, scid,
cap_msat))
return;
!new_chan_extra(chan_extra_map, scid,
cap_msat)) {
/* If the new chan_extra cannot be created we
* skip this channel. */
skipped_count++;
continue;
}
}
}
assert(chan_extra_map_count(chan_extra_map) + skipped_count ==
gossmap_num_chans(gossmap));
return skipped_count;
}
struct uncertainty *uncertainty_new(const tal_t *ctx)

View file

@ -35,8 +35,8 @@ void uncertainty_channel_cannot_send(struct uncertainty *uncertainty,
struct short_channel_id scid,
int direction);
void uncertainty_update(struct uncertainty *uncertainty,
struct gossmap *gossmap);
WARN_UNUSED_RESULT int uncertainty_update(struct uncertainty *uncertainty,
struct gossmap *gossmap);
struct uncertainty *uncertainty_new(const tal_t *ctx);