@@ -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 };
@@ -2137,6 +2145,180 @@ where
21372145 Ok(())
21382146 }
21392147
2148+ pub fn funding_transaction_signed<F: Deref, L: Deref>(
2149+ &mut self, funding_txid_signed: Txid, witnesses: Vec<Witness>, best_block_height: u32,
2150+ fee_estimator: &LowerBoundedFeeEstimator<F>, logger: &L,
2151+ ) -> Result<FundingTxSigned, APIError>
2152+ where
2153+ F::Target: FeeEstimator,
2154+ L::Target: Logger,
2155+ {
2156+ let (context, funding, pending_splice) = match &mut self.phase {
2157+ ChannelPhase::Undefined => unreachable!(),
2158+ ChannelPhase::UnfundedV2(channel) => (&mut channel.context, &channel.funding, None),
2159+ ChannelPhase::Funded(channel) => {
2160+ (&mut channel.context, &channel.funding, channel.pending_splice.as_ref())
2161+ },
2162+ _ => {
2163+ return Err(APIError::APIMisuseError {
2164+ err: format!(
2165+ "Channel with id {} not expecting funding signatures",
2166+ self.context().channel_id
2167+ ),
2168+ });
2169+ },
2170+ };
2171+
2172+ let signing_session = if let Some(signing_session) =
2173+ context.interactive_tx_signing_session.as_mut()
2174+ {
2175+ if let Some(pending_splice) = pending_splice.as_ref() {
2176+ debug_assert!(pending_splice
2177+ .funding_negotiation
2178+ .as_ref()
2179+ .map(|funding_negotiation| matches!(
2180+ funding_negotiation,
2181+ FundingNegotiation::AwaitingSignatures { .. }
2182+ ))
2183+ .unwrap_or(false));
2184+ }
2185+
2186+ if signing_session.holder_tx_signatures().is_some() {
2187+ // Our `tx_signatures` either should've been the first time we processed them,
2188+ // or we're waiting for our counterparty to send theirs first.
2189+ return Ok(FundingTxSigned {
2190+ commitment_signed: None,
2191+ counterparty_initial_commitment_signed_result: None,
2192+ tx_signatures: None,
2193+ funding_tx: None,
2194+ splice_negotiated: None,
2195+ splice_locked: None,
2196+ });
2197+ }
2198+
2199+ signing_session
2200+ } else {
2201+ if Some(funding_txid_signed) == funding.get_funding_txid() {
2202+ // We may be handling a duplicate call and the funding was already locked so we
2203+ // no longer have the signing session present.
2204+ return Ok(FundingTxSigned {
2205+ commitment_signed: None,
2206+ counterparty_initial_commitment_signed_result: None,
2207+ tx_signatures: None,
2208+ funding_tx: None,
2209+ splice_negotiated: None,
2210+ splice_locked: None,
2211+ });
2212+ }
2213+ let err = format!("Channel {} not expecting funding signatures", context.channel_id);
2214+ return Err(APIError::APIMisuseError { err });
2215+ };
2216+
2217+ let tx = signing_session.unsigned_tx().tx();
2218+ if funding_txid_signed != tx.compute_txid() {
2219+ return Err(APIError::APIMisuseError {
2220+ err: "Transaction was malleated prior to signing".to_owned(),
2221+ });
2222+ }
2223+
2224+ let shared_input_signature =
2225+ if let Some(splice_input_index) = signing_session.unsigned_tx().shared_input_index() {
2226+ let sig = match &context.holder_signer {
2227+ ChannelSignerType::Ecdsa(signer) => signer.sign_splice_shared_input(
2228+ &funding.channel_transaction_parameters,
2229+ tx,
2230+ splice_input_index as usize,
2231+ &context.secp_ctx,
2232+ ),
2233+ #[cfg(taproot)]
2234+ ChannelSignerType::Taproot(_) => todo!(),
2235+ };
2236+ Some(sig)
2237+ } else {
2238+ None
2239+ };
2240+ debug_assert_eq!(pending_splice.is_some(), shared_input_signature.is_some());
2241+
2242+ let tx_signatures = msgs::TxSignatures {
2243+ channel_id: context.channel_id,
2244+ tx_hash: funding_txid_signed,
2245+ witnesses,
2246+ shared_input_signature,
2247+ };
2248+ let (tx_signatures, funding_tx) = signing_session
2249+ .provide_holder_witnesses(tx_signatures, &context.secp_ctx)
2250+ .map_err(|err| APIError::APIMisuseError { err })?;
2251+
2252+ let logger = WithChannelContext::from(logger, &context, None);
2253+ if tx_signatures.is_some() {
2254+ log_info!(
2255+ logger,
2256+ "Sending tx_signatures for interactive funding transaction {funding_txid_signed}"
2257+ );
2258+ }
2259+
2260+ let funding = pending_splice
2261+ .as_ref()
2262+ .and_then(|pending_splice| pending_splice.funding_negotiation.as_ref())
2263+ .and_then(|funding_negotiation| funding_negotiation.as_funding())
2264+ .unwrap_or(funding);
2265+ let commitment_signed = context.get_initial_commitment_signed_v2(funding, &&logger);
2266+
2267+ // In the common case for zero conf channels, we don't expect the funding transaction to be
2268+ // ready for broadcast yet as our counterparty shouldn't have sent their `tx_signatures`
2269+ // without us having sent our initial commitment signed to them first. However, in the event
2270+ // they do, we choose to handle it anyway.
2271+ let (splice_negotiated, splice_locked) = if let Some(funding_tx) = funding_tx.clone() {
2272+ debug_assert!(tx_signatures.is_some());
2273+ let funded_channel = self.as_funded_mut().expect(
2274+ "Funding transactions ready for broadcast can only exist for funded channels",
2275+ );
2276+ funded_channel.on_tx_signatures_exchange(funding_tx, best_block_height, &logger)
2277+ } else {
2278+ (None, None)
2279+ };
2280+
2281+ // If we have a pending splice with a buffered initial commitment signed from our
2282+ // counterparty, process it now that we have provided our signatures.
2283+ let counterparty_initial_commitment_signed_result =
2284+ if let Some(funded_channel) = self.as_funded_mut() {
2285+ if let Some(commit_sig) = funded_channel
2286+ .pending_splice
2287+ .as_mut()
2288+ .and_then(|pending_splice| pending_splice.funding_negotiation.as_mut())
2289+ .and_then(|funding_negotiation| {
2290+ if let FundingNegotiation::AwaitingSignatures {
2291+ ref mut initial_commitment_signed_from_counterparty,
2292+ ..
2293+ } = funding_negotiation
2294+ {
2295+ initial_commitment_signed_from_counterparty.take()
2296+ } else {
2297+ None
2298+ }
2299+ }) {
2300+ Some(funded_channel.splice_initial_commitment_signed(
2301+ &commit_sig,
2302+ fee_estimator,
2303+ &&logger,
2304+ ))
2305+ } else {
2306+ None
2307+ }
2308+ } else {
2309+ None
2310+ };
2311+
2312+ Ok(FundingTxSigned {
2313+ commitment_signed,
2314+ counterparty_initial_commitment_signed_result,
2315+ tx_signatures,
2316+ funding_tx,
2317+ splice_negotiated,
2318+ splice_locked,
2319+ })
2320+ }
2321+
21402322 pub fn force_shutdown(&mut self, closure_reason: ClosureReason) -> ShutdownResult {
21412323 let (funding, context) = self.funding_and_context_mut();
21422324 context.force_shutdown(funding, closure_reason)
@@ -2206,7 +2388,7 @@ where
22062388 .unwrap_or(false);
22072389
22082390 // We delay processing this until the user manually approves the splice via
2209- // [`FundedChannel ::funding_transaction_signed`], as otherwise, there would be a
2391+ // [`Channel ::funding_transaction_signed`], as otherwise, there would be a
22102392 // [`ChannelMonitorUpdateStep::RenegotiatedFunding`] committed that we would
22112393 // need to undo if they no longer wish to proceed.
22122394 if has_holder_tx_signatures {
@@ -2710,7 +2892,7 @@ enum FundingNegotiation {
27102892 is_initiator: bool,
27112893 /// The initial [`msgs::CommitmentSigned`] message received for the [`FundingScope`] above.
27122894 /// We delay processing this until the user manually approves the splice via
2713- /// [`FundedChannel ::funding_transaction_signed`], as otherwise, there would be a
2895+ /// [`Channel ::funding_transaction_signed`], as otherwise, there would be a
27142896 /// [`ChannelMonitorUpdateStep::RenegotiatedFunding`] committed that we would need to undo
27152897 /// if they no longer wish to proceed.
27162898 ///
@@ -9117,149 +9299,6 @@ where
91179299 }
91189300 }
91199301
9120- pub fn funding_transaction_signed<F: Deref, L: Deref>(
9121- &mut self, funding_txid_signed: Txid, witnesses: Vec<Witness>, best_block_height: u32,
9122- fee_estimator: &LowerBoundedFeeEstimator<F>, logger: &L,
9123- ) -> Result<FundingTxSigned, APIError>
9124- where
9125- F::Target: FeeEstimator,
9126- L::Target: Logger,
9127- {
9128- let signing_session =
9129- if let Some(signing_session) = self.context.interactive_tx_signing_session.as_mut() {
9130- if let Some(pending_splice) = self.pending_splice.as_ref() {
9131- debug_assert!(pending_splice
9132- .funding_negotiation
9133- .as_ref()
9134- .map(|funding_negotiation| matches!(
9135- funding_negotiation,
9136- FundingNegotiation::AwaitingSignatures { .. }
9137- ))
9138- .unwrap_or(false));
9139- }
9140-
9141- if signing_session.holder_tx_signatures().is_some() {
9142- // Our `tx_signatures` either should've been the first time we processed them,
9143- // or we're waiting for our counterparty to send theirs first.
9144- return Ok(FundingTxSigned {
9145- commitment_signed: None,
9146- counterparty_initial_commitment_signed_result: None,
9147- tx_signatures: None,
9148- funding_tx: None,
9149- splice_negotiated: None,
9150- splice_locked: None,
9151- });
9152- }
9153-
9154- signing_session
9155- } else {
9156- if Some(funding_txid_signed) == self.funding.get_funding_txid() {
9157- // We may be handling a duplicate call and the funding was already locked so we
9158- // no longer have the signing session present.
9159- return Ok(FundingTxSigned {
9160- commitment_signed: None,
9161- counterparty_initial_commitment_signed_result: None,
9162- tx_signatures: None,
9163- funding_tx: None,
9164- splice_negotiated: None,
9165- splice_locked: None,
9166- });
9167- }
9168- let err =
9169- format!("Channel {} not expecting funding signatures", self.context.channel_id);
9170- return Err(APIError::APIMisuseError { err });
9171- };
9172-
9173- let tx = signing_session.unsigned_tx().tx();
9174- if funding_txid_signed != tx.compute_txid() {
9175- return Err(APIError::APIMisuseError {
9176- err: "Transaction was malleated prior to signing".to_owned(),
9177- });
9178- }
9179-
9180- let shared_input_signature =
9181- if let Some(splice_input_index) = signing_session.unsigned_tx().shared_input_index() {
9182- let sig = match &self.context.holder_signer {
9183- ChannelSignerType::Ecdsa(signer) => signer.sign_splice_shared_input(
9184- &self.funding.channel_transaction_parameters,
9185- tx,
9186- splice_input_index as usize,
9187- &self.context.secp_ctx,
9188- ),
9189- #[cfg(taproot)]
9190- ChannelSignerType::Taproot(_) => todo!(),
9191- };
9192- Some(sig)
9193- } else {
9194- None
9195- };
9196- debug_assert_eq!(self.pending_splice.is_some(), shared_input_signature.is_some());
9197-
9198- let tx_signatures = msgs::TxSignatures {
9199- channel_id: self.context.channel_id,
9200- tx_hash: funding_txid_signed,
9201- witnesses,
9202- shared_input_signature,
9203- };
9204- let (tx_signatures, funding_tx) = signing_session
9205- .provide_holder_witnesses(tx_signatures, &self.context.secp_ctx)
9206- .map_err(|err| APIError::APIMisuseError { err })?;
9207-
9208- let logger = WithChannelContext::from(logger, &self.context, None);
9209- if tx_signatures.is_some() {
9210- log_info!(
9211- logger,
9212- "Sending tx_signatures for interactive funding transaction {funding_txid_signed}"
9213- );
9214- }
9215-
9216- let (splice_negotiated, splice_locked) = if let Some(funding_tx) = funding_tx.clone() {
9217- debug_assert!(tx_signatures.is_some());
9218- self.on_tx_signatures_exchange(funding_tx, best_block_height, &logger)
9219- } else {
9220- (None, None)
9221- };
9222-
9223- let funding = self
9224- .pending_splice
9225- .as_ref()
9226- .and_then(|pending_splice| pending_splice.funding_negotiation.as_ref())
9227- .and_then(|funding_negotiation| funding_negotiation.as_funding())
9228- .unwrap_or(&self.funding);
9229- let commitment_signed = self.context.get_initial_commitment_signed_v2(funding, &&logger);
9230-
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-
9253- Ok(FundingTxSigned {
9254- commitment_signed,
9255- counterparty_initial_commitment_signed_result,
9256- tx_signatures,
9257- funding_tx,
9258- splice_negotiated,
9259- splice_locked,
9260- })
9261- }
9262-
92639302 pub fn tx_signatures<L: Deref>(
92649303 &mut self, msg: &msgs::TxSignatures, best_block_height: u32, logger: &L,
92659304 ) -> Result<FundingTxSigned, ChannelError>
0 commit comments