From 355a7ae8272edae02c7ee0fe3b6ee64aab861a1c Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Mon, 27 Feb 2023 13:55:34 +1030 Subject: [PATCH] pay: fix delpay to actually delete. It works for the trivial case, where groupid and partid are the same, but silently deletes nothing in the other cases (or worse, deletes the wrong entry!). See: #5835 Changelog-Fixed: `delpay`: actually delete the specified payment (mainly found by `autoclean`). Signed-off-by: Rusty Russell --- lightningd/pay.c | 2 +- tests/test_pay.py | 31 +++++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/lightningd/pay.c b/lightningd/pay.c index 75cdbcc42..6262aba4e 100644 --- a/lightningd/pay.c +++ b/lightningd/pay.c @@ -1702,7 +1702,7 @@ static struct command_result *json_delpay(struct command *cmd, "No payment for that payment_hash with that partid and groupid"); } - wallet_payment_delete(cmd->ld->wallet, payment_hash, partid, groupid); + wallet_payment_delete(cmd->ld->wallet, payment_hash, groupid, partid); response = json_stream_success(cmd); json_array_start(response, "payments"); diff --git a/tests/test_pay.py b/tests/test_pay.py index 1db4d796a..6744e7394 100644 --- a/tests/test_pay.py +++ b/tests/test_pay.py @@ -5350,3 +5350,34 @@ def test_pay_multichannel_use_zeroconf(bitcoind, node_factory): # 3. Send a payment over the zeroconf channel riskfactor = 0 l1.rpc.pay(inv['bolt11'], riskfactor=riskfactor) + + +@pytest.mark.developer("needs dev-no-reconnect, dev-routes to force failover") +def test_delpay_works(node_factory, bitcoind): + """ + One failure, one success; deleting the success works (groupid=1, partid=2) + """ + l1, l2, l3 = node_factory.line_graph(3, fundamount=10**5, + wait_for_announce=True) + # Expensive route! + l4 = node_factory.get_node(options={'fee-per-satoshi': 1000, + 'fee-base': 2000}) + node_factory.join_nodes([l1, l4, l3], wait_for_announce=True) + + # Don't give a hint, so l1 chooses cheapest. + inv = l3.dev_invoice(10**5, 'lbl', 'desc', dev_routes=[]) + l3.rpc.disconnect(l2.info['id'], force=True) + l1.rpc.pay(inv['bolt11']) + + assert len(l1.rpc.listsendpays()['payments']) == 2 + failed = [p for p in l1.rpc.listsendpays()['payments'] if p['status'] == 'complete'][0] + l1.rpc.delpay(payment_hash=failed['payment_hash'], + status=failed['status'], + groupid=failed['groupid'], + partid=failed['partid']) + + with pytest.raises(RpcError, match=r'No payment for that payment_hash'): + l1.rpc.delpay(payment_hash=failed['payment_hash'], + status=failed['status'], + groupid=failed['groupid'], + partid=failed['partid'])