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 <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell 2024-12-16 11:09:52 +10:30
parent 80c43ec97d
commit 8202929a00
2 changed files with 46 additions and 8 deletions

View File

@ -1788,7 +1788,8 @@ static void register_payment_and_waiter(struct command *cmd,
const char *label,
const char *invstring,
struct sha256 *local_invreq_id,
const struct secret *shared_secret)
const struct secret *shared_secret,
const struct node_id *destination TAKES)
{
wallet_add_payment(cmd,
cmd->ld->wallet,
@ -1798,7 +1799,7 @@ static void register_payment_and_waiter(struct command *cmd,
partid,
groupid,
PAYMENT_PENDING,
NULL,
destination,
destination_msat,
msat_sent,
total_msat,
@ -1845,6 +1846,7 @@ static struct command_result *json_injectpaymentonion(struct command *cmd,
struct htlc_out *hout;
const struct wallet_payment *prev_payment;
const char *explanation;
struct node_id *destination;
if (!param_check(cmd, buffer, params,
p_req("onion", param_bin_from_hex, &onion),
@ -1926,6 +1928,28 @@ static struct command_result *json_injectpaymentonion(struct command *cmd,
failtlvtype, failtlvpos, explanation);
}
/* If we have and can decode invstring, we extract destination for listsendpays */
if (invstring) {
struct bolt11 *b11;
char *fail;
b11 = bolt11_decode(cmd, invstring, NULL, NULL, NULL, &fail);
if (b11) {
destination = &b11->receiver_id;
} else {
struct tlv_invoice *b12;
b12 = invoice_decode(cmd, invstring, strlen(invstring),
NULL, NULL, &fail);
if (b12 && b12->invoice_node_id) {
destination = tal(cmd, struct node_id);
node_id_from_pubkey(destination, b12->invoice_node_id);
} else
destination = NULL;
}
} else
destination = NULL;
if (payload->final) {
struct selfpay *selfpay;
@ -1944,7 +1968,8 @@ static struct command_result *json_injectpaymentonion(struct command *cmd,
*partid, *groupid,
*destination_msat, *msat, AMOUNT_MSAT(0),
label, invstring, local_invreq_id,
&shared_secret);
&shared_secret,
destination);
/* Mark it pending now, though htlc_set_add might
* not resolve immediately */
@ -2058,7 +2083,8 @@ static struct command_result *json_injectpaymentonion(struct command *cmd,
*partid, *groupid,
*destination_msat, *msat, AMOUNT_MSAT(0),
label, invstring, local_invreq_id,
&shared_secret);
&shared_secret,
destination);
/* If unknown, we set this equal (so accounting logs 0 fees) */
if (amount_msat_eq(*destination_msat, AMOUNT_MSAT(0)))

View File

@ -6210,6 +6210,8 @@ def test_injectpaymentonion_3hop(node_factory, executor):
assert lsp['payment_hash'] == inv3['payment_hash']
assert lsp['status'] == 'complete'
assert lsp['amount_msat'] == 1000
# We didn't give it an invstring, so it doesn't know destination
assert 'destination' not in lsp
def test_injectpaymentonion_selfpay(node_factory, executor):
@ -6227,6 +6229,7 @@ def test_injectpaymentonion_selfpay(node_factory, executor):
ret = l1.rpc.injectpaymentonion(onion=onion['onion'],
payment_hash=inv4['payment_hash'],
invstring=inv4['bolt11'],
amount_msat=1000,
cltv_expiry=blockheight + 18,
partid=1,
@ -6238,6 +6241,7 @@ def test_injectpaymentonion_selfpay(node_factory, executor):
assert lsp['partid'] == 1
assert lsp['payment_hash'] == inv4['payment_hash']
assert lsp['status'] == 'complete'
assert lsp['destination'] == l1.info['id']
# Test self-pay with MPP.
inv5 = l1.rpc.invoice(1000, "test_injectpaymentonion5", "test_injectpaymentonion5")
@ -6278,6 +6282,7 @@ def test_injectpaymentonion_selfpay(node_factory, executor):
assert lsp['partid'] == 1 or lsp['partid'] == 2
assert lsp['payment_hash'] == inv5['payment_hash']
assert lsp['status'] == 'complete'
assert 'destination' not in lsp
assert len(lsps) == 2
# Check listpays gives a reasonable result!
@ -6362,7 +6367,8 @@ def test_injectpaymentonion_selfpay(node_factory, executor):
amount_msat=1000,
cltv_expiry=blockheight + 18,
partid=1,
groupid=0)
groupid=0,
invstring=inv10['invoice'])
assert sha256(bytes.fromhex(ret['payment_preimage'])).hexdigest() == decoded['invoice_payment_hash']
# The label for the invoice is deterministic.
label = f"{decoded['offer_id']}-{decoded['invreq_payer_id']}-0"
@ -6372,6 +6378,7 @@ def test_injectpaymentonion_selfpay(node_factory, executor):
assert lsp['partid'] == 1
assert lsp['payment_hash'] == inv4['payment_hash']
assert lsp['status'] == 'complete'
assert lsp['destination'] == l1.info['id']
def test_injectpaymentonion_blindedpath(node_factory, executor):
@ -6440,7 +6447,8 @@ def test_injectpaymentonion_blindedpath(node_factory, executor):
amount_msat=1000,
cltv_expiry=blockheight + 18 + 6,
partid=1,
groupid=0)
groupid=0,
invstring=inv7['invoice'])
assert sha256(bytes.fromhex(ret['payment_preimage'])).hexdigest() == decoded['invoice_payment_hash']
# The label for l2's invoice is deterministic.
label = f"{decoded['offer_id']}-{decoded['invreq_payer_id']}-0"
@ -6492,7 +6500,8 @@ def test_injectpaymentonion_blindedpath(node_factory, executor):
amount_msat=1001,
cltv_expiry=blockheight + 18 + 6,
partid=1,
groupid=0)
groupid=0,
invstring=inv8['invoice'])
assert sha256(bytes.fromhex(ret['payment_preimage'])).hexdigest() == decoded['invoice_payment_hash']
# The label for l4's invoice is deterministic.
label = f"{decoded['offer_id']}-{decoded['invreq_payer_id']}-0"
@ -6502,6 +6511,7 @@ def test_injectpaymentonion_blindedpath(node_factory, executor):
assert lsp['partid'] == 1
assert lsp['payment_hash'] == decoded['invoice_payment_hash']
assert lsp['status'] == 'complete'
assert lsp['destination'] == decoded['invoice_node_id']
# Finally, with blinded path which starts with us.
offer = l4.rpc.offer('any')
@ -6535,7 +6545,8 @@ def test_injectpaymentonion_blindedpath(node_factory, executor):
amount_msat=1001,
cltv_expiry=blockheight + 18 + 6,
partid=1,
groupid=0)
groupid=0,
invstring=inv9['invoice'])
assert sha256(bytes.fromhex(ret['payment_preimage'])).hexdigest() == decoded['invoice_payment_hash']
# The label for the invoice is deterministic.
label = f"{decoded['offer_id']}-{decoded['invreq_payer_id']}-0"
@ -6545,6 +6556,7 @@ def test_injectpaymentonion_blindedpath(node_factory, executor):
assert lsp['partid'] == 1
assert lsp['payment_hash'] == decoded['invoice_payment_hash']
assert lsp['status'] == 'complete'
assert lsp['destination'] == decoded['invoice_node_id']
def test_injectpaymentonion_failures(node_factory, executor):