From 436112c1421b90e85062cf6ab610ed9a8be33d88 Mon Sep 17 00:00:00 2001 From: Jeffrey Czyz Date: Wed, 2 Jul 2025 15:30:44 -0500 Subject: [PATCH 1/5] Remove FundedChannel::pending_funding persistence FundedChannel::pending_funding is to be moved to PendingSplice. As such, it will be persisted with PendingSplice once persistence is added for the latter. --- lightning/src/ln/channel.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/lightning/src/ln/channel.rs b/lightning/src/ln/channel.rs index 09c9f5804fc..574925e5e95 100644 --- a/lightning/src/ln/channel.rs +++ b/lightning/src/ln/channel.rs @@ -12615,7 +12615,6 @@ where (49, self.context.local_initiated_shutdown, option), // Added in 0.0.122 (51, is_manual_broadcast, option), // Added in 0.0.124 (53, funding_tx_broadcast_safe_event_emitted, option), // Added in 0.0.124 - (54, self.pending_funding, optional_vec), // Added in 0.2 (55, removed_htlc_failure_attribution_data, optional_vec), // Added in 0.2 (57, holding_cell_failure_attribution_data, optional_vec), // Added in 0.2 (58, self.interactive_tx_signing_session, option), // Added in 0.2 @@ -12979,7 +12978,6 @@ where (49, local_initiated_shutdown, option), (51, is_manual_broadcast, option), (53, funding_tx_broadcast_safe_event_emitted, option), - (54, pending_funding, optional_vec), // Added in 0.2 (55, removed_htlc_failure_attribution_data, optional_vec), (57, holding_cell_failure_attribution_data, optional_vec), (58, interactive_tx_signing_session, option), // Added in 0.2 From ed7834559db3021357ca15271277b6c217e1a8f5 Mon Sep 17 00:00:00 2001 From: Jeffrey Czyz Date: Wed, 2 Jul 2025 15:52:33 -0500 Subject: [PATCH 2/5] Move FundedChannel::pending_funding into PendingSplice FundedChannel::pending_funding and FundedChannel::pending_splice were developed independently, but the former will only contain values when the latter is set. --- lightning/src/ln/channel.rs | 138 +++++++++++++++++++++++------------- 1 file changed, 88 insertions(+), 50 deletions(-) diff --git a/lightning/src/ln/channel.rs b/lightning/src/ln/channel.rs index 574925e5e95..e196d51d7b3 100644 --- a/lightning/src/ln/channel.rs +++ b/lightning/src/ln/channel.rs @@ -1807,7 +1807,6 @@ where }; let mut funded_channel = FundedChannel { funding: chan.funding, - pending_funding: vec![], context: chan.context, interactive_tx_signing_session: chan.interactive_tx_signing_session, holder_commitment_point, @@ -2179,6 +2178,7 @@ impl FundingScope { struct PendingSplice { pub our_funding_contribution: i64, funding: Option, + pending_funding: Vec, /// The funding txid used in the `splice_locked` sent to the counterparty. sent_funding_txid: Option, @@ -2190,11 +2190,14 @@ struct PendingSplice { #[cfg(splicing)] impl PendingSplice { fn check_get_splice_locked( - &mut self, context: &ChannelContext, funding: &FundingScope, height: u32, + &mut self, context: &ChannelContext, confirmed_funding_index: usize, height: u32, ) -> Option where SP::Target: SignerProvider, { + debug_assert!(confirmed_funding_index < self.pending_funding.len()); + + let funding = &self.pending_funding[confirmed_funding_index]; if !context.check_funding_meets_minimum_depth(funding, height) { return None; } @@ -5885,7 +5888,6 @@ where SP::Target: SignerProvider, { pub funding: FundingScope, - pending_funding: Vec, pub context: ChannelContext, /// The signing session for the current interactive tx construction, if any. /// @@ -5909,7 +5911,6 @@ macro_rules! promote_splice_funding { } core::mem::swap(&mut $self.funding, $funding); $self.pending_splice = None; - $self.pending_funding.clear(); $self.context.announcement_sigs_state = AnnouncementSigsState::NotSent; }; } @@ -5995,6 +5996,36 @@ where SP::Target: SignerProvider, ::EcdsaSigner: EcdsaChannelSigner, { + #[cfg(splicing)] + fn pending_funding(&self) -> &[FundingScope] { + if let Some(pending_splice) = &self.pending_splice { + pending_splice.pending_funding.as_slice() + } else { + &[] + } + } + + #[cfg(not(splicing))] + fn pending_funding(&self) -> &[FundingScope] { + &[] + } + + #[cfg(splicing)] + fn funding_and_pending_funding_iter_mut(&mut self) -> impl Iterator { + core::iter::once(&mut self.funding).chain( + self.pending_splice + .as_mut() + .map(|pending_splice| pending_splice.pending_funding.as_mut_slice()) + .unwrap_or(&mut []) + .iter_mut(), + ) + } + + #[cfg(not(splicing))] + fn funding_and_pending_funding_iter_mut(&mut self) -> impl Iterator { + core::iter::once(&mut self.funding) + } + #[rustfmt::skip] fn check_remote_fee( channel_type: &ChannelTypeFeatures, fee_estimator: &LowerBoundedFeeEstimator, @@ -6559,7 +6590,7 @@ where } core::iter::once(&self.funding) - .chain(self.pending_funding.iter()) + .chain(self.pending_funding().iter()) .try_for_each(|funding| self.context.validate_update_add_htlc(funding, msg, fee_estimator))?; // Now update local state: @@ -6802,7 +6833,7 @@ where { self.commitment_signed_check_state()?; - if !self.pending_funding.is_empty() { + if !self.pending_funding().is_empty() { return Err(ChannelError::close( "Got a single commitment_signed message when expecting a batch".to_owned(), )); @@ -6861,9 +6892,9 @@ where // Any commitment_signed not associated with a FundingScope is ignored below if a // pending splice transaction has confirmed since receiving the batch. - let mut commitment_txs = Vec::with_capacity(self.pending_funding.len() + 1); + let mut commitment_txs = Vec::with_capacity(self.pending_funding().len() + 1); let mut htlc_data = None; - for funding in core::iter::once(&self.funding).chain(self.pending_funding.iter()) { + for funding in core::iter::once(&self.funding).chain(self.pending_funding().iter()) { let funding_txid = funding.get_funding_txid().expect("Funding txid must be known for pending scope"); let msg = messages.get(&funding_txid).ok_or_else(|| { @@ -7265,9 +7296,7 @@ where #[cfg(any(test, fuzzing))] { - for funding in - core::iter::once(&mut self.funding).chain(self.pending_funding.iter_mut()) - { + for funding in self.funding_and_pending_funding_iter_mut() { *funding.next_local_commitment_tx_fee_info_cached.lock().unwrap() = None; *funding.next_remote_commitment_tx_fee_info_cached.lock().unwrap() = None; } @@ -7470,7 +7499,7 @@ where } } - for funding in core::iter::once(&mut self.funding).chain(self.pending_funding.iter_mut()) { + for funding in self.funding_and_pending_funding_iter_mut() { funding.value_to_self_msat = (funding.value_to_self_msat as i64 + value_to_self_msat_diff) as u64; } @@ -7735,7 +7764,7 @@ where } let can_send_update_fee = core::iter::once(&self.funding) - .chain(self.pending_funding.iter()) + .chain(self.pending_funding().iter()) .all(|funding| self.context.can_send_update_fee(funding, feerate_per_kw, fee_estimator, logger)); if !can_send_update_fee { return None; @@ -8024,14 +8053,14 @@ where } core::iter::once(&self.funding) - .chain(self.pending_funding.iter()) + .chain(self.pending_funding().iter()) .try_for_each(|funding| FundedChannel::::check_remote_fee(funding.get_channel_type(), fee_estimator, msg.feerate_per_kw, Some(self.context.feerate_per_kw), logger))?; self.context.pending_update_fee = Some((msg.feerate_per_kw, FeeUpdateState::RemoteAnnounced)); self.context.update_time_counter += 1; core::iter::once(&self.funding) - .chain(self.pending_funding.iter()) + .chain(self.pending_funding().iter()) .try_for_each(|funding| self.context.validate_update_fee(funding, fee_estimator, msg)) } @@ -9224,7 +9253,7 @@ where let dust_exposure_limiting_feerate = self.context.get_dust_exposure_limiting_feerate(&fee_estimator); core::iter::once(&self.funding) - .chain(self.pending_funding.iter()) + .chain(self.pending_funding().iter()) .try_for_each(|funding| self.context.can_accept_incoming_htlc(funding, msg, dust_exposure_limiting_feerate, &logger)) } @@ -9513,9 +9542,11 @@ where L::Target: Logger, { debug_assert!(self.pending_splice.is_some()); - debug_assert!(confirmed_funding_index < self.pending_funding.len()); let pending_splice = self.pending_splice.as_mut().unwrap(); + + debug_assert!(confirmed_funding_index < pending_splice.pending_funding.len()); + let splice_txid = match pending_splice.sent_funding_txid { Some(sent_funding_txid) => sent_funding_txid, None => { @@ -9532,7 +9563,7 @@ where &self.context.channel_id, ); - let funding = self.pending_funding.get_mut(confirmed_funding_index).unwrap(); + let funding = &mut pending_splice.pending_funding[confirmed_funding_index]; debug_assert_eq!(Some(splice_txid), funding.get_funding_txid()); promote_splice_funding!(self, funding); @@ -9606,18 +9637,20 @@ where #[cfg(splicing)] let mut funding_already_confirmed = false; #[cfg(splicing)] - for (index, funding) in self.pending_funding.iter_mut().enumerate() { - if self.context.check_for_funding_tx_confirmed( - funding, block_hash, height, index_in_block, &mut confirmed_tx, logger, - )? { - if funding_already_confirmed || confirmed_funding_index.is_some() { - let err_reason = "splice tx of another pending funding already confirmed"; - return Err(ClosureReason::ProcessingError { err: err_reason.to_owned() }); - } + if let Some(pending_splice) = &mut self.pending_splice { + for (index, funding) in pending_splice.pending_funding.iter_mut().enumerate() { + if self.context.check_for_funding_tx_confirmed( + funding, block_hash, height, index_in_block, &mut confirmed_tx, logger, + )? { + if funding_already_confirmed || confirmed_funding_index.is_some() { + let err_reason = "splice tx of another pending funding already confirmed"; + return Err(ClosureReason::ProcessingError { err: err_reason.to_owned() }); + } - confirmed_funding_index = Some(index); - } else if funding.funding_tx_confirmation_height != 0 { - funding_already_confirmed = true; + confirmed_funding_index = Some(index); + } else if funding.funding_tx_confirmation_height != 0 { + funding_already_confirmed = true; + } } } @@ -9632,11 +9665,15 @@ where return Err(ClosureReason::ProcessingError { err }); }, }; - let funding = self.pending_funding.get(confirmed_funding_index).unwrap(); - if let Some(splice_locked) = pending_splice.check_get_splice_locked(&self.context, funding, height) { + if let Some(splice_locked) = pending_splice.check_get_splice_locked( + &self.context, + confirmed_funding_index, + height, + ) { for &(idx, tx) in txdata.iter() { if idx > index_in_block { + let funding = &pending_splice.pending_funding[confirmed_funding_index]; self.context.check_for_funding_tx_spent(funding, tx, logger)?; } } @@ -9665,10 +9702,11 @@ where self.context.check_for_funding_tx_spent(&self.funding, tx, logger)?; #[cfg(splicing)] - for funding in self.pending_funding.iter() { - self.context.check_for_funding_tx_spent(funding, tx, logger)?; + if let Some(pending_splice) = self.pending_splice.as_ref() { + for funding in pending_splice.pending_funding.iter() { + self.context.check_for_funding_tx_spent(funding, tx, logger)?; + } } - } Ok((None, None)) @@ -9772,7 +9810,7 @@ where #[cfg(splicing)] let mut confirmed_funding_index = None; #[cfg(splicing)] - for (index, funding) in self.pending_funding.iter().enumerate() { + for (index, funding) in self.pending_funding().iter().enumerate() { if funding.funding_tx_confirmation_height != 0 { if confirmed_funding_index.is_some() { let err_reason = "splice tx of another pending funding already confirmed"; @@ -9794,7 +9832,7 @@ where return Err(ClosureReason::ProcessingError { err }); }, }; - let funding = self.pending_funding.get_mut(confirmed_funding_index).unwrap(); + let funding = &mut pending_splice.pending_funding[confirmed_funding_index]; // Check if the splice funding transaction was unconfirmed if funding.get_funding_tx_confirmations(height) == 0 { @@ -9813,8 +9851,11 @@ where } let pending_splice = self.pending_splice.as_mut().unwrap(); - let funding = self.pending_funding.get(confirmed_funding_index).unwrap(); - if let Some(splice_locked) = pending_splice.check_get_splice_locked(&self.context, funding, height) { + if let Some(splice_locked) = pending_splice.check_get_splice_locked( + &self.context, + confirmed_funding_index, + height, + ) { log_info!(logger, "Sending a splice_locked to our peer for channel {}", &self.context.channel_id); let funding_promoted = @@ -9844,7 +9885,7 @@ where pub fn get_relevant_txids(&self) -> impl Iterator)> + '_ { core::iter::once(&self.funding) - .chain(self.pending_funding.iter()) + .chain(self.pending_funding().iter()) .map(|funding| { ( funding.get_funding_txid(), @@ -9874,8 +9915,8 @@ where where L::Target: Logger, { - let unconfirmed_funding = core::iter::once(&mut self.funding) - .chain(self.pending_funding.iter_mut()) + let unconfirmed_funding = self + .funding_and_pending_funding_iter_mut() .find(|funding| funding.get_funding_txid() == Some(*txid)); if let Some(funding) = unconfirmed_funding { @@ -10232,6 +10273,7 @@ where self.pending_splice = Some(PendingSplice { our_funding_contribution: our_funding_contribution_satoshis, funding: None, + pending_funding: vec![], sent_funding_txid: None, received_funding_txid: None, }); @@ -10348,7 +10390,7 @@ where if let Some(sent_funding_txid) = pending_splice.sent_funding_txid { if sent_funding_txid == msg.splice_txid { - if let Some(funding) = self + if let Some(funding) = pending_splice .pending_funding .iter_mut() .find(|funding| funding.get_funding_txid() == Some(sent_funding_txid)) @@ -10547,7 +10589,7 @@ where F::Target: FeeEstimator, { core::iter::once(&self.funding) - .chain(self.pending_funding.iter()) + .chain(self.pending_funding().iter()) .map(|funding| self.context.get_available_balances_for_scope(funding, fee_estimator)) .reduce(|acc, e| { AvailableBalances { @@ -10594,7 +10636,7 @@ where } self.context.resend_order = RAACommitmentOrder::RevokeAndACKFirst; - let update = if self.pending_funding.is_empty() { + let update = if self.pending_funding().is_empty() { let (htlcs_ref, counterparty_commitment_tx) = self.build_commitment_no_state_update(&self.funding, logger); let htlc_outputs = htlcs_ref.into_iter() @@ -10617,7 +10659,7 @@ where } else { let mut htlc_data = None; let commitment_txs = core::iter::once(&self.funding) - .chain(self.pending_funding.iter()) + .chain(self.pending_funding().iter()) .map(|funding| { let (htlcs_ref, counterparty_commitment_tx) = self.build_commitment_no_state_update(funding, logger); @@ -10699,7 +10741,7 @@ where L::Target: Logger, { core::iter::once(&self.funding) - .chain(self.pending_funding.iter()) + .chain(self.pending_funding().iter()) .map(|funding| self.send_commitment_no_state_update_for_funding(funding, logger)) .collect::, ChannelError>>() } @@ -11476,7 +11518,6 @@ where let mut channel = FundedChannel { funding: self.funding, - pending_funding: vec![], context: self.context, interactive_tx_signing_session: None, holder_commitment_point, @@ -11768,7 +11809,6 @@ where // `ChannelMonitor`. let mut channel = FundedChannel { funding: self.funding, - pending_funding: vec![], context: self.context, interactive_tx_signing_session: None, holder_commitment_point, @@ -12936,7 +12976,6 @@ where let mut next_holder_commitment_point_opt: Option = None; let mut is_manual_broadcast = None; - let mut pending_funding = Some(Vec::new()); let mut historical_scids = Some(Vec::new()); let mut interactive_tx_signing_session: Option = None; @@ -13160,7 +13199,6 @@ where short_channel_id, minimum_depth_override, }, - pending_funding: pending_funding.unwrap(), context: ChannelContext { user_id, From 6858925b14f9a14b704f9cab98462bb5a0ff8952 Mon Sep 17 00:00:00 2001 From: Jeffrey Czyz Date: Thu, 3 Jul 2025 10:15:40 -0500 Subject: [PATCH 3/5] Rename PendingSplice::pending_funding to negotiated_candidates An upcoming commit will rename PendingSplice to PendingFunding. Thus, rename the similarly named field to something more meaningful. It includes FundingScopes that have been negotiated but have not reached enough confirmations by both parties to have exchanged splice_locked. --- lightning/src/ln/channel.rs | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/lightning/src/ln/channel.rs b/lightning/src/ln/channel.rs index e196d51d7b3..63effb66294 100644 --- a/lightning/src/ln/channel.rs +++ b/lightning/src/ln/channel.rs @@ -2178,7 +2178,10 @@ impl FundingScope { struct PendingSplice { pub our_funding_contribution: i64, funding: Option, - pending_funding: Vec, + + /// Funding candidates that have been negotiated but have not reached enough confirmations + /// by both counterparties to have exchanged `splice_locked` and be promoted. + negotiated_candidates: Vec, /// The funding txid used in the `splice_locked` sent to the counterparty. sent_funding_txid: Option, @@ -2195,9 +2198,9 @@ impl PendingSplice { where SP::Target: SignerProvider, { - debug_assert!(confirmed_funding_index < self.pending_funding.len()); + debug_assert!(confirmed_funding_index < self.negotiated_candidates.len()); - let funding = &self.pending_funding[confirmed_funding_index]; + let funding = &self.negotiated_candidates[confirmed_funding_index]; if !context.check_funding_meets_minimum_depth(funding, height) { return None; } @@ -5999,7 +6002,7 @@ where #[cfg(splicing)] fn pending_funding(&self) -> &[FundingScope] { if let Some(pending_splice) = &self.pending_splice { - pending_splice.pending_funding.as_slice() + pending_splice.negotiated_candidates.as_slice() } else { &[] } @@ -6015,7 +6018,7 @@ where core::iter::once(&mut self.funding).chain( self.pending_splice .as_mut() - .map(|pending_splice| pending_splice.pending_funding.as_mut_slice()) + .map(|pending_splice| pending_splice.negotiated_candidates.as_mut_slice()) .unwrap_or(&mut []) .iter_mut(), ) @@ -9545,7 +9548,7 @@ where let pending_splice = self.pending_splice.as_mut().unwrap(); - debug_assert!(confirmed_funding_index < pending_splice.pending_funding.len()); + debug_assert!(confirmed_funding_index < pending_splice.negotiated_candidates.len()); let splice_txid = match pending_splice.sent_funding_txid { Some(sent_funding_txid) => sent_funding_txid, @@ -9563,7 +9566,7 @@ where &self.context.channel_id, ); - let funding = &mut pending_splice.pending_funding[confirmed_funding_index]; + let funding = &mut pending_splice.negotiated_candidates[confirmed_funding_index]; debug_assert_eq!(Some(splice_txid), funding.get_funding_txid()); promote_splice_funding!(self, funding); @@ -9638,7 +9641,7 @@ where let mut funding_already_confirmed = false; #[cfg(splicing)] if let Some(pending_splice) = &mut self.pending_splice { - for (index, funding) in pending_splice.pending_funding.iter_mut().enumerate() { + for (index, funding) in pending_splice.negotiated_candidates.iter_mut().enumerate() { if self.context.check_for_funding_tx_confirmed( funding, block_hash, height, index_in_block, &mut confirmed_tx, logger, )? { @@ -9673,7 +9676,7 @@ where ) { for &(idx, tx) in txdata.iter() { if idx > index_in_block { - let funding = &pending_splice.pending_funding[confirmed_funding_index]; + let funding = &pending_splice.negotiated_candidates[confirmed_funding_index]; self.context.check_for_funding_tx_spent(funding, tx, logger)?; } } @@ -9703,7 +9706,7 @@ where self.context.check_for_funding_tx_spent(&self.funding, tx, logger)?; #[cfg(splicing)] if let Some(pending_splice) = self.pending_splice.as_ref() { - for funding in pending_splice.pending_funding.iter() { + for funding in pending_splice.negotiated_candidates.iter() { self.context.check_for_funding_tx_spent(funding, tx, logger)?; } } @@ -9832,7 +9835,7 @@ where return Err(ClosureReason::ProcessingError { err }); }, }; - let funding = &mut pending_splice.pending_funding[confirmed_funding_index]; + let funding = &mut pending_splice.negotiated_candidates[confirmed_funding_index]; // Check if the splice funding transaction was unconfirmed if funding.get_funding_tx_confirmations(height) == 0 { @@ -10273,7 +10276,7 @@ where self.pending_splice = Some(PendingSplice { our_funding_contribution: our_funding_contribution_satoshis, funding: None, - pending_funding: vec![], + negotiated_candidates: vec![], sent_funding_txid: None, received_funding_txid: None, }); @@ -10391,7 +10394,7 @@ where if let Some(sent_funding_txid) = pending_splice.sent_funding_txid { if sent_funding_txid == msg.splice_txid { if let Some(funding) = pending_splice - .pending_funding + .negotiated_candidates .iter_mut() .find(|funding| funding.get_funding_txid() == Some(sent_funding_txid)) { From 5532253cb70db213ecbdd80bd8d070d8691767c5 Mon Sep 17 00:00:00 2001 From: Jeffrey Czyz Date: Thu, 3 Jul 2025 10:32:55 -0500 Subject: [PATCH 4/5] Rename PendingSplice to PendingFunding While PendingSplice is only used for splicing a FundedChannel, it will be useful when supporting RBF for V2 channel establishment. --- lightning/src/ln/channel.rs | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/lightning/src/ln/channel.rs b/lightning/src/ln/channel.rs index 63effb66294..d51aa5795ea 100644 --- a/lightning/src/ln/channel.rs +++ b/lightning/src/ln/channel.rs @@ -2173,10 +2173,15 @@ impl FundingScope { } } -/// Info about a pending splice, used in the pre-splice channel +/// Information about pending attempts at funding a channel. This includes funding currently under +/// negotiation and any negotiated attempts waiting enough on-chain confirmations. More than one +/// such attempt indicates use of RBF to increase the chances of confirmation. #[cfg(splicing)] -struct PendingSplice { +struct PendingFunding { pub our_funding_contribution: i64, + + /// The current funding attempt under negotiation. Once signatures have been exchanged, this + /// will move to `negotiated_candidates`. funding: Option, /// Funding candidates that have been negotiated but have not reached enough confirmations @@ -2191,7 +2196,7 @@ struct PendingSplice { } #[cfg(splicing)] -impl PendingSplice { +impl PendingFunding { fn check_get_splice_locked( &mut self, context: &ChannelContext, confirmed_funding_index: usize, height: u32, ) -> Option @@ -5903,7 +5908,7 @@ where holder_commitment_point: HolderCommitmentPoint, /// Info about an in-progress, pending splice (if any), on the pre-splice channel #[cfg(splicing)] - pending_splice: Option, + pending_splice: Option, } #[cfg(splicing)] @@ -10273,7 +10278,7 @@ where self.context.channel_id(), err, )})?; - self.pending_splice = Some(PendingSplice { + self.pending_splice = Some(PendingFunding { our_funding_contribution: our_funding_contribution_satoshis, funding: None, negotiated_candidates: vec![], From 6dabb816657564b7fb59308fa85cbc87815a8e9b Mon Sep 17 00:00:00 2001 From: Jeffrey Czyz Date: Thu, 3 Jul 2025 10:47:32 -0500 Subject: [PATCH 5/5] Remove unnecessary FundedChannel::pending_splice checks Now that PendingFunding directly contains the negotiated candidates, some unnecessary checks can be removed. --- lightning/src/ln/channel.rs | 181 ++++++++++++++++-------------------- 1 file changed, 80 insertions(+), 101 deletions(-) diff --git a/lightning/src/ln/channel.rs b/lightning/src/ln/channel.rs index d51aa5795ea..90c789c0673 100644 --- a/lightning/src/ln/channel.rs +++ b/lightning/src/ln/channel.rs @@ -9640,12 +9640,11 @@ where } } - #[cfg(splicing)] - let mut confirmed_funding_index = None; - #[cfg(splicing)] - let mut funding_already_confirmed = false; #[cfg(splicing)] if let Some(pending_splice) = &mut self.pending_splice { + let mut confirmed_funding_index = None; + let mut funding_already_confirmed = false; + for (index, funding) in pending_splice.negotiated_candidates.iter_mut().enumerate() { if self.context.check_for_funding_tx_confirmed( funding, block_hash, height, index_in_block, &mut confirmed_tx, logger, @@ -9660,51 +9659,40 @@ where funding_already_confirmed = true; } } - } - - #[cfg(splicing)] - if let Some(confirmed_funding_index) = confirmed_funding_index { - let pending_splice = match self.pending_splice.as_mut() { - Some(pending_splice) => pending_splice, - None => { - // TODO: Move pending_funding into pending_splice - debug_assert!(false); - let err = "expected a pending splice".to_string(); - return Err(ClosureReason::ProcessingError { err }); - }, - }; - if let Some(splice_locked) = pending_splice.check_get_splice_locked( - &self.context, - confirmed_funding_index, - height, - ) { - for &(idx, tx) in txdata.iter() { - if idx > index_in_block { - let funding = &pending_splice.negotiated_candidates[confirmed_funding_index]; - self.context.check_for_funding_tx_spent(funding, tx, logger)?; + if let Some(confirmed_funding_index) = confirmed_funding_index { + if let Some(splice_locked) = pending_splice.check_get_splice_locked( + &self.context, + confirmed_funding_index, + height, + ) { + for &(idx, tx) in txdata.iter() { + if idx > index_in_block { + let funding = &pending_splice.negotiated_candidates[confirmed_funding_index]; + self.context.check_for_funding_tx_spent(funding, tx, logger)?; + } } - } - log_info!( - logger, - "Sending splice_locked txid {} to our peer for channel {}", - splice_locked.splice_txid, - &self.context.channel_id, - ); + log_info!( + logger, + "Sending splice_locked txid {} to our peer for channel {}", + splice_locked.splice_txid, + &self.context.channel_id, + ); - let funding_promoted = - self.maybe_promote_splice_funding(confirmed_funding_index, logger); - let funding_txo = funding_promoted.then(|| { - self.funding - .get_funding_txo() - .expect("Splice FundingScope should always have a funding_txo") - }); - let announcement_sigs = funding_promoted - .then(|| self.get_announcement_sigs(node_signer, chain_hash, user_config, height, logger)) - .flatten(); + let funding_promoted = + self.maybe_promote_splice_funding(confirmed_funding_index, logger); + let funding_txo = funding_promoted.then(|| { + self.funding + .get_funding_txo() + .expect("Splice FundingScope should always have a funding_txo") + }); + let announcement_sigs = funding_promoted + .then(|| self.get_announcement_sigs(node_signer, chain_hash, user_config, height, logger)) + .flatten(); - return Ok((Some(FundingConfirmedMessage::Splice(splice_locked, funding_txo)), announcement_sigs)); + return Ok((Some(FundingConfirmedMessage::Splice(splice_locked, funding_txo)), announcement_sigs)); + } } } @@ -9816,72 +9804,63 @@ where } #[cfg(splicing)] - let mut confirmed_funding_index = None; - #[cfg(splicing)] - for (index, funding) in self.pending_funding().iter().enumerate() { - if funding.funding_tx_confirmation_height != 0 { - if confirmed_funding_index.is_some() { - let err_reason = "splice tx of another pending funding already confirmed"; - return Err(ClosureReason::ProcessingError { err: err_reason.to_owned() }); - } + if let Some(pending_splice) = &mut self.pending_splice { + let mut confirmed_funding_index = None; - confirmed_funding_index = Some(index); - } - } + for (index, funding) in pending_splice.negotiated_candidates.iter().enumerate() { + if funding.funding_tx_confirmation_height != 0 { + if confirmed_funding_index.is_some() { + let err_reason = "splice tx of another pending funding already confirmed"; + return Err(ClosureReason::ProcessingError { err: err_reason.to_owned() }); + } - #[cfg(splicing)] - if let Some(confirmed_funding_index) = confirmed_funding_index { - let pending_splice = match self.pending_splice.as_mut() { - Some(pending_splice) => pending_splice, - None => { - // TODO: Move pending_funding into pending_splice - debug_assert!(false); - let err = "expected a pending splice".to_string(); - return Err(ClosureReason::ProcessingError { err }); - }, - }; - let funding = &mut pending_splice.negotiated_candidates[confirmed_funding_index]; + confirmed_funding_index = Some(index); + } + } - // Check if the splice funding transaction was unconfirmed - if funding.get_funding_tx_confirmations(height) == 0 { - funding.funding_tx_confirmation_height = 0; - if let Some(sent_funding_txid) = pending_splice.sent_funding_txid { - if Some(sent_funding_txid) == funding.get_funding_txid() { - log_warn!( - logger, - "Unconfirming sent splice_locked txid {} for channel {}", - sent_funding_txid, - &self.context.channel_id, - ); - pending_splice.sent_funding_txid = None; + if let Some(confirmed_funding_index) = confirmed_funding_index { + let funding = &mut pending_splice.negotiated_candidates[confirmed_funding_index]; + + // Check if the splice funding transaction was unconfirmed + if funding.get_funding_tx_confirmations(height) == 0 { + funding.funding_tx_confirmation_height = 0; + if let Some(sent_funding_txid) = pending_splice.sent_funding_txid { + if Some(sent_funding_txid) == funding.get_funding_txid() { + log_warn!( + logger, + "Unconfirming sent splice_locked txid {} for channel {}", + sent_funding_txid, + &self.context.channel_id, + ); + pending_splice.sent_funding_txid = None; + } } } - } - let pending_splice = self.pending_splice.as_mut().unwrap(); - if let Some(splice_locked) = pending_splice.check_get_splice_locked( - &self.context, - confirmed_funding_index, - height, - ) { - log_info!(logger, "Sending a splice_locked to our peer for channel {}", &self.context.channel_id); + if let Some(splice_locked) = pending_splice.check_get_splice_locked( + &self.context, + confirmed_funding_index, + height, + ) { + log_info!(logger, "Sending a splice_locked to our peer for channel {}", &self.context.channel_id); - let funding_promoted = - self.maybe_promote_splice_funding(confirmed_funding_index, logger); - let funding_txo = funding_promoted.then(|| { - self.funding - .get_funding_txo() - .expect("Splice FundingScope should always have a funding_txo") - }); - let announcement_sigs = funding_promoted - .then(|| chain_node_signer - .and_then(|(chain_hash, node_signer, user_config)| - self.get_announcement_sigs(node_signer, chain_hash, user_config, height, logger) + let funding_promoted = + self.maybe_promote_splice_funding(confirmed_funding_index, logger); + let funding_txo = funding_promoted.then(|| { + self.funding + .get_funding_txo() + .expect("Splice FundingScope should always have a funding_txo") + }); + let announcement_sigs = funding_promoted + .then(|| chain_node_signer + .and_then(|(chain_hash, node_signer, user_config)| + self.get_announcement_sigs(node_signer, chain_hash, user_config, height, logger) + ) ) - ) - .flatten(); + .flatten(); - return Ok((Some(FundingConfirmedMessage::Splice(splice_locked, funding_txo)), timed_out_htlcs, announcement_sigs)); + return Ok((Some(FundingConfirmedMessage::Splice(splice_locked, funding_txo)), timed_out_htlcs, announcement_sigs)); + } } }