Skip to content

Commit 0d30005

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 bfb503e commit 0d30005

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
@@ -2663,9 +2663,10 @@ where
26632663
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> {
26642664
let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(self);
26652665

2666-
let mut failed_htlcs: Vec<(HTLCSource, PaymentHash)>;
2667-
let shutdown_result;
2668-
loop {
2666+
let mut failed_htlcs: Vec<(HTLCSource, PaymentHash)> = Vec::new();
2667+
let mut shutdown_result = None;
2668+
2669+
{
26692670
let per_peer_state = self.per_peer_state.read().unwrap();
26702671

26712672
let peer_state_mutex = per_peer_state.get(counterparty_node_id)
@@ -2682,8 +2683,6 @@ where
26822683
let (shutdown_msg, mut monitor_update_opt, htlcs) =
26832684
chan.get_shutdown(&self.signer_provider, their_features, target_feerate_sats_per_1000_weight, override_shutdown_script)?;
26842685
failed_htlcs = htlcs;
2685-
shutdown_result = None;
2686-
debug_assert_eq!(shutdown_result.is_some(), chan.is_shutdown());
26872686

26882687
// We can send the `shutdown` message before updating the `ChannelMonitor`
26892688
// here as we don't need the monitor update to complete until we send a
@@ -2700,20 +2699,11 @@ where
27002699
if let Some(monitor_update) = monitor_update_opt.take() {
27012700
handle_new_monitor_update!(self, funding_txo_opt.unwrap(), monitor_update,
27022701
peer_state_lock, peer_state, per_peer_state, chan);
2703-
break;
27042702
}
2705-
2706-
if chan.is_shutdown() {
2707-
if let ChannelPhase::Funded(chan) = remove_channel_phase!(self, chan_phase_entry) {
2708-
if let Ok(channel_update) = self.get_channel_update_for_broadcast(&chan) {
2709-
peer_state.pending_msg_events.push(events::MessageSendEvent::BroadcastChannelUpdate {
2710-
msg: channel_update
2711-
});
2712-
}
2713-
self.issue_channel_close_events(&chan.context, ClosureReason::HolderForceClosed);
2714-
}
2715-
}
2716-
break;
2703+
} else {
2704+
self.issue_channel_close_events(chan_phase_entry.get().context(), ClosureReason::HolderForceClosed);
2705+
let mut chan_phase = remove_channel_phase!(self, chan_phase_entry);
2706+
shutdown_result = Some(chan_phase.context_mut().force_shutdown(false));
27172707
}
27182708
},
27192709
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)