Skip to content

Commit 85d86fe

Browse files
committed
Add test for error message hangline resulting in force-close
1 parent a16a9d5 commit 85d86fe

File tree

1 file changed

+63
-0
lines changed

1 file changed

+63
-0
lines changed

lightning/src/ln/functional_tests.rs

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8836,3 +8836,66 @@ fn test_duplicate_chan_id() {
88368836
update_nodes_with_chan_announce(&nodes, 0, 1, &announcement, &as_update, &bs_update);
88378837
send_payment(&nodes[0], &[&nodes[1]], 8000000, 8_000_000);
88388838
}
8839+
8840+
#[test]
8841+
fn test_error_chans_closed() {
8842+
// Test that we properly handle error messages, closing appropriate channels.
8843+
//
8844+
// Prior to #787 we'd allow a peer to make us force-close a channel we had with a different
8845+
// peer. The "real" fix for that is to index channels with peers_ids, however in the mean time
8846+
// we can test various edge cases around it to ensure we don't regress.
8847+
let chanmon_cfgs = create_chanmon_cfgs(3);
8848+
let node_cfgs = create_node_cfgs(3, &chanmon_cfgs);
8849+
let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, None, None]);
8850+
let nodes = create_network(3, &node_cfgs, &node_chanmgrs);
8851+
8852+
// Create some initial channels
8853+
let chan_1 = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 10001, InitFeatures::known(), InitFeatures::known());
8854+
let chan_2 = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 10001, InitFeatures::known(), InitFeatures::known());
8855+
let chan_3 = create_announced_chan_between_nodes_with_value(&nodes, 0, 2, 100000, 10001, InitFeatures::known(), InitFeatures::known());
8856+
8857+
assert_eq!(nodes[0].node.list_usable_channels().len(), 3);
8858+
assert_eq!(nodes[1].node.list_usable_channels().len(), 2);
8859+
assert_eq!(nodes[2].node.list_usable_channels().len(), 1);
8860+
8861+
// Closing a channel from a different peer has no effect
8862+
nodes[0].node.handle_error(&nodes[1].node.get_our_node_id(), &msgs::ErrorMessage { channel_id: chan_3.2, data: "ERR".to_owned() });
8863+
assert_eq!(nodes[0].node.list_usable_channels().len(), 3);
8864+
8865+
// Closing one channel doesn't impact others
8866+
nodes[0].node.handle_error(&nodes[1].node.get_our_node_id(), &msgs::ErrorMessage { channel_id: chan_2.2, data: "ERR".to_owned() });
8867+
check_added_monitors!(nodes[0], 1);
8868+
check_closed_broadcast!(nodes[0], false);
8869+
assert_eq!(nodes[0].node.list_usable_channels().len(), 2);
8870+
assert!(nodes[0].node.list_usable_channels()[0].channel_id == chan_1.2 || nodes[0].node.list_usable_channels()[1].channel_id == chan_1.2);
8871+
assert!(nodes[0].node.list_usable_channels()[0].channel_id == chan_3.2 || nodes[0].node.list_usable_channels()[1].channel_id == chan_3.2);
8872+
8873+
// A null channel ID should close all channels
8874+
let _chan_4 = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 10001, InitFeatures::known(), InitFeatures::known());
8875+
nodes[0].node.handle_error(&nodes[1].node.get_our_node_id(), &msgs::ErrorMessage { channel_id: [0; 32], data: "ERR".to_owned() });
8876+
check_added_monitors!(nodes[0], 2);
8877+
let events = nodes[0].node.get_and_clear_pending_msg_events();
8878+
assert_eq!(events.len(), 2);
8879+
match events[0] {
8880+
MessageSendEvent::BroadcastChannelUpdate { ref msg } => {
8881+
assert_eq!(msg.contents.flags & 2, 2);
8882+
},
8883+
_ => panic!("Unexpected event"),
8884+
}
8885+
match events[1] {
8886+
MessageSendEvent::BroadcastChannelUpdate { ref msg } => {
8887+
assert_eq!(msg.contents.flags & 2, 2);
8888+
},
8889+
_ => panic!("Unexpected event"),
8890+
}
8891+
// Note that at this point users of a standard PeerHandler will end up calling
8892+
// peer_disconnected with no_connection_possible set to false, duplicating the
8893+
// close-all-channels logic. That's OK, we don't want to end up not force-closing channels for
8894+
// users with their own peer handling logic. We duplicate the call here, however.
8895+
assert_eq!(nodes[0].node.list_usable_channels().len(), 1);
8896+
assert!(nodes[0].node.list_usable_channels()[0].channel_id == chan_3.2);
8897+
8898+
nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id(), true);
8899+
assert_eq!(nodes[0].node.list_usable_channels().len(), 1);
8900+
assert!(nodes[0].node.list_usable_channels()[0].channel_id == chan_3.2);
8901+
}

0 commit comments

Comments
 (0)