pytest: test for bcli crash with huge PSBTs.
What changed, and why it matters
This commit adds a test that checks whether Core Lightning's bitcoin backend plugin (bcli) crashes when handling very large transactions. The test is marked as expected to fail for now, meaning the underlying crash bug is known but not yet fixed. It does not itself change production code.
Treat this as a regression-test commit for a known issue. A separate fix for bcli's handling of very large PSBTs should be developed and the xfail marker removed once the crash is resolved. Review bcli memory allocation and RPC response handling paths for large PSBTs.
Security signals we found
Denial-of-service vector: large PSBT may crash the bitcoin backend plugin
Test-only commit documenting a known crash condition
No production patch or mitigation present in this commit
Evidence from the diff
The diff adds a pytest test, test_bitcoin_backend_gianttx, which creates 700 bech32 addresses, funds them in one transaction, then withdraws all funds to produce a large PSBT. The test is decorated with @pytest.mark.xfail(strict=True), indicating it documents a reproducible crash in bcli when processing huge PSBTs. No fix or production code change is included.
Changed components
tests/test_plugin.pybcli (bitcoin backend plugin) - indirectly, by the new regression testInspect captured patch +17 / −0
diff --git a/tests/test_plugin.py b/tests/test_plugin.py
index bc3e6c9..314e436 100644
--- a/tests/test_plugin.py
+++ b/tests/test_plugin.py
@@ -1875,6 +1875,23 @@ def test_bitcoin_backend(node_factory, bitcoind):
" bitcoind")
+@pytest.mark.xfail(strict=True)
+def test_bitcoin_backend_gianttx(node_factory, bitcoind):
+ """Test that a giant tx doesn't crash bcli"""
+ l1 = node_factory.get_node(start=False)
+ # With memleak we spend far too much time gathering backtraces.
+ if "LIGHTNINGD_DEV_MEMLEAK" in l1.daemon.env:
+ del l1.daemon.env["LIGHTNINGD_DEV_MEMLEAK"]
+ l1.start()
+ addrs = {addr: 0.00200000 for addr in [l1.rpc.newaddr('bech32')['bech32'] for _ in range(700)]}
+ bitcoind.rpc.sendmany("", addrs)
+ bitcoind.generate_block(1, wait_for_mempool=1)
+ sync_blockheight(bitcoind, [l1])
+
+ l1.rpc.withdraw(bitcoind.getnewaddress(), 'all')
+ bitcoind.generate_block(1, wait_for_mempool=1)
+
+
def test_bitcoin_bad_estimatefee(node_factory, bitcoind):
"""
This tests that we don't crash if bitcoind backend gives bad estimatefees.
Why this scored 34/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.