@@ -1902,10 +1902,11 @@ where
19021902 }
19031903 }
19041904
1905- pub fn tx_complete<L: Deref>(
1906- &mut self, msg: &msgs::TxComplete, logger: &L,
1905+ pub fn tx_complete<F: Deref, L: Deref>(
1906+ &mut self, msg: &msgs::TxComplete, fee_estimator: &LowerBoundedFeeEstimator<F>, logger: &L,
19071907 ) -> Result<TxCompleteResult, (ChannelError, Option<SpliceFundingFailed>)>
19081908 where
1909+ F::Target: FeeEstimator,
19091910 L::Target: Logger,
19101911 {
19111912 let tx_complete_action = match self.interactive_tx_constructor_mut() {
@@ -1954,7 +1955,7 @@ where
19541955 let funding_tx_signed = if !has_local_contribution {
19551956 let funding_txid = signing_session.unsigned_tx().tx().compute_txid();
19561957 if let ChannelPhase::Funded(chan) = &mut self.phase {
1957- chan.funding_transaction_signed(funding_txid, vec![], 0, logger).ok()
1958+ chan.funding_transaction_signed(funding_txid, vec![], 0, fee_estimator, logger).ok()
19581959 } else {
19591960 None
19601961 }
@@ -2104,7 +2105,11 @@ where
21042105 funding.channel_transaction_parameters.funding_outpoint =
21052106 Some(funding_outpoint);
21062107 pending_splice.funding_negotiation =
2107- Some(FundingNegotiation::AwaitingSignatures { is_initiator, funding });
2108+ Some(FundingNegotiation::AwaitingSignatures {
2109+ is_initiator,
2110+ funding,
2111+ initial_commitment_signed_from_counterparty: None,
2112+ });
21082113 interactive_tx_constructor
21092114 } else {
21102115 // Replace the taken state for later error handling
@@ -2193,9 +2198,33 @@ where
21932198 // which must always come after the initial commitment signed is sent.
21942199 .unwrap_or(true);
21952200 let res = if has_negotiated_pending_splice && !session_received_commitment_signed {
2196- funded_channel
2197- .splice_initial_commitment_signed(msg, fee_estimator, logger)
2198- .map(|monitor_update_opt| (None, monitor_update_opt))
2201+ let has_holder_tx_signatures = funded_channel
2202+ .context
2203+ .interactive_tx_signing_session
2204+ .as_ref()
2205+ .map(|session| session.holder_tx_signatures().is_some())
2206+ .unwrap_or(false);
2207+
2208+ // We delay processing this until the user manually approves the splice via
2209+ // [`FundedChannel::funding_transaction_signed`], as otherwise, there would be a
2210+ // [`ChannelMonitorUpdateStep::RenegotiatedFunding`] committed that we would
2211+ // need to undo if they no longer wish to proceed.
2212+ if has_holder_tx_signatures {
2213+ funded_channel
2214+ .splice_initial_commitment_signed(msg, fee_estimator, logger)
2215+ .map(|monitor_update_opt| (None, monitor_update_opt))
2216+ } else {
2217+ let pending_splice = funded_channel.pending_splice.as_mut()
2218+ .expect("We have a pending splice negotiated");
2219+ let funding_negotiation = pending_splice.funding_negotiation.as_mut()
2220+ .expect("We have a pending splice negotiated");
2221+ if let FundingNegotiation::AwaitingSignatures {
2222+ ref mut initial_commitment_signed_from_counterparty, ..
2223+ } = funding_negotiation {
2224+ *initial_commitment_signed_from_counterparty = Some(msg.clone());
2225+ }
2226+ Ok((None, None))
2227+ }
21992228 } else {
22002229 funded_channel.commitment_signed(msg, fee_estimator, logger)
22012230 .map(|monitor_update_opt| (None, monitor_update_opt))
@@ -2679,13 +2708,25 @@ enum FundingNegotiation {
26792708 AwaitingSignatures {
26802709 funding: FundingScope,
26812710 is_initiator: bool,
2711+ /// The initial [`msgs::CommitmentSigned`] message received for the [`FundingScope`] above.
2712+ /// We delay processing this until the user manually approves the splice via
2713+ /// [`FundedChannel::funding_transaction_signed`], as otherwise, there would be a
2714+ /// [`ChannelMonitorUpdateStep::RenegotiatedFunding`] committed that we would need to undo
2715+ /// if they no longer wish to proceed.
2716+ ///
2717+ /// Note that this doesn't need to be done with dual-funded channels as there is no
2718+ /// equivalent monitor update for them, and we can just force close the channel.
2719+ ///
2720+ /// This field is not persisted as the message should be resent on reconnections.
2721+ initial_commitment_signed_from_counterparty: Option<msgs::CommitmentSigned>,
26822722 },
26832723}
26842724
26852725impl_writeable_tlv_based_enum_upgradable!(FundingNegotiation,
26862726 (0, AwaitingSignatures) => {
26872727 (1, funding, required),
26882728 (3, is_initiator, required),
2729+ (_unused, initial_commitment_signed_from_counterparty, (static_value, None)),
26892730 },
26902731 unread_variants: AwaitingAck, ConstructingTransaction
26912732);
@@ -6834,7 +6875,7 @@ type BestBlockUpdatedRes = (
68346875);
68356876
68366877/// The result of handling a `tx_complete` message during interactive transaction construction.
6837- pub(crate ) struct TxCompleteResult {
6878+ pub(super ) struct TxCompleteResult {
68386879 /// The message to send to the counterparty, if any.
68396880 pub interactive_tx_msg_send: Option<InteractiveTxMessageSend>,
68406881
@@ -6848,10 +6889,15 @@ pub(crate) struct TxCompleteResult {
68486889}
68496890
68506891/// The result of signing a funding transaction negotiated using the interactive-tx protocol.
6851- pub struct FundingTxSigned {
6892+ pub(super) struct FundingTxSigned {
68526893 /// The initial `commitment_signed` message to send to the counterparty, if necessary.
68536894 pub commitment_signed: Option<msgs::CommitmentSigned>,
68546895
6896+ /// The result of processing a buffered initial commitment signed from our counterparty,
6897+ /// if any.
6898+ pub counterparty_initial_commitment_signed_result:
6899+ Option<Result<Option<ChannelMonitorUpdate>, ChannelError>>,
6900+
68556901 /// Signatures that should be sent to the counterparty, if necessary.
68566902 pub tx_signatures: Option<msgs::TxSignatures>,
68576903
@@ -9071,11 +9117,12 @@ where
90719117 }
90729118 }
90739119
9074- pub fn funding_transaction_signed<L: Deref>(
9120+ pub fn funding_transaction_signed<F: Deref, L: Deref>(
90759121 &mut self, funding_txid_signed: Txid, witnesses: Vec<Witness>, best_block_height: u32,
9076- logger: &L,
9122+ fee_estimator: &LowerBoundedFeeEstimator<F>, logger: &L,
90779123 ) -> Result<FundingTxSigned, APIError>
90789124 where
9125+ F::Target: FeeEstimator,
90799126 L::Target: Logger,
90809127 {
90819128 let signing_session =
@@ -9096,6 +9143,7 @@ where
90969143 // or we're waiting for our counterparty to send theirs first.
90979144 return Ok(FundingTxSigned {
90989145 commitment_signed: None,
9146+ counterparty_initial_commitment_signed_result: None,
90999147 tx_signatures: None,
91009148 funding_tx: None,
91019149 splice_negotiated: None,
@@ -9110,6 +9158,7 @@ where
91109158 // no longer have the signing session present.
91119159 return Ok(FundingTxSigned {
91129160 commitment_signed: None,
9161+ counterparty_initial_commitment_signed_result: None,
91139162 tx_signatures: None,
91149163 funding_tx: None,
91159164 splice_negotiated: None,
@@ -9179,8 +9228,31 @@ where
91799228 .unwrap_or(&self.funding);
91809229 let commitment_signed = self.context.get_initial_commitment_signed_v2(funding, &&logger);
91819230
9231+ // If we have a pending splice with a buffered initial commitment_signed from our
9232+ // counterparty, process it now that we have provided our signatures.
9233+ let counterparty_initial_commitment_signed_result = if let Some(commit_sig) = self
9234+ .pending_splice
9235+ .as_mut()
9236+ .and_then(|pending_splice| pending_splice.funding_negotiation.as_mut())
9237+ .and_then(|funding_negotiation| {
9238+ if let FundingNegotiation::AwaitingSignatures {
9239+ ref mut initial_commitment_signed_from_counterparty,
9240+ ..
9241+ } = funding_negotiation
9242+ {
9243+ initial_commitment_signed_from_counterparty.take()
9244+ } else {
9245+ None
9246+ }
9247+ }) {
9248+ Some(self.splice_initial_commitment_signed(&commit_sig, fee_estimator, &&logger))
9249+ } else {
9250+ None
9251+ };
9252+
91829253 Ok(FundingTxSigned {
91839254 commitment_signed,
9255+ counterparty_initial_commitment_signed_result,
91849256 tx_signatures,
91859257 funding_tx,
91869258 splice_negotiated,
@@ -9254,6 +9326,7 @@ where
92549326
92559327 Ok(FundingTxSigned {
92569328 commitment_signed: None,
9329+ counterparty_initial_commitment_signed_result: None,
92579330 tx_signatures: holder_tx_signatures,
92589331 funding_tx,
92599332 splice_negotiated,
0 commit comments