Skip to content

Commit 0fd3d31

Browse files
committed
Re-enable the test, improve the comments, and handle general cleanup
- Repurpose the test_disconnect_in_funding_batch to test that all channels in the batch close when one them closes
1 parent 231a0bd commit 0fd3d31

File tree

2 files changed

+118
-99
lines changed

2 files changed

+118
-99
lines changed

lightning/src/ln/channelmanager.rs

+26-16
Original file line numberDiff line numberDiff line change
@@ -892,8 +892,9 @@ impl <SP: Deref> PeerState<SP> where SP::Target: SignerProvider {
892892
if require_disconnected && self.is_connected {
893893
return false
894894
}
895-
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
895+
!self.channel_by_id.iter().any(|(_, phase)|
896+
matches!(phase, ChannelPhase::Funded(_) | ChannelPhase::UnfundedOutboundV1(_))
897+
)
897898
&& self.monitor_update_blocked_actions.is_empty()
898899
&& self.in_flight_monitor_updates.is_empty()
899900
}
@@ -9015,20 +9016,29 @@ where
90159016
let pending_msg_events = &mut peer_state.pending_msg_events;
90169017

90179018
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-
});
9019+
match phase {
9020+
ChannelPhase::Funded(chan) => {
9021+
let logger = WithChannelContext::from(&self.logger, &chan.context);
9022+
pending_msg_events.push(events::MessageSendEvent::SendChannelReestablish {
9023+
node_id: chan.context.get_counterparty_node_id(),
9024+
msg: chan.get_channel_reestablish(&&logger),
9025+
});
9026+
}
9027+
9028+
ChannelPhase::UnfundedOutboundV1(chan) => {
9029+
pending_msg_events.push(events::MessageSendEvent::SendOpenChannel {
9030+
node_id: chan.context.get_counterparty_node_id(),
9031+
msg: chan.get_open_channel(self.chain_hash),
9032+
});
9033+
}
9034+
9035+
ChannelPhase::UnfundedInboundV1(_) => {
9036+
// Since unfunded inbound channel maps are cleared upon disconnecting a peer,
9037+
// they are not persisted and won't be recovered after a crash.
9038+
// Therefore, they shouldn't exist at this point.
9039+
debug_assert!(false);
9040+
}
90309041
}
9031-
// else don't do anything if the channel is UnfundedInbound Channel.
90329042
}
90339043
}
90349044

@@ -11146,7 +11156,7 @@ mod tests {
1114611156
use bitcoin::secp256k1::{PublicKey, Secp256k1, SecretKey};
1114711157
use core::sync::atomic::Ordering;
1114811158
use crate::events::{Event, HTLCDestination, MessageSendEvent, MessageSendEventsProvider, ClosureReason};
11149-
use crate::ln::{PaymentPreimage, PaymentHash, PaymentSecret};
11159+
use crate::ln::{PaymentPreimage, PaymentHash, PaymentSecret};
1115011160
use crate::ln::ChannelId;
1115111161
use crate::ln::channelmanager::{create_recv_pending_htlc_info, HTLCForwardInfo, inbound_payment, PaymentId, PaymentSendFailure, RecipientOnionFields, InterceptId};
1115211162
use crate::ln::functional_test_utils::*;

lightning/src/ln/functional_tests.rs

+92-83
Original file line numberDiff line numberDiff line change
@@ -3692,13 +3692,7 @@ 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
37003695
#[test]
3701-
#[ignore]
37023696
fn test_peer_disconnected_before_funding_broadcasted() {
37033697
// Test that channels are closed with `ClosureReason::DisconnectedPeer` if the peer disconnects
37043698
// before the funding transaction has been broadcasted, and doesn't reconnect back within time.
@@ -3730,12 +3724,19 @@ fn test_peer_disconnected_before_funding_broadcasted() {
37303724
assert_eq!(nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap().len(), 0);
37313725
}
37323726

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

3738-
check_closed_event!(&nodes[0], 2, ClosureReason::DisconnectedPeer, true
3731+
// The time for peers to reconnect expires.
3732+
for _ in 0..UNFUNDED_CHANNEL_AGE_LIMIT_TICKS {
3733+
nodes[0].node.timer_tick_occurred();
3734+
}
3735+
3736+
// Ensure that the channel is closed with `ClosureReason::HolderForceClosed`
3737+
// when the peers are disconnected and do not reconnect before the funding
3738+
// transaction is broadcasted.
3739+
check_closed_event!(&nodes[0], 2, ClosureReason::HolderForceClosed, true
37393740
, [nodes[1].node.get_our_node_id()], 1000000);
37403741
check_closed_event!(&nodes[1], 1, ClosureReason::DisconnectedPeer, false
37413742
, [nodes[0].node.get_our_node_id()], 1000000);
@@ -10512,22 +10513,22 @@ fn test_remove_expired_inbound_unfunded_channels() {
1051210513
}
1051310514

1051410515
#[test]
10515-
fn test_channel_close_when_not_timely_accepted() {
10516-
// Create network of two nodes
10517-
let chanmon_cfgs = create_chanmon_cfgs(2);
10518-
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
10519-
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
10520-
let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
10516+
fn test_channel_close_when_not_timely_accepted() {
10517+
// Create network of two nodes
10518+
let chanmon_cfgs = create_chanmon_cfgs(2);
10519+
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
10520+
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
10521+
let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
1052110522

10522-
// Simulate peer-diconnects mid-handshake
10523-
// The channel is initiated from the node 0 side,
10524-
// But the nodes disconnects before node 1 could send accept channel
10525-
let create_chan_id = nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), 100000, 10001, 42, None, None).unwrap();
10526-
let open_channel_msg = get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id());
10527-
assert_eq!(open_channel_msg.temporary_channel_id, create_chan_id);
10523+
// Simulate peer-disconnects mid-handshake
10524+
// The channel is initiated from the node 0 side,
10525+
// but the nodes disconnect before node 1 could send accept channel
10526+
let create_chan_id = nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), 100000, 10001, 42, None, None).unwrap();
10527+
let open_channel_msg = get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id());
10528+
assert_eq!(open_channel_msg.temporary_channel_id, create_chan_id);
1052810529

10529-
nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id());
10530-
nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id());
10530+
nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id());
10531+
nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id());
1053110532

1053210533
// Make sure that we have not removed the OutboundV1Channel from node[0] immediately.
1053310534
assert_eq!(nodes[0].node.list_channels().len(), 1);
@@ -10539,42 +10540,41 @@ fn test_remove_expired_inbound_unfunded_channels() {
1053910540
assert!(per_peer_state.is_none());
1054010541
}
1054110542

10542-
// In the meantime, some time passes.
10543-
for _ in 0..UNFUNDED_CHANNEL_AGE_LIMIT_TICKS {
10544-
nodes[0].node.timer_tick_occurred();
10545-
}
10546-
10547-
// Since we disconnected from peer and did not connect back within time
10548-
// We should have forced-closed the channel by now.
10549-
check_closed_event!(nodes[0], 1, ClosureReason::HolderForceClosed, [nodes[1].node.get_our_node_id()], 100000);
10543+
// In the meantime, some time passes.
10544+
for _ in 0..UNFUNDED_CHANNEL_AGE_LIMIT_TICKS {
10545+
nodes[0].node.timer_tick_occurred();
10546+
}
1055010547

10551-
{
10552-
// Since accept channel message was never received
10553-
// The channel should be forced close by now from node 0 side
10554-
// and the peer removed from per_peer_state
10555-
let node_0_per_peer_state = nodes[0].node.per_peer_state.read().unwrap();
10556-
assert_eq!(node_0_per_peer_state.len(), 0);
10557-
}
10548+
// Since we disconnected from peer and did not connect back within time,
10549+
// we should have forced-closed the channel by now.
10550+
check_closed_event!(nodes[0], 1, ClosureReason::HolderForceClosed, [nodes[1].node.get_our_node_id()], 100000);
1055810551

10552+
{
10553+
// Since accept channel message was never received
10554+
// The channel should be forced close by now from node 0 side
10555+
// and the peer removed from per_peer_state
10556+
let node_0_per_peer_state = nodes[0].node.per_peer_state.read().unwrap();
10557+
assert_eq!(node_0_per_peer_state.len(), 0);
1055910558
}
10559+
}
1056010560

10561-
#[test]
10562-
fn test_rebroadcast_open_channel_when_reconnect_mid_handshake() {
10563-
// Create network of two nodes
10564-
let chanmon_cfgs = create_chanmon_cfgs(2);
10565-
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
10566-
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
10567-
let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
10561+
#[test]
10562+
fn test_rebroadcast_open_channel_when_reconnect_mid_handshake() {
10563+
// Create network of two nodes
10564+
let chanmon_cfgs = create_chanmon_cfgs(2);
10565+
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
10566+
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
10567+
let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
1056810568

10569-
// Simulate peer-diconnects mid-handshake
10570-
// The channel is initiated from the node 0 side,
10571-
// But the nodes disconnects before node 1 could send accept channel
10572-
let create_chan_id = nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), 100000, 10001, 42, None, None).unwrap();
10573-
let open_channel_msg = get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id());
10574-
assert_eq!(open_channel_msg.temporary_channel_id, create_chan_id);
10569+
// Simulate peer-disconnects mid-handshake
10570+
// The channel is initiated from the node 0 side,
10571+
// but the nodes disconnect before node 1 could send accept channel
10572+
let create_chan_id = nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), 100000, 10001, 42, None, None).unwrap();
10573+
let open_channel_msg = get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id());
10574+
assert_eq!(open_channel_msg.temporary_channel_id, create_chan_id);
1057510575

10576-
nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id());
10577-
nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id());
10576+
nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id());
10577+
nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id());
1057810578

1057910579
// Make sure that we have not removed the OutboundV1Channel from node[0] immediately.
1058010580
assert_eq!(nodes[0].node.list_channels().len(), 1);
@@ -10586,13 +10586,13 @@ fn test_remove_expired_inbound_unfunded_channels() {
1058610586
assert!(per_peer_state.is_none());
1058710587
}
1058810588

10589-
// The peers now reconnect
10590-
nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init {
10591-
features: nodes[1].node.init_features(), networks: None, remote_network_address: None
10592-
}, true).unwrap();
10593-
nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init {
10594-
features: nodes[0].node.init_features(), networks: None, remote_network_address: None
10595-
}, false).unwrap();
10589+
// The peers now reconnect
10590+
nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init {
10591+
features: nodes[1].node.init_features(), networks: None, remote_network_address: None
10592+
}, true).unwrap();
10593+
nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init {
10594+
features: nodes[0].node.init_features(), networks: None, remote_network_address: None
10595+
}, false).unwrap();
1059610596

1059710597
// Make sure the SendOpenChannel message is added to node_0 pending message events
1059810598
let msg_events = nodes[0].node.get_and_clear_pending_msg_events();
@@ -10759,7 +10759,9 @@ fn test_batch_channel_open() {
1075910759
}
1076010760

1076110761
#[test]
10762-
fn test_disconnect_in_funding_batch() {
10762+
fn test_close_in_funding_batch() {
10763+
// This test ensures that if one of the channels
10764+
// in the batch closes, the complete batch will close.
1076310765
let chanmon_cfgs = create_chanmon_cfgs(3);
1076410766
let node_cfgs = create_node_cfgs(3, &chanmon_cfgs);
1076510767
let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, None, None]);
@@ -10783,19 +10785,39 @@ fn test_disconnect_in_funding_batch() {
1078310785
// The transaction should not have been broadcast before all channels are ready.
1078410786
assert_eq!(nodes[0].tx_broadcaster.txn_broadcast().len(), 0);
1078510787

10786-
// The remaining peer in the batch disconnects.
10787-
nodes[0].node.peer_disconnected(&nodes[2].node.get_our_node_id());
10788-
10789-
// After the time expires for allowing peer to connect back
10790-
for _ in 0..UNFUNDED_CHANNEL_AGE_LIMIT_TICKS {
10791-
nodes[0].node.timer_tick_occurred();
10792-
}
10793-
10794-
// The channels in the batch will close immediately.
10788+
// Force-close the channel for which we've completed the initial monitor.
1079510789
let funding_txo_1 = OutPoint { txid: tx.txid(), index: 0 };
1079610790
let funding_txo_2 = OutPoint { txid: tx.txid(), index: 1 };
1079710791
let channel_id_1 = funding_txo_1.to_channel_id();
1079810792
let channel_id_2 = funding_txo_2.to_channel_id();
10793+
10794+
nodes[0].node.force_close_broadcasting_latest_txn(&channel_id_1, &nodes[1].node.get_our_node_id()).unwrap();
10795+
10796+
// The monitor should become closed.
10797+
check_added_monitors(&nodes[0], 1);
10798+
{
10799+
let mut monitor_updates = nodes[0].chain_monitor.monitor_updates.lock().unwrap();
10800+
let monitor_updates_1 = monitor_updates.get(&channel_id_1).unwrap();
10801+
assert_eq!(monitor_updates_1.len(), 1);
10802+
assert_eq!(monitor_updates_1[0].update_id, CLOSED_CHANNEL_UPDATE_ID);
10803+
}
10804+
10805+
let msg_events = nodes[0].node.get_and_clear_pending_msg_events();
10806+
match msg_events[0] {
10807+
MessageSendEvent::HandleError { .. } => (),
10808+
_ => panic!("Unexpected message."),
10809+
}
10810+
10811+
// We broadcast the commitment transaction as part of the force-close.
10812+
{
10813+
let broadcasted_txs = nodes[0].tx_broadcaster.txn_broadcast();
10814+
assert_eq!(broadcasted_txs.len(), 1);
10815+
assert!(broadcasted_txs[0].txid() != tx.txid());
10816+
assert_eq!(broadcasted_txs[0].input.len(), 1);
10817+
assert_eq!(broadcasted_txs[0].input[0].previous_output.txid, tx.txid());
10818+
}
10819+
10820+
// All channels in the batch should close immediately.
1079910821
check_closed_events(&nodes[0], &[
1080010822
ExpectedCloseEvent {
1080110823
channel_id: Some(channel_id_1),
@@ -10813,19 +10835,6 @@ fn test_disconnect_in_funding_batch() {
1081310835
},
1081410836
]);
1081510837

10816-
// The monitor should become closed.
10817-
check_added_monitors(&nodes[0], 1);
10818-
{
10819-
let mut monitor_updates = nodes[0].chain_monitor.monitor_updates.lock().unwrap();
10820-
let monitor_updates_1 = monitor_updates.get(&channel_id_1).unwrap();
10821-
assert_eq!(monitor_updates_1.len(), 1);
10822-
assert_eq!(monitor_updates_1[0].update_id, CLOSED_CHANNEL_UPDATE_ID);
10823-
}
10824-
10825-
// The funding transaction should not have been broadcast, and therefore, we don't need
10826-
// to broadcast a force-close transaction for the closed monitor.
10827-
assert_eq!(nodes[0].tx_broadcaster.txn_broadcast().len(), 0);
10828-
1082910838
// Ensure the channels don't exist anymore.
1083010839
assert!(nodes[0].node.list_channels().is_empty());
1083110840
}

0 commit comments

Comments
 (0)