Skip to content

Commit 3a2690c

Browse files
committed
Move pre-funded-channel immediate shutdown logic to the right place
Because a `Funded` `Channel` cannot possibly be pre-funding, the logic in `ChannelManager::close_channel_internal` to handle pre-funding channels is in the wrong place. Rather than being handled inside the `Funded` branch, it should be in an `else` following it, handling either of the two `ChannelPhases` outside of `Funded`. Sadly, because of a previous control flow management `loop {}`, the existing code will infinite loop, which is fixed here.
1 parent 1667b4d commit 3a2690c

File tree

2 files changed

+23
-18
lines changed

2 files changed

+23
-18
lines changed

lightning/src/ln/channelmanager.rs

Lines changed: 8 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2714,9 +2714,10 @@ where
27142714
fn close_channel_internal(&self, channel_id: &ChannelId, counterparty_node_id: &PublicKey, target_feerate_sats_per_1000_weight: Option<u32>, override_shutdown_script: Option<ShutdownScript>) -> Result<(), APIError> {
27152715
let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(self);
27162716

2717-
let mut failed_htlcs: Vec<(HTLCSource, PaymentHash)>;
2718-
let shutdown_result;
2719-
loop {
2717+
let mut failed_htlcs: Vec<(HTLCSource, PaymentHash)> = Vec::new();
2718+
let mut shutdown_result = None;
2719+
2720+
{
27202721
let per_peer_state = self.per_peer_state.read().unwrap();
27212722

27222723
let peer_state_mutex = per_peer_state.get(counterparty_node_id)
@@ -2733,8 +2734,6 @@ where
27332734
let (shutdown_msg, mut monitor_update_opt, htlcs) =
27342735
chan.get_shutdown(&self.signer_provider, their_features, target_feerate_sats_per_1000_weight, override_shutdown_script)?;
27352736
failed_htlcs = htlcs;
2736-
shutdown_result = None;
2737-
debug_assert_eq!(shutdown_result.is_some(), chan.is_shutdown());
27382737

27392738
// We can send the `shutdown` message before updating the `ChannelMonitor`
27402739
// here as we don't need the monitor update to complete until we send a
@@ -2751,20 +2750,11 @@ where
27512750
if let Some(monitor_update) = monitor_update_opt.take() {
27522751
handle_new_monitor_update!(self, funding_txo_opt.unwrap(), monitor_update,
27532752
peer_state_lock, peer_state, per_peer_state, chan);
2754-
break;
27552753
}
2756-
2757-
if chan.is_shutdown() {
2758-
if let ChannelPhase::Funded(chan) = remove_channel_phase!(self, chan_phase_entry) {
2759-
if let Ok(channel_update) = self.get_channel_update_for_broadcast(&chan) {
2760-
peer_state.pending_msg_events.push(events::MessageSendEvent::BroadcastChannelUpdate {
2761-
msg: channel_update
2762-
});
2763-
}
2764-
self.issue_channel_close_events(&chan.context, ClosureReason::HolderForceClosed);
2765-
}
2766-
}
2767-
break;
2754+
} else {
2755+
self.issue_channel_close_events(chan_phase_entry.get().context(), ClosureReason::HolderForceClosed);
2756+
let mut chan_phase = remove_channel_phase!(self, chan_phase_entry);
2757+
shutdown_result = Some(chan_phase.context_mut().force_shutdown(false));
27682758
}
27692759
},
27702760
hash_map::Entry::Vacant(_) => {

lightning/src/ln/shutdown_tests.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,21 @@ fn shutdown_on_unfunded_channel() {
277277
check_closed_event!(nodes[0], 1, ClosureReason::CounterpartyCoopClosedUnfundedChannel, [nodes[1].node.get_our_node_id()], 1_000_000);
278278
}
279279

280+
#[test]
281+
fn close_on_unfunded_channel() {
282+
// Test the user asking us to close prior to funding generation
283+
let chanmon_cfgs = create_chanmon_cfgs(2);
284+
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
285+
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
286+
let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
287+
288+
let chan_id = nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), 1_000_000, 100_000, 0, None, None).unwrap();
289+
let _open_chan = get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id());
290+
291+
nodes[0].node.close_channel(&chan_id, &nodes[1].node.get_our_node_id()).unwrap();
292+
check_closed_event!(nodes[0], 1, ClosureReason::HolderForceClosed, [nodes[1].node.get_our_node_id()], 1_000_000);
293+
}
294+
280295
#[test]
281296
fn expect_channel_shutdown_state_with_force_closure() {
282297
// Test sending a shutdown prior to channel_ready after funding generation

0 commit comments

Comments
 (0)