Skip to content

Commit 19018b3

Browse files
committed
Finish handling tx_complete in signer_unblocked
Expand ChannelManager::signer_unblocked to finish handling tx_complete messages. This completes support for async signing in V2 channel establishment.
1 parent 254362c commit 19018b3

File tree

1 file changed

+117
-41
lines changed

1 file changed

+117
-41
lines changed

lightning/src/ln/channelmanager.rs

+117-41
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)