Skip to content

Commit

Permalink
lightningd: insist on payment_secret if bit compulsory on invoices.
Browse files Browse the repository at this point in the history
This grandfathers in old invoices for the moment.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
  • Loading branch information
rustyrussell committed Jul 12, 2021
1 parent e06e86b commit d4d46e6
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 3 deletions.
12 changes: 12 additions & 0 deletions lightningd/htlc_set.c
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#include <common/features.h>
#include <common/timeout.h>
#include <lightningd/htlc_end.h>
#include <lightningd/htlc_set.h>
Expand Down Expand Up @@ -114,6 +115,17 @@ void htlc_set_add(struct lightningd *ld,
return;
}

/* If we insist on a payment secret, it must always have it */
if (feature_is_set(details->features, COMPULSORY_FEATURE(OPT_PAYMENT_SECRET))
&& !payment_secret) {
log_debug(ld->log, "Missing payment_secret, but required for %s",
type_to_string(tmpctx, struct sha256,
&hin->payment_hash));
local_fail_in_htlc(hin,
take(failmsg_incorrect_or_unknown(NULL, ld, hin)));
return;
}

/* BOLT #4:
* - otherwise, if it supports `basic_mpp`:
* - MUST add it to the HTLC set corresponding to that `payment_hash`.
Expand Down
17 changes: 14 additions & 3 deletions tests/test_pay.py
Original file line number Diff line number Diff line change
Expand Up @@ -562,6 +562,18 @@ def only_one(arr):
l1.rpc.sendpay([rs], rhash, payment_secret=inv['payment_secret'])
assert invoice_unpaid(l2, 'testpayment2')

# Bad payment_secret
l1.rpc.sendpay([routestep], rhash, payment_secret="00" * 32)
with pytest.raises(RpcError):
l1.rpc.waitsendpay(rhash)
assert invoice_unpaid(l2, 'testpayment2')

# Missing payment_secret
l1.rpc.sendpay([routestep], rhash)
with pytest.raises(RpcError):
l1.rpc.waitsendpay(rhash)
assert invoice_unpaid(l2, 'testpayment2')

# FIXME: test paying via another node, should fail to pay twice.
p1 = l1.rpc.getpeer(l2.info['id'], 'info')
p2 = l2.rpc.getpeer(l1.info['id'], 'info')
Expand Down Expand Up @@ -2506,9 +2518,8 @@ def test_pay_no_secret(node_factory, bitcoind):

# Produced from old version (no secret!)
inv_nosecret = 'lnbcrt1u1pwue4vapp5ve584t0cv27hwmy0cx9ca8uwyqyfw9y9dm3r8vus9fv36r2l9yjsdqaw3jhxazlwpshjhmwda0hxetrwfjhgxq8pmnt9qqcqp9570xsjyykvssa6ty8fjth6f2y8h09myngad9utesttwjwclv95fz3lgd402f9e5yzpnxmkypg55rkvpg522gcz4ymsjl2w3m4jhw4jsp55m7tl'
# This succeeds until we make secrets compulsory.
l1.rpc.pay(inv_nosecret)
l2.daemon.wait_for_log(r'HTLC set contains 1 HTLCs, for a total of 100000msat out of 100000msat \(no payment_secret\)')
with pytest.raises(RpcError, match=r"INCORRECT_OR_UNKNOWN_PAYMENT_DETAILS.*'erring_index': 1"):
l1.rpc.pay(inv_nosecret)


@flaky
Expand Down

0 comments on commit d4d46e6

Please sign in to comment.