mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-02-22 14:42:40 +01:00
plugins/pay: separate route destination and pay destination.
For bolt12, we have blinded paths so we route to the head of the blinded path, which may not be the same as the final payment destination. This matters mainly for detecting self-pay. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
parent
73e5d9a78a
commit
47c1ca8d85
4 changed files with 41 additions and 34 deletions
|
@ -74,13 +74,13 @@ static void keysend_cb(struct keysend_data *d, struct payment *p) {
|
|||
featurebit method.*/
|
||||
|
||||
if (p->result != NULL &&
|
||||
node_id_eq(p->destination, p->result->erring_node) &&
|
||||
node_id_eq(p->route_destination, p->result->erring_node) &&
|
||||
p->result->failcode == WIRE_INVALID_ONION_PAYLOAD) {
|
||||
return payment_abort(
|
||||
p,
|
||||
"Recipient %s reported an invalid payload, this "
|
||||
"usually means they don't support keysend.",
|
||||
fmt_node_id(tmpctx, p->destination));
|
||||
fmt_node_id(tmpctx, p->route_destination));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -244,7 +244,8 @@ static struct command_result *json_keysend(struct command *cmd, const char *buf,
|
|||
p->local_id = &my_id;
|
||||
p->json_buffer = tal_dup_talarr(p, const char, buf);
|
||||
p->json_toks = params;
|
||||
p->destination = tal_steal(p, destination);
|
||||
p->route_destination = tal_steal(p, destination);
|
||||
p->pay_destination = p->route_destination;
|
||||
p->payment_secret = NULL;
|
||||
p->payment_metadata = NULL;
|
||||
p->blindedpath = NULL;
|
||||
|
@ -264,7 +265,7 @@ static struct command_result *json_keysend(struct command *cmd, const char *buf,
|
|||
p->deadline = timeabs_add(time_now(), time_from_sec(*retryfor));
|
||||
p->getroute->riskfactorppm = 10000000;
|
||||
|
||||
if (node_id_eq(&my_id, p->destination)) {
|
||||
if (node_id_eq(&my_id, p->route_destination)) {
|
||||
return command_fail(
|
||||
cmd, JSONRPC2_INVALID_PARAMS,
|
||||
"We are the destination. Keysend cannot be used to send funds to yourself");
|
||||
|
@ -297,7 +298,7 @@ static struct command_result *json_keysend(struct command *cmd, const char *buf,
|
|||
preapprovekeysend_succeed,
|
||||
forward_error, p);
|
||||
}
|
||||
json_add_node_id(req->js, "destination", p->destination);
|
||||
json_add_node_id(req->js, "destination", p->route_destination);
|
||||
json_add_sha256(req->js, "payment_hash", p->payment_hash);
|
||||
json_add_amount_msat(req->js, "amount_msat", p->our_amount);
|
||||
return send_outreq(cmd->plugin, req);
|
||||
|
|
|
@ -96,7 +96,8 @@ struct payment *payment_new(tal_t *ctx, struct command *cmd,
|
|||
if (parent != NULL) {
|
||||
assert(cmd == NULL);
|
||||
tal_arr_expand(&parent->children, p);
|
||||
p->destination = parent->destination;
|
||||
p->route_destination = parent->route_destination;
|
||||
p->pay_destination = parent->pay_destination;
|
||||
p->final_amount = parent->final_amount;
|
||||
p->our_amount = parent->our_amount;
|
||||
p->label = parent->label;
|
||||
|
@ -344,7 +345,7 @@ void payment_start_at_blockheight(struct payment *p, u32 blockheight)
|
|||
|
||||
/* Pre-generate the getroute request, so modifiers can have their say,
|
||||
* before we actually call `getroute` */
|
||||
p->getroute->destination = p->destination;
|
||||
p->getroute->destination = p->route_destination;
|
||||
p->getroute->max_hops = ROUTING_MAX_HOPS;
|
||||
p->getroute->cltv = root->min_final_cltv_expiry;
|
||||
p->getroute->amount = p->our_amount;
|
||||
|
@ -1724,8 +1725,8 @@ static struct command_result *payment_createonion_success(struct command *cmd,
|
|||
root->invstring_used = true;
|
||||
}
|
||||
|
||||
if (p->destination)
|
||||
json_add_node_id(req->js, "destination", p->destination);
|
||||
if (p->pay_destination)
|
||||
json_add_node_id(req->js, "destination", p->pay_destination);
|
||||
|
||||
if (p->local_invreq_id)
|
||||
json_add_sha256(req->js, "localinvreqid", p->local_invreq_id);
|
||||
|
@ -2079,7 +2080,7 @@ void json_add_payment_success(struct json_stream *js,
|
|||
struct json_stream *n;
|
||||
struct payment *root = payment_root(p);
|
||||
|
||||
json_add_node_id(js, "destination", p->destination);
|
||||
json_add_node_id(js, "destination", p->pay_destination);
|
||||
json_add_sha256(js, "payment_hash", p->payment_hash);
|
||||
json_add_timeabs(js, "created_at", p->start_time);
|
||||
if (result)
|
||||
|
@ -2200,7 +2201,7 @@ static void payment_finished(struct payment *p)
|
|||
json_add_hex_talarr(ret, "raw_message",
|
||||
result.failure->raw_message);
|
||||
json_add_num(ret, "created_at", p->start_time.ts.tv_sec);
|
||||
json_add_node_id(ret, "destination", p->destination);
|
||||
json_add_node_id(ret, "destination", p->pay_destination);
|
||||
json_add_sha256(ret, "payment_hash", p->payment_hash);
|
||||
|
||||
if (result.leafstates & PAYMENT_STEP_SUCCESS) {
|
||||
|
@ -2796,7 +2797,7 @@ static const struct node_id *route_pubkey(const struct payment *p,
|
|||
size_t n)
|
||||
{
|
||||
if (n == tal_count(routehint))
|
||||
return p->destination;
|
||||
return p->route_destination;
|
||||
return &routehint[n].pubkey;
|
||||
}
|
||||
|
||||
|
@ -2840,7 +2841,7 @@ struct node_id *routehint_generate_exclusion_list(const tal_t *ctx,
|
|||
|
||||
/* Also exclude the destination, because it would be foolish to
|
||||
* pass through it and *then* go to the routehint entry point. */
|
||||
exc[tal_count(routehint)-1] = *payment->destination;
|
||||
exc[tal_count(routehint)-1] = *payment->route_destination;
|
||||
return exc;
|
||||
}
|
||||
|
||||
|
@ -2896,7 +2897,7 @@ static void routehint_check_reachable(struct payment *p)
|
|||
* without routehints. This will later be used to mix in
|
||||
* attempts without routehints. */
|
||||
src = gossmap_find_node(gossmap, p->local_id);
|
||||
dst = gossmap_find_node(gossmap, p->destination);
|
||||
dst = gossmap_find_node(gossmap, p->route_destination);
|
||||
if (dst == NULL)
|
||||
d->destination_reachable = false;
|
||||
else if (src != NULL) {
|
||||
|
@ -2940,7 +2941,7 @@ static void routehint_check_reachable(struct payment *p)
|
|||
p,
|
||||
"Destination %s is not reachable directly and "
|
||||
"all routehints were unusable.",
|
||||
fmt_node_id(tmpctx, p->destination));
|
||||
fmt_node_id(tmpctx, p->route_destination));
|
||||
put_gossmap(p);
|
||||
return;
|
||||
}
|
||||
|
@ -3344,7 +3345,7 @@ static void shadow_route_cb(struct shadow_route_data *d,
|
|||
if (p->step != PAYMENT_STEP_INITIALIZED)
|
||||
return payment_continue(p);
|
||||
|
||||
d->destination = *p->destination;
|
||||
d->destination = *p->route_destination;
|
||||
|
||||
/* Allow shadowroutes to consume up to 1/4th of our budget. */
|
||||
d->constraints.cltv_budget = p->constraints.cltv_budget / 4;
|
||||
|
@ -3394,7 +3395,7 @@ static void direct_pay_override(struct payment *p) {
|
|||
p->route[0].delay = p->getroute->cltv;
|
||||
p->route[0].scid = hint->scid.scid;
|
||||
p->route[0].direction = hint->scid.dir;
|
||||
p->route[0].node_id = *p->destination;
|
||||
p->route[0].node_id = *p->route_destination;
|
||||
paymod_log(p, LOG_DBG,
|
||||
"Found a direct channel (%s) with sufficient "
|
||||
"capacity, skipping route computation.",
|
||||
|
@ -3421,7 +3422,7 @@ static struct command_result *direct_pay_listpeerchannels(struct command *cmd,
|
|||
for (size_t i=0; i<tal_count(channels); i++) {
|
||||
struct listpeers_channel *chan = channels[i];
|
||||
|
||||
if (!node_id_eq(&chan->id, p->destination))
|
||||
if (!node_id_eq(&chan->id, p->route_destination))
|
||||
continue;
|
||||
|
||||
if (!chan->connected)
|
||||
|
@ -3747,7 +3748,7 @@ payee_incoming_limit_count(struct command *cmd,
|
|||
"Destination %s has %zd channels, "
|
||||
"assuming %d HTLCs per channel",
|
||||
fmt_node_id(tmpctx,
|
||||
p->destination),
|
||||
p->route_destination),
|
||||
num_channels,
|
||||
ASSUMED_MAX_HTLCS_PER_CHANNEL);
|
||||
lim = num_channels * ASSUMED_MAX_HTLCS_PER_CHANNEL;
|
||||
|
@ -3772,7 +3773,7 @@ static void payee_incoming_limit_step_cb(void *d UNUSED, struct payment *p)
|
|||
req = jsonrpc_request_start(p->plugin, NULL, "listchannels",
|
||||
&payee_incoming_limit_count,
|
||||
&payment_rpc_failure, p);
|
||||
json_add_node_id(req->js, "source", p->destination);
|
||||
json_add_node_id(req->js, "source", p->route_destination);
|
||||
(void) send_outreq(p->plugin, req);
|
||||
}
|
||||
|
||||
|
@ -3804,7 +3805,7 @@ static void route_exclusions_step_cb(struct route_exclusions_data *d,
|
|||
channel_hints_update(p, e->u.chan_id.scid, e->u.chan_id.dir,
|
||||
false, false, NULL, NULL);
|
||||
} else {
|
||||
if (node_id_eq(&e->u.node_id, p->destination)) {
|
||||
if (node_id_eq(&e->u.node_id, p->route_destination)) {
|
||||
payment_abort(p, "Payee is manually excluded");
|
||||
return;
|
||||
} else if (node_id_eq(&e->u.node_id, p->local_id)) {
|
||||
|
|
|
@ -180,8 +180,11 @@ struct payment {
|
|||
/* The current phase we are in. */
|
||||
enum payment_step step;
|
||||
|
||||
/* Real destination we want to route to */
|
||||
struct node_id *destination;
|
||||
/* Destination we want to route to */
|
||||
struct node_id *route_destination;
|
||||
|
||||
/* Destination we want to pay to (can be different for blinded paths!) */
|
||||
struct node_id *pay_destination;
|
||||
|
||||
/* Payment hash extracted from the invoice if any. */
|
||||
struct sha256 *payment_hash;
|
||||
|
|
|
@ -215,7 +215,7 @@ static struct command_result *json_paystatus(struct command *cmd,
|
|||
json_add_invstring(ret, p->invstring);
|
||||
json_add_amount_msat(ret, "amount_msat", p->our_amount);
|
||||
|
||||
json_add_node_id(ret, "destination", p->destination);
|
||||
json_add_node_id(ret, "destination", p->pay_destination);
|
||||
|
||||
/* TODO(cdecker) Add label in once we track labels. */
|
||||
/* TODO(cdecker) Add routehint_modifications in once we track
|
||||
|
@ -628,7 +628,7 @@ static void on_payment_success(struct payment *payment)
|
|||
p->cmd = NULL;
|
||||
|
||||
ret = jsonrpc_stream_success(cmd);
|
||||
json_add_node_id(ret, "destination", p->destination);
|
||||
json_add_node_id(ret, "destination", p->pay_destination);
|
||||
json_add_sha256(ret, "payment_hash", p->payment_hash);
|
||||
json_add_timeabs(ret, "created_at", p->start_time);
|
||||
json_add_num(ret, "parts", result.attempts);
|
||||
|
@ -754,7 +754,7 @@ static void on_payment_failure(struct payment *payment)
|
|||
json_add_hex_talarr(ret, "raw_message",
|
||||
result.failure->raw_message);
|
||||
json_add_num(ret, "created_at", p->start_time.ts.tv_sec);
|
||||
json_add_node_id(ret, "destination", p->destination);
|
||||
json_add_node_id(ret, "destination", p->pay_destination);
|
||||
json_add_sha256(ret, "payment_hash", p->payment_hash);
|
||||
// OK
|
||||
if (result.leafstates & PAYMENT_STEP_SUCCESS) {
|
||||
|
@ -952,7 +952,7 @@ payment_listsendpays_previous(struct command *cmd, const char *buf,
|
|||
json_add_string(ret, "status", "complete");
|
||||
json_add_amount_msat(ret, "amount_msat", msat);
|
||||
json_add_amount_msat(ret, "amount_sent_msat", sent);
|
||||
json_add_node_id(ret, "destination", p->destination);
|
||||
json_add_node_id(ret, "destination", p->pay_destination);
|
||||
json_add_sha256(ret, "payment_hash", p->payment_hash);
|
||||
json_add_u32(ret, "created_at", created_at);
|
||||
json_add_num(ret, "parts", parts);
|
||||
|
@ -971,7 +971,7 @@ payment_listsendpays_previous(struct command *cmd, const char *buf,
|
|||
p->on_payment_failure = on_payment_failure;
|
||||
|
||||
/* Bypass everything if we're doing (synchronous) self-pay */
|
||||
if (node_id_eq(&my_id, p->destination))
|
||||
if (node_id_eq(&my_id, p->pay_destination))
|
||||
return selfpay(cmd, p);
|
||||
|
||||
payment_start(p);
|
||||
|
@ -1109,7 +1109,8 @@ static struct command_result *json_pay(struct command *cmd,
|
|||
invmsat = b11->msat;
|
||||
invexpiry = b11->timestamp + b11->expiry;
|
||||
|
||||
p->destination = tal_dup(p, struct node_id, &b11->receiver_id);
|
||||
p->pay_destination = tal_dup(p, struct node_id, &b11->receiver_id);
|
||||
p->route_destination = p->pay_destination;
|
||||
p->payment_hash = tal_dup(p, struct sha256, &b11->payment_hash);
|
||||
p->payment_secret =
|
||||
tal_dup_or_null(p, struct secret, b11->payment_secret);
|
||||
|
@ -1159,8 +1160,8 @@ static struct command_result *json_pay(struct command *cmd,
|
|||
invmsat = tal(cmd, struct amount_msat);
|
||||
*invmsat = amount_msat(*b12->invoice_amount);
|
||||
|
||||
p->destination = tal(p, struct node_id);
|
||||
node_id_from_pubkey(p->destination, b12->invoice_node_id);
|
||||
p->pay_destination = tal(p, struct node_id);
|
||||
node_id_from_pubkey(p->pay_destination, b12->invoice_node_id);
|
||||
p->payment_hash = tal_dup(p, struct sha256,
|
||||
b12->invoice_payment_hash);
|
||||
if (b12->invreq_recurrence_counter && !label)
|
||||
|
@ -1198,8 +1199,9 @@ static struct command_result *json_pay(struct command *cmd,
|
|||
}
|
||||
p->min_final_cltv_expiry = p->blindedpay->cltv_expiry_delta;
|
||||
|
||||
/* Set destination to introduction point */
|
||||
node_id_from_pubkey(p->destination, &p->blindedpath->first_node_id.pubkey);
|
||||
/* Set route destination to introduction point */
|
||||
p->route_destination = tal(p, struct node_id);
|
||||
node_id_from_pubkey(p->route_destination, &p->blindedpath->first_node_id.pubkey);
|
||||
p->payment_metadata = NULL;
|
||||
p->routes = NULL;
|
||||
/* BOLT-offers #12:
|
||||
|
@ -1246,7 +1248,7 @@ static struct command_result *json_pay(struct command *cmd,
|
|||
"partial_msat must be less or equal to total amount %s",
|
||||
fmt_amount_msat(tmpctx, p->final_amount));
|
||||
}
|
||||
if (node_id_eq(&my_id, p->destination)) {
|
||||
if (node_id_eq(&my_id, p->pay_destination)) {
|
||||
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||
"partial_msat not supported (yet?) for self-pay");
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue