Skip to content

Commit 92018f6

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 53fc264 commit 92018f6

File tree

1 file changed

+117
-41
lines changed

1 file changed

+117
-41
lines changed

lightning/src/ln/channelmanager.rs

Lines changed: 117 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -8275,7 +8275,78 @@ where
82758275
}
82768276
})
82778277
}
8278+
}
8279+
8280+
macro_rules! finish_tx_complete {
8281+
($self: ident, $counterparty_node_id: ident, $peer_state: ident, $chan_phase_entry: ident) => {
8282+
loop {
8283+
let result = match $chan_phase_entry.get_mut() {
8284+
ChannelPhase::UnfundedOutboundV2(chan) => {
8285+
chan.funding_tx_constructed(&$self.logger)
8286+
},
8287+
ChannelPhase::UnfundedInboundV2(chan) => {
8288+
chan.funding_tx_constructed(&$self.logger)
8289+
},
8290+
_ => unreachable!(),
8291+
};
8292+
let (commitment_signed_opt, funding_ready_for_sig_event_opt) = match result {
8293+
Ok((commitment_signed_opt, funding_ready_for_sig_event_opt)) => {
8294+
(commitment_signed_opt, funding_ready_for_sig_event_opt)
8295+
},
8296+
Err(e) => break Err(e),
8297+
};
8298+
8299+
// Check if the signer returned a result.
8300+
//
8301+
// TODO: This can be removed once ChannelPhase is refactored into Channel as the phase
8302+
// transition will happen internally.
8303+
if commitment_signed_opt.is_none() {
8304+
break Ok(());
8305+
}
8306+
8307+
let (channel_id, channel_phase) = $chan_phase_entry.remove_entry();
8308+
let channel = match channel_phase {
8309+
ChannelPhase::UnfundedOutboundV2(chan) => chan.into_channel(),
8310+
ChannelPhase::UnfundedInboundV2(chan) => chan.into_channel(),
8311+
_ => unreachable!(),
8312+
};
8313+
$peer_state.channel_by_id.insert(channel_id, ChannelPhase::Funded(channel));
82788314

8315+
if let Some(funding_ready_for_sig_event) = funding_ready_for_sig_event_opt {
8316+
let mut pending_events = $self.pending_events.lock().unwrap();
8317+
pending_events.push_back((funding_ready_for_sig_event, None));
8318+
}
8319+
8320+
if let Some(commitment_signed) = commitment_signed_opt {
8321+
$peer_state.pending_msg_events.push(events::MessageSendEvent::UpdateHTLCs {
8322+
node_id: $counterparty_node_id,
8323+
updates: CommitmentUpdate {
8324+
commitment_signed,
8325+
update_add_htlcs: vec![],
8326+
update_fulfill_htlcs: vec![],
8327+
update_fail_htlcs: vec![],
8328+
update_fail_malformed_htlcs: vec![],
8329+
update_fee: None,
8330+
},
8331+
});
8332+
}
8333+
break Ok(());
8334+
}
8335+
}
8336+
}
8337+
8338+
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>
8339+
where
8340+
M::Target: chain::Watch<<SP::Target as SignerProvider>::EcdsaSigner>,
8341+
T::Target: BroadcasterInterface,
8342+
ES::Target: EntropySource,
8343+
NS::Target: NodeSigner,
8344+
SP::Target: SignerProvider,
8345+
F::Target: FeeEstimator,
8346+
R::Target: Router,
8347+
MR::Target: MessageRouter,
8348+
L::Target: Logger,
8349+
{
82798350
fn internal_tx_complete(&self, counterparty_node_id: PublicKey, msg: &msgs::TxComplete) -> Result<(), MsgHandleErrInternal> {
82808351
let per_peer_state = self.per_peer_state.read().unwrap();
82818352
let peer_state_mutex = per_peer_state.get(&counterparty_node_id)
@@ -8305,56 +8376,22 @@ where
83058376
peer_state.pending_msg_events.push(msg_send_event);
83068377
};
83078378
if let Some(signing_session) = signing_session_opt {
8308-
let (commitment_signed_opt, funding_ready_for_sig_event_opt) = match chan_phase_entry.get_mut() {
8379+
match chan_phase_entry.get_mut() {
83098380
ChannelPhase::UnfundedOutboundV2(chan) => {
83108381
*chan.interactive_tx_signing_session_mut() = Some(signing_session);
8311-
chan.funding_tx_constructed(&self.logger)
83128382
},
83138383
ChannelPhase::UnfundedInboundV2(chan) => {
83148384
*chan.interactive_tx_signing_session_mut() = Some(signing_session);
8315-
chan.funding_tx_constructed(&self.logger)
83168385
},
8317-
_ => Err(ChannelError::Warn(
8318-
"Got a tx_complete message with no interactive transaction construction expected or in-progress"
8319-
.into())),
8320-
}.map_err(|err| MsgHandleErrInternal::send_err_msg_no_close(format!("{}", err), msg.channel_id))?;
8321-
8322-
// Check if the signer returned a result.
8323-
//
8324-
// TODO: This can be removed once ChannelPhase is refactored into Channel as the phase
8325-
// transition will happen internally.
8326-
let commitment_signed = match commitment_signed_opt {
8327-
Some(commitment_signed) => commitment_signed,
8328-
None => return Ok(()),
8329-
};
8330-
8331-
let (channel_id, channel_phase) = chan_phase_entry.remove_entry();
8332-
let channel = match channel_phase {
8333-
ChannelPhase::UnfundedOutboundV2(chan) => Ok(chan.into_channel()),
8334-
ChannelPhase::UnfundedInboundV2(chan) => Ok(chan.into_channel()),
83358386
_ => {
8336-
debug_assert!(false); // It cannot be another variant as we are in the `Ok` branch of the above match.
8337-
Err(ChannelError::Warn(
8338-
"Got a tx_complete message with no interactive transaction construction expected or in-progress"
8339-
.into()))
8387+
let err = ChannelError::Warn(
8388+
"Got a tx_complete message with no interactive transaction construction expected or in-progress".into()
8389+
);
8390+
return Err(MsgHandleErrInternal::send_err_msg_no_close(format!("{}", err), msg.channel_id));
83408391
},
8341-
}.map_err(|err| MsgHandleErrInternal::send_err_msg_no_close(format!("{}", err), msg.channel_id))?;
8342-
peer_state.channel_by_id.insert(channel_id, ChannelPhase::Funded(channel));
8343-
if let Some(funding_ready_for_sig_event) = funding_ready_for_sig_event_opt {
8344-
let mut pending_events = self.pending_events.lock().unwrap();
8345-
pending_events.push_back((funding_ready_for_sig_event, None));
83468392
}
8347-
peer_state.pending_msg_events.push(events::MessageSendEvent::UpdateHTLCs {
8348-
node_id: counterparty_node_id,
8349-
updates: CommitmentUpdate {
8350-
commitment_signed,
8351-
update_add_htlcs: vec![],
8352-
update_fulfill_htlcs: vec![],
8353-
update_fail_htlcs: vec![],
8354-
update_fail_malformed_htlcs: vec![],
8355-
update_fee: None,
8356-
},
8357-
});
8393+
finish_tx_complete!(self, counterparty_node_id, peer_state, chan_phase_entry)
8394+
.map_err(|err| MsgHandleErrInternal::send_err_msg_no_close(format!("{}", err), msg.channel_id))?;
83588395
}
83598396
Ok(())
83608397
},
@@ -9558,6 +9595,45 @@ where
95589595
for shutdown_result in shutdown_results.drain(..) {
95599596
self.finish_close_channel(shutdown_result);
95609597
}
9598+
9599+
// Finish any tx_complete handling waiting on async signing.
9600+
//
9601+
// TODO: Move this into the earlier channel iteration to avoid duplication and the Vec
9602+
// allocation once ChannelPhase is refactored into Channel. This can't be avoided with the
9603+
// current data model because tx_complete handling requires removing the entry from the
9604+
// channel_by_id map and re-inserting it, which can't be done while iterating over the map.
9605+
let channels = match channel_opt {
9606+
Some((counterparty_node_id, channel_id)) => vec![(counterparty_node_id, channel_id)],
9607+
None => {
9608+
let per_peer_state = self.per_peer_state.read().unwrap();
9609+
let mut channels = Vec::with_capacity(per_peer_state.len());
9610+
for (counterparty_node_id, peer_state_mutex) in per_peer_state.iter() {
9611+
let mut peer_state_lock = peer_state_mutex.lock().unwrap();
9612+
let peer_state = &mut *peer_state_lock;
9613+
for (channel_id, channel) in peer_state.channel_by_id.iter() {
9614+
if let ChannelPhase::UnfundedInboundV2(_) | ChannelPhase::UnfundedOutboundV2(_) = channel {
9615+
channels.push((*counterparty_node_id, *channel_id));
9616+
}
9617+
}
9618+
}
9619+
channels
9620+
}
9621+
};
9622+
for (counterparty_node_id, channel_id) in channels {
9623+
let per_peer_state = self.per_peer_state.read().unwrap();
9624+
if let Some(peer_state_mutex) = per_peer_state.get(&counterparty_node_id) {
9625+
let mut peer_state_lock = peer_state_mutex.lock().unwrap();
9626+
let peer_state = &mut *peer_state_lock;
9627+
if let hash_map::Entry::Occupied(mut chan_phase_entry) = peer_state.channel_by_id.entry(channel_id) {
9628+
match chan_phase_entry.get_mut() {
9629+
ChannelPhase::UnfundedInboundV2(_) | ChannelPhase::UnfundedOutboundV2(_) => {
9630+
let _ = finish_tx_complete!(self, counterparty_node_id, peer_state, chan_phase_entry);
9631+
},
9632+
_ => {},
9633+
}
9634+
}
9635+
}
9636+
}
95619637
}
95629638

95639639
/// Check whether any channels have finished removing all pending updates after a shutdown

0 commit comments

Comments
 (0)