@@ -2042,7 +2042,7 @@ where L::Target: Logger {
20422042				// in the regular network graph. 
20432043				first_hop_targets. get ( & intro_node_id) . is_some ( )  ||
20442044				network_nodes. get ( & intro_node_id) . is_some ( ) ; 
2045- 			if  !have_intro_node_in_graph {  continue  } 
2045+ 			if  !have_intro_node_in_graph || our_node_id == intro_node_id  {  continue  } 
20462046			let  candidate = if  hint. 1 . blinded_hops . len ( )  == 1  { 
20472047				CandidateRouteHop :: OneHopBlinded  {  hint,  hint_idx } 
20482048			}  else  {  CandidateRouteHop :: Blinded  {  hint,  hint_idx }  } ; 
@@ -7075,6 +7075,116 @@ mod tests {
70757075		assert_eq ! ( route. get_total_fees( ) ,  blinded_payinfo. fee_base_msat as  u64 ) ; 
70767076		assert_eq ! ( route. get_total_amount( ) ,  amt_msat) ; 
70777077	} 
7078+ 
7079+ 	#[ test]  
7080+ 	fn  we_are_intro_node_candidate_hops ( )  { 
7081+ 		// This previously led to a panic in the router because we'd generate a Path with only a 
7082+ 		// BlindedTail and 0 unblinded hops, due to the only candidate hops being blinded route hints 
7083+ 		// where the origin node is the intro node. We now fully disallow considering candidate hops 
7084+ 		// where the origin node is the intro node. 
7085+ 		let  ( secp_ctx,  network_graph,  _,  _,  logger)  = build_graph ( ) ; 
7086+ 		let  ( _,  our_id,  _,  nodes)  = get_nodes ( & secp_ctx) ; 
7087+ 		let  scorer = ln_test_utils:: TestScorer :: new ( ) ; 
7088+ 		let  keys_manager = ln_test_utils:: TestKeysInterface :: new ( & [ 0u8 ;  32 ] ,  Network :: Testnet ) ; 
7089+ 		let  random_seed_bytes = keys_manager. get_secure_random_bytes ( ) ; 
7090+ 		let  config = UserConfig :: default ( ) ; 
7091+ 
7092+ 		// Values are taken from the fuzz input that uncovered this panic. 
7093+ 		let  amt_msat = 21_7020_5185_1423_0019 ; 
7094+ 
7095+ 		let  blinded_path = BlindedPath  { 
7096+ 			introduction_node_id :  our_id, 
7097+ 			blinding_point :  ln_test_utils:: pubkey ( 42 ) , 
7098+ 			blinded_hops :  vec ! [ 
7099+ 				BlindedHop  {  blinded_node_id:  ln_test_utils:: pubkey( 42  as  u8 ) ,  encrypted_payload:  Vec :: new( )  } , 
7100+ 				BlindedHop  {  blinded_node_id:  ln_test_utils:: pubkey( 42  as  u8 ) ,  encrypted_payload:  Vec :: new( )  } 
7101+ 			] , 
7102+ 		} ; 
7103+ 		let  blinded_payinfo = BlindedPayInfo  { 
7104+ 			fee_base_msat :  5052_9027 , 
7105+ 			fee_proportional_millionths :  5052_9027 , 
7106+ 			htlc_minimum_msat :  21_7020_5185_1423_0019 , 
7107+ 			htlc_maximum_msat :  1844_6744_0737_0955_1615 , 
7108+ 			cltv_expiry_delta :  0 , 
7109+ 			features :  BlindedHopFeatures :: empty ( ) , 
7110+ 		} ; 
7111+ 		let  mut  blinded_hints = vec ! [ 
7112+ 			( blinded_payinfo. clone( ) ,  blinded_path. clone( ) ) , 
7113+ 			( blinded_payinfo. clone( ) ,  blinded_path. clone( ) ) , 
7114+ 		] ; 
7115+ 		blinded_hints[ 1 ] . 1 . introduction_node_id  = nodes[ 6 ] ; 
7116+ 
7117+ 		let  bolt12_features:  Bolt12InvoiceFeatures  = channelmanager:: provided_invoice_features ( & config) . to_context ( ) ; 
7118+ 		let  payment_params = PaymentParameters :: blinded ( blinded_hints. clone ( ) ) 
7119+ 			. with_bolt12_features ( bolt12_features. clone ( ) ) . unwrap ( ) ; 
7120+ 
7121+ 		let  netgraph = network_graph. read_only ( ) ; 
7122+ 		let  route_params = RouteParameters :: from_payment_params_and_value ( 
7123+ 			payment_params,  amt_msat) ; 
7124+ 		if  let  Err ( LightningError  {  err,  .. } )  = get_route ( 
7125+ 			& our_id,  & route_params,  & netgraph,  None ,  Arc :: clone ( & logger) ,  & scorer,  & ( ) ,  & random_seed_bytes
7126+ 		)  { 
7127+ 			assert_eq ! ( err,  "Failed to find a path to the given destination" ) ; 
7128+ 		}  else  {  panic ! ( )  } 
7129+ 	} 
7130+ 
7131+ 	#[ test]  
7132+ 	fn  we_are_intro_node_bp_in_final_path_fee_calc ( )  { 
7133+ 		// This previously led to a debug panic in the router because we'd find an invalid Path with 
7134+ 		// 0 unblinded hops and a blinded tail, leading to the generation of a final 
7135+ 		// PaymentPathHop::fee_msat that included both the blinded path fees and the final value of 
7136+ 		// the payment, when it was intended to only include the final value of the payment. 
7137+ 		let  ( secp_ctx,  network_graph,  _,  _,  logger)  = build_graph ( ) ; 
7138+ 		let  ( _,  our_id,  _,  nodes)  = get_nodes ( & secp_ctx) ; 
7139+ 		let  scorer = ln_test_utils:: TestScorer :: new ( ) ; 
7140+ 		let  keys_manager = ln_test_utils:: TestKeysInterface :: new ( & [ 0u8 ;  32 ] ,  Network :: Testnet ) ; 
7141+ 		let  random_seed_bytes = keys_manager. get_secure_random_bytes ( ) ; 
7142+ 		let  config = UserConfig :: default ( ) ; 
7143+ 
7144+ 		// Values are taken from the fuzz input that uncovered this panic. 
7145+ 		let  amt_msat = 21_7020_5185_1423_0019 ; 
7146+ 
7147+ 		let  blinded_path = BlindedPath  { 
7148+ 			introduction_node_id :  our_id, 
7149+ 			blinding_point :  ln_test_utils:: pubkey ( 42 ) , 
7150+ 			blinded_hops :  vec ! [ 
7151+ 				BlindedHop  {  blinded_node_id:  ln_test_utils:: pubkey( 42  as  u8 ) ,  encrypted_payload:  Vec :: new( )  } , 
7152+ 				BlindedHop  {  blinded_node_id:  ln_test_utils:: pubkey( 42  as  u8 ) ,  encrypted_payload:  Vec :: new( )  } 
7153+ 			] , 
7154+ 		} ; 
7155+ 		let  blinded_payinfo = BlindedPayInfo  { 
7156+ 			fee_base_msat :  10_4425_1395 ,  // hint_idx 237 
7157+ 			fee_proportional_millionths :  1_6973_9011 , 
7158+ 			htlc_minimum_msat :  21_7301_9934_9094_0931 , 
7159+ 			htlc_maximum_msat :  1844_6744_0737_0955_1615 , 
7160+ 			cltv_expiry_delta :  0 , 
7161+ 			features :  BlindedHopFeatures :: empty ( ) , 
7162+ 		} ; 
7163+ 		let  mut  blinded_hints = vec ! [ 
7164+ 			( blinded_payinfo. clone( ) ,  blinded_path. clone( ) ) , 
7165+ 			( blinded_payinfo. clone( ) ,  blinded_path. clone( ) ) , 
7166+ 			( blinded_payinfo. clone( ) ,  blinded_path. clone( ) ) , 
7167+ 		] ; 
7168+ 		blinded_hints[ 1 ] . 0 . fee_base_msat  = 5052_9027 ;  // hint_idx 240 
7169+ 		blinded_hints[ 1 ] . 0 . fee_proportional_millionths  = 5052_9027 ; 
7170+ 		blinded_hints[ 1 ] . 0 . htlc_minimum_msat  = 21_7020_5185_1423_0019 ; 
7171+ 		blinded_hints[ 1 ] . 0 . htlc_maximum_msat  = 1844_6744_0737_0955_1615 ; 
7172+ 
7173+ 		blinded_hints[ 2 ] . 1 . introduction_node_id  = nodes[ 6 ] ; 
7174+ 
7175+ 		let  bolt12_features:  Bolt12InvoiceFeatures  = channelmanager:: provided_invoice_features ( & config) . to_context ( ) ; 
7176+ 		let  payment_params = PaymentParameters :: blinded ( blinded_hints. clone ( ) ) 
7177+ 			. with_bolt12_features ( bolt12_features. clone ( ) ) . unwrap ( ) ; 
7178+ 
7179+ 		let  netgraph = network_graph. read_only ( ) ; 
7180+ 		let  route_params = RouteParameters :: from_payment_params_and_value ( 
7181+ 			payment_params,  amt_msat) ; 
7182+ 		if  let  Err ( LightningError  {  err,  .. } )  = get_route ( 
7183+ 			& our_id,  & route_params,  & netgraph,  None ,  Arc :: clone ( & logger) ,  & scorer,  & ( ) ,  & random_seed_bytes
7184+ 		)  { 
7185+ 			assert_eq ! ( err,  "Failed to find a path to the given destination" ) ; 
7186+ 		}  else  {  panic ! ( )  } 
7187+ 	} 
70787188} 
70797189
70807190#[ cfg( all( any( test,  ldk_bench) ,  not( feature = "no-std" ) ) ) ]  
0 commit comments