@@ -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