From edab0df611cf47f6cbc28c32320fbcff421e3651 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Thu, 12 Dec 2019 10:48:27 +1030 Subject: [PATCH] lightningd: fix spurious "more than twice final" error. Bastien TEINTURIER writes: > It looks like the split on c-lightning side is quite limited at the moment: > the only option is to split a payment in exactly its two halves, > otherwise I get rejected because of the rule of overpaying more than > twice the amount? We only tested exactly two equal-size payments; indeed, our finalhop test was backwards. We only complain if the final hop pays more than twice msat (technically, this test is still too loose for mpp: the spec says we should sum to the exact amount). Reported-by: @t-bast Signed-off-by: Rusty Russell --- lightningd/pay.c | 18 +++++++++--------- tests/test_pay.py | 6 +++--- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/lightningd/pay.c b/lightningd/pay.c index 7d20aecf8..446fd9823 100644 --- a/lightningd/pay.c +++ b/lightningd/pay.c @@ -1292,26 +1292,26 @@ static struct command_result *json_sendpay(struct command *cmd, return command_fail(cmd, JSONRPC2_INVALID_PARAMS, "Must specify msatoshi with partid"); - /* if not: finalhop.amount <= 2 * msatoshi, fail. */ + /* finalhop.amount > 2 * msatoshi, fail. */ if (msat) { - struct amount_msat limit = route[routetok->size-1].amount; + struct amount_msat limit; - if (!amount_msat_add(&limit, limit, limit)) + if (!amount_msat_add(&limit, *msat, *msat)) return command_fail(cmd, JSONRPC2_INVALID_PARAMS, - "Unbelievable final amount %s", + "Unbelievable msatoshi %s", type_to_string(tmpctx, struct amount_msat, - &route[routetok->size-1].amount)); + msat)); - if (amount_msat_greater(*msat, limit)) + if (amount_msat_greater(route[routetok->size-1].amount, limit)) return command_fail(cmd, JSONRPC2_INVALID_PARAMS, - "msatoshi %s more than twice final %s", + "final %s more than twice msatoshi %s", type_to_string(tmpctx, struct amount_msat, - msat), + &route[routetok->size-1].amount), type_to_string(tmpctx, struct amount_msat, - &route[routetok->size-1].amount)); + msat)); } /* It's easier to leave this in the API, then ignore it here. */ diff --git a/tests/test_pay.py b/tests/test_pay.py index a72a1cfa3..547bf50fc 100644 --- a/tests/test_pay.py +++ b/tests/test_pay.py @@ -2593,8 +2593,8 @@ def test_partial_payment(node_factory, bitcoind, executor): paysecret = l4.rpc.decodepay(inv['bolt11'])['payment_secret'] # Separate routes for each part of the payment. - r134 = l1.rpc.getroute(l4.info['id'], 500, 1, exclude=[scid24 + '/0', scid24 + '/1'])['route'] - r124 = l1.rpc.getroute(l4.info['id'], 500, 1, exclude=[scid34 + '/0', scid34 + '/1'])['route'] + r134 = l1.rpc.getroute(l4.info['id'], 501, 1, exclude=[scid24 + '/0', scid24 + '/1'])['route'] + r124 = l1.rpc.getroute(l4.info['id'], 499, 1, exclude=[scid34 + '/0', scid34 + '/1'])['route'] # These can happen in parallel. l1.rpc.call('sendpay', [r134, inv['payment_hash'], None, 1000, inv['bolt11'], paysecret, 1]) @@ -2638,7 +2638,7 @@ def test_partial_payment(node_factory, bitcoind, executor): for i in range(2): line = l4.daemon.wait_for_log('print_htlc_onion.py: Got onion') assert "'type': 'tlv'" in line - assert "'forward_amount': '500msat'" in line + assert "'forward_amount': '499msat'" in line or "'forward_amount': '501msat'" in line assert "'total_msat': '1000msat'" in line assert "'payment_secret': '{}'".format(paysecret) in line