The logs show that it doesn't exclude the routehint early: in successful runs we get "After filtering routehints we're left with 0 usable hints". Perhaps this is something to do with the timing of our own notifications?
``` 2026-01-07T05:51:10.7902502Z lightningd-1 2026-01-07T05:31:29.706Z DEBUG plugin-pay: cmd -c:pay#64/cln:pay#121 partid 0: Received getchaininfo blockcount=108, headercount=108 2026-01-07T05:51:10.7903334Z lightningd-1 2026-01-07T05:31:29.715Z DEBUG plugin-pay: cmd -c:pay#64/cln:pay#121 partid 0: waitblockheight reports syncheight=108 2026-01-07T05:51:10.7904256Z lightningd-1 2026-01-07T05:31:29.734Z DEBUG plugin-pay: cmd -c:pay#64/cln:pay#121 partid 0: Updated a channel hint for 103x2x0/1: enabled true, estimated capacity 978718000msat 2026-01-07T05:51:10.7905355Z lightningd-1 2026-01-07T05:31:29.734Z DEBUG plugin-pay: cmd -c:pay#64/cln:pay#121 partid 0: Updated a channel hint for 7269357x11669990x33910/1: enabled false, estimated capacity UNKNOWN 2026-01-07T05:51:10.7906580Z lightningd-1 2026-01-07T05:31:29.735Z DEBUG plugin-pay: cmd -c:pay#64/cln:pay#121 partid 0: Updated a channel hint for 103x2x0/1: enabled false, estimated capacity UNKNOWN 2026-01-07T05:51:10.7907665Z lightningd-1 2026-01-07T05:31:29.735Z INFO plugin-pay: cmd -c:pay#64/cln:pay#121 partid 0: Payment fee constraint 615msat is below exemption threshold, allowing a maximum fee of 5000msat 2026-01-07T05:51:10.7908845Z lightningd-1 2026-01-07T05:31:29.752Z DEBUG plugin-pay: Received a channel_hint {.scid = 103x2x0/1, .enabled = 1, .estimate = 978718000msat, .capacity = 1000000000msat } 2026-01-07T05:51:10.7909710Z lightningd-1 2026-01-07T05:31:29.754Z INFO plugin-pay: cmd -c:pay#64/cln:pay#121 partid 0: Filtering out 1 routehints 2026-01-07T05:51:10.7910544Z lightningd-1 2026-01-07T05:31:29.779Z DEBUG plugin-pay: cmd -c:pay#64/cln:pay#121 partid 0: Checking hint {.scid=103x2x0/1, .enabled=1, .estimate=978718000msat} 2026-01-07T05:51:10.7911470Z lightningd-1 2026-01-07T05:31:29.780Z DEBUG plugin-pay: cmd -c:pay#64/cln:pay#121 partid 0: After filtering routehints we're left with 1 usable hints 2026-01-07T05:51:10.7912385Z lightningd-1 2026-01-07T05:31:29.780Z DEBUG plugin-pay: cmd -c:pay#64/cln:pay#121 partid 0: Checking hint {.scid=103x2x0/1, .enabled=1, .estimate=978718000msat} 2026-01-07T05:51:10.7913471Z lightningd-1 2026-01-07T05:31:29.780Z DEBUG plugin-pay: cmd -c:pay#64/cln:pay#121 partid 0: Using routehint 022d223620a359a47ff7f7ac447c85c46c923da53389221a0054c11c1e3ca31d59 (103x1x0) cltv_delta=6 ```
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
✓ Descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context✓ Mentions testing or verification✓ Links an issue, advisory, or supporting reference
The short version
What changed, and why it matters
This commit only adds a test-flakiness workaround. It marks an existing test as flaky so the test suite will retry it if it fails. The underlying behavior being tested—a payment command sometimes ignoring an excluded route—was already known and labeled WONTFIX by the project. No production code was changed, and there is no indication this is treated as a security issue.
Recommended action
No security action needed. If the flaky behavior is concerning for operational reliability, consider investigating the `pay` plugin's handling of `exclude` and channel-hint timing, but this commit itself is only a test workaround.
Security signals we found
No strong security signals were identified.
Technical analysis
Evidence from the diff
The diff adds a single pytest decorator @pytest.mark.flaky(reruns=2) to test_pay_manual_exclude in tests/test_pay.py. The commit message explains that pay occasionally ignores the exclude list, causing the test to fail with ‘Ran out of routes to try’ instead of the expected ‘is not reachable directly and all routehints were unusable.’ The author speculates it may be a timing issue with notifications and marks it WONTFIX. No fix to the pay plugin or any other production code is included.
Changed components
tests/test_pay.py
Inspect captured patch +1 / −0
diff --git a/tests/test_pay.py b/tests/test_pay.py
index 1b35d509..c921b907 100644
--- a/tests/test_pay.py
+++ b/tests/test_pay.py
@@ -5255,6 +5255,7 @@ def test_sendpay_grouping(node_factory, bitcoind):
assert([p['status'] for p in pays] == ['failed', 'failed', 'complete'])
+@pytest.mark.flaky(reruns=2)
def test_pay_manual_exclude(node_factory, bitcoind):
l1, l2, l3 = node_factory.line_graph(3, wait_for_announce=True)
l1_id = l1.rpc.getinfo()['id']
This commit is a simple documentation revert. It undoes a previous change that told macOS users to install GNU make and GNU patch from Homebrew and to put those tools first in their command path. The reverted instructions now omit gpatch a…
This commit re-adds an old-style 'x' prefix to a string comparison in a test helper script. It is a test-only change with no effect on the actual Core Lightning node software, user funds, network behavior, or security. The change simply re…
This commit only updates macOS installation instructions in the documentation. It tells macOS users to install newer GNU versions of 'make' and 'patch' from Homebrew because Apple's built-in tools are too old for building and running sourc…