Skip to content

Commit e5b68ca

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 <[email protected]>
1 parent 1102d80 commit e5b68ca

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
@@ -148,6 +148,8 @@ struct hop {
148148
u32 cltv_value_in;
149149
/* This is the delay, out from node. */
150150
u32 cltv_value_out;
151+
/* This is a fake channel. */
152+
bool fake_channel;
151153
};
152154

153155
/* Each actual payment attempt */
@@ -481,18 +483,6 @@ static void payment_give_up(struct command *aux_cmd,
481483
cleanup(aux_cmd, payment);
482484
}
483485

484-
/* We usually add things we learned to the global layer, but not
485-
* if it's a fake channel */
486-
static const char *layer_of(const struct payment *payment,
487-
const struct short_channel_id_dir *scidd)
488-
{
489-
struct gossmap *gossmap = get_gossmap(xpay_of(payment->plugin));
490-
491-
if (gossmap_find_chan(gossmap, &scidd->scid))
492-
return "xpay";
493-
return payment->private_layer;
494-
}
495-
496486
static void add_result_summary(struct attempt *attempt,
497487
enum log_level level,
498488
const char *fmt, ...)
@@ -713,8 +703,11 @@ static void update_knowledge_from_error(struct command *aux_cmd,
713703
/* We learned something about prior nodes */
714704
for (size_t i = 0; i < index; i++) {
715705
req = payment_ignored_req(aux_cmd, attempt, "askrene-inform-channel");
706+
/* Put what we learned in xpay, unless it's a fake channel */
716707
json_add_string(req->js, "layer",
717-
layer_of(attempt->payment, &attempt->hops[i].scidd));
708+
attempt->hops[i].fake_channel
709+
? attempt->payment->private_layer
710+
: "xpay");
718711
json_add_short_channel_id_dir(req->js,
719712
"short_channel_id_dir",
720713
attempt->hops[i].scidd);
@@ -881,8 +874,11 @@ static void update_knowledge_from_error(struct command *aux_cmd,
881874

882875
channel_capacity:
883876
req = payment_ignored_req(aux_cmd, attempt, "askrene-inform-channel");
877+
/* Put what we learned in xpay, unless it's a fake channel */
884878
json_add_string(req->js, "layer",
885-
layer_of(attempt->payment, &attempt->hops[index].scidd));
879+
attempt->hops[index].fake_channel
880+
? attempt->payment->private_layer
881+
: "xpay");
886882
json_add_short_channel_id_dir(req->js,
887883
"short_channel_id_dir",
888884
attempt->hops[index].scidd);
@@ -918,6 +914,8 @@ static struct command_result *unreserve_path(struct command *aux_cmd,
918914
json_object_start(req->js, NULL);
919915
json_add_short_channel_id_dir(req->js, "short_channel_id_dir", hop->scidd);
920916
json_add_amount_msat(req->js, "amount_msat", hop->amount_out);
917+
if (hop->fake_channel)
918+
json_add_string(req->js, "layer", attempt->payment->private_layer);
921919
json_object_end(req->js);
922920
}
923921
json_array_end(req->js);
@@ -1203,6 +1201,7 @@ static struct command_result *getroutes_done(struct command *aux_cmd,
12031201
const jsmntok_t *t, *routes;
12041202
size_t i;
12051203
struct amount_msat needs_routing, was_routing;
1204+
struct gossmap *gossmap = get_gossmap(xpay_of(payment->plugin));
12061205

12071206
payment_log(payment, LOG_DBG, "getroutes_done: %s",
12081207
payment->cmd ? "continuing" : "ignoring");
@@ -1270,6 +1269,7 @@ static struct command_result *getroutes_done(struct command *aux_cmd,
12701269
if (err)
12711270
plugin_err(aux_cmd->plugin, "Malformed routes: %s",
12721271
err);
1272+
hop->fake_channel = !gossmap_find_chan(gossmap, &hop->scidd.scid);
12731273
if (j > 0) {
12741274
hops[j-1].amount_out = hop->amount_in;
12751275
hops[j-1].cltv_value_out = hop->cltv_value_in;
@@ -1294,6 +1294,8 @@ static struct command_result *getroutes_done(struct command *aux_cmd,
12941294
json_add_short_channel_id_dir(req->js, "short_channel_id_dir",
12951295
hop->scidd);
12961296
json_add_amount_msat(req->js, "amount_msat", hop->amount_out);
1297+
if (hop->fake_channel)
1298+
json_add_string(req->js, "layer", payment->private_layer);
12971299
json_object_end(req->js);
12981300
}
12991301
json_array_end(req->js);

0 commit comments

Comments
 (0)