mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-02-24 07:07:46 +01:00
xpay: give an additional block "slack" for CLTV values.
pay does this, xpay does not. Which means if a block comes in (or you're behind), you get gratuitous failures: ``` def test_xpay_simple(node_factory): l1, l2, l3, l4 = node_factory.get_nodes(4, opts={'may_reconnect': True}) node_factory.join_nodes([l1, l2, l3], wait_for_announce=True) node_factory.join_nodes([l3, l4], announce_channels=False) # BOLT 11, direct peer b11 = l2.rpc.invoice('10000msat', 'test_xpay_simple', 'test_xpay_simple bolt11')['bolt11'] > ret = l1.rpc.xpay(b11) tests/test_xpay.py:148: ... if not isinstance(resp, dict): raise TypeError("Malformed response, response is not a dictionary %s." % resp) elif "error" in resp: > raise RpcError(method, payload, resp['error']) E pyln.client.lightning.RpcError: RPC call failed: method: xpay, payload: ('lnbcrt100n1pn5qu7csp53rp0mfwtfsyyy8gzsggepnxgslyalwvz3jkg9ptmqq452ln2nmgqpp58ak9nmfz9l93r0fpm266ewyjrhurhatrs05nda0r03p82cykp0vsdp9w3jhxazl0pcxz72lwd5k6urvv5sxymmvwscnzxqyjw5qcqp99qxpqysgqa798258yppu2tlfj8herr3zuz0zgux79zvtx6z57cmfzs2wdesmr4nvnkcmyssyu6k64ud54eg0v45c3mcw342jj6uy7tu202p6klrcp6ljc9w',), error: {'code': 203, 'message': "Destination said it doesn't know invoice: incorrect_or_unknown_payment_details"} ``` Signed-off-by: Rusty Russell <rusty@rustcorp.com.au> Changelog-None: xpay is new this release.
This commit is contained in:
parent
4186591a70
commit
90ab9325a1
1 changed files with 13 additions and 8 deletions
|
@ -777,11 +777,11 @@ static struct command_result *injectpaymentonion_succeeded(struct command *aux_c
|
||||||
|
|
||||||
static void append_blinded_payloads(struct sphinx_path *sp,
|
static void append_blinded_payloads(struct sphinx_path *sp,
|
||||||
const struct attempt *attempt,
|
const struct attempt *attempt,
|
||||||
|
u32 effective_bheight,
|
||||||
size_t path_num)
|
size_t path_num)
|
||||||
{
|
{
|
||||||
const struct blinded_path *path = attempt->payment->paths[path_num];
|
const struct blinded_path *path = attempt->payment->paths[path_num];
|
||||||
struct xpay *xpay = xpay_of(attempt->payment->plugin);
|
u32 final_cltv = attempt->payment->final_cltv + effective_bheight;
|
||||||
u32 final_cltv = attempt->payment->final_cltv + xpay->blockheight;
|
|
||||||
|
|
||||||
for (size_t i = 0; i < tal_count(path->path); i++) {
|
for (size_t i = 0; i < tal_count(path->path); i++) {
|
||||||
bool first = (i == 0);
|
bool first = (i == 0);
|
||||||
|
@ -813,7 +813,9 @@ static void append_blinded_payloads(struct sphinx_path *sp,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static const u8 *create_onion(const tal_t *ctx, struct attempt *attempt)
|
static const u8 *create_onion(const tal_t *ctx,
|
||||||
|
struct attempt *attempt,
|
||||||
|
u32 effective_bheight)
|
||||||
{
|
{
|
||||||
struct xpay *xpay = xpay_of(attempt->payment->plugin);
|
struct xpay *xpay = xpay_of(attempt->payment->plugin);
|
||||||
bool blinded_path = false;
|
bool blinded_path = false;
|
||||||
|
@ -834,7 +836,8 @@ static const u8 *create_onion(const tal_t *ctx, struct attempt *attempt)
|
||||||
if (pubkey_eq(&hop->next_node, &xpay->fakenode)
|
if (pubkey_eq(&hop->next_node, &xpay->fakenode)
|
||||||
&& hop->scidd.scid.u64 < tal_count(attempt->payment->paths)) {
|
&& hop->scidd.scid.u64 < tal_count(attempt->payment->paths)) {
|
||||||
blinded_path = true;
|
blinded_path = true;
|
||||||
append_blinded_payloads(sp, attempt, hop->scidd.scid.u64);
|
append_blinded_payloads(sp, attempt, effective_bheight,
|
||||||
|
hop->scidd.scid.u64);
|
||||||
/* This must be at the end, unless they put the fake nodeid
|
/* This must be at the end, unless they put the fake nodeid
|
||||||
* in a layer, in which case it doesn't matter what we put
|
* in a layer, in which case it doesn't matter what we put
|
||||||
* in the rest of the onion. */
|
* in the rest of the onion. */
|
||||||
|
@ -842,7 +845,7 @@ static const u8 *create_onion(const tal_t *ctx, struct attempt *attempt)
|
||||||
}
|
}
|
||||||
/* We tell it how much to send *out* */
|
/* We tell it how much to send *out* */
|
||||||
payload = onion_nonfinal_hop(NULL, &hop->scidd.scid, hop->amount_out,
|
payload = onion_nonfinal_hop(NULL, &hop->scidd.scid, hop->amount_out,
|
||||||
hop->cltv_value_out + xpay->blockheight);
|
hop->cltv_value_out + effective_bheight);
|
||||||
sphinx_add_hop_has_length(sp, node, take(payload));
|
sphinx_add_hop_has_length(sp, node, take(payload));
|
||||||
node = &hop->next_node;
|
node = &hop->next_node;
|
||||||
}
|
}
|
||||||
|
@ -853,7 +856,7 @@ static const u8 *create_onion(const tal_t *ctx, struct attempt *attempt)
|
||||||
sphinx_add_hop_has_length(sp, node,
|
sphinx_add_hop_has_length(sp, node,
|
||||||
take(onion_final_hop(NULL,
|
take(onion_final_hop(NULL,
|
||||||
attempt->delivers,
|
attempt->delivers,
|
||||||
attempt->payment->final_cltv + xpay->blockheight,
|
attempt->payment->final_cltv + effective_bheight,
|
||||||
attempt->payment->full_amount,
|
attempt->payment->full_amount,
|
||||||
attempt->payment->payment_secret,
|
attempt->payment->payment_secret,
|
||||||
attempt->payment->payment_metadata)));
|
attempt->payment->payment_metadata)));
|
||||||
|
@ -876,8 +879,10 @@ static struct command_result *do_inject(struct command *aux_cmd,
|
||||||
struct out_req *req;
|
struct out_req *req;
|
||||||
const u8 *onion;
|
const u8 *onion;
|
||||||
struct xpay *xpay = xpay_of(attempt->payment->plugin);
|
struct xpay *xpay = xpay_of(attempt->payment->plugin);
|
||||||
|
/* In case a block comes in, we give CLTVs an extra 1. */
|
||||||
|
u32 effective_bheight = xpay->blockheight + 1;
|
||||||
|
|
||||||
onion = create_onion(tmpctx, attempt);
|
onion = create_onion(tmpctx, attempt, effective_bheight);
|
||||||
/* FIXME: Handle this better! */
|
/* FIXME: Handle this better! */
|
||||||
if (!onion) {
|
if (!onion) {
|
||||||
payment_failed(aux_cmd, attempt->payment, PAY_UNSPECIFIED_ERROR,
|
payment_failed(aux_cmd, attempt->payment, PAY_UNSPECIFIED_ERROR,
|
||||||
|
@ -894,7 +899,7 @@ static struct command_result *do_inject(struct command *aux_cmd,
|
||||||
json_add_sha256(req->js, "payment_hash", &attempt->payment->payment_hash);
|
json_add_sha256(req->js, "payment_hash", &attempt->payment->payment_hash);
|
||||||
/* If no route, its the same as delivery (self-pay) */
|
/* If no route, its the same as delivery (self-pay) */
|
||||||
json_add_amount_msat(req->js, "amount_msat", initial_sent(attempt));
|
json_add_amount_msat(req->js, "amount_msat", initial_sent(attempt));
|
||||||
json_add_u32(req->js, "cltv_expiry", initial_cltv_delta(attempt) + xpay->blockheight);
|
json_add_u32(req->js, "cltv_expiry", initial_cltv_delta(attempt) + effective_bheight);
|
||||||
json_add_u64(req->js, "partid", attempt->partid);
|
json_add_u64(req->js, "partid", attempt->partid);
|
||||||
json_add_u64(req->js, "groupid", attempt->payment->group_id);
|
json_add_u64(req->js, "groupid", attempt->payment->group_id);
|
||||||
json_add_string(req->js, "invstring", attempt->payment->invstring);
|
json_add_string(req->js, "invstring", attempt->payment->invstring);
|
||||||
|
|
Loading…
Add table
Reference in a new issue