From 9fd8be64631b6ded5a028576751334a60c5ec887 Mon Sep 17 00:00:00 2001 From: Christian Decker Date: Fri, 11 Jan 2019 22:39:18 +0100 Subject: [PATCH] pytest: Add tests for htlc_accepted_hook Two tests: one for failures and one for in-path resolution. Signed-off-by: Christian Decker --- tests/plugins/fail_htlcs.py | 15 ++++++++++ tests/plugins/shortcircuit.py | 13 +++++++++ tests/test_plugin.py | 53 +++++++++++++++++++++++++++++++++++ 3 files changed, 81 insertions(+) create mode 100755 tests/plugins/fail_htlcs.py create mode 100755 tests/plugins/shortcircuit.py diff --git a/tests/plugins/fail_htlcs.py b/tests/plugins/fail_htlcs.py new file mode 100755 index 000000000..b925dff54 --- /dev/null +++ b/tests/plugins/fail_htlcs.py @@ -0,0 +1,15 @@ +#!/usr/bin/env python3 + +from lightning import Plugin + +plugin = Plugin() + + +@plugin.hook("htlc_accepted") +def on_htlc_accepted(htlc, onion, plugin): + plugin.log("Failing htlc on purpose") + plugin.log("onion: %r" % (onion)) + return {"result": "fail", "failure_code": 16399} + + +plugin.run() diff --git a/tests/plugins/shortcircuit.py b/tests/plugins/shortcircuit.py new file mode 100755 index 000000000..3696c721f --- /dev/null +++ b/tests/plugins/shortcircuit.py @@ -0,0 +1,13 @@ +#!/usr/bin/env python3 + +from lightning import Plugin + +plugin = Plugin() + + +@plugin.hook("htlc_accepted") +def on_htlc_accepted(onion, htlc, plugin): + return {"result": "resolve", "payment_key": "00" * 32} + + +plugin.run() diff --git a/tests/test_plugin.py b/tests/test_plugin.py index 32d043938..0b2bd1388 100644 --- a/tests/test_plugin.py +++ b/tests/test_plugin.py @@ -331,3 +331,56 @@ def test_openchannel_hook(node_factory, bitcoind): l1.connect(l2) with pytest.raises(RpcError, match=r"I don't like odd amounts"): l1.rpc.fundchannel(l2.info['id'], 100001) + + +def test_htlc_accepted_hook_fail(node_factory): + """Send payments from l1 to l2, but l2 just declines everything. + + l2 is configured with a plugin that'll hook into htlc_accepted and + always return failures. The same should also work for forwarded + htlcs in the second half. + + """ + l1, l2, l3 = node_factory.line_graph(3, opts=[ + {}, + {'plugin': 'tests/plugins/fail_htlcs.py'}, + {} + ], wait_for_announce=True) + + # This must fail + inv = l2.rpc.invoice(1000, "lbl", "desc")['bolt11'] + with pytest.raises(RpcError) as excinfo: + l1.rpc.pay(inv) + assert excinfo.value.error['data']['failcode'] == 16399 + assert excinfo.value.error['data']['erring_index'] == 1 + + # And the invoice must still be unpaid + inv = l2.rpc.listinvoices("lbl")['invoices'] + assert len(inv) == 1 and inv[0]['status'] == 'unpaid' + + # Now try with forwarded HTLCs: l2 should still fail them + # This must fail + inv = l3.rpc.invoice(1000, "lbl", "desc")['bolt11'] + with pytest.raises(RpcError) as excinfo: + l1.rpc.pay(inv) + + # And the invoice must still be unpaid + inv = l3.rpc.listinvoices("lbl")['invoices'] + assert len(inv) == 1 and inv[0]['status'] == 'unpaid' + + +def test_htlc_accepted_hook_resolve(node_factory): + """l3 creates an invoice, l2 knows the preimage and will shortcircuit. + """ + l1, l2, l3 = node_factory.line_graph(3, opts=[ + {}, + {'plugin': 'tests/plugins/shortcircuit.py'}, + {} + ], wait_for_announce=True) + + inv = l3.rpc.invoice(msatoshi=1000, label="lbl", description="desc", preimage="00" * 32)['bolt11'] + l1.rpc.pay(inv) + + # And the invoice must still be unpaid + inv = l3.rpc.listinvoices("lbl")['invoices'] + assert len(inv) == 1 and inv[0]['status'] == 'unpaid'