From 4e881e56cec2a0e7c8a190532c9daece46bafbcf Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Mon, 12 Jul 2021 16:19:19 +0930 Subject: [PATCH] pytest: always provide payment_secret when making payments. They're about to become compulsory. Signed-off-by: Rusty Russell --- contrib/pyln-testing/pyln/testing/utils.py | 7 +- tests/benchmark.py | 11 +- tests/test_closing.py | 70 +++++----- tests/test_connection.py | 63 +++++---- tests/test_misc.py | 24 ++-- tests/test_pay.py | 142 ++++++++++++--------- tests/test_plugin.py | 59 +++++---- 7 files changed, 212 insertions(+), 164 deletions(-) diff --git a/contrib/pyln-testing/pyln/testing/utils.py b/contrib/pyln-testing/pyln/testing/utils.py index 20288e58d..7f8cd0fb4 100644 --- a/contrib/pyln-testing/pyln/testing/utils.py +++ b/contrib/pyln-testing/pyln/testing/utils.py @@ -996,7 +996,10 @@ class LightningNode(object): assert len(self.rpc.listpeers(dst_id).get('peers')) == 1 # make an invoice - rhash = dst.rpc.invoice(amt, label, label)['payment_hash'] + inv = dst.rpc.invoice(amt, label, label) + # FIXME: pre 0.10.1 invoice calls didn't have payment_secret field + psecret = dst.rpc.decodepay(inv['bolt11'])['payment_secret'] + rhash = inv['payment_hash'] invoices = dst.rpc.listinvoices(label)['invoices'] assert len(invoices) == 1 and invoices[0]['status'] == 'unpaid' @@ -1008,7 +1011,7 @@ class LightningNode(object): } # sendpay is async now - self.rpc.sendpay([routestep], rhash) + self.rpc.sendpay([routestep], rhash, payment_secret=psecret) # wait for sendpay to comply result = self.rpc.waitsendpay(rhash) assert(result.get('status') == 'complete') diff --git a/tests/benchmark.py b/tests/benchmark.py index edc4475c2..030cb8578 100644 --- a/tests/benchmark.py +++ b/tests/benchmark.py @@ -30,19 +30,20 @@ def test_single_hop(node_factory, executor): fs = [] invoices = [] for i in tqdm(range(num_payments)): - invoices.append(l2.rpc.invoice(1000, 'invoice-%d' % (i), 'desc')['payment_hash']) + inv = l2.rpc.invoice(1000, 'invoice-%d' % (i), 'desc') + invoices.append((inv['payment_hash'], inv['payment_secret'])) route = l1.rpc.getroute(l2.rpc.getinfo()['id'], 1000, 1)['route'] print("Sending payments") start_time = time() - def do_pay(i): - p = l1.rpc.sendpay(route, i) + def do_pay(i, s): + p = l1.rpc.sendpay(route, i, payment_secret=s) r = l1.rpc.waitsendpay(p['payment_hash']) return r - for i in invoices: - fs.append(executor.submit(do_pay, i)) + for i, s in invoices: + fs.append(executor.submit(do_pay, i, s)) for f in tqdm(futures.as_completed(fs), total=len(fs)): f.result() diff --git a/tests/test_closing.py b/tests/test_closing.py index 0bb6c170b..4a2f4ba61 100644 --- a/tests/test_closing.py +++ b/tests/test_closing.py @@ -777,7 +777,7 @@ def test_penalty_htlc_tx_fulfill(node_factory, bitcoind, chainparams): amt = 10**8 // 2 sticky_inv = l1.rpc.invoice(amt, '2', 'sticky') route = l4.rpc.getroute(l1.info['id'], amt, 1)['route'] - l4.rpc.sendpay(route, sticky_inv['payment_hash']) + l4.rpc.sendpay(route, sticky_inv['payment_hash'], payment_secret=sticky_inv['payment_secret']) l1.daemon.wait_for_log('dev_disconnect: -WIRE_UPDATE_FULFILL_HTLC') wait_for(lambda: len(l2.rpc.listpeers(l3.info['id'])['peers'][0]['channels'][0]['htlcs']) == 1) @@ -927,12 +927,12 @@ def test_penalty_htlc_tx_timeout(node_factory, bitcoind, chainparams): amt = 10**8 // 2 sticky_inv_1 = l5.rpc.invoice(amt, '2', 'sticky') route = l1.rpc.getroute(l5.info['id'], amt, 1)['route'] - l1.rpc.sendpay(route, sticky_inv_1['payment_hash']) + l1.rpc.sendpay(route, sticky_inv_1['payment_hash'], payment_secret=sticky_inv_1['payment_secret']) l5.daemon.wait_for_log('dev_disconnect: -WIRE_UPDATE_FULFILL_HTLC') sticky_inv_2 = l1.rpc.invoice(amt, '2', 'sticky') route = l4.rpc.getroute(l1.info['id'], amt, 1)['route'] - l4.rpc.sendpay(route, sticky_inv_2['payment_hash']) + l4.rpc.sendpay(route, sticky_inv_2['payment_hash'], payment_secret=sticky_inv_2['payment_secret']) l1.daemon.wait_for_log('dev_disconnect: -WIRE_UPDATE_FULFILL_HTLC') wait_for(lambda: len(l2.rpc.listpeers(l3.info['id'])['peers'][0]['channels'][0]['htlcs']) == 2) @@ -1350,14 +1350,15 @@ def test_onchaind_replay(node_factory, bitcoind): 'feerates': (7500, 7500, 7500, 7500)}, {'watchtime-blocks': 201, 'cltv-delta': 101}]) - rhash = l2.rpc.invoice(10**8, 'onchaind_replay', 'desc')['payment_hash'] + inv = l2.rpc.invoice(10**8, 'onchaind_replay', 'desc') + rhash = inv['payment_hash'] routestep = { 'msatoshi': 10**8 - 1, 'id': l2.info['id'], 'delay': 101, 'channel': '1x1x1' } - l1.rpc.sendpay([routestep], rhash) + l1.rpc.sendpay([routestep], rhash, payment_secret=inv['payment_secret']) l1.daemon.wait_for_log('sendrawtx exit 0') bitcoind.generate_block(1, wait_for_mempool=1) @@ -1409,7 +1410,8 @@ def test_onchain_dust_out(node_factory, bitcoind, executor): channel_id = first_channel_id(l1, l2) # Must be dust! - rhash = l2.rpc.invoice(1, 'onchain_dust_out', 'desc')['payment_hash'] + inv = l2.rpc.invoice(1, 'onchain_dust_out', 'desc') + rhash = inv['payment_hash'] routestep = { 'msatoshi': 1, 'id': l2.info['id'], @@ -1417,7 +1419,7 @@ def test_onchain_dust_out(node_factory, bitcoind, executor): 'channel': '1x1x1' } - l1.rpc.sendpay([routestep], rhash) + l1.rpc.sendpay([routestep], rhash, payment_secret=inv['payment_secret']) payfuture = executor.submit(l1.rpc.waitsendpay, rhash) # l1 will drop to chain. @@ -1437,7 +1439,7 @@ def test_onchain_dust_out(node_factory, bitcoind, executor): # Retry payment, this should fail (and, as a side-effect, tickle a # bug). with pytest.raises(RpcError, match=r'WIRE_UNKNOWN_NEXT_PEER'): - l1.rpc.sendpay([routestep], rhash) + l1.rpc.sendpay([routestep], rhash, payment_secret=inv['payment_secret']) # 6 later, l1 should collect its to-self payment. bitcoind.generate_block(6) @@ -1479,7 +1481,8 @@ def test_onchain_timeout(node_factory, bitcoind, executor): channel_id = first_channel_id(l1, l2) - rhash = l2.rpc.invoice(10**8, 'onchain_timeout', 'desc')['payment_hash'] + inv = l2.rpc.invoice(10**8, 'onchain_timeout', 'desc') + rhash = inv['payment_hash'] # We underpay, so it fails. routestep = { 'msatoshi': 10**8 - 1, @@ -1488,7 +1491,7 @@ def test_onchain_timeout(node_factory, bitcoind, executor): 'channel': '1x1x1' } - l1.rpc.sendpay([routestep], rhash) + l1.rpc.sendpay([routestep], rhash, payment_secret=inv['payment_secret']) with pytest.raises(RpcError): l1.rpc.waitsendpay(rhash) @@ -1497,7 +1500,7 @@ def test_onchain_timeout(node_factory, bitcoind, executor): sync_blockheight(bitcoind, [l1]) # Second one will cause drop to chain. - l1.rpc.sendpay([routestep], rhash) + l1.rpc.sendpay([routestep], rhash, payment_secret=inv['payment_secret']) payfuture = executor.submit(l1.rpc.waitsendpay, rhash) # l1 will drop to chain. @@ -1575,7 +1578,8 @@ def test_onchain_middleman(node_factory, bitcoind): l2.pay(l1, 2 * 10**8) # Must be bigger than dust! - rhash = l3.rpc.invoice(10**8, 'middleman', 'desc')['payment_hash'] + inv = l3.rpc.invoice(10**8, 'middleman', 'desc') + rhash = inv['payment_hash'] route = l1.rpc.getroute(l3.info['id'], 10**8, 1)["route"] assert len(route) == 2 @@ -1584,7 +1588,7 @@ def test_onchain_middleman(node_factory, bitcoind): def try_pay(): try: - l1.rpc.sendpay(route, rhash) + l1.rpc.sendpay(route, rhash, payment_secret=inv['payment_secret']) l1.rpc.waitsendpay(rhash) q.put(None) except Exception as err: @@ -1665,7 +1669,8 @@ def test_onchain_middleman_their_unilateral_in(node_factory, bitcoind): l2.pay(l1, 2 * 10**8) # Must be bigger than dust! - rhash = l3.rpc.invoice(10**8, 'middleman', 'desc')['payment_hash'] + inv = l3.rpc.invoice(10**8, 'middleman', 'desc') + rhash = inv['payment_hash'] route = l1.rpc.getroute(l3.info['id'], 10**8, 1)["route"] assert len(route) == 2 @@ -1674,7 +1679,7 @@ def test_onchain_middleman_their_unilateral_in(node_factory, bitcoind): def try_pay(): try: - l1.rpc.sendpay(route, rhash) + l1.rpc.sendpay(route, rhash, payment_secret=inv['payment_secret']) l1.rpc.waitsendpay(rhash) q.put(None) except Exception as err: @@ -1743,9 +1748,9 @@ def test_onchain_their_unilateral_out(node_factory, bitcoind): def try_pay(): try: - # rhash is fake + # rhash is fake (so is payment_secret) rhash = 'B1' * 32 - l1.rpc.sendpay(route, rhash) + l1.rpc.sendpay(route, rhash, payment_secret=rhash) q.put(None) except Exception as err: q.put(err) @@ -1834,7 +1839,8 @@ def test_onchain_feechange(node_factory, bitcoind, executor): } ]) - rhash = l2.rpc.invoice(10**8, 'onchain_timeout', 'desc')['payment_hash'] + inv = l2.rpc.invoice(10**8, 'onchain_timeout', 'desc') + rhash = inv['payment_hash'] # We underpay, so it fails. routestep = { 'msatoshi': 10**8 - 1, @@ -1843,7 +1849,7 @@ def test_onchain_feechange(node_factory, bitcoind, executor): 'channel': '1x1x1' } - executor.submit(l1.rpc.sendpay, [routestep], rhash) + executor.submit(l1.rpc.sendpay, [routestep], rhash, payment_secret=inv['payment_secret']) # l2 will drop to chain. l2.daemon.wait_for_log('permfail') @@ -1917,7 +1923,8 @@ def test_onchain_all_dust(node_factory, bitcoind, executor): l1.fundchannel(l2, 10**6) channel_id = first_channel_id(l1, l2) - rhash = l2.rpc.invoice(10**8, 'onchain_timeout', 'desc')['payment_hash'] + inv = l2.rpc.invoice(10**8, 'onchain_timeout', 'desc') + rhash = inv['payment_hash'] # We underpay, so it fails. routestep = { 'msatoshi': 10**7 - 1, @@ -1926,7 +1933,7 @@ def test_onchain_all_dust(node_factory, bitcoind, executor): 'channel': '1x1x1' } - executor.submit(l1.rpc.sendpay, [routestep], rhash) + executor.submit(l1.rpc.sendpay, [routestep], rhash, payment_secret=inv['payment_secret']) # l2 will drop to chain. l2.daemon.wait_for_log('permfail') @@ -2088,19 +2095,20 @@ def setup_multihtlc_test(node_factory, bitcoind): nodes[-1].rpc.dev_ignore_htlcs(id=nodes[-2].info['id'], ignore=True) preimage = "0" * 64 - h = nodes[0].rpc.invoice(msatoshi=10**8, label='x', description='desc', - preimage=preimage)['payment_hash'] + inv = nodes[0].rpc.invoice(msatoshi=10**8, label='x', description='desc', + preimage=preimage) + h = inv['payment_hash'] nodes[-1].rpc.invoice(msatoshi=10**8, label='x', description='desc', preimage=preimage)['payment_hash'] # First, the failed attempts (paying wrong node). CLTV1 r = nodes[0].rpc.getroute(nodes[-2].info['id'], 10**8, 1)["route"] - nodes[0].rpc.sendpay(r, h) + nodes[0].rpc.sendpay(r, h, payment_secret=inv['payment_secret']) with pytest.raises(RpcError, match=r'INCORRECT_OR_UNKNOWN_PAYMENT_DETAILS'): nodes[0].rpc.waitsendpay(h) r = nodes[-1].rpc.getroute(nodes[1].info['id'], 10**8, 1)["route"] - nodes[-1].rpc.sendpay(r, h) + nodes[-1].rpc.sendpay(r, h, payment_secret=inv['payment_secret']) with pytest.raises(RpcError, match=r'INCORRECT_OR_UNKNOWN_PAYMENT_DETAILS'): nodes[-1].rpc.waitsendpay(h) @@ -2110,25 +2118,25 @@ def setup_multihtlc_test(node_factory, bitcoind): # Now, the live attempts with CLTV2 (blackholed by end nodes) r = nodes[0].rpc.getroute(nodes[-1].info['id'], 10**8, 1)["route"] - nodes[0].rpc.sendpay(r, h) + nodes[0].rpc.sendpay(r, h, payment_secret=inv['payment_secret']) r = nodes[-1].rpc.getroute(nodes[0].info['id'], 10**8, 1)["route"] - nodes[-1].rpc.sendpay(r, h) + nodes[-1].rpc.sendpay(r, h, payment_secret=inv['payment_secret']) # We send second HTLC from different node, since they refuse to send # multiple with same hash. r = nodes[1].rpc.getroute(nodes[-1].info['id'], 10**8, 1)["route"] - nodes[1].rpc.sendpay(r, h) + nodes[1].rpc.sendpay(r, h, payment_secret=inv['payment_secret']) r = nodes[-2].rpc.getroute(nodes[0].info['id'], 10**8, 1)["route"] - nodes[-2].rpc.sendpay(r, h) + nodes[-2].rpc.sendpay(r, h, payment_secret=inv['payment_secret']) # Now increment CLTV -> CLTV3. bitcoind.generate_block(1) sync_blockheight(bitcoind, nodes) r = nodes[2].rpc.getroute(nodes[-1].info['id'], 10**8, 1)["route"] - nodes[2].rpc.sendpay(r, h) + nodes[2].rpc.sendpay(r, h, payment_secret=inv['payment_secret']) r = nodes[-3].rpc.getroute(nodes[0].info['id'], 10**8, 1)["route"] - nodes[-3].rpc.sendpay(r, h) + nodes[-3].rpc.sendpay(r, h, payment_secret=inv['payment_secret']) # Make sure HTLCs have reached the end. nodes[0].daemon.wait_for_logs(['peer_in WIRE_UPDATE_ADD_HTLC'] * 3) diff --git a/tests/test_connection.py b/tests/test_connection.py index 9db21ac9f..631a9d799 100644 --- a/tests/test_connection.py +++ b/tests/test_connection.py @@ -668,21 +668,22 @@ def test_reconnect_sender_add1(node_factory): l1.fundchannel(l2, 10**6) amt = 200000000 - rhash = l2.rpc.invoice(amt, 'test_reconnect_sender_add1', 'desc')['payment_hash'] + inv = l2.rpc.invoice(amt, 'test_reconnect_sender_add1', 'desc') + rhash = inv['payment_hash'] assert only_one(l2.rpc.listinvoices('test_reconnect_sender_add1')['invoices'])['status'] == 'unpaid' route = [{'msatoshi': amt, 'id': l2.info['id'], 'delay': 5, 'channel': '1x1x1'}] for i in range(0, len(disconnects)): with pytest.raises(RpcError): - l1.rpc.sendpay(route, rhash) + l1.rpc.sendpay(route, rhash, payment_secret=inv['payment_secret']) l1.rpc.waitsendpay(rhash) # Wait for reconnection. l1.daemon.wait_for_log('Already have funding locked in') # This will send commit, so will reconnect as required. - l1.rpc.sendpay(route, rhash) + l1.rpc.sendpay(route, rhash, payment_secret=inv['payment_secret']) @pytest.mark.developer @@ -708,13 +709,14 @@ def test_reconnect_sender_add(node_factory): l1.fundchannel(l2, 10**6) amt = 200000000 - rhash = l2.rpc.invoice(amt, 'testpayment', 'desc')['payment_hash'] + inv = l2.rpc.invoice(amt, 'testpayment', 'desc') + rhash = inv['payment_hash'] assert only_one(l2.rpc.listinvoices('testpayment')['invoices'])['status'] == 'unpaid' route = [{'msatoshi': amt, 'id': l2.info['id'], 'delay': 5, 'channel': '1x1x1'}] # This will send commit, so will reconnect as required. - l1.rpc.sendpay(route, rhash) + l1.rpc.sendpay(route, rhash, payment_secret=inv['payment_secret']) # Should have printed this for every reconnect. for i in range(0, len(disconnects)): l1.daemon.wait_for_log('Already have funding locked in') @@ -743,11 +745,12 @@ def test_reconnect_receiver_add(node_factory): l1.fundchannel(l2, 10**6) amt = 200000000 - rhash = l2.rpc.invoice(amt, 'testpayment2', 'desc')['payment_hash'] + inv = l2.rpc.invoice(amt, 'testpayment2', 'desc') + rhash = inv['payment_hash'] assert only_one(l2.rpc.listinvoices('testpayment2')['invoices'])['status'] == 'unpaid' route = [{'msatoshi': amt, 'id': l2.info['id'], 'delay': 5, 'channel': '1x1x1'}] - l1.rpc.sendpay(route, rhash) + l1.rpc.sendpay(route, rhash, payment_secret=inv['payment_secret']) for i in range(len(disconnects)): l1.daemon.wait_for_log('Already have funding locked in') assert only_one(l2.rpc.listinvoices('testpayment2')['invoices'])['status'] == 'paid' @@ -775,11 +778,12 @@ def test_reconnect_receiver_fulfill(node_factory): l1.fundchannel(l2, 10**6) amt = 200000000 - rhash = l2.rpc.invoice(amt, 'testpayment2', 'desc')['payment_hash'] + inv = l2.rpc.invoice(amt, 'testpayment2', 'desc') + rhash = inv['payment_hash'] assert only_one(l2.rpc.listinvoices('testpayment2')['invoices'])['status'] == 'unpaid' route = [{'msatoshi': amt, 'id': l2.info['id'], 'delay': 5, 'channel': '1x1x1'}] - l1.rpc.sendpay(route, rhash) + l1.rpc.sendpay(route, rhash, payment_secret=inv['payment_secret']) for i in range(len(disconnects)): l1.daemon.wait_for_log('Already have funding locked in') assert only_one(l2.rpc.listinvoices('testpayment2')['invoices'])['status'] == 'paid' @@ -2980,7 +2984,7 @@ def test_restart_many_payments(node_factory, bitcoind): wait_for(lambda: [c['public'] for c in n.rpc.listchannels()['channels']] == [True] * len(nodes) * 2) # Manually create routes, get invoices - Payment = namedtuple('Payment', ['innode', 'route', 'payment_hash']) + Payment = namedtuple('Payment', ['innode', 'route', 'payment_hash', 'payment_secret']) to_pay = [] for i in range(len(innodes)): @@ -2993,8 +2997,9 @@ def test_restart_many_payments(node_factory, bitcoind): 'id': outnodes[i].info['id'], 'delay': 5, 'channel': outchans[i]}] - payment_hash = outnodes[i].rpc.invoice(100000000, "invoice", "invoice")['payment_hash'] - to_pay.append(Payment(innodes[i], route, payment_hash)) + inv = outnodes[i].rpc.invoice(100000000, "invoice", "invoice") + payment_hash = inv['payment_hash'] + to_pay.append(Payment(innodes[i], route, payment_hash, inv['payment_secret'])) # This one should be routed through to the outnode. route = [{'msatoshi': 100001001, @@ -3005,12 +3010,13 @@ def test_restart_many_payments(node_factory, bitcoind): 'id': outnodes[i].info['id'], 'delay': 5, 'channel': outchans[i]}] - payment_hash = outnodes[i].rpc.invoice(100000000, "invoice2", "invoice2")['payment_hash'] - to_pay.append(Payment(innodes[i], route, payment_hash)) + inv = outnodes[i].rpc.invoice(100000000, "invoice2", "invoice2") + payment_hash = inv['payment_hash'] + to_pay.append(Payment(innodes[i], route, payment_hash, inv['payment_secret'])) # sendpay is async. for p in to_pay: - p.innode.rpc.sendpay(p.route, p.payment_hash) + p.innode.rpc.sendpay(p.route, p.payment_hash, p.payment_secret) # Now restart l1 while traffic is flowing... l1.restart() @@ -3247,14 +3253,15 @@ def test_pay_disconnect_stress(node_factory, executor): routel2l1 = [{'msatoshi': '10000msat', 'id': l1.info['id'], 'delay': 5, 'channel': scid12}] # Get invoice from l1 to pay. - payhash1 = l1.rpc.invoice(10000, "invoice", "invoice")['payment_hash'] + inv = l1.rpc.invoice(10000, "invoice", "invoice") + payhash1 = inv['payment_hash'] # Start balancing payment. fut = executor.submit(l1.pay, l2, 10**9 // 2) # As soon as reverse payment is accepted, reconnect. while True: - l2.rpc.sendpay(routel2l1, payhash1) + l2.rpc.sendpay(routel2l1, payhash1, payment_secret=inv['payment_secret']) try: # This will usually fail with Capacity exceeded l2.rpc.waitsendpay(payhash1, timeout=TIMEOUT) @@ -3406,7 +3413,7 @@ def test_htlc_retransmit_order(node_factory, executor): '=WIRE_UPDATE_ADD_HTLC*' + str(NUM_HTLCS - 1), '-WIRE_COMMITMENT_SIGNED']}, {'may_reconnect': True}]) - payment_hashes = [l2.rpc.invoice(1000, str(x), str(x))['payment_hash'] for x in range(NUM_HTLCS)] + invoices = [l2.rpc.invoice(1000, str(x), str(x)) for x in range(NUM_HTLCS)] routestep = { 'msatoshi': 1000, @@ -3414,8 +3421,8 @@ def test_htlc_retransmit_order(node_factory, executor): 'delay': 5, 'channel': '1x1x1' # note: can be bogus for 1-hop direct payments } - for p in payment_hashes: - executor.submit(l1.rpc.sendpay, [routestep], p) + for inv in invoices: + executor.submit(l1.rpc.sendpay, [routestep], inv['payment_hash'], payment_secret=inv['payment_secret']) l1.daemon.wait_for_logs(['dev_disconnect'] * 2) l1.rpc.call('dev-reenable-commit', [l2.info['id']]) @@ -3424,8 +3431,8 @@ def test_htlc_retransmit_order(node_factory, executor): # Now reconnect. l1.rpc.connect(l2.info['id'], 'localhost', port=l2.port) - for p in payment_hashes: - result = l1.rpc.waitsendpay(p) + for inv in invoices: + result = l1.rpc.waitsendpay(inv['payment_hash']) assert(result['status'] == 'complete') # If order was wrong, we'll get a LOG_BROKEN and fixtures will complain. @@ -3631,7 +3638,7 @@ def test_upgrade_statickey_fail(node_factory, executor, bitcoind): 'disconnect': l2_disconnects}]) # This HTLC will fail - l1.rpc.sendpay([{'msatoshi': 1000, 'id': l2.info['id'], 'delay': 5, 'channel': '1x1x1'}], '00' * 32) + l1.rpc.sendpay([{'msatoshi': 1000, 'id': l2.info['id'], 'delay': 5, 'channel': '1x1x1'}], '00' * 32, payment_secret='00' * 32) # Each one should cause one disconnection, no upgrade. for d in l1_disconnects + l2_disconnects[:-1]: @@ -3681,7 +3688,7 @@ def test_htlc_failed_noclose(node_factory): """Test a bug where the htlc timeout would kick in even if the HTLC failed""" l1, l2 = node_factory.line_graph(2) - payment_hash = l2.rpc.invoice(1000, "test", "test")['payment_hash'] + inv = l2.rpc.invoice(1000, "test", "test") routestep = { 'msatoshi': FUNDAMOUNT * 1000, 'id': l2.info['id'], @@ -3690,14 +3697,14 @@ def test_htlc_failed_noclose(node_factory): } # This fails at channeld - l1.rpc.sendpay([routestep], payment_hash) + l1.rpc.sendpay([routestep], inv['payment_hash'], payment_secret=inv['payment_secret']) with pytest.raises(RpcError, match="Capacity exceeded"): - l1.rpc.waitsendpay(payment_hash) + l1.rpc.waitsendpay(inv['payment_hash']) # Send a second one, too: make sure we don't crash. - l1.rpc.sendpay([routestep], payment_hash) + l1.rpc.sendpay([routestep], inv['payment_hash'], payment_secret=inv['payment_secret']) with pytest.raises(RpcError, match="Capacity exceeded"): - l1.rpc.waitsendpay(payment_hash) + l1.rpc.waitsendpay(inv['payment_hash']) time.sleep(35) assert l1.rpc.getpeer(l2.info['id'])['connected'] diff --git a/tests/test_misc.py b/tests/test_misc.py index 4e76c847f..71ac07417 100644 --- a/tests/test_misc.py +++ b/tests/test_misc.py @@ -1700,7 +1700,7 @@ def test_bad_onion(node_factory, bitcoind): l1, l2, l3, l4 = node_factory.line_graph(4, wait_for_announce=True, opts={'log-level': 'io'}) - h = l4.rpc.invoice(123000, 'test_bad_onion', 'description')['payment_hash'] + inv = l4.rpc.invoice(123000, 'test_bad_onion', 'description') route = l1.rpc.getroute(l4.info['id'], 123000, 1)['route'] assert len(route) == 3 @@ -1709,9 +1709,9 @@ def test_bad_onion(node_factory, bitcoind): # Replace id with a different pubkey, so onion encoded badly at third hop. route[2]['id'] = mangled_nodeid - l1.rpc.sendpay(route, h) + l1.rpc.sendpay(route, inv['payment_hash'], payment_secret=inv['payment_secret']) with pytest.raises(RpcError) as err: - l1.rpc.waitsendpay(h) + l1.rpc.waitsendpay(inv['payment_hash']) # FIXME: #define PAY_TRY_OTHER_ROUTE 204 PAY_TRY_OTHER_ROUTE = 204 @@ -1733,9 +1733,9 @@ def test_bad_onion(node_factory, bitcoind): # Replace id with a different pubkey, so onion encoded badly at second hop. route[1]['id'] = mangled_nodeid - l1.rpc.sendpay(route, h) + l1.rpc.sendpay(route, inv['payment_hash'], payment_secret=inv['payment_secret']) with pytest.raises(RpcError) as err: - l1.rpc.waitsendpay(h) + l1.rpc.waitsendpay(inv['payment_hash']) # FIXME: #define PAY_TRY_OTHER_ROUTE 204 PAY_TRY_OTHER_ROUTE = 204 @@ -1750,13 +1750,13 @@ def test_bad_onion_immediate_peer(node_factory, bitcoind): """Test that we handle the malformed msg when we're the origin""" l1, l2 = node_factory.line_graph(2, opts={'dev-fail-process-onionpacket': None}) - h = l2.rpc.invoice(123000, 'test_bad_onion_immediate_peer', 'description')['payment_hash'] + inv = l2.rpc.invoice(123000, 'test_bad_onion_immediate_peer', 'description') route = l1.rpc.getroute(l2.info['id'], 123000, 1)['route'] assert len(route) == 1 - l1.rpc.sendpay(route, h) + l1.rpc.sendpay(route, inv['payment_hash'], payment_secret=inv['payment_secret']) with pytest.raises(RpcError) as err: - l1.rpc.waitsendpay(h) + l1.rpc.waitsendpay(inv['payment_hash']) # FIXME: #define PAY_UNPARSEABLE_ONION 202 PAY_UNPARSEABLE_ONION = 202 @@ -2478,14 +2478,14 @@ def test_listforwards(node_factory, bitcoind): l1.rpc.pay(i41['bolt11']) # failed payment - failed_payment_hash = l3.rpc.invoice(4000, 'failed', 'desc')['payment_hash'] + failed_inv = l3.rpc.invoice(4000, 'failed', 'desc') failed_route = l1.rpc.getroute(l3.info['id'], 4000, 1)['route'] l2.rpc.close(c23, 1) with pytest.raises(RpcError): - l1.rpc.sendpay(failed_route, failed_payment_hash) - l1.rpc.waitsendpay(failed_payment_hash) + l1.rpc.sendpay(failed_route, failed_inv['payment_hash'], payment_secret=failed_inv['payment_secret']) + l1.rpc.waitsendpay(failed_inv['payment_hash']) all_forwards = l2.rpc.listforwards()['forwards'] print(json.dumps(all_forwards, indent=True)) @@ -2493,7 +2493,7 @@ def test_listforwards(node_factory, bitcoind): assert len(all_forwards) == 3 assert i31['payment_hash'] in map(lambda x: x['payment_hash'], all_forwards) assert i41['payment_hash'] in map(lambda x: x['payment_hash'], all_forwards) - assert failed_payment_hash in map(lambda x: x['payment_hash'], all_forwards) + assert failed_inv['payment_hash'] in map(lambda x: x['payment_hash'], all_forwards) # status=settled settled_forwards = l2.rpc.listforwards(status='settled')['forwards'] diff --git a/tests/test_pay.py b/tests/test_pay.py index 997a588de..dcf683990 100644 --- a/tests/test_pay.py +++ b/tests/test_pay.py @@ -228,7 +228,7 @@ def test_pay0(node_factory): } # Amount must be nonzero! - l1.rpc.sendpay([routestep], rhash) + l1.rpc.sendpay([routestep], rhash, payment_secret=inv['payment_secret']) with pytest.raises(RpcError, match=r'WIRE_AMOUNT_BELOW_MINIMUM'): l1.rpc.waitsendpay(rhash) @@ -256,7 +256,7 @@ def test_pay_disconnect(node_factory, bitcoind): # Can't pay while its offline. with pytest.raises(RpcError, match=r'failed: WIRE_TEMPORARY_CHANNEL_FAILURE \(First peer not ready\)'): - l1.rpc.sendpay(route, rhash) + l1.rpc.sendpay(route, rhash, payment_secret=inv['payment_secret']) l2.start() l1.daemon.wait_for_log('peer_out WIRE_CHANNEL_REESTABLISH') @@ -275,7 +275,7 @@ def test_pay_disconnect(node_factory, bitcoind): # Should fail due to permenant channel fail with pytest.raises(RpcError, match=r'WIRE_UNKNOWN_NEXT_PEER'): - l1.rpc.sendpay(route, rhash) + l1.rpc.sendpay(route, rhash, payment_secret=inv['payment_secret']) assert not l1.daemon.is_in_log('Payment is still in progress') @@ -512,7 +512,8 @@ def test_sendpay(node_factory): l1, l2 = node_factory.line_graph(2, fundamount=10**6) amt = 200000000 - rhash = l2.rpc.invoice(amt, 'testpayment2', 'desc')['payment_hash'] + inv = l2.rpc.invoice(amt, 'testpayment2', 'desc') + rhash = inv['payment_hash'] def invoice_unpaid(dst, label): invoices = dst.rpc.listinvoices(label)['invoices'] @@ -533,7 +534,7 @@ def test_sendpay(node_factory): with pytest.raises(RpcError): rs = copy.deepcopy(routestep) rs['msatoshi'] = rs['msatoshi'] - 1 - l1.rpc.sendpay([rs], rhash) + l1.rpc.sendpay([rs], rhash, payment_secret=inv['payment_secret']) l1.rpc.waitsendpay(rhash) assert invoice_unpaid(l2, 'testpayment2') @@ -541,7 +542,7 @@ def test_sendpay(node_factory): with pytest.raises(RpcError): rs = copy.deepcopy(routestep) rs['msatoshi'] = rs['msatoshi'] * 2 + 1 - l1.rpc.sendpay([rs], rhash) + l1.rpc.sendpay([rs], rhash, payment_secret=inv['payment_secret']) l1.rpc.waitsendpay(rhash) assert invoice_unpaid(l2, 'testpayment2') @@ -549,7 +550,7 @@ def test_sendpay(node_factory): with pytest.raises(RpcError): rs = copy.deepcopy(routestep) rs['delay'] = rs['delay'] - 2 - l1.rpc.sendpay([rs], rhash) + l1.rpc.sendpay([rs], rhash, payment_secret=inv['payment_secret']) l1.rpc.waitsendpay(rhash) assert invoice_unpaid(l2, 'testpayment2') @@ -557,7 +558,7 @@ def test_sendpay(node_factory): with pytest.raises(RpcError): rs = copy.deepcopy(routestep) rs['id'] = '00000000000000000000000000000000' - l1.rpc.sendpay([rs], rhash) + l1.rpc.sendpay([rs], rhash, payment_secret=inv['payment_secret']) assert invoice_unpaid(l2, 'testpayment2') # FIXME: test paying via another node, should fail to pay twice. @@ -570,7 +571,7 @@ def test_sendpay(node_factory): # This works. before = int(time.time()) - details = l1.rpc.sendpay([routestep], rhash) + details = l1.rpc.sendpay([routestep], rhash, payment_secret=inv['payment_secret']) after = int(time.time()) preimage = l1.rpc.waitsendpay(rhash)['payment_preimage'] # Check details @@ -599,7 +600,7 @@ def test_sendpay(node_factory): # Repeat will "succeed", but won't actually send anything (duplicate) assert not l1.daemon.is_in_log('Payment 0/1: .* COMPLETE') - details = l1.rpc.sendpay([routestep], rhash) + details = l1.rpc.sendpay([routestep], rhash, payment_secret=inv['payment_secret']) assert details['status'] == "complete" preimage2 = details['payment_preimage'] assert preimage == preimage2 @@ -608,10 +609,11 @@ def test_sendpay(node_factory): assert only_one(l2.rpc.listinvoices('testpayment2')['invoices'])['msatoshi_received'] == rs['msatoshi'] # Overpaying by "only" a factor of 2 succeeds. - rhash = l2.rpc.invoice(amt, 'testpayment3', 'desc')['payment_hash'] + inv = l2.rpc.invoice(amt, 'testpayment3', 'desc') + rhash = inv['payment_hash'] assert only_one(l2.rpc.listinvoices('testpayment3')['invoices'])['status'] == 'unpaid' routestep = {'msatoshi': amt * 2, 'id': l2.info['id'], 'delay': 5, 'channel': '1x1x1'} - l1.rpc.sendpay([routestep], rhash) + l1.rpc.sendpay([routestep], rhash, payment_secret=inv['payment_secret']) preimage3 = l1.rpc.waitsendpay(rhash)['payment_preimage'] assert only_one(l2.rpc.listinvoices('testpayment3')['invoices'])['status'] == 'paid' assert only_one(l2.rpc.listinvoices('testpayment3')['invoices'])['msatoshi_received'] == amt * 2 @@ -1030,7 +1032,8 @@ def test_forward(node_factory, bitcoind): assert only_one(l2.rpc.getpeer(l1.info['id'])['channels'])['short_channel_id'] == chanid1 assert only_one(l3.rpc.getpeer(l2.info['id'])['channels'])['short_channel_id'] == chanid2 - rhash = l3.rpc.invoice(100000000, 'testpayment1', 'desc')['payment_hash'] + inv = l3.rpc.invoice(100000000, 'testpayment1', 'desc') + rhash = inv['payment_hash'] assert only_one(l3.rpc.listinvoices('testpayment1')['invoices'])['status'] == 'unpaid' # Fee for node2 is 10 millionths, plus 1. @@ -1049,27 +1052,27 @@ def test_forward(node_factory, bitcoind): # Unknown other peer route = copy.deepcopy(baseroute) route[1]['id'] = '031a8dc444e41bb989653a4501e11175a488a57439b0c4947704fd6e3de5dca607' - l1.rpc.sendpay(route, rhash) + l1.rpc.sendpay(route, rhash, payment_secret=inv['payment_secret']) with pytest.raises(RpcError): l1.rpc.waitsendpay(rhash) # Delay too short (we always add one internally anyway, so subtract 2 here). route = copy.deepcopy(baseroute) route[0]['delay'] = 8 - l1.rpc.sendpay(route, rhash) + l1.rpc.sendpay(route, rhash, payment_secret=inv['payment_secret']) with pytest.raises(RpcError): l1.rpc.waitsendpay(rhash) # Final delay too short route = copy.deepcopy(baseroute) route[1]['delay'] = 3 - l1.rpc.sendpay(route, rhash) + l1.rpc.sendpay(route, rhash, payment_secret=inv['payment_secret']) with pytest.raises(RpcError): l1.rpc.waitsendpay(rhash) # This one works route = copy.deepcopy(baseroute) - l1.rpc.sendpay(route, rhash) + l1.rpc.sendpay(route, rhash, payment_secret=inv['payment_secret']) l1.rpc.waitsendpay(rhash) @@ -1181,11 +1184,12 @@ def test_forward_different_fees_and_cltv(node_factory, bitcoind): assert route[1]['msatoshi'] == 4999999 assert route[1]['delay'] == 9 + shadow_route - rhash = l3.rpc.invoice(4999999, 'test_forward_different_fees_and_cltv', 'desc')['payment_hash'] + inv = l3.rpc.invoice(4999999, 'test_forward_different_fees_and_cltv', 'desc') + rhash = inv['payment_hash'] assert only_one(l3.rpc.listinvoices('test_forward_different_fees_and_cltv')['invoices'])['status'] == 'unpaid' # This should work. - l1.rpc.sendpay(route, rhash) + l1.rpc.sendpay(route, rhash, payment_secret=inv['payment_secret']) l1.rpc.waitsendpay(rhash) # We add one to the blockcount for a bit of fuzz (FIXME: Shadowroute would fix this!) @@ -1254,8 +1258,9 @@ def test_forward_pad_fees_and_cltv(node_factory, bitcoind): route[1]['delay'] += 10 # This should work. - rhash = l3.rpc.invoice(4999999, 'test_forward_pad_fees_and_cltv', 'desc')['payment_hash'] - l1.rpc.sendpay(route, rhash) + inv = l3.rpc.invoice(4999999, 'test_forward_pad_fees_and_cltv', 'desc') + rhash = inv['payment_hash'] + l1.rpc.sendpay(route, rhash, payment_secret=inv['payment_secret']) l1.rpc.waitsendpay(rhash) assert only_one(l3.rpc.listinvoices('test_forward_pad_fees_and_cltv')['invoices'])['status'] == 'paid' @@ -1282,24 +1287,26 @@ def test_forward_stats(node_factory, bitcoind): wait_for(lambda: len(l1.rpc.listchannels()['channels']) == 8) - payment_hash = l3.rpc.invoice(amount, "first", "desc")['payment_hash'] + inv = l3.rpc.invoice(amount, "first", "desc") + payment_hash = inv['payment_hash'] route = l1.rpc.getroute(l3.info['id'], amount, 1)['route'] - l1.rpc.sendpay(route, payment_hash) + l1.rpc.sendpay(route, payment_hash, payment_secret=inv['payment_secret']) l1.rpc.waitsendpay(payment_hash) # l4 rejects since it doesn't know the payment_hash route = l1.rpc.getroute(l4.info['id'], amount, 1)['route'] payment_hash = "F" * 64 with pytest.raises(RpcError): - l1.rpc.sendpay(route, payment_hash) + l1.rpc.sendpay(route, payment_hash, payment_secret=inv['payment_secret']) l1.rpc.waitsendpay(payment_hash) # l5 will hold the HTLC hostage. l5.rpc.dev_ignore_htlcs(id=l2.info['id'], ignore=True) route = l1.rpc.getroute(l5.info['id'], amount, 1)['route'] - payment_hash = l5.rpc.invoice(amount, "first", "desc")['payment_hash'] - l1.rpc.sendpay(route, payment_hash) + inv = l5.rpc.invoice(amount, "first", "desc") + payment_hash = inv['payment_hash'] + l1.rpc.sendpay(route, payment_hash, payment_secret=inv['payment_secret']) l5.daemon.wait_for_log(r'their htlc .* dev_ignore_htlcs') @@ -1420,13 +1427,14 @@ def test_forward_local_failed_stats(node_factory, bitcoind, executor): because of WIRE_UNKNOWN_NEXT_PEER; """ - payment_hash = l3.rpc.invoice(amount, "first", "desc")['payment_hash'] + inv = l3.rpc.invoice(amount, "first", "desc") + payment_hash = inv['payment_hash'] route = l1.rpc.getroute(l3.info['id'], amount, 1)['route'] l2.rpc.close(c23, 1) with pytest.raises(RpcError): - l1.rpc.sendpay(route, payment_hash) + l1.rpc.sendpay(route, payment_hash, payment_secret=inv['payment_secret']) l1.rpc.waitsendpay(payment_hash) """2. When Master handle the forward process with the htlc_in and @@ -1437,7 +1445,8 @@ def test_forward_local_failed_stats(node_factory, bitcoind, executor): payment will fail in l2 becase of WIRE_FEE_INSUFFICIENT; """ - payment_hash = l4.rpc.invoice(amount, "third", "desc")['payment_hash'] + inv = l4.rpc.invoice(amount, "third", "desc") + payment_hash = inv['payment_hash'] fee = amount * 10 // 1000000 + 1 route = [{'msatoshi': amount, @@ -1450,7 +1459,7 @@ def test_forward_local_failed_stats(node_factory, bitcoind, executor): 'channel': c24}] with pytest.raises(RpcError): - l1.rpc.sendpay(route, payment_hash) + l1.rpc.sendpay(route, payment_hash, payment_secret=inv['payment_secret']) l1.rpc.waitsendpay(payment_hash) """3. When we send htlc_out, Master asks Channeld to add a new htlc @@ -1462,7 +1471,8 @@ def test_forward_local_failed_stats(node_factory, bitcoind, executor): fail in l2 because of CHANNEL_ERR_MAX_HTLC_VALUE_EXCEEDED; """ - payment_hash = l5.rpc.invoice(amount, "second", "desc")['payment_hash'] + inv = l5.rpc.invoice(amount, "second", "desc") + payment_hash = inv['payment_hash'] fee = amount * 10 // 1000000 + 1 route = [{'msatoshi': amount + fee, @@ -1475,7 +1485,7 @@ def test_forward_local_failed_stats(node_factory, bitcoind, executor): 'channel': c25}] with pytest.raises(RpcError): - l1.rpc.sendpay(route, payment_hash) + l1.rpc.sendpay(route, payment_hash, payment_secret=inv['payment_secret']) l1.rpc.waitsendpay(payment_hash) """4. When Channeld receives a new revoke message, if the state of @@ -1488,7 +1498,8 @@ def test_forward_local_failed_stats(node_factory, bitcoind, executor): fail in l2 because of WIRE_INVALID_ONION_KEY; """ - payment_hash = l4.rpc.invoice(amount, 'fourth', 'desc')['payment_hash'] + inv = l4.rpc.invoice(amount, 'fourth', 'desc') + payment_hash = inv['payment_hash'] route = l6.rpc.getroute(l4.info['id'], amount, 1)['route'] mangled_nodeid = '0265b6ab5ec860cd257865d61ef0bbf5b3339c36cbda8b26b74e7f1dca490b6510' @@ -1497,7 +1508,7 @@ def test_forward_local_failed_stats(node_factory, bitcoind, executor): route[1]['id'] = mangled_nodeid with pytest.raises(RpcError): - l6.rpc.sendpay(route, payment_hash) + l6.rpc.sendpay(route, payment_hash, payment_secret=inv['payment_secret']) l6.rpc.waitsendpay(payment_hash) """5. When Onchaind finds the htlc time out or missing htlc, Master @@ -1509,7 +1520,8 @@ def test_forward_local_failed_stats(node_factory, bitcoind, executor): before sending update_fail_htlc, so the htlc will be holding until l2 meets timeout and handle it as local_fail. """ - payment_hash = l4.rpc.invoice(amount, 'onchain_timeout', 'desc')['payment_hash'] + inv = l4.rpc.invoice(amount, 'onchain_timeout', 'desc') + payment_hash = inv['payment_hash'] fee = amount * 10 // 1000000 + 1 # We underpay, so it fails. @@ -1522,7 +1534,7 @@ def test_forward_local_failed_stats(node_factory, bitcoind, executor): 'delay': 5, 'channel': c24}] - executor.submit(l1.rpc.sendpay, route, payment_hash) + executor.submit(l1.rpc.sendpay, route, payment_hash, payment_secret=inv['payment_secret']) l4.daemon.wait_for_log('permfail') l4.wait_for_channel_onchain(l2.info['id']) @@ -1568,12 +1580,13 @@ def test_htlcs_cltv_only_difference(node_factory, bitcoind): # l3 will see a reconnect from l4 when l4 restarts. l1, l2, l3, l4 = node_factory.line_graph(4, wait_for_announce=True, opts=[{}] * 2 + [{'dev-no-reconnect': None, 'may_reconnect': True}] * 2) - h = l4.rpc.invoice(msatoshi=10**8, label='x', description='desc')['payment_hash'] + inv = l4.rpc.invoice(msatoshi=10**8, label='x', description='desc') + h = inv['payment_hash'] l4.rpc.dev_ignore_htlcs(id=l3.info['id'], ignore=True) # L2 tries to pay r = l2.rpc.getroute(l4.info['id'], 10**8, 1)["route"] - l2.rpc.sendpay(r, h) + l2.rpc.sendpay(r, h, payment_secret=inv['payment_secret']) # Now increment CLTV bitcoind.generate_block(1) @@ -1581,7 +1594,7 @@ def test_htlcs_cltv_only_difference(node_factory, bitcoind): # L1 tries to pay r = l1.rpc.getroute(l4.info['id'], 10**8, 1)["route"] - l1.rpc.sendpay(r, h) + l1.rpc.sendpay(r, h, payment_secret=inv['payment_secret']) # Now increment CLTV bitcoind.generate_block(1) @@ -1589,7 +1602,7 @@ def test_htlcs_cltv_only_difference(node_factory, bitcoind): # L3 tries to pay r = l3.rpc.getroute(l4.info['id'], 10**8, 1)["route"] - l3.rpc.sendpay(r, h) + l3.rpc.sendpay(r, h, payment_secret=inv['payment_secret']) # Give them time to go through. time.sleep(5) @@ -1656,7 +1669,7 @@ def test_pay_retry(node_factory, bitcoind, executor, chainparams): 'delay': 10, 'channel': scid } - opener.rpc.sendpay([routestep], inv['payment_hash']) + opener.rpc.sendpay([routestep], inv['payment_hash'], payment_secret=inv['payment_secret']) opener.rpc.waitsendpay(inv['payment_hash']) # We connect every node to l5; in a line and individually. @@ -2240,12 +2253,13 @@ def test_channel_spendable(node_factory, bitcoind): l1, l2 = node_factory.line_graph(2, fundamount=sats, wait_for_announce=True, opts={'plugin': os.path.join(os.getcwd(), 'tests/plugins/hold_invoice.py'), 'holdtime': '30'}) - payment_hash = l2.rpc.invoice('any', 'inv', 'for testing')['payment_hash'] + inv = l2.rpc.invoice('any', 'inv', 'for testing') + payment_hash = inv['payment_hash'] # We should be able to spend this much, and not one msat more! amount = l1.rpc.listpeers()['peers'][0]['channels'][0]['spendable_msat'] route = l1.rpc.getroute(l2.info['id'], amount + 1, riskfactor=1, fuzzpercent=0)['route'] - l1.rpc.sendpay(route, payment_hash) + l1.rpc.sendpay(route, payment_hash, payment_secret=inv['payment_secret']) # This should fail locally with "capacity exceeded" with pytest.raises(RpcError, match=r"Capacity exceeded.*'erring_index': 0"): @@ -2253,7 +2267,7 @@ def test_channel_spendable(node_factory, bitcoind): # Exact amount should succeed. route = l1.rpc.getroute(l2.info['id'], amount, riskfactor=1, fuzzpercent=0)['route'] - l1.rpc.sendpay(route, payment_hash) + l1.rpc.sendpay(route, payment_hash, payment_secret=inv['payment_secret']) # Amount should drop to 0 once HTLC is sent; we have time, thanks to # hold_invoice.py plugin. @@ -2264,12 +2278,13 @@ def test_channel_spendable(node_factory, bitcoind): # Make sure l2 thinks it's all over. wait_for(lambda: len(l2.rpc.listpeers()['peers'][0]['channels'][0]['htlcs']) == 0) # Now, reverse should work similarly. - payment_hash = l1.rpc.invoice('any', 'inv', 'for testing')['payment_hash'] + inv = l1.rpc.invoice('any', 'inv', 'for testing') + payment_hash = inv['payment_hash'] amount = l2.rpc.listpeers()['peers'][0]['channels'][0]['spendable_msat'] # Turns out we won't route this, as it's over max - reserve: route = l2.rpc.getroute(l1.info['id'], amount + 1, riskfactor=1, fuzzpercent=0)['route'] - l2.rpc.sendpay(route, payment_hash) + l2.rpc.sendpay(route, payment_hash, payment_secret=inv['payment_secret']) # This should fail locally with "capacity exceeded" with pytest.raises(RpcError, match=r"Capacity exceeded.*'erring_index': 0"): @@ -2277,7 +2292,7 @@ def test_channel_spendable(node_factory, bitcoind): # Exact amount should succeed. route = l2.rpc.getroute(l1.info['id'], amount, riskfactor=1, fuzzpercent=0)['route'] - l2.rpc.sendpay(route, payment_hash) + l2.rpc.sendpay(route, payment_hash, payment_secret=inv['payment_secret']) # Amount should drop to 0 once HTLC is sent; we have time, thanks to # hold_invoice.py plugin. @@ -2293,12 +2308,13 @@ def test_channel_receivable(node_factory, bitcoind): l1, l2 = node_factory.line_graph(2, fundamount=sats, wait_for_announce=True, opts={'plugin': os.path.join(os.getcwd(), 'tests/plugins/hold_invoice.py'), 'holdtime': '30'}) - payment_hash = l2.rpc.invoice('any', 'inv', 'for testing')['payment_hash'] + inv = l2.rpc.invoice('any', 'inv', 'for testing') + payment_hash = inv['payment_hash'] # We should be able to receive this much, and not one msat more! amount = l2.rpc.listpeers()['peers'][0]['channels'][0]['receivable_msat'] route = l1.rpc.getroute(l2.info['id'], amount + 1, riskfactor=1, fuzzpercent=0)['route'] - l1.rpc.sendpay(route, payment_hash) + l1.rpc.sendpay(route, payment_hash, payment_secret=inv['payment_secret']) # This should fail locally with "capacity exceeded" with pytest.raises(RpcError, match=r"Capacity exceeded.*'erring_index': 0"): @@ -2306,7 +2322,7 @@ def test_channel_receivable(node_factory, bitcoind): # Exact amount should succeed. route = l1.rpc.getroute(l2.info['id'], amount, riskfactor=1, fuzzpercent=0)['route'] - l1.rpc.sendpay(route, payment_hash) + l1.rpc.sendpay(route, payment_hash, payment_secret=inv['payment_secret']) # Amount should drop to 0 once HTLC is sent; we have time, thanks to # hold_invoice.py plugin. @@ -2317,12 +2333,13 @@ def test_channel_receivable(node_factory, bitcoind): # Make sure l2 thinks it's all over. wait_for(lambda: len(l2.rpc.listpeers()['peers'][0]['channels'][0]['htlcs']) == 0) # Now, reverse should work similarly. - payment_hash = l1.rpc.invoice('any', 'inv', 'for testing')['payment_hash'] + inv = l1.rpc.invoice('any', 'inv', 'for testing') + payment_hash = inv['payment_hash'] amount = l1.rpc.listpeers()['peers'][0]['channels'][0]['receivable_msat'] # Turns out we won't route this, as it's over max - reserve: route = l2.rpc.getroute(l1.info['id'], amount + 1, riskfactor=1, fuzzpercent=0)['route'] - l2.rpc.sendpay(route, payment_hash) + l2.rpc.sendpay(route, payment_hash, payment_secret=inv['payment_secret']) # This should fail locally with "capacity exceeded" with pytest.raises(RpcError, match=r"Capacity exceeded.*'erring_index': 0"): @@ -2330,7 +2347,7 @@ def test_channel_receivable(node_factory, bitcoind): # Exact amount should succeed. route = l2.rpc.getroute(l1.info['id'], amount, riskfactor=1, fuzzpercent=0)['route'] - l2.rpc.sendpay(route, payment_hash) + l2.rpc.sendpay(route, payment_hash, payment_secret=inv['payment_secret']) # Amount should drop to 0 once HTLC is sent; we have time, thanks to # hold_invoice.py plugin. @@ -2354,7 +2371,8 @@ def test_channel_spendable_large(node_factory, bitcoind): } ) - payment_hash = l2.rpc.invoice('any', 'inv', 'for testing')['payment_hash'] + inv = l2.rpc.invoice('any', 'inv', 'for testing') + payment_hash = inv['payment_hash'] # We should be able to spend this much, and not one msat more! spendable = l1.rpc.listpeers()['peers'][0]['channels'][0]['spendable_msat'] @@ -2366,12 +2384,12 @@ def test_channel_spendable_large(node_factory, bitcoind): # route or waitsendpay fill fail. with pytest.raises(RpcError): route = l1.rpc.getroute(l2.info['id'], spendable + 1, riskfactor=1, fuzzpercent=0)['route'] - l1.rpc.sendpay(route, payment_hash) + l1.rpc.sendpay(route, payment_hash, payment_secret=inv['payment_secret']) l1.rpc.waitsendpay(payment_hash, TIMEOUT) # Exact amount should succeed. route = l1.rpc.getroute(l2.info['id'], spendable, riskfactor=1, fuzzpercent=0)['route'] - l1.rpc.sendpay(route, payment_hash) + l1.rpc.sendpay(route, payment_hash, payment_secret=inv['payment_secret']) l1.rpc.waitsendpay(payment_hash, TIMEOUT) @@ -2417,7 +2435,7 @@ def test_error_returns_blockheight(node_factory, bitcoind): 'id': l2.info['id'], 'delay': 10, 'channel': l1.get_channel_scid(l2)}], - '00' * 32) + '00' * 32, payment_secret='00' * 32) with pytest.raises(RpcError, match=r"INCORRECT_OR_UNKNOWN_PAYMENT_DETAILS.*'erring_index': 1") as err: l1.rpc.waitsendpay('00' * 32, TIMEOUT) @@ -2925,18 +2943,18 @@ caused a crash in 0.8.0, so we then disallowed it. with pytest.raises(RpcError, match=r'Do not specify msatoshi \(1001msat\) without' ' partid: if you do, it must be exactly' r' the final amount \(1000msat\)'): - l1.rpc.sendpay(route=l1.rpc.getroute(l2.info['id'], 1000, 1)['route'], payment_hash=inv['payment_hash'], msatoshi=1001, bolt11=inv['bolt11']) + l1.rpc.sendpay(route=l1.rpc.getroute(l2.info['id'], 1000, 1)['route'], payment_hash=inv['payment_hash'], msatoshi=1001, bolt11=inv['bolt11'], payment_secret=inv['payment_secret']) with pytest.raises(RpcError, match=r'Do not specify msatoshi \(999msat\) without' ' partid: if you do, it must be exactly' r' the final amount \(1000msat\)'): - l1.rpc.sendpay(route=l1.rpc.getroute(l2.info['id'], 1000, 1)['route'], payment_hash=inv['payment_hash'], msatoshi=999, bolt11=inv['bolt11']) + l1.rpc.sendpay(route=l1.rpc.getroute(l2.info['id'], 1000, 1)['route'], payment_hash=inv['payment_hash'], msatoshi=999, bolt11=inv['bolt11'], payment_secret=inv['payment_secret']) # Can't send MPP payment which pays any more than amount. with pytest.raises(RpcError, match=r'Final amount 1001msat is greater than 1000msat, despite MPP'): - l1.rpc.sendpay(route=l1.rpc.getroute(l2.info['id'], 1001, 1)['route'], payment_hash=inv['payment_hash'], msatoshi=1000, bolt11=inv['bolt11'], partid=1) + l1.rpc.sendpay(route=l1.rpc.getroute(l2.info['id'], 1001, 1)['route'], payment_hash=inv['payment_hash'], msatoshi=1000, bolt11=inv['bolt11'], partid=1, payment_secret=inv['payment_secret']) # But this works - l1.rpc.sendpay(route=l1.rpc.getroute(l2.info['id'], 1001, 1)['route'], payment_hash=inv['payment_hash'], msatoshi=1001, bolt11=inv['bolt11']) + l1.rpc.sendpay(route=l1.rpc.getroute(l2.info['id'], 1001, 1)['route'], payment_hash=inv['payment_hash'], msatoshi=1001, bolt11=inv['bolt11'], payment_secret=inv['payment_secret']) l1.rpc.waitsendpay(inv['payment_hash']) inv = only_one(l2.rpc.listinvoices('inv')['invoices']) @@ -3017,7 +3035,7 @@ def test_sendpay_blinding(node_factory): 'style': 'tlv'}] l1.rpc.sendpay(route=route, payment_hash=inv['payment_hash'], - bolt11=inv['bolt11']) + bolt11=inv['bolt11'], payment_secret=inv['payment_secret']) l1.rpc.waitsendpay(inv['payment_hash']) diff --git a/tests/test_plugin.py b/tests/test_plugin.py index 5ad43a318..342e4381e 100644 --- a/tests/test_plugin.py +++ b/tests/test_plugin.py @@ -1001,13 +1001,14 @@ def test_htlc_accepted_hook_fail(node_factory): ], wait_for_announce=True) # This must fail - phash = l2.rpc.invoice(1000, "lbl", "desc")['payment_hash'] + inv = l2.rpc.invoice(1000, "lbl", "desc") + phash = inv['payment_hash'] route = l1.rpc.getroute(l2.info['id'], 1000, 1)['route'] # Here shouldn't use `pay` command because l2 rejects with WIRE_TEMPORARY_NODE_FAILURE, # then it will be excluded when l1 try another pay attempt. # Note if the destination is excluded, the route result is undefined. - l1.rpc.sendpay(route, phash) + l1.rpc.sendpay(route, phash, payment_secret=inv['payment_secret']) with pytest.raises(RpcError) as excinfo: l1.rpc.waitsendpay(phash) assert excinfo.value.error['data']['failcode'] == 0x2002 @@ -1231,22 +1232,24 @@ def test_forward_event_notification(node_factory, bitcoind, executor): wait_for(lambda: len(l1.rpc.listchannels()['channels']) == 8) - payment_hash13 = l3.rpc.invoice(amount, "first", "desc")['payment_hash'] + inv = l3.rpc.invoice(amount, "first", "desc") + payment_hash13 = inv['payment_hash'] route = l1.rpc.getroute(l3.info['id'], amount, 1)['route'] # status: offered -> settled - l1.rpc.sendpay(route, payment_hash13) + l1.rpc.sendpay(route, payment_hash13, payment_secret=inv['payment_secret']) l1.rpc.waitsendpay(payment_hash13) # status: offered -> failed route = l1.rpc.getroute(l4.info['id'], amount, 1)['route'] payment_hash14 = "f" * 64 with pytest.raises(RpcError): - l1.rpc.sendpay(route, payment_hash14) + l1.rpc.sendpay(route, payment_hash14, payment_secret="f" * 64) l1.rpc.waitsendpay(payment_hash14) # status: offered -> local_failed - payment_hash15 = l5.rpc.invoice(amount, 'onchain_timeout', 'desc')['payment_hash'] + inv = l5.rpc.invoice(amount, 'onchain_timeout', 'desc') + payment_hash15 = inv['payment_hash'] fee = amount * 10 // 1000000 + 1 c12 = l1.get_channel_scid(l2) c25 = l2.get_channel_scid(l5) @@ -1259,7 +1262,7 @@ def test_forward_event_notification(node_factory, bitcoind, executor): 'delay': 5, 'channel': c25}] - executor.submit(l1.rpc.sendpay, route, payment_hash15) + executor.submit(l1.rpc.sendpay, route, payment_hash15, payment_secret=inv['payment_secret']) l5.daemon.wait_for_log('permfail') l5.wait_for_channel_onchain(l2.info['id']) @@ -1320,16 +1323,18 @@ def test_sendpay_notifications(node_factory, bitcoind): l1, l2, l3 = node_factory.line_graph(3, opts=opts, wait_for_announce=True) chanid23 = l2.get_channel_scid(l3) - payment_hash1 = l3.rpc.invoice(amount, "first", "desc")['payment_hash'] - payment_hash2 = l3.rpc.invoice(amount, "second", "desc")['payment_hash'] + inv1 = l3.rpc.invoice(amount, "first", "desc") + payment_hash1 = inv1['payment_hash'] + inv2 = l3.rpc.invoice(amount, "second", "desc") + payment_hash2 = inv2['payment_hash'] route = l1.rpc.getroute(l3.info['id'], amount, 1)['route'] - l1.rpc.sendpay(route, payment_hash1) + l1.rpc.sendpay(route, payment_hash1, payment_secret=inv1['payment_secret']) response1 = l1.rpc.waitsendpay(payment_hash1) l2.rpc.close(chanid23, 1) - l1.rpc.sendpay(route, payment_hash2) + l1.rpc.sendpay(route, payment_hash2, payment_secret=inv2['payment_secret']) with pytest.raises(RpcError) as err: l1.rpc.waitsendpay(payment_hash2) @@ -1349,16 +1354,18 @@ def test_sendpay_notifications_nowaiter(node_factory): chanid23 = l2.get_channel_scid(l3) amount = 10**8 - payment_hash1 = l3.rpc.invoice(amount, "first", "desc")['payment_hash'] - payment_hash2 = l3.rpc.invoice(amount, "second", "desc")['payment_hash'] + inv1 = l3.rpc.invoice(amount, "first", "desc") + payment_hash1 = inv1['payment_hash'] + inv2 = l3.rpc.invoice(amount, "second", "desc") + payment_hash2 = inv2['payment_hash'] route = l1.rpc.getroute(l3.info['id'], amount, 1)['route'] - l1.rpc.sendpay(route, payment_hash1) + l1.rpc.sendpay(route, payment_hash1, payment_secret=inv1['payment_secret']) l1.daemon.wait_for_log(r'Received a sendpay_success') l2.rpc.close(chanid23, 1) - l1.rpc.sendpay(route, payment_hash2) + l1.rpc.sendpay(route, payment_hash2, payment_secret=inv2['payment_secret']) l1.daemon.wait_for_log(r'Received a sendpay_failure') results = l1.rpc.call('listsendpays_plugin') @@ -1980,36 +1987,40 @@ def test_coin_movement_notices(node_factory, bitcoind, chainparams): wait_for(lambda: len(l1.rpc.listchannels()['channels']) == 4) amount = 10**8 - payment_hash13 = l3.rpc.invoice(amount, "first", "desc")['payment_hash'] + inv = l3.rpc.invoice(amount, "first", "desc") + payment_hash13 = inv['payment_hash'] route = l1.rpc.getroute(l3.info['id'], amount, 1)['route'] # status: offered -> settled - l1.rpc.sendpay(route, payment_hash13) + l1.rpc.sendpay(route, payment_hash13, payment_secret=inv['payment_secret']) l1.rpc.waitsendpay(payment_hash13) # status: offered -> failed route = l1.rpc.getroute(l3.info['id'], amount, 1)['route'] payment_hash13 = "f" * 64 with pytest.raises(RpcError): - l1.rpc.sendpay(route, payment_hash13) + l1.rpc.sendpay(route, payment_hash13, payment_secret=inv['payment_secret']) l1.rpc.waitsendpay(payment_hash13) # go the other direction - payment_hash31 = l1.rpc.invoice(amount // 2, "first", "desc")['payment_hash'] + inv = l1.rpc.invoice(amount // 2, "first", "desc") + payment_hash31 = inv['payment_hash'] route = l3.rpc.getroute(l1.info['id'], amount // 2, 1)['route'] - l3.rpc.sendpay(route, payment_hash31) + l3.rpc.sendpay(route, payment_hash31, payment_secret=inv['payment_secret']) l3.rpc.waitsendpay(payment_hash31) # receive a payment (endpoint) - payment_hash12 = l2.rpc.invoice(amount, "first", "desc")['payment_hash'] + inv = l2.rpc.invoice(amount, "first", "desc") + payment_hash12 = inv['payment_hash'] route = l1.rpc.getroute(l2.info['id'], amount, 1)['route'] - l1.rpc.sendpay(route, payment_hash12) + l1.rpc.sendpay(route, payment_hash12, payment_secret=inv['payment_secret']) l1.rpc.waitsendpay(payment_hash12) # send a payment (originator) - payment_hash21 = l1.rpc.invoice(amount // 2, "second", "desc")['payment_hash'] + inv = l1.rpc.invoice(amount // 2, "second", "desc") + payment_hash21 = inv['payment_hash'] route = l2.rpc.getroute(l1.info['id'], amount // 2, 1)['route'] - l2.rpc.sendpay(route, payment_hash21) + l2.rpc.sendpay(route, payment_hash21, payment_secret=inv['payment_secret']) l2.rpc.waitsendpay(payment_hash21) # restart to test index