From 3d6c4e93b3d4f5e50a0c28ea07780cbb022d6565 Mon Sep 17 00:00:00 2001 From: Christian Decker Date: Wed, 9 Sep 2020 14:15:01 +0200 Subject: [PATCH] pytest: Add a test to reproduce #3748 --- tests/plugins/htlc_accepted-crash.py | 14 +++++++++++++ tests/test_plugin.py | 30 ++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) create mode 100755 tests/plugins/htlc_accepted-crash.py diff --git a/tests/plugins/htlc_accepted-crash.py b/tests/plugins/htlc_accepted-crash.py new file mode 100755 index 000000000..266174300 --- /dev/null +++ b/tests/plugins/htlc_accepted-crash.py @@ -0,0 +1,14 @@ +#!/usr/bin/env python3 +from pyln.client import Plugin + + +plugin = Plugin() + + +@plugin.hook('htlc_accepted') +def on_htlc_accepted(plugin, **kwargs): + plugin.log("Crashing on purpose...") + raise ValueError() + + +plugin.run() diff --git a/tests/test_plugin.py b/tests/test_plugin.py index f12e67b3c..9057b041b 100644 --- a/tests/test_plugin.py +++ b/tests/test_plugin.py @@ -1858,3 +1858,33 @@ def test_important_plugin(node_factory): def test_dev_builtin_plugins_unimportant(node_factory): n = node_factory.get_node(options={"dev-builtin-plugins-unimportant": None}) n.rpc.plugin_stop(plugin="pay") + + +@pytest.mark.xfail(strict=True) +def test_htlc_accepted_hook_crash(node_factory, executor): + """Test that we do not hang incoming HTLCs if the hook plugin crashes. + + Reproduces #3748. + """ + plugin = os.path.join(os.getcwd(), 'tests/plugins/htlc_accepted-crash.py') + l1 = node_factory.get_node() + l2 = node_factory.get_node( + options={'plugin': plugin}, + allow_broken_log=True + ) + l1.connect(l2) + l1.fund_channel(l2, 10**6) + + i = l2.rpc.invoice(500, "crashpls", "crashpls")['bolt11'] + + # This should still succeed + + f = executor.submit(l1.rpc.pay, i) + + l2.daemon.wait_for_log(r'Crashing on purpose...') + l2.daemon.wait_for_log( + r'Hook handler for htlc_accepted failed with an exception.' + ) + + with pytest.raises(RpcError, match=r'failed: WIRE_TEMPORARY_NODE_FAILURE'): + f.result(10)