pytest: test for fetchinvoice when a onion-message-capable peer is disconnected.
What changed, and why it matters
This commit adds a new automated test to Core Lightning. The test checks that when a user tries to fetch a BOLT12 invoice through a peer that is currently disconnected, the software should not attempt to use that disconnected peer. The commit message shows the test previously failed with an 'unknown next peer' error, suggesting a bug where disconnected onion-message-capable peers were incorrectly selected as routing hops. This is a test-only change; no production code is patched here.
Treat this as a test-only commit that documents a bug. The actual fix for the 'unknown next peer' behavior when an onion-message-capable peer is disconnected must be located in a separate commit that updates the routing/peer-selection logic. Reviewers should run the new test and verify it passes only after the corresponding production fix is applied; if it still fails, the bug remains unpatched.
Security signals we found
Regression test for routing failure involving disconnected onion-message peers
Failure mode exposes peer public key in error message ('unknown next peer')
Potential denial-of-service or reliability issue if disconnected peers are selected as invoice-fetch paths
No production code change in this commit
Evidence from the diff
The diff adds a pytest test, test_fetchinvoice_autoconnect_if_disconnected, in tests/test_pay.py. It sets up a three-node line graph (l1-l2-l3), creates a BOLT12 offer on l3, fetches an invoice from l1 (which works while l2 is connected), then force-disconnects l2 from l1 and attempts fetchinvoice again. The test documents expected behavior: after disconnection, l1 should not try to route the onion message through l2. The commit message reproduces a prior failure: ‘onion msg: unknown next peer
Changed components
tests/test_pay.pyBOLT12 fetchinvoice RPConion message routingInspect captured patch +13 / −0
diff --git a/tests/test_pay.py b/tests/test_pay.py
index 5e26b7e4..899e6189 100644
--- a/tests/test_pay.py
+++ b/tests/test_pay.py
@@ -4784,6 +4784,19 @@ def test_fetchinvoice_autoconnect(node_factory, bitcoind):
assert l3.rpc.listpeers(l2.info['id'])['peers'] != []
+def test_fetchinvoice_autoconnect_if_disconnected(node_factory, bitcoind):
+ """If peer is disconnected, we should NOT try to use it"""
+ l1, l2, l3 = node_factory.line_graph(3, wait_for_announce=True,
+ opts={'dev-allow-localhost': None})
+
+ offer = l3.rpc.offer(amount='2msat', description='test_fetchinvoice_autoconnect_if_disconnected1')['bolt12']
+ l1.rpc.fetchinvoice(offer)
+
+ l1.rpc.disconnect(l2.info['id'], force=True)
+ l1.rpc.fetchinvoice(offer)
+
+
+@pytest.mark.xfail(strict=True)
def test_fetchinvoice_disconnected_reply(node_factory, bitcoind):
"""We ask for invoice, but reply path doesn't lead directly from recipient"""
l1, l2, l3 = node_factory.get_nodes(3,
Why this scored 26/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.