From ca204eacfafcc1f739e85ac66b474c11f2176006 Mon Sep 17 00:00:00 2001 From: Christian Decker Date: Wed, 6 Jan 2021 18:48:53 +0100 Subject: [PATCH] pytest: Reproduce waitblockheight timeout issue #4309 --- tests/plugins/endlesswaitblockheight.py | 22 ++++++++++++++++++++++ tests/test_pay.py | 19 +++++++++++++++++++ 2 files changed, 41 insertions(+) create mode 100755 tests/plugins/endlesswaitblockheight.py diff --git a/tests/plugins/endlesswaitblockheight.py b/tests/plugins/endlesswaitblockheight.py new file mode 100755 index 000000000..78dc2c65a --- /dev/null +++ b/tests/plugins/endlesswaitblockheight.py @@ -0,0 +1,22 @@ +#!/usr/bin/env python3 +"""Simple plugin to cause a waitblockheight that times out. + +We report an error with a future blockheight, which causes the sender +to wait, and ultimately retry, excluding us because we misbehaved. + +""" + + +from pyln.client import Plugin +plugin = Plugin() + + +@plugin.hook('htlc_accepted') +def on_htlc_accepted(onion, htlc, **kwargs): + return { + 'result': "fail", + "failure_message": "400f00000000000000007fffffff", # Bogus error with INT32_MAX as blockheight + } + + +plugin.run() diff --git a/tests/test_pay.py b/tests/test_pay.py index 392d757f4..cef792f88 100644 --- a/tests/test_pay.py +++ b/tests/test_pay.py @@ -3933,3 +3933,22 @@ def test_fetchinvoice(node_factory, bitcoind): l1.rpc.call('fetchinvoice', {'offer': offer, 'recurrence_counter': 2, 'recurrence_label': 'test recurrence'}) + + +@pytest.mark.xfail(strict=True) +def test_pay_waitblockheight_timeout(node_factory, bitcoind): + plugin = os.path.join(os.path.dirname(__file__), 'plugins', 'endlesswaitblockheight.py') + l1, l2 = node_factory.line_graph(2, opts=[{}, {'plugin': plugin}]) + + sync_blockheight(bitcoind, [l1, l2]) + inv = l2.rpc.invoice(42, 'lbl', 'desc')['bolt11'] + + with pytest.raises(RpcError, match=r'WIRE_INCORRECT_OR_UNKNOWN_PAYMENT_DETAILS'): + l1.rpc.pay(inv) + + # Post mortem checks that we tried only once. + status = l1.rpc.paystatus(inv) + + # Should have only one attempt that triggered the wait, which then failed. + assert len(status['pay']) == 1 + assert len(status['pay'][0]['attempts']) == 1