@@ -1401,10 +1401,17 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CM
14011401
14021402 // Need an Init as first message
14031403 if let wire:: Message :: Init ( msg) = message {
1404- if msg. features . requires_unknown_bits ( ) {
1405- log_debug ! ( self . logger, "Peer features required unknown version bits" ) ;
1404+ let our_features = self . init_features ( & their_node_id) ;
1405+ if msg. features . requires_unknown_bits_from ( & our_features) {
1406+ log_debug ! ( self . logger, "Peer requires features unknown to us" ) ;
14061407 return Err ( PeerHandleError { } . into ( ) ) ;
14071408 }
1409+
1410+ if our_features. requires_unknown_bits_from ( & msg. features ) {
1411+ log_debug ! ( self . logger, "We require features unknown to our peer" ) ;
1412+ return Err ( PeerHandleError { } . into ( ) ) ;
1413+ }
1414+
14081415 if peer_lock. their_features . is_some ( ) {
14091416 return Err ( PeerHandleError { } . into ( ) ) ;
14101417 }
@@ -2276,16 +2283,19 @@ fn is_gossip_msg(type_id: u16) -> bool {
22762283mod tests {
22772284 use crate :: sign:: { NodeSigner , Recipient } ;
22782285 use crate :: events;
2286+ use crate :: io;
2287+ use crate :: ln:: features:: { InitFeatures , NodeFeatures } ;
22792288 use crate :: ln:: peer_channel_encryptor:: PeerChannelEncryptor ;
2280- use crate :: ln:: peer_handler:: { PeerManager , MessageHandler , SocketDescriptor , IgnoringMessageHandler , filter_addresses} ;
2289+ use crate :: ln:: peer_handler:: { CustomMessageHandler , PeerManager , MessageHandler , SocketDescriptor , IgnoringMessageHandler , filter_addresses} ;
22812290 use crate :: ln:: { msgs, wire} ;
2282- use crate :: ln:: msgs:: NetAddress ;
2291+ use crate :: ln:: msgs:: { LightningError , NetAddress } ;
22832292 use crate :: util:: test_utils;
22842293
2285- use bitcoin:: secp256k1:: SecretKey ;
2294+ use bitcoin:: secp256k1:: { PublicKey , SecretKey } ;
22862295
22872296 use crate :: prelude:: * ;
22882297 use crate :: sync:: { Arc , Mutex } ;
2298+ use core:: convert:: Infallible ;
22892299 use core:: sync:: atomic:: { AtomicBool , Ordering } ;
22902300
22912301 #[ derive( Clone ) ]
@@ -2318,19 +2328,74 @@ mod tests {
23182328 struct PeerManagerCfg {
23192329 chan_handler : test_utils:: TestChannelMessageHandler ,
23202330 routing_handler : test_utils:: TestRoutingMessageHandler ,
2331+ custom_handler : TestCustomMessageHandler ,
23212332 logger : test_utils:: TestLogger ,
23222333 node_signer : test_utils:: TestNodeSigner ,
23232334 }
23242335
2336+ struct TestCustomMessageHandler {
2337+ features : InitFeatures ,
2338+ }
2339+
2340+ impl wire:: CustomMessageReader for TestCustomMessageHandler {
2341+ type CustomMessage = Infallible ;
2342+ fn read < R : io:: Read > ( & self , _: u16 , _: & mut R ) -> Result < Option < Self :: CustomMessage > , msgs:: DecodeError > {
2343+ Ok ( None )
2344+ }
2345+ }
2346+
2347+ impl CustomMessageHandler for TestCustomMessageHandler {
2348+ fn handle_custom_message ( & self , _: Infallible , _: & PublicKey ) -> Result < ( ) , LightningError > {
2349+ unreachable ! ( ) ;
2350+ }
2351+
2352+ fn get_and_clear_pending_msg ( & self ) -> Vec < ( PublicKey , Self :: CustomMessage ) > { Vec :: new ( ) }
2353+
2354+ fn provided_node_features ( & self ) -> NodeFeatures { NodeFeatures :: empty ( ) }
2355+
2356+ fn provided_init_features ( & self , _: & PublicKey ) -> InitFeatures {
2357+ self . features . clone ( )
2358+ }
2359+ }
2360+
23252361 fn create_peermgr_cfgs ( peer_count : usize ) -> Vec < PeerManagerCfg > {
23262362 let mut cfgs = Vec :: new ( ) ;
23272363 for i in 0 ..peer_count {
23282364 let node_secret = SecretKey :: from_slice ( & [ 42 + i as u8 ; 32 ] ) . unwrap ( ) ;
2365+ let features = {
2366+ let mut feature_bits = vec ! [ 0u8 ; 33 ] ;
2367+ feature_bits[ 32 ] = 0b00000001 ;
2368+ InitFeatures :: from_le_bytes ( feature_bits)
2369+ } ;
2370+ cfgs. push (
2371+ PeerManagerCfg {
2372+ chan_handler : test_utils:: TestChannelMessageHandler :: new ( ) ,
2373+ logger : test_utils:: TestLogger :: new ( ) ,
2374+ routing_handler : test_utils:: TestRoutingMessageHandler :: new ( ) ,
2375+ custom_handler : TestCustomMessageHandler { features } ,
2376+ node_signer : test_utils:: TestNodeSigner :: new ( node_secret) ,
2377+ }
2378+ ) ;
2379+ }
2380+
2381+ cfgs
2382+ }
2383+
2384+ fn create_incompatible_peermgr_cfgs ( peer_count : usize ) -> Vec < PeerManagerCfg > {
2385+ let mut cfgs = Vec :: new ( ) ;
2386+ for i in 0 ..peer_count {
2387+ let node_secret = SecretKey :: from_slice ( & [ 42 + i as u8 ; 32 ] ) . unwrap ( ) ;
2388+ let features = {
2389+ let mut feature_bits = vec ! [ 0u8 ; 33 + i + 1 ] ;
2390+ feature_bits[ 33 + i] = 0b00000001 ;
2391+ InitFeatures :: from_le_bytes ( feature_bits)
2392+ } ;
23292393 cfgs. push (
23302394 PeerManagerCfg {
23312395 chan_handler : test_utils:: TestChannelMessageHandler :: new ( ) ,
23322396 logger : test_utils:: TestLogger :: new ( ) ,
23332397 routing_handler : test_utils:: TestRoutingMessageHandler :: new ( ) ,
2398+ custom_handler : TestCustomMessageHandler { features } ,
23342399 node_signer : test_utils:: TestNodeSigner :: new ( node_secret) ,
23352400 }
23362401 ) ;
@@ -2339,13 +2404,13 @@ mod tests {
23392404 cfgs
23402405 }
23412406
2342- fn create_network < ' a > ( peer_count : usize , cfgs : & ' a Vec < PeerManagerCfg > ) -> Vec < PeerManager < FileDescriptor , & ' a test_utils:: TestChannelMessageHandler , & ' a test_utils:: TestRoutingMessageHandler , IgnoringMessageHandler , & ' a test_utils:: TestLogger , IgnoringMessageHandler , & ' a test_utils:: TestNodeSigner > > {
2407+ fn create_network < ' a > ( peer_count : usize , cfgs : & ' a Vec < PeerManagerCfg > ) -> Vec < PeerManager < FileDescriptor , & ' a test_utils:: TestChannelMessageHandler , & ' a test_utils:: TestRoutingMessageHandler , IgnoringMessageHandler , & ' a test_utils:: TestLogger , & ' a TestCustomMessageHandler , & ' a test_utils:: TestNodeSigner > > {
23432408 let mut peers = Vec :: new ( ) ;
23442409 for i in 0 ..peer_count {
23452410 let ephemeral_bytes = [ i as u8 ; 32 ] ;
23462411 let msg_handler = MessageHandler {
23472412 chan_handler : & cfgs[ i] . chan_handler , route_handler : & cfgs[ i] . routing_handler ,
2348- onion_message_handler : IgnoringMessageHandler { } , custom_message_handler : IgnoringMessageHandler { }
2413+ onion_message_handler : IgnoringMessageHandler { } , custom_message_handler : & cfgs [ i ] . custom_handler
23492414 } ;
23502415 let peer = PeerManager :: new ( msg_handler, 0 , & ephemeral_bytes, & cfgs[ i] . logger , & cfgs[ i] . node_signer ) ;
23512416 peers. push ( peer) ;
@@ -2354,7 +2419,7 @@ mod tests {
23542419 peers
23552420 }
23562421
2357- fn establish_connection < ' a > ( peer_a : & PeerManager < FileDescriptor , & ' a test_utils:: TestChannelMessageHandler , & ' a test_utils:: TestRoutingMessageHandler , IgnoringMessageHandler , & ' a test_utils:: TestLogger , IgnoringMessageHandler , & ' a test_utils:: TestNodeSigner > , peer_b : & PeerManager < FileDescriptor , & ' a test_utils:: TestChannelMessageHandler , & ' a test_utils:: TestRoutingMessageHandler , IgnoringMessageHandler , & ' a test_utils:: TestLogger , IgnoringMessageHandler , & ' a test_utils:: TestNodeSigner > ) -> ( FileDescriptor , FileDescriptor ) {
2422+ fn establish_connection < ' a > ( peer_a : & PeerManager < FileDescriptor , & ' a test_utils:: TestChannelMessageHandler , & ' a test_utils:: TestRoutingMessageHandler , IgnoringMessageHandler , & ' a test_utils:: TestLogger , & ' a TestCustomMessageHandler , & ' a test_utils:: TestNodeSigner > , peer_b : & PeerManager < FileDescriptor , & ' a test_utils:: TestChannelMessageHandler , & ' a test_utils:: TestRoutingMessageHandler , IgnoringMessageHandler , & ' a test_utils:: TestLogger , & ' a TestCustomMessageHandler , & ' a test_utils:: TestNodeSigner > ) -> ( FileDescriptor , FileDescriptor ) {
23582423 let id_a = peer_a. node_signer . get_node_id ( Recipient :: Node ) . unwrap ( ) ;
23592424 let mut fd_a = FileDescriptor {
23602425 fd : 1 , outbound_data : Arc :: new ( Mutex :: new ( Vec :: new ( ) ) ) ,
@@ -2469,6 +2534,42 @@ mod tests {
24692534 thrd_b. join ( ) . unwrap ( ) ;
24702535 }
24712536
2537+ #[ test]
2538+ fn test_incompatible_peers ( ) {
2539+ let cfgs = create_peermgr_cfgs ( 2 ) ;
2540+ let incompatible_cfgs = create_incompatible_peermgr_cfgs ( 2 ) ;
2541+
2542+ let peers = create_network ( 2 , & cfgs) ;
2543+ let incompatible_peers = create_network ( 2 , & incompatible_cfgs) ;
2544+ let peer_pairs = [ ( & peers[ 0 ] , & incompatible_peers[ 0 ] ) , ( & incompatible_peers[ 1 ] , & peers[ 1 ] ) ] ;
2545+ for ( peer_a, peer_b) in peer_pairs {
2546+ let id_a = peer_a. node_signer . get_node_id ( Recipient :: Node ) . unwrap ( ) ;
2547+ let mut fd_a = FileDescriptor {
2548+ fd : 1 , outbound_data : Arc :: new ( Mutex :: new ( Vec :: new ( ) ) ) ,
2549+ disconnect : Arc :: new ( AtomicBool :: new ( false ) ) ,
2550+ } ;
2551+ let addr_a = NetAddress :: IPv4 { addr : [ 127 , 0 , 0 , 1 ] , port : 1000 } ;
2552+ let mut fd_b = FileDescriptor {
2553+ fd : 1 , outbound_data : Arc :: new ( Mutex :: new ( Vec :: new ( ) ) ) ,
2554+ disconnect : Arc :: new ( AtomicBool :: new ( false ) ) ,
2555+ } ;
2556+ let addr_b = NetAddress :: IPv4 { addr : [ 127 , 0 , 0 , 1 ] , port : 1001 } ;
2557+ let initial_data = peer_b. new_outbound_connection ( id_a, fd_b. clone ( ) , Some ( addr_a. clone ( ) ) ) . unwrap ( ) ;
2558+ peer_a. new_inbound_connection ( fd_a. clone ( ) , Some ( addr_b. clone ( ) ) ) . unwrap ( ) ;
2559+ assert_eq ! ( peer_a. read_event( & mut fd_a, & initial_data) . unwrap( ) , false ) ;
2560+ peer_a. process_events ( ) ;
2561+
2562+ let a_data = fd_a. outbound_data . lock ( ) . unwrap ( ) . split_off ( 0 ) ;
2563+ assert_eq ! ( peer_b. read_event( & mut fd_b, & a_data) . unwrap( ) , false ) ;
2564+
2565+ peer_b. process_events ( ) ;
2566+ let b_data = fd_b. outbound_data . lock ( ) . unwrap ( ) . split_off ( 0 ) ;
2567+
2568+ // Should fail because of unknown required features
2569+ assert ! ( peer_a. read_event( & mut fd_a, & b_data) . is_err( ) ) ;
2570+ }
2571+ }
2572+
24722573 #[ test]
24732574 fn test_disconnect_peer ( ) {
24742575 // Simple test which builds a network of PeerManager, connects and brings them to NoiseState::Finished and
0 commit comments