pytest: test case where we crash before bitcoind gets the opening tx.
What changed, and why it matters
This commit only adds a new pytest test case. It does not change any production code. The test simulates a crash scenario during a Lightning channel opening to make sure the software handles it correctly in the future. It is marked as expected to fail (xfail), meaning it documents a known problem rather than fixing it.
No immediate action required. Treat as test-suite maintenance. If investigating the underlying issue, review the related bug report or follow-up fix that this xfail test is meant to guard against.
Security signals we found
No production code changes
Test-only commit
xfail marker indicates known unfixed behavior
Evidence from the diff
The diff adds a single test function, test_opening_crash, to tests/test_opening.py. The test mocks sendrawtransaction so the funding transaction is not broadcast, opens a channel, stops and restarts one node, then asks bitcoind to mine a block while waiting for the txid to appear in the mempool. The @pytest.mark.xfail(strict=True) decorator indicates the test is currently expected to fail, so this commit is a regression test for a not-yet-resolved bug.
Changed components
tests/test_opening.pyInspect captured patch +23 / −0
diff --git a/tests/test_opening.py b/tests/test_opening.py
index 805ed7ee..69e71a26 100644
--- a/tests/test_opening.py
+++ b/tests/test_opening.py
@@ -2825,3 +2825,26 @@ def test_opening_below_min_capacity_sat(bitcoind, node_factory):
# But we shouldn't have bothered l2
assert not l2.daemon.is_in_log('peer_in WIRE_ERROR')
+
+
+@pytest.mark.xfail(strict=True)
+@pytest.mark.openchannel('v1')
+@pytest.mark.openchannel('v2')
+def test_opening_crash(bitcoind, node_factory):
+ """Stop transmission of initial funding tx, check it eventually opens"""
+ l1, l2 = node_factory.get_nodes(2)
+
+ def censoring_sendrawtx(r):
+ return {'id': r['id'], 'result': {}}
+
+ l1.daemon.rpcproxy.mock_rpc('sendrawtransaction', censoring_sendrawtx)
+ l2.daemon.rpcproxy.mock_rpc('sendrawtransaction', censoring_sendrawtx)
+ l1.fundwallet(3_000_000)
+ l1.connect(l2)
+ txid = l1.rpc.fundchannel(l2.info['id'], "2000000sat")['txid']
+
+ l1.stop()
+ l1.daemon.rpcproxy.mock_rpc('sendrawtransaction', None)
+ l1.start()
+
+ bitcoind.generate_block(1, wait_for_mempool=txid)
Why this scored 11/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.