Enforce that the splice initiator set a non-zero funding contribution
What changed, and why it matters
This commit adds a check in the Lightning Dev Kit's channel code to reject splice attempts where the party initiating the splice contributes zero new funds. Previously, such a zero-contribution splice could be accepted, which may have allowed a peer to trigger invalid or unintended splice state transitions. The fix disconnects the peer with a warning when this happens.
Treat as a low-to-moderate hardening fix. Review the full splice flow for additional missing validation, add regression tests for zero and negative contributions, and complete the noted TODO reserve checks before enabling splicing in production.
Security signals we found
Missing input validation on a peer-controlled field (funding_contribution_satoshis) before state transition
Peer-triggered error path now disconnects with warning, indicating a protocol-violating condition
Splicing is an advanced, less-audited code path in Lightning implementations
Patch is partial: adjacent TODO notes additional reserve checks are still unimplemented
Evidence from the diff
In lightning/src/ln/channel.rs, a new guard is inserted in the splice negotiation path: if the remote peer is the splice initiator and msg.funding_contribution_satoshis is zero, the node now returns ChannelError::WarnAndDisconnect before calling validate_splice_contribution. This enforces the protocol invariant that a splice initiator must add or remove funds (non-zero contribution). The patch is small and defensive; it does not include tests or documentation describing a specific exploitable outcome.
Changed components
lightning/src/ln/channel.rsLDK splice negotiation / interactive-tx flowInspect captured patch +7 / −0
diff --git a/lightning/src/ln/channel.rs b/lightning/src/ln/channel.rs
index cc8b0d0..0f3285a 100644
--- a/lightning/src/ln/channel.rs
+++ b/lightning/src/ln/channel.rs
@@ -11302,6 +11302,13 @@ where
}
let their_funding_contribution = SignedAmount::from_sat(msg.funding_contribution_satoshis);
+ if their_funding_contribution == SignedAmount::ZERO {
+ return Err(ChannelError::WarnAndDisconnect(format!(
+ "Channel {} cannot be spliced; they are the initiator, and their contribution is zero",
+ self.context.channel_id(),
+ )));
+ }
+
self.validate_splice_contribution(their_funding_contribution)?;
// TODO(splicing): Check that channel balance does not go below the channel reserve
Why this scored 49/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.