@@ -8252,7 +8252,78 @@ where
82528252 }
82538253 })
82548254 }
8255+ }
8256+
8257+ macro_rules! finish_tx_complete {
8258+ ($self: ident, $counterparty_node_id: ident, $peer_state: ident, $chan_phase_entry: ident) => {
8259+ loop {
8260+ let result = match $chan_phase_entry.get_mut() {
8261+ ChannelPhase::UnfundedOutboundV2(chan) => {
8262+ chan.funding_tx_constructed(&$self.logger)
8263+ },
8264+ ChannelPhase::UnfundedInboundV2(chan) => {
8265+ chan.funding_tx_constructed(&$self.logger)
8266+ },
8267+ _ => unreachable!(),
8268+ };
8269+ let (commitment_signed_opt, funding_ready_for_sig_event_opt) = match result {
8270+ Ok((commitment_signed_opt, funding_ready_for_sig_event_opt)) => {
8271+ (commitment_signed_opt, funding_ready_for_sig_event_opt)
8272+ },
8273+ Err(e) => break Err(e),
8274+ };
8275+
8276+ // Check if the signer returned a result.
8277+ //
8278+ // TODO: This can be removed once ChannelPhase is refactored into Channel as the phase
8279+ // transition will happen internally.
8280+ if commitment_signed_opt.is_none() {
8281+ break Ok(());
8282+ }
8283+
8284+ let (channel_id, channel_phase) = $chan_phase_entry.remove_entry();
8285+ let channel = match channel_phase {
8286+ ChannelPhase::UnfundedOutboundV2(chan) => chan.into_channel(),
8287+ ChannelPhase::UnfundedInboundV2(chan) => chan.into_channel(),
8288+ _ => unreachable!(),
8289+ };
8290+ $peer_state.channel_by_id.insert(channel_id, ChannelPhase::Funded(channel));
8291+
8292+ if let Some(funding_ready_for_sig_event) = funding_ready_for_sig_event_opt {
8293+ let mut pending_events = $self.pending_events.lock().unwrap();
8294+ pending_events.push_back((funding_ready_for_sig_event, None));
8295+ }
8296+
8297+ if let Some(commitment_signed) = commitment_signed_opt {
8298+ $peer_state.pending_msg_events.push(events::MessageSendEvent::UpdateHTLCs {
8299+ node_id: $counterparty_node_id,
8300+ updates: CommitmentUpdate {
8301+ commitment_signed,
8302+ update_add_htlcs: vec![],
8303+ update_fulfill_htlcs: vec![],
8304+ update_fail_htlcs: vec![],
8305+ update_fail_malformed_htlcs: vec![],
8306+ update_fee: None,
8307+ },
8308+ });
8309+ }
8310+ break Ok(());
8311+ }
8312+ }
8313+ }
82558314
8315+ impl<M: Deref, T: Deref, ES: Deref, NS: Deref, SP: Deref, F: Deref, R: Deref, MR: Deref, L: Deref> ChannelManager<M, T, ES, NS, SP, F, R, MR, L>
8316+ where
8317+ M::Target: chain::Watch<<SP::Target as SignerProvider>::EcdsaSigner>,
8318+ T::Target: BroadcasterInterface,
8319+ ES::Target: EntropySource,
8320+ NS::Target: NodeSigner,
8321+ SP::Target: SignerProvider,
8322+ F::Target: FeeEstimator,
8323+ R::Target: Router,
8324+ MR::Target: MessageRouter,
8325+ L::Target: Logger,
8326+ {
82568327 fn internal_tx_complete(&self, counterparty_node_id: PublicKey, msg: &msgs::TxComplete) -> Result<(), MsgHandleErrInternal> {
82578328 let per_peer_state = self.per_peer_state.read().unwrap();
82588329 let peer_state_mutex = per_peer_state.get(&counterparty_node_id)
@@ -8307,56 +8378,22 @@ where
83078378 peer_state.pending_msg_events.push(msg_send_event);
83088379 };
83098380 if let Some(signing_session) = signing_session_opt {
8310- let (commitment_signed_opt, funding_ready_for_sig_event_opt) = match chan_phase_entry.get_mut() {
8381+ match chan_phase_entry.get_mut() {
83118382 ChannelPhase::UnfundedOutboundV2(chan) => {
83128383 *chan.interactive_tx_signing_session_mut() = Some(signing_session);
8313- chan.funding_tx_constructed(&self.logger)
83148384 },
83158385 ChannelPhase::UnfundedInboundV2(chan) => {
83168386 *chan.interactive_tx_signing_session_mut() = Some(signing_session);
8317- chan.funding_tx_constructed(&self.logger)
83188387 },
8319- _ => Err(ChannelError::Warn(
8320- "Got a tx_complete message with no interactive transaction construction expected or in-progress"
8321- .into())),
8322- }.map_err(|err| MsgHandleErrInternal::send_err_msg_no_close(format!("{}", err), msg.channel_id))?;
8323-
8324- // Check if the signer returned a result.
8325- //
8326- // TODO: This can be removed once ChannelPhase is refactored into Channel as the phase
8327- // transition will happen internally.
8328- let commitment_signed = match commitment_signed_opt {
8329- Some(commitment_signed) => commitment_signed,
8330- None => return Ok(()),
8331- };
8332-
8333- let (channel_id, channel_phase) = chan_phase_entry.remove_entry();
8334- let channel = match channel_phase {
8335- ChannelPhase::UnfundedOutboundV2(chan) => Ok(chan.into_channel()),
8336- ChannelPhase::UnfundedInboundV2(chan) => Ok(chan.into_channel()),
83378388 _ => {
8338- debug_assert!(false); // It cannot be another variant as we are in the `Ok` branch of the above match.
8339- Err(ChannelError::Warn(
8340- "Got a tx_complete message with no interactive transaction construction expected or in-progress"
8341- .into()))
8389+ let err = ChannelError::Warn(
8390+ "Got a tx_complete message with no interactive transaction construction expected or in-progress".into()
8391+ );
8392+ return Err(MsgHandleErrInternal::send_err_msg_no_close(format!("{}", err), msg.channel_id));
83428393 },
8343- }.map_err(|err| MsgHandleErrInternal::send_err_msg_no_close(format!("{}", err), msg.channel_id))?;
8344- peer_state.channel_by_id.insert(channel_id, ChannelPhase::Funded(channel));
8345- if let Some(funding_ready_for_sig_event) = funding_ready_for_sig_event_opt {
8346- let mut pending_events = self.pending_events.lock().unwrap();
8347- pending_events.push_back((funding_ready_for_sig_event, None));
83488394 }
8349- peer_state.pending_msg_events.push(events::MessageSendEvent::UpdateHTLCs {
8350- node_id: counterparty_node_id,
8351- updates: CommitmentUpdate {
8352- commitment_signed,
8353- update_add_htlcs: vec![],
8354- update_fulfill_htlcs: vec![],
8355- update_fail_htlcs: vec![],
8356- update_fail_malformed_htlcs: vec![],
8357- update_fee: None,
8358- },
8359- });
8395+ finish_tx_complete!(self, counterparty_node_id, peer_state, chan_phase_entry)
8396+ .map_err(|err| MsgHandleErrInternal::send_err_msg_no_close(format!("{}", err), msg.channel_id))?;
83608397 }
83618398 Ok(())
83628399 },
@@ -9562,6 +9599,45 @@ where
95629599 for shutdown_result in shutdown_results.drain(..) {
95639600 self.finish_close_channel(shutdown_result);
95649601 }
9602+
9603+ // Finish any tx_complete handling waiting on async signing.
9604+ //
9605+ // TODO: Move this into the earlier channel iteration to avoid duplication and the Vec
9606+ // allocation once ChannelPhase is refactored into Channel. This can't be avoided with the
9607+ // current data model because tx_complete handling requires removing the entry from the
9608+ // channel_by_id map and re-inserting it, which can't be done while iterating over the map.
9609+ let channels = match channel_opt {
9610+ Some((counterparty_node_id, channel_id)) => vec![(counterparty_node_id, channel_id)],
9611+ None => {
9612+ let per_peer_state = self.per_peer_state.read().unwrap();
9613+ let mut channels = Vec::with_capacity(per_peer_state.len());
9614+ for (counterparty_node_id, peer_state_mutex) in per_peer_state.iter() {
9615+ let mut peer_state_lock = peer_state_mutex.lock().unwrap();
9616+ let peer_state = &mut *peer_state_lock;
9617+ for (channel_id, channel) in peer_state.channel_by_id.iter() {
9618+ if let ChannelPhase::UnfundedInboundV2(_) | ChannelPhase::UnfundedOutboundV2(_) = channel {
9619+ channels.push((*counterparty_node_id, *channel_id));
9620+ }
9621+ }
9622+ }
9623+ channels
9624+ }
9625+ };
9626+ for (counterparty_node_id, channel_id) in channels {
9627+ let per_peer_state = self.per_peer_state.read().unwrap();
9628+ if let Some(peer_state_mutex) = per_peer_state.get(&counterparty_node_id) {
9629+ let mut peer_state_lock = peer_state_mutex.lock().unwrap();
9630+ let peer_state = &mut *peer_state_lock;
9631+ if let hash_map::Entry::Occupied(mut chan_phase_entry) = peer_state.channel_by_id.entry(channel_id) {
9632+ match chan_phase_entry.get_mut() {
9633+ ChannelPhase::UnfundedInboundV2(_) | ChannelPhase::UnfundedOutboundV2(_) => {
9634+ let _ = finish_tx_complete!(self, counterparty_node_id, peer_state, chan_phase_entry);
9635+ },
9636+ _ => {},
9637+ }
9638+ }
9639+ }
9640+ }
95659641 }
95669642
95679643 /// Check whether any channels have finished removing all pending updates after a shutdown
0 commit comments