Fail commitment sig verification without counterparty params
What changed, and why it matters
This change adds a safety check in a Bitcoin Lightning Network library (LDK). Previously, if the software tried to verify a peer's commitment signature before it had learned the peer's channel parameters, it could crash with a panic. Now it logs an error and closes the channel gracefully instead. The commit message says this situation should never happen in normal operation, so this is defensive hardening against a potential peer-triggered crash.
Treat as a hardening fix. Review whether any other peer-driven paths assume counterparty_parameters is present and may panic similarly. No immediate incident response required unless crashes have been observed in the wild.
Security signals we found
Defensive check added on peer-driven code path to prevent panic
Missing counterparty_parameters could previously cause panic during commitment transaction construction
Channel closure returned instead of panic
Funding outpoint cleared for inbound channels before closing to avoid unsafe broadcast
Evidence from the diff
In rust-lightning’s channel.rs, two functions that verify commitment_signed signatures now check whether counterparty_parameters is set before proceeding. If missing, they emit a debug_assert!(false), log an error, clear the funding outpoint for inbound channels to avoid broadcasting a commitment for funding that may never be published, and return a ChannelError::close. This replaces a downstream panic that would occur when building the commitment transaction without the counterparty’s funding pubkey and contest delay.
Changed components
lightning/src/ln/channel.rsInitialRemoteCommitmentReceiver::initial_received_commitmentChannelContext::validate_commitment_signedInspect captured patch +24 / −0
### lightning/src/ln/channel.rs
@@ -3970,6 +3970,20 @@ trait InitialRemoteCommitmentReceiver<SP: SignerProvider> {
) -> Result<(ChannelMonitor<SP::EcdsaSigner>, CommitmentTransaction), ChannelError> {
let context = self.context();
+ if self.funding().channel_transaction_parameters.counterparty_parameters.is_none() {
+ debug_assert!(false);
+ log_error!(
+ logger,
+ "Missing counterparty channel parameters for channel {}, cannot verify the commitment sigs we were sent. This indicates a bug in LDK, please report it at https://github.com/lightningdevkit/rust-lightning/issues/new",
+ context.channel_id(),
+ );
+ // TODO(dual_funding): Update for V2 established channels.
+ if !self.funding().is_outbound() {
+ self.funding_mut().channel_transaction_parameters.funding_outpoint = None;
+ }
+ return Err(ChannelError::close("Received commitment failed validation".to_owned()));
+ }
+
let remote_commitment_data = context.build_commitment_transaction(
self.funding(),
context.counterparty_next_commitment_transaction_number,
@@ -6070,6 +6084,16 @@ impl<SP: SignerProvider> ChannelContext<SP> {
(HolderCommitmentTransaction, Vec<(HTLCOutputInCommitment, Option<&HTLCSource>)>),
ChannelError,
> {
+ if funding.channel_transaction_parameters.counterparty_parameters.is_none() {
+ debug_assert!(false);
+ log_error!(
+ logger,
+ "Missing counterparty channel parameters for channel {}, cannot verify the commitment sigs we were sent. This indicates a bug in LDK, please report it at https://github.com/lightningdevkit/rust-lightning/issues/new",
+ self.channel_id(),
+ );
+ return Err(ChannelError::close("Received commitment failed validation".to_owned()));
+ }
+
// If our counterparty updated the channel fee in this commitment transaction, check that
// they can actually afford the new fee now.
if let Some((new_feerate_per_kw, FeeUpdateState::RemoteAnnounced)) = self.pending_update_feeWhy this scored 54/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.