Fix empty witness filter in funding_transaction_signed
What changed, and why it matters
This commit fixes a simple but significant logic bug in the code that handles signed funding transactions for Lightning channels. The original code accidentally kept only empty witnesses (filtering for witness.is_empty()) instead of keeping the actual non-empty signatures (filtering for !witness.is_empty()). As a result, when a peer sent valid signatures to finalize a channel, the local node would receive an empty list and likely fail to complete the channel setup or produce an invalid transaction. This could disrupt channel opens and, in the worst case, be used to stall or deny service to a node, but it does not directly steal funds because the signatures themselves are still validated elsewhere.
Apply the patch. After applying, verify that channel funding completes successfully with non-empty witnesses and that empty witnesses are correctly ignored. Consider adding regression tests covering both empty and non-empty witness inputs to funding_transaction_signed.
Security signals we found
Logic inversion in witness filtering
Channel funding flow affected
Potential denial of service during channel establishment
No direct signature validation bypass evident from diff
Evidence from the diff
In lightning/src/ln/channelmanager.rs, funding_transaction_signed is called with a vector of witnesses collected from the funding transaction’s inputs. The bug used .filter(|witness| witness.is_empty()), which retained only empty witnesses. The fix changes the predicate to .filter(|witness| !witness.is_empty()), so that non-empty witnesses are passed to funding_transaction_signed. Empty witnesses are expected for non-witness inputs or placeholder entries; passing only empty ones means the channel’s funding transaction cannot be properly signed and finalized. The downstream code likely rejects or mishandles the empty vector, causing channel establishment to fail.
Changed components
lightning/src/ln/channelmanager.rsfunding_transaction_signed handlerLightning channel establishment (funding_signed path)Inspect captured patch +1 / −1
diff --git a/lightning/src/ln/channelmanager.rs b/lightning/src/ln/channelmanager.rs
index 6836965..6db55a5 100644
--- a/lightning/src/ln/channelmanager.rs
+++ b/lightning/src/ln/channelmanager.rs
@@ -5973,7 +5973,7 @@ where
.input
.into_iter()
.map(|input| input.witness)
- .filter(|witness| witness.is_empty())
+ .filter(|witness| !witness.is_empty())
.collect();
match chan.funding_transaction_signed(witnesses) {
Ok((Some(tx_signatures), funding_tx_opt)) => {
Why this scored 59/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.