Skip to content

Commit 73b20e2

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 3a67c81 commit 73b20e2

File tree

2 files changed

+24
-16
lines changed

2 files changed

+24
-16
lines changed

lightning/src/ln/channelmanager.rs

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2603,7 +2603,8 @@ where
26032603

26042604
let mut failed_htlcs: Vec<(HTLCSource, PaymentHash)>;
26052605
let mut shutdown_result = None;
2606-
loop {
2606+
2607+
{
26072608
let per_peer_state = self.per_peer_state.read().unwrap();
26082609

26092610
let peer_state_mutex = per_peer_state.get(counterparty_node_id)
@@ -2614,10 +2615,11 @@ where
26142615

26152616
match peer_state.channel_by_id.entry(channel_id.clone()) {
26162617
hash_map::Entry::Occupied(mut chan_phase_entry) => {
2618+
let unbroadcasted_batch_funding_txid =
2619+
chan_phase_entry.get().context().unbroadcasted_batch_funding_txid();
26172620
if let ChannelPhase::Funded(chan) = chan_phase_entry.get_mut() {
26182621
let funding_txo_opt = chan.context.get_funding_txo();
26192622
let their_features = &peer_state.latest_features;
2620-
let unbroadcasted_batch_funding_txid = chan.context.unbroadcasted_batch_funding_txid();
26212623
let (shutdown_msg, mut monitor_update_opt, htlcs) =
26222624
chan.get_shutdown(&self.signer_provider, their_features, target_feerate_sats_per_1000_weight, override_shutdown_script)?;
26232625
failed_htlcs = htlcs;
@@ -2637,21 +2639,12 @@ where
26372639
if let Some(monitor_update) = monitor_update_opt.take() {
26382640
handle_new_monitor_update!(self, funding_txo_opt.unwrap(), monitor_update,
26392641
peer_state_lock, peer_state, per_peer_state, chan);
2640-
break;
2641-
}
2642-
2643-
if chan.is_shutdown() {
2644-
if let ChannelPhase::Funded(chan) = remove_channel_phase!(self, chan_phase_entry) {
2645-
if let Ok(channel_update) = self.get_channel_update_for_broadcast(&chan) {
2646-
peer_state.pending_msg_events.push(events::MessageSendEvent::BroadcastChannelUpdate {
2647-
msg: channel_update
2648-
});
2649-
}
2650-
self.issue_channel_close_events(&chan.context, ClosureReason::HolderForceClosed);
2651-
shutdown_result = Some((None, Vec::new(), unbroadcasted_batch_funding_txid));
2652-
}
26532642
}
2654-
break;
2643+
} else {
2644+
self.issue_channel_close_events(chan_phase_entry.get().context(), ClosureReason::HolderForceClosed);
2645+
failed_htlcs = Vec::new();
2646+
remove_channel_phase!(self, chan_phase_entry);
2647+
shutdown_result = Some((None, Vec::new(), unbroadcasted_batch_funding_txid));
26552648
}
26562649
},
26572650
hash_map::Entry::Vacant(_) => {

lightning/src/ln/shutdown_tests.rs

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

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

0 commit comments

Comments
 (0)