@@ -1954,11 +1954,19 @@ where
19541954
19551955 let funding_tx_signed = if !has_local_contribution {
19561956 let funding_txid = signing_session.unsigned_tx().tx().compute_txid();
1957- if let ChannelPhase::Funded(chan) = &mut self.phase {
1958- chan.funding_transaction_signed(funding_txid, vec![], 0, fee_estimator, logger).ok()
1959- } else {
1960- None
1961- }
1957+ Some(
1958+ self.funding_transaction_signed(funding_txid, vec![], 0, fee_estimator, logger)
1959+ .map_err(|err| {
1960+ log_error!(
1961+ logger,
1962+ "Failed signing funding transaction without local contribution: {err:?}"
1963+ );
1964+ self.fail_interactive_tx_negotiation(
1965+ AbortReason::InternalError("Signing failed"),
1966+ logger,
1967+ )
1968+ })?,
1969+ )
19621970 } else {
19631971 None
19641972 };
@@ -2144,6 +2152,180 @@ where
21442152 Ok(())
21452153 }
21462154
2155+ pub fn funding_transaction_signed<F: Deref, L: Deref>(
2156+ &mut self, funding_txid_signed: Txid, witnesses: Vec<Witness>, best_block_height: u32,
2157+ fee_estimator: &LowerBoundedFeeEstimator<F>, logger: &L,
2158+ ) -> Result<FundingTxSigned, APIError>
2159+ where
2160+ F::Target: FeeEstimator,
2161+ L::Target: Logger,
2162+ {
2163+ let (context, funding, pending_splice) = match &mut self.phase {
2164+ ChannelPhase::Undefined => unreachable!(),
2165+ ChannelPhase::UnfundedV2(channel) => (&mut channel.context, &channel.funding, None),
2166+ ChannelPhase::Funded(channel) => {
2167+ (&mut channel.context, &channel.funding, channel.pending_splice.as_ref())
2168+ },
2169+ _ => {
2170+ return Err(APIError::APIMisuseError {
2171+ err: format!(
2172+ "Channel with id {} not expecting funding signatures",
2173+ self.context().channel_id
2174+ ),
2175+ });
2176+ },
2177+ };
2178+
2179+ let signing_session = if let Some(signing_session) =
2180+ context.interactive_tx_signing_session.as_mut()
2181+ {
2182+ if let Some(pending_splice) = pending_splice.as_ref() {
2183+ debug_assert!(pending_splice
2184+ .funding_negotiation
2185+ .as_ref()
2186+ .map(|funding_negotiation| matches!(
2187+ funding_negotiation,
2188+ FundingNegotiation::AwaitingSignatures { .. }
2189+ ))
2190+ .unwrap_or(false));
2191+ }
2192+
2193+ if signing_session.holder_tx_signatures().is_some() {
2194+ // Our `tx_signatures` either should've been the first time we processed them,
2195+ // or we're waiting for our counterparty to send theirs first.
2196+ return Ok(FundingTxSigned {
2197+ commitment_signed: None,
2198+ counterparty_initial_commitment_signed_result: None,
2199+ tx_signatures: None,
2200+ funding_tx: None,
2201+ splice_negotiated: None,
2202+ splice_locked: None,
2203+ });
2204+ }
2205+
2206+ signing_session
2207+ } else {
2208+ if Some(funding_txid_signed) == funding.get_funding_txid() {
2209+ // We may be handling a duplicate call and the funding was already locked so we
2210+ // no longer have the signing session present.
2211+ return Ok(FundingTxSigned {
2212+ commitment_signed: None,
2213+ counterparty_initial_commitment_signed_result: None,
2214+ tx_signatures: None,
2215+ funding_tx: None,
2216+ splice_negotiated: None,
2217+ splice_locked: None,
2218+ });
2219+ }
2220+ let err = format!("Channel {} not expecting funding signatures", context.channel_id);
2221+ return Err(APIError::APIMisuseError { err });
2222+ };
2223+
2224+ let tx = signing_session.unsigned_tx().tx();
2225+ if funding_txid_signed != tx.compute_txid() {
2226+ return Err(APIError::APIMisuseError {
2227+ err: "Transaction was malleated prior to signing".to_owned(),
2228+ });
2229+ }
2230+
2231+ let shared_input_signature =
2232+ if let Some(splice_input_index) = signing_session.unsigned_tx().shared_input_index() {
2233+ let sig = match &context.holder_signer {
2234+ ChannelSignerType::Ecdsa(signer) => signer.sign_splice_shared_input(
2235+ &funding.channel_transaction_parameters,
2236+ tx,
2237+ splice_input_index as usize,
2238+ &context.secp_ctx,
2239+ ),
2240+ #[cfg(taproot)]
2241+ ChannelSignerType::Taproot(_) => todo!(),
2242+ };
2243+ Some(sig)
2244+ } else {
2245+ None
2246+ };
2247+ debug_assert_eq!(pending_splice.is_some(), shared_input_signature.is_some());
2248+
2249+ let tx_signatures = msgs::TxSignatures {
2250+ channel_id: context.channel_id,
2251+ tx_hash: funding_txid_signed,
2252+ witnesses,
2253+ shared_input_signature,
2254+ };
2255+ let (tx_signatures, funding_tx) = signing_session
2256+ .provide_holder_witnesses(tx_signatures, &context.secp_ctx)
2257+ .map_err(|err| APIError::APIMisuseError { err })?;
2258+
2259+ let logger = WithChannelContext::from(logger, &context, None);
2260+ if tx_signatures.is_some() {
2261+ log_info!(
2262+ logger,
2263+ "Sending tx_signatures for interactive funding transaction {funding_txid_signed}"
2264+ );
2265+ }
2266+
2267+ let funding = pending_splice
2268+ .as_ref()
2269+ .and_then(|pending_splice| pending_splice.funding_negotiation.as_ref())
2270+ .and_then(|funding_negotiation| funding_negotiation.as_funding())
2271+ .unwrap_or(funding);
2272+ let commitment_signed = context.get_initial_commitment_signed_v2(funding, &&logger);
2273+
2274+ // In the common case for zero conf channels, we don't expect the funding transaction to be
2275+ // ready for broadcast yet as our counterparty shouldn't have sent their `tx_signatures`
2276+ // without us having sent our initial commitment signed to them first. However, in the event
2277+ // they do, we choose to handle it anyway.
2278+ let (splice_negotiated, splice_locked) = if let Some(funding_tx) = funding_tx.clone() {
2279+ debug_assert!(tx_signatures.is_some());
2280+ let funded_channel = self.as_funded_mut().expect(
2281+ "Funding transactions ready for broadcast can only exist for funded channels",
2282+ );
2283+ funded_channel.on_tx_signatures_exchange(funding_tx, best_block_height, &logger)
2284+ } else {
2285+ (None, None)
2286+ };
2287+
2288+ // If we have a pending splice with a buffered initial commitment signed from our
2289+ // counterparty, process it now that we have provided our signatures.
2290+ let counterparty_initial_commitment_signed_result =
2291+ if let Some(funded_channel) = self.as_funded_mut() {
2292+ if let Some(commit_sig) = funded_channel
2293+ .pending_splice
2294+ .as_mut()
2295+ .and_then(|pending_splice| pending_splice.funding_negotiation.as_mut())
2296+ .and_then(|funding_negotiation| {
2297+ if let FundingNegotiation::AwaitingSignatures {
2298+ ref mut initial_commitment_signed_from_counterparty,
2299+ ..
2300+ } = funding_negotiation
2301+ {
2302+ initial_commitment_signed_from_counterparty.take()
2303+ } else {
2304+ None
2305+ }
2306+ }) {
2307+ Some(funded_channel.splice_initial_commitment_signed(
2308+ &commit_sig,
2309+ fee_estimator,
2310+ &&logger,
2311+ ))
2312+ } else {
2313+ None
2314+ }
2315+ } else {
2316+ None
2317+ };
2318+
2319+ Ok(FundingTxSigned {
2320+ commitment_signed,
2321+ counterparty_initial_commitment_signed_result,
2322+ tx_signatures,
2323+ funding_tx,
2324+ splice_negotiated,
2325+ splice_locked,
2326+ })
2327+ }
2328+
21472329 pub fn force_shutdown(&mut self, closure_reason: ClosureReason) -> ShutdownResult {
21482330 let (funding, context) = self.funding_and_context_mut();
21492331 context.force_shutdown(funding, closure_reason)
@@ -2213,7 +2395,7 @@ where
22132395 .unwrap_or(false);
22142396
22152397 // We delay processing this until the user manually approves the splice via
2216- // [`FundedChannel ::funding_transaction_signed`], as otherwise, there would be a
2398+ // [`Channel ::funding_transaction_signed`], as otherwise, there would be a
22172399 // [`ChannelMonitorUpdateStep::RenegotiatedFunding`] committed that we would
22182400 // need to undo if they no longer wish to proceed.
22192401 if has_holder_tx_signatures {
@@ -2717,7 +2899,7 @@ enum FundingNegotiation {
27172899 is_initiator: bool,
27182900 /// The initial [`msgs::CommitmentSigned`] message received for the [`FundingScope`] above.
27192901 /// We delay processing this until the user manually approves the splice via
2720- /// [`FundedChannel ::funding_transaction_signed`], as otherwise, there would be a
2902+ /// [`Channel ::funding_transaction_signed`], as otherwise, there would be a
27212903 /// [`ChannelMonitorUpdateStep::RenegotiatedFunding`] committed that we would need to undo
27222904 /// if they no longer wish to proceed.
27232905 ///
@@ -9124,149 +9306,6 @@ where
91249306 }
91259307 }
91269308
9127- pub fn funding_transaction_signed<F: Deref, L: Deref>(
9128- &mut self, funding_txid_signed: Txid, witnesses: Vec<Witness>, best_block_height: u32,
9129- fee_estimator: &LowerBoundedFeeEstimator<F>, logger: &L,
9130- ) -> Result<FundingTxSigned, APIError>
9131- where
9132- F::Target: FeeEstimator,
9133- L::Target: Logger,
9134- {
9135- let signing_session =
9136- if let Some(signing_session) = self.context.interactive_tx_signing_session.as_mut() {
9137- if let Some(pending_splice) = self.pending_splice.as_ref() {
9138- debug_assert!(pending_splice
9139- .funding_negotiation
9140- .as_ref()
9141- .map(|funding_negotiation| matches!(
9142- funding_negotiation,
9143- FundingNegotiation::AwaitingSignatures { .. }
9144- ))
9145- .unwrap_or(false));
9146- }
9147-
9148- if signing_session.holder_tx_signatures().is_some() {
9149- // Our `tx_signatures` either should've been the first time we processed them,
9150- // or we're waiting for our counterparty to send theirs first.
9151- return Ok(FundingTxSigned {
9152- commitment_signed: None,
9153- counterparty_initial_commitment_signed_result: None,
9154- tx_signatures: None,
9155- funding_tx: None,
9156- splice_negotiated: None,
9157- splice_locked: None,
9158- });
9159- }
9160-
9161- signing_session
9162- } else {
9163- if Some(funding_txid_signed) == self.funding.get_funding_txid() {
9164- // We may be handling a duplicate call and the funding was already locked so we
9165- // no longer have the signing session present.
9166- return Ok(FundingTxSigned {
9167- commitment_signed: None,
9168- counterparty_initial_commitment_signed_result: None,
9169- tx_signatures: None,
9170- funding_tx: None,
9171- splice_negotiated: None,
9172- splice_locked: None,
9173- });
9174- }
9175- let err =
9176- format!("Channel {} not expecting funding signatures", self.context.channel_id);
9177- return Err(APIError::APIMisuseError { err });
9178- };
9179-
9180- let tx = signing_session.unsigned_tx().tx();
9181- if funding_txid_signed != tx.compute_txid() {
9182- return Err(APIError::APIMisuseError {
9183- err: "Transaction was malleated prior to signing".to_owned(),
9184- });
9185- }
9186-
9187- let shared_input_signature =
9188- if let Some(splice_input_index) = signing_session.unsigned_tx().shared_input_index() {
9189- let sig = match &self.context.holder_signer {
9190- ChannelSignerType::Ecdsa(signer) => signer.sign_splice_shared_input(
9191- &self.funding.channel_transaction_parameters,
9192- tx,
9193- splice_input_index as usize,
9194- &self.context.secp_ctx,
9195- ),
9196- #[cfg(taproot)]
9197- ChannelSignerType::Taproot(_) => todo!(),
9198- };
9199- Some(sig)
9200- } else {
9201- None
9202- };
9203- debug_assert_eq!(self.pending_splice.is_some(), shared_input_signature.is_some());
9204-
9205- let tx_signatures = msgs::TxSignatures {
9206- channel_id: self.context.channel_id,
9207- tx_hash: funding_txid_signed,
9208- witnesses,
9209- shared_input_signature,
9210- };
9211- let (tx_signatures, funding_tx) = signing_session
9212- .provide_holder_witnesses(tx_signatures, &self.context.secp_ctx)
9213- .map_err(|err| APIError::APIMisuseError { err })?;
9214-
9215- let logger = WithChannelContext::from(logger, &self.context, None);
9216- if tx_signatures.is_some() {
9217- log_info!(
9218- logger,
9219- "Sending tx_signatures for interactive funding transaction {funding_txid_signed}"
9220- );
9221- }
9222-
9223- let (splice_negotiated, splice_locked) = if let Some(funding_tx) = funding_tx.clone() {
9224- debug_assert!(tx_signatures.is_some());
9225- self.on_tx_signatures_exchange(funding_tx, best_block_height, &logger)
9226- } else {
9227- (None, None)
9228- };
9229-
9230- let funding = self
9231- .pending_splice
9232- .as_ref()
9233- .and_then(|pending_splice| pending_splice.funding_negotiation.as_ref())
9234- .and_then(|funding_negotiation| funding_negotiation.as_funding())
9235- .unwrap_or(&self.funding);
9236- let commitment_signed = self.context.get_initial_commitment_signed_v2(funding, &&logger);
9237-
9238- // If we have a pending splice with a buffered initial commitment_signed from our
9239- // counterparty, process it now that we have provided our signatures.
9240- let counterparty_initial_commitment_signed_result = if let Some(commit_sig) = self
9241- .pending_splice
9242- .as_mut()
9243- .and_then(|pending_splice| pending_splice.funding_negotiation.as_mut())
9244- .and_then(|funding_negotiation| {
9245- if let FundingNegotiation::AwaitingSignatures {
9246- ref mut initial_commitment_signed_from_counterparty,
9247- ..
9248- } = funding_negotiation
9249- {
9250- initial_commitment_signed_from_counterparty.take()
9251- } else {
9252- None
9253- }
9254- }) {
9255- Some(self.splice_initial_commitment_signed(&commit_sig, fee_estimator, &&logger))
9256- } else {
9257- None
9258- };
9259-
9260- Ok(FundingTxSigned {
9261- commitment_signed,
9262- counterparty_initial_commitment_signed_result,
9263- tx_signatures,
9264- funding_tx,
9265- splice_negotiated,
9266- splice_locked,
9267- })
9268- }
9269-
92709309 pub fn tx_signatures<L: Deref>(
92719310 &mut self, msg: &msgs::TxSignatures, best_block_height: u32, logger: &L,
92729311 ) -> Result<FundingTxSigned, ChannelError>
0 commit comments