@@ -2110,6 +2110,7 @@ where
21102110 Some(FundingNegotiation::AwaitingSignatures {
21112111 is_initiator,
21122112 funding,
2113+ initial_commitment_signed_from_counterparty: None,
21132114 });
21142115 Some(interactive_tx_constructor)
21152116 } else {
@@ -2203,9 +2204,33 @@ where
22032204 // which must always come after the initial commitment signed is sent.
22042205 .unwrap_or(true);
22052206 let res = if has_negotiated_pending_splice && !session_received_commitment_signed {
2206- funded_channel
2207- .splice_initial_commitment_signed(msg, fee_estimator, logger)
2208- .map(|monitor_update_opt| (None, monitor_update_opt))
2207+ let has_holder_tx_signatures = funded_channel
2208+ .context
2209+ .interactive_tx_signing_session
2210+ .as_ref()
2211+ .map(|session| session.holder_tx_signatures().is_some())
2212+ .unwrap_or(false);
2213+
2214+ // We delay processing this until the user manually approves the splice via
2215+ // [`Channel::funding_transaction_signed`], as otherwise, there would be a
2216+ // [`ChannelMonitorUpdateStep::RenegotiatedFunding`] committed that we would
2217+ // need to undo if they no longer wish to proceed.
2218+ if has_holder_tx_signatures {
2219+ funded_channel
2220+ .splice_initial_commitment_signed(msg, fee_estimator, logger)
2221+ .map(|monitor_update_opt| (None, monitor_update_opt))
2222+ } else {
2223+ let pending_splice = funded_channel.pending_splice.as_mut()
2224+ .expect("We have a pending splice negotiated");
2225+ let funding_negotiation = pending_splice.funding_negotiation.as_mut()
2226+ .expect("We have a pending splice negotiated");
2227+ if let FundingNegotiation::AwaitingSignatures {
2228+ ref mut initial_commitment_signed_from_counterparty, ..
2229+ } = funding_negotiation {
2230+ *initial_commitment_signed_from_counterparty = Some(msg.clone());
2231+ }
2232+ Ok((None, None))
2233+ }
22092234 } else {
22102235 funded_channel.commitment_signed(msg, fee_estimator, logger)
22112236 .map(|monitor_update_opt| (None, monitor_update_opt))
@@ -2689,13 +2714,25 @@ enum FundingNegotiation {
26892714 AwaitingSignatures {
26902715 funding: FundingScope,
26912716 is_initiator: bool,
2717+ /// The initial [`msgs::CommitmentSigned`] message received for the [`FundingScope`] above.
2718+ /// We delay processing this until the user manually approves the splice via
2719+ /// [`Channel::funding_transaction_signed`], as otherwise, there would be a
2720+ /// [`ChannelMonitorUpdateStep::RenegotiatedFunding`] committed that we would need to undo
2721+ /// if they no longer wish to proceed.
2722+ ///
2723+ /// Note that this doesn't need to be done with dual-funded channels as there is no
2724+ /// equivalent monitor update for them, and we can just force close the channel.
2725+ ///
2726+ /// This field is not persisted as the message should be resent on reconnections.
2727+ initial_commitment_signed_from_counterparty: Option<msgs::CommitmentSigned>,
26922728 },
26932729}
26942730
26952731impl_writeable_tlv_based_enum_upgradable!(FundingNegotiation,
26962732 (0, AwaitingSignatures) => {
26972733 (1, funding, required),
26982734 (3, is_initiator, required),
2735+ (_unused, initial_commitment_signed_from_counterparty, (static_value, None)),
26992736 },
27002737 unread_variants: AwaitingAck, ConstructingTransaction
27012738);
@@ -9023,6 +9060,50 @@ where
90239060 }
90249061 }
90259062
9063+ /// If a counterparty's initial `msgs::CommitmentSigned` is currently pending to be processed
9064+ /// due to the holder signatures not being avialable at the time of receipt, attempt to process
9065+ /// it now if they are available.
9066+ pub fn maybe_process_pending_counterparty_initial_commitment_signed<F: Deref, L: Deref>(
9067+ &mut self, fee_estimator: &LowerBoundedFeeEstimator<F>, logger: &L,
9068+ ) -> Result<Option<ChannelMonitorUpdate>, ChannelError>
9069+ where
9070+ F::Target: FeeEstimator,
9071+ L::Target: Logger,
9072+ {
9073+ if self
9074+ .context
9075+ .interactive_tx_signing_session
9076+ .as_ref()
9077+ .map(|signing_session| {
9078+ !signing_session.has_local_contribution()
9079+ && signing_session.holder_tx_signatures().is_none()
9080+ })
9081+ .unwrap_or(true)
9082+ {
9083+ return Ok(None);
9084+ }
9085+
9086+ if let Some(commit_sig) = self
9087+ .pending_splice
9088+ .as_mut()
9089+ .and_then(|pending_splice| pending_splice.funding_negotiation.as_mut())
9090+ .and_then(|funding_negotiation| {
9091+ if let FundingNegotiation::AwaitingSignatures {
9092+ ref mut initial_commitment_signed_from_counterparty,
9093+ ..
9094+ } = funding_negotiation
9095+ {
9096+ initial_commitment_signed_from_counterparty.take()
9097+ } else {
9098+ None
9099+ }
9100+ }) {
9101+ self.splice_initial_commitment_signed(&commit_sig, fee_estimator, logger)
9102+ } else {
9103+ Ok(None)
9104+ }
9105+ }
9106+
90269107 fn on_tx_signatures_exchange<'a, L: Deref>(
90279108 &mut self, funding_tx: Transaction, best_block_height: u32,
90289109 logger: &WithChannelContext<'a, L>,
@@ -9106,6 +9187,7 @@ where
91069187 // or we're waiting for our counterparty to send theirs first.
91079188 return Ok(FundingTxSigned {
91089189 commitment_signed: None,
9190+
91099191 tx_signatures: None,
91109192 funding_tx: None,
91119193 splice_negotiated: None,
0 commit comments