Skip to content

Commit fbae522

Browse files
committed
xpay: don't place global reservations on generated channels.
We generate fake scids for routehints and blinded paths. But then we were placing reservations on them as if they were global. If there are two xpays going at once these reservations will clash, even though the same scid refers to different channels. Reported-by: @Lagrang3 Changelog-Fixed: xpay: fixed theoretical clash with simultanous payments via routehints and blinded paths. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
1 parent 62ee437 commit fbae522

File tree

1 file changed

+16
-14
lines changed

1 file changed

+16
-14
lines changed

plugins/xpay/xpay.c

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,8 @@ struct hop {
139139
u32 cltv_value_in;
140140
/* This is the delay, out from node. */
141141
u32 cltv_value_out;
142+
/* This is a fake channel. */
143+
bool fake_channel;
142144
};
143145

144146
/* Each actual payment attempt */
@@ -450,18 +452,6 @@ static void payment_give_up(struct command *aux_cmd,
450452
cleanup(aux_cmd, payment);
451453
}
452454

453-
/* We usually add things we learned to the global layer, but not
454-
* if it's a fake channel */
455-
static const char *layer_of(const struct payment *payment,
456-
const struct short_channel_id_dir *scidd)
457-
{
458-
struct gossmap *gossmap = get_gossmap(xpay_of(payment->plugin));
459-
460-
if (gossmap_find_chan(gossmap, &scidd->scid))
461-
return "xpay";
462-
return payment->private_layer;
463-
}
464-
465455
static void add_result_summary(struct attempt *attempt,
466456
enum log_level level,
467457
const char *fmt, ...)
@@ -601,8 +591,11 @@ static void update_knowledge_from_error(struct command *aux_cmd,
601591
/* We learned something about prior nodes */
602592
for (size_t i = 0; i < index; i++) {
603593
req = payment_ignored_req(aux_cmd, attempt, "askrene-inform-channel");
594+
/* Put what we learned in xpay, unless it's a fake channel */
604595
json_add_string(req->js, "layer",
605-
layer_of(attempt->payment, &attempt->hops[i].scidd));
596+
attempt->hops[i].fake_channel
597+
? attempt->payment->private_layer
598+
: "xpay");
606599
json_add_short_channel_id_dir(req->js,
607600
"short_channel_id_dir",
608601
attempt->hops[i].scidd);
@@ -758,8 +751,11 @@ static void update_knowledge_from_error(struct command *aux_cmd,
758751

759752
channel_capacity:
760753
req = payment_ignored_req(aux_cmd, attempt, "askrene-inform-channel");
754+
/* Put what we learned in xpay, unless it's a fake channel */
761755
json_add_string(req->js, "layer",
762-
layer_of(attempt->payment, &attempt->hops[index].scidd));
756+
attempt->hops[index].fake_channel
757+
? attempt->payment->private_layer
758+
: "xpay");
763759
json_add_short_channel_id_dir(req->js,
764760
"short_channel_id_dir",
765761
attempt->hops[index].scidd);
@@ -795,6 +791,8 @@ static struct command_result *unreserve_path(struct command *aux_cmd,
795791
json_object_start(req->js, NULL);
796792
json_add_short_channel_id_dir(req->js, "short_channel_id_dir", hop->scidd);
797793
json_add_amount_msat(req->js, "amount_msat", hop->amount_out);
794+
if (hop->fake_channel)
795+
json_add_string(req->js, "layer", attempt->payment->private_layer);
798796
json_object_end(req->js);
799797
}
800798
json_array_end(req->js);
@@ -1075,6 +1073,7 @@ static struct command_result *getroutes_done(struct command *aux_cmd,
10751073
const jsmntok_t *t, *routes;
10761074
size_t i;
10771075
struct amount_msat needs_routing, was_routing;
1076+
struct gossmap *gossmap = get_gossmap(xpay_of(payment->plugin));
10781077

10791078
payment_log(payment, LOG_DBG, "getroutes_done: %s",
10801079
payment->cmd ? "continuing" : "ignoring");
@@ -1142,6 +1141,7 @@ static struct command_result *getroutes_done(struct command *aux_cmd,
11421141
if (err)
11431142
plugin_err(aux_cmd->plugin, "Malformed routes: %s",
11441143
err);
1144+
hop->fake_channel = !gossmap_find_chan(gossmap, &hop->scidd.scid);
11451145
if (j > 0) {
11461146
hops[j-1].amount_out = hop->amount_in;
11471147
hops[j-1].cltv_value_out = hop->cltv_value_in;
@@ -1166,6 +1166,8 @@ static struct command_result *getroutes_done(struct command *aux_cmd,
11661166
json_add_short_channel_id_dir(req->js, "short_channel_id_dir",
11671167
hop->scidd);
11681168
json_add_amount_msat(req->js, "amount_msat", hop->amount_out);
1169+
if (hop->fake_channel)
1170+
json_add_string(req->js, "layer", payment->private_layer);
11691171
json_object_end(req->js);
11701172
}
11711173
json_array_end(req->js);

0 commit comments

Comments
 (0)