@@ -8836,3 +8836,66 @@ fn test_duplicate_chan_id() {
8836
8836
update_nodes_with_chan_announce ( & nodes, 0 , 1 , & announcement, & as_update, & bs_update) ;
8837
8837
send_payment ( & nodes[ 0 ] , & [ & nodes[ 1 ] ] , 8000000 , 8_000_000 ) ;
8838
8838
}
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