Skip to content

Commit dc6a5f8

Browse files
committed
lightningd: populate listsendpays destination from injectpaymentonion if we can.
If they give us the invstring, we can at least set who signed the invoice. Of course, it might not be a real node_id (with blinded paths). Signed-off-by: Rusty Russell <[email protected]>
1 parent cf0bd39 commit dc6a5f8

File tree

2 files changed

+46
-8
lines changed

2 files changed

+46
-8
lines changed

lightningd/pay.c

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1788,7 +1788,8 @@ static void register_payment_and_waiter(struct command *cmd,
17881788
const char *label,
17891789
const char *invstring,
17901790
struct sha256 *local_invreq_id,
1791-
const struct secret *shared_secret)
1791+
const struct secret *shared_secret,
1792+
const struct node_id *destination TAKES)
17921793
{
17931794
wallet_add_payment(cmd,
17941795
cmd->ld->wallet,
@@ -1798,7 +1799,7 @@ static void register_payment_and_waiter(struct command *cmd,
17981799
partid,
17991800
groupid,
18001801
PAYMENT_PENDING,
1801-
NULL,
1802+
destination,
18021803
destination_msat,
18031804
msat_sent,
18041805
total_msat,
@@ -1845,6 +1846,7 @@ static struct command_result *json_injectpaymentonion(struct command *cmd,
18451846
struct htlc_out *hout;
18461847
const struct wallet_payment *prev_payment;
18471848
const char *explanation;
1849+
struct node_id *destination;
18481850

18491851
if (!param_check(cmd, buffer, params,
18501852
p_req("onion", param_bin_from_hex, &onion),
@@ -1926,6 +1928,28 @@ static struct command_result *json_injectpaymentonion(struct command *cmd,
19261928
failtlvtype, failtlvpos, explanation);
19271929
}
19281930

1931+
/* If we have and can decode invstring, we extract destination for listsendpays */
1932+
if (invstring) {
1933+
struct bolt11 *b11;
1934+
char *fail;
1935+
1936+
b11 = bolt11_decode(cmd, invstring, NULL, NULL, NULL, &fail);
1937+
if (b11) {
1938+
destination = &b11->receiver_id;
1939+
} else {
1940+
struct tlv_invoice *b12;
1941+
1942+
b12 = invoice_decode(cmd, invstring, strlen(invstring),
1943+
NULL, NULL, &fail);
1944+
if (b12 && b12->invoice_node_id) {
1945+
destination = tal(cmd, struct node_id);
1946+
node_id_from_pubkey(destination, b12->invoice_node_id);
1947+
} else
1948+
destination = NULL;
1949+
}
1950+
} else
1951+
destination = NULL;
1952+
19291953
if (payload->final) {
19301954
struct selfpay *selfpay;
19311955

@@ -1944,7 +1968,8 @@ static struct command_result *json_injectpaymentonion(struct command *cmd,
19441968
*partid, *groupid,
19451969
*destination_msat, *msat, AMOUNT_MSAT(0),
19461970
label, invstring, local_invreq_id,
1947-
&shared_secret);
1971+
&shared_secret,
1972+
destination);
19481973

19491974
/* Mark it pending now, though htlc_set_add might
19501975
* not resolve immediately */
@@ -2058,7 +2083,8 @@ static struct command_result *json_injectpaymentonion(struct command *cmd,
20582083
*partid, *groupid,
20592084
*destination_msat, *msat, AMOUNT_MSAT(0),
20602085
label, invstring, local_invreq_id,
2061-
&shared_secret);
2086+
&shared_secret,
2087+
destination);
20622088

20632089
/* If unknown, we set this equal (so accounting logs 0 fees) */
20642090
if (amount_msat_eq(*destination_msat, AMOUNT_MSAT(0)))

tests/test_pay.py

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6210,6 +6210,8 @@ def test_injectpaymentonion_3hop(node_factory, executor):
62106210
assert lsp['payment_hash'] == inv3['payment_hash']
62116211
assert lsp['status'] == 'complete'
62126212
assert lsp['amount_msat'] == 1000
6213+
# We didn't give it an invstring, so it doesn't know destination
6214+
assert 'destination' not in lsp
62136215

62146216

62156217
def test_injectpaymentonion_selfpay(node_factory, executor):
@@ -6227,6 +6229,7 @@ def test_injectpaymentonion_selfpay(node_factory, executor):
62276229

62286230
ret = l1.rpc.injectpaymentonion(onion=onion['onion'],
62296231
payment_hash=inv4['payment_hash'],
6232+
invstring=inv4['bolt11'],
62306233
amount_msat=1000,
62316234
cltv_expiry=blockheight + 18,
62326235
partid=1,
@@ -6238,6 +6241,7 @@ def test_injectpaymentonion_selfpay(node_factory, executor):
62386241
assert lsp['partid'] == 1
62396242
assert lsp['payment_hash'] == inv4['payment_hash']
62406243
assert lsp['status'] == 'complete'
6244+
assert lsp['destination'] == l1.info['id']
62416245

62426246
# Test self-pay with MPP.
62436247
inv5 = l1.rpc.invoice(1000, "test_injectpaymentonion5", "test_injectpaymentonion5")
@@ -6278,6 +6282,7 @@ def test_injectpaymentonion_selfpay(node_factory, executor):
62786282
assert lsp['partid'] == 1 or lsp['partid'] == 2
62796283
assert lsp['payment_hash'] == inv5['payment_hash']
62806284
assert lsp['status'] == 'complete'
6285+
assert 'destination' not in lsp
62816286
assert len(lsps) == 2
62826287

62836288
# Check listpays gives a reasonable result!
@@ -6362,7 +6367,8 @@ def test_injectpaymentonion_selfpay(node_factory, executor):
63626367
amount_msat=1000,
63636368
cltv_expiry=blockheight + 18,
63646369
partid=1,
6365-
groupid=0)
6370+
groupid=0,
6371+
invstring=inv10['invoice'])
63666372
assert sha256(bytes.fromhex(ret['payment_preimage'])).hexdigest() == decoded['invoice_payment_hash']
63676373
# The label for the invoice is deterministic.
63686374
label = f"{decoded['offer_id']}-{decoded['invreq_payer_id']}-0"
@@ -6372,6 +6378,7 @@ def test_injectpaymentonion_selfpay(node_factory, executor):
63726378
assert lsp['partid'] == 1
63736379
assert lsp['payment_hash'] == inv4['payment_hash']
63746380
assert lsp['status'] == 'complete'
6381+
assert lsp['destination'] == l1.info['id']
63756382

63766383

63776384
def test_injectpaymentonion_blindedpath(node_factory, executor):
@@ -6440,7 +6447,8 @@ def test_injectpaymentonion_blindedpath(node_factory, executor):
64406447
amount_msat=1000,
64416448
cltv_expiry=blockheight + 18 + 6,
64426449
partid=1,
6443-
groupid=0)
6450+
groupid=0,
6451+
invstring=inv7['invoice'])
64446452
assert sha256(bytes.fromhex(ret['payment_preimage'])).hexdigest() == decoded['invoice_payment_hash']
64456453
# The label for l2's invoice is deterministic.
64466454
label = f"{decoded['offer_id']}-{decoded['invreq_payer_id']}-0"
@@ -6492,7 +6500,8 @@ def test_injectpaymentonion_blindedpath(node_factory, executor):
64926500
amount_msat=1001,
64936501
cltv_expiry=blockheight + 18 + 6,
64946502
partid=1,
6495-
groupid=0)
6503+
groupid=0,
6504+
invstring=inv8['invoice'])
64966505
assert sha256(bytes.fromhex(ret['payment_preimage'])).hexdigest() == decoded['invoice_payment_hash']
64976506
# The label for l4's invoice is deterministic.
64986507
label = f"{decoded['offer_id']}-{decoded['invreq_payer_id']}-0"
@@ -6502,6 +6511,7 @@ def test_injectpaymentonion_blindedpath(node_factory, executor):
65026511
assert lsp['partid'] == 1
65036512
assert lsp['payment_hash'] == decoded['invoice_payment_hash']
65046513
assert lsp['status'] == 'complete'
6514+
assert lsp['destination'] == decoded['invoice_node_id']
65056515

65066516
# Finally, with blinded path which starts with us.
65076517
offer = l4.rpc.offer('any')
@@ -6535,7 +6545,8 @@ def test_injectpaymentonion_blindedpath(node_factory, executor):
65356545
amount_msat=1001,
65366546
cltv_expiry=blockheight + 18 + 6,
65376547
partid=1,
6538-
groupid=0)
6548+
groupid=0,
6549+
invstring=inv9['invoice'])
65396550
assert sha256(bytes.fromhex(ret['payment_preimage'])).hexdigest() == decoded['invoice_payment_hash']
65406551
# The label for the invoice is deterministic.
65416552
label = f"{decoded['offer_id']}-{decoded['invreq_payer_id']}-0"
@@ -6545,6 +6556,7 @@ def test_injectpaymentonion_blindedpath(node_factory, executor):
65456556
assert lsp['partid'] == 1
65466557
assert lsp['payment_hash'] == decoded['invoice_payment_hash']
65476558
assert lsp['status'] == 'complete'
6559+
assert lsp['destination'] == decoded['invoice_node_id']
65486560

65496561

65506562
def test_injectpaymentonion_failures(node_factory, executor):

0 commit comments

Comments
 (0)