Skip to content

Commit 7aa38e3

Browse files
committed
Do not remove Outbound Channel immediately when peer disconnects
- Do not remove channel immediately when peer_disconnect, instead removed it after some time if peer doesn't reconnect soon (handled in previous commit). - Do not mark per ok_to_remove if we have some OutboundV1Channels too. - Rebroadcast SendOpenChannel for outboundV1Channel when peer reconnects. - Also, update the relevant tests to account for the new behavior change
1 parent fbeb7ac commit 7aa38e3

File tree

2 files changed

+36
-15
lines changed

2 files changed

+36
-15
lines changed

lightning/src/ln/channelmanager.rs

+22-12
Original file line numberDiff line numberDiff line change
@@ -893,6 +893,7 @@ impl <SP: Deref> PeerState<SP> where SP::Target: SignerProvider {
893893
return false
894894
}
895895
self.channel_by_id.iter().filter(|(_, phase)| matches!(phase, ChannelPhase::Funded(_))).count() == 0
896+
&& self.channel_by_id.iter().filter(|(_, phase)| matches!(phase, ChannelPhase::UnfundedOutboundV1(_))).count() == 0
896897
&& self.monitor_update_blocked_actions.is_empty()
897898
&& self.in_flight_monitor_updates.is_empty()
898899
}
@@ -8869,10 +8870,12 @@ where
88698870
}
88708871
&mut chan.context
88718872
},
8872-
// Unfunded channels will always be removed.
8873-
ChannelPhase::UnfundedOutboundV1(chan) => {
8874-
&mut chan.context
8873+
// We retain UnfundedOutboundV1 channel for some time in case
8874+
// peer unexpectedly disconnects, and intends to reconnect again.
8875+
ChannelPhase::UnfundedOutboundV1(_) => {
8876+
return true;
88758877
},
8878+
// Unfunded inbound channels will always be removed.
88768879
ChannelPhase::UnfundedInboundV1(chan) => {
88778880
&mut chan.context
88788881
},
@@ -9011,15 +9014,22 @@ where
90119014
let peer_state = &mut *peer_state_lock;
90129015
let pending_msg_events = &mut peer_state.pending_msg_events;
90139016

9014-
peer_state.channel_by_id.iter_mut().filter_map(|(_, phase)|
9015-
if let ChannelPhase::Funded(chan) = phase { Some(chan) } else { None }
9016-
).for_each(|chan| {
9017-
let logger = WithChannelContext::from(&self.logger, &chan.context);
9018-
pending_msg_events.push(events::MessageSendEvent::SendChannelReestablish {
9019-
node_id: chan.context.get_counterparty_node_id(),
9020-
msg: chan.get_channel_reestablish(&&logger),
9021-
});
9022-
});
9017+
for (_, phase) in peer_state.channel_by_id.iter_mut() {
9018+
if let ChannelPhase::Funded(chan) = phase {
9019+
let logger = WithChannelContext::from(&self.logger, &chan.context);
9020+
pending_msg_events.push(events::MessageSendEvent::SendChannelReestablish {
9021+
node_id: chan.context.get_counterparty_node_id(),
9022+
msg: chan.get_channel_reestablish(&&logger),
9023+
});
9024+
}
9025+
else if let ChannelPhase::UnfundedOutboundV1(chan) = phase {
9026+
pending_msg_events.push(events::MessageSendEvent::SendOpenChannel {
9027+
node_id: chan.context.get_counterparty_node_id(),
9028+
msg: chan.get_open_channel(self.chain_hash),
9029+
});
9030+
}
9031+
// else don't do anything if the channel is UnfundedInbound Channel.
9032+
}
90239033
}
90249034

90259035
return NotifyOption::SkipPersistHandleEvents;

lightning/src/ln/functional_tests.rs

+14-3
Original file line numberDiff line numberDiff line change
@@ -3692,10 +3692,16 @@ fn test_dup_events_on_peer_disconnect() {
36923692
expect_payment_path_successful!(nodes[0]);
36933693
}
36943694

3695+
3696+
// The following test is disabled because we no longer close the channel
3697+
// immediately after funding brodcasts. Instead we wait for some time for
3698+
// the peer to reconnect back, and only close it after it become stale for
3699+
// UNFUNDED_CHANNEL_AGE_LIMIT_TICKS
36953700
#[test]
3701+
#[ignore]
36963702
fn test_peer_disconnected_before_funding_broadcasted() {
36973703
// Test that channels are closed with `ClosureReason::DisconnectedPeer` if the peer disconnects
3698-
// before the funding transaction has been broadcasted.
3704+
// before the funding transaction has been broadcasted, and doesn't reconnect back within time.
36993705
let chanmon_cfgs = create_chanmon_cfgs(2);
37003706
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
37013707
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
@@ -3724,8 +3730,8 @@ fn test_peer_disconnected_before_funding_broadcasted() {
37243730
assert_eq!(nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap().len(), 0);
37253731
}
37263732

3727-
// Ensure that the channel is closed with `ClosureReason::DisconnectedPeer` when the peers are
3728-
// disconnected before the funding transaction was broadcasted.
3733+
// Ensure that the channel is closed after timeout with `ClosureReason::DisconnectedPeer`
3734+
// when the peers are disconnected before the funding transaction was broadcasted.
37293735
nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id());
37303736
nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id());
37313737

@@ -10688,6 +10694,11 @@ fn test_disconnect_in_funding_batch() {
1068810694
// The remaining peer in the batch disconnects.
1068910695
nodes[0].node.peer_disconnected(&nodes[2].node.get_our_node_id());
1069010696

10697+
// After the time expires for allowing peer to connect back
10698+
for _ in 0..UNFUNDED_CHANNEL_AGE_LIMIT_TICKS {
10699+
nodes[0].node.timer_tick_occurred();
10700+
}
10701+
1069110702
// The channels in the batch will close immediately.
1069210703
let funding_txo_1 = OutPoint { txid: tx.txid(), index: 0 };
1069310704
let funding_txo_2 = OutPoint { txid: tx.txid(), index: 1 };

0 commit comments

Comments
 (0)