pytest: explicitly test failed case exposed by race.
What changed, and why it matters
This commit only adds a new test case to the project's test suite. It does not change any production code. The test is marked as expected to fail (xfail) and documents a race condition where a second call to check a failed payment can return a different error code than the first call. There is no fix or security-relevant change to the software itself.
No immediate action required for security. Treat as a test-quality issue. If the underlying race is later determined to have security implications, a separate fix would be needed.
Security signals we found
No production code changed
Test-only commit
Race condition documented in test, not fixed
Expected-fail marker indicates known behavioral inconsistency
Evidence from the diff
The diff adds an @pytest.mark.xfail(strict=True) decorator to test_bad_onion_immediate_peer and extends the test to call waitsendpay a second time after the first failure. The commit message describes a flaky test caused by a race between sendpay resolution and waitsendpay invocation. The new assertion expects the same error code (PAY_UNPARSEABLE_ONION, 202) and failcode on the second call, but the test is marked xfail because the observed behavior returns 204 instead. No runtime code is modified.
Changed components
tests/test_misc.pyInspect captured patch +8 / −0
diff --git a/tests/test_misc.py b/tests/test_misc.py
index c7a69739..7d85942f 100644
--- a/tests/test_misc.py
+++ b/tests/test_misc.py
@@ -2135,6 +2135,7 @@ def test_bad_onion(node_factory, bitcoind):
assert err.value.error['data']['erring_channel'] == route[1]['channel']
+@pytest.mark.xfail(strict=True)
def test_bad_onion_immediate_peer(node_factory, bitcoind):
"""Test that we handle the malformed msg when we're the origin"""
l1, l2 = node_factory.line_graph(2, opts=[{}, {'dev-fail-process-onionpacket': None}])
@@ -2154,6 +2155,13 @@ def test_bad_onion_immediate_peer(node_factory, bitcoind):
WIRE_INVALID_ONION_HMAC = 0x8000 | 0x4000 | 5
assert err.value.error['data']['failcode'] == WIRE_INVALID_ONION_HMAC
+ # Asking again about the same payment should give same result.
+ with pytest.raises(RpcError) as err:
+ l1.rpc.waitsendpay(inv['payment_hash'])
+
+ assert err.value.error['code'] == PAY_UNPARSEABLE_ONION
+ assert err.value.error['data']['failcode'] == WIRE_INVALID_ONION_HMAC
+
# Same, but using injectpaymentonion with corrupt onion.
blockheight = l1.rpc.getinfo()['blockheight']
hops = [{'pubkey': l1.info['id'],
Why this scored 14/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.