@@ -3031,6 +3031,92 @@ fn held_htlc_timeout() {
30313031	) ; 
30323032} 
30333033
3034+ #[ test]  
3035+ fn  fail_held_htlc_on_reconnect ( )  { 
3036+ 	// Test that if a held HTLC by the sender LSP fails but the async sender is offline, the HTLC 
3037+ 	// is failed on reconnect instead of FC the channel. 
3038+ 	let  chanmon_cfgs = create_chanmon_cfgs ( 4 ) ; 
3039+ 	let  node_cfgs = create_node_cfgs ( 4 ,  & chanmon_cfgs) ; 
3040+ 
3041+ 	let  ( sender_cfg,  recipient_cfg)  = ( often_offline_node_cfg ( ) ,  often_offline_node_cfg ( ) ) ; 
3042+ 	let  mut  sender_lsp_cfg = test_default_channel_config ( ) ; 
3043+ 	sender_lsp_cfg. enable_htlc_hold  = true ; 
3044+ 	let  mut  invoice_server_cfg = test_default_channel_config ( ) ; 
3045+ 	invoice_server_cfg. accept_forwards_to_priv_channels  = true ; 
3046+ 
3047+ 	let  node_chanmgrs = create_node_chanmgrs ( 
3048+ 		4 , 
3049+ 		& node_cfgs, 
3050+ 		& [ Some ( sender_cfg) ,  Some ( sender_lsp_cfg) ,  Some ( invoice_server_cfg) ,  Some ( recipient_cfg) ] , 
3051+ 	) ; 
3052+ 	let  nodes = create_network ( 4 ,  & node_cfgs,  & node_chanmgrs) ; 
3053+ 	let  chan = create_unannounced_chan_between_nodes_with_value ( & nodes,  0 ,  1 ,  1_000_000 ,  0 ) ; 
3054+ 	create_announced_chan_between_nodes_with_value ( & nodes,  1 ,  2 ,  1_000_000 ,  0 ) ; 
3055+ 	create_unannounced_chan_between_nodes_with_value ( & nodes,  2 ,  3 ,  1_000_000 ,  0 ) ; 
3056+ 	unify_blockheight_across_nodes ( & nodes) ; 
3057+ 	let  sender = & nodes[ 0 ] ; 
3058+ 	let  sender_lsp = & nodes[ 1 ] ; 
3059+ 	let  invoice_server = & nodes[ 2 ] ; 
3060+ 	let  recipient = & nodes[ 3 ] ; 
3061+ 
3062+ 	let  amt_msat = 5000 ; 
3063+ 	let  ( _,  peer_node_id,  static_invoice_om)  = build_async_offer_and_init_payment ( amt_msat,  & nodes) ; 
3064+ 	let  payment_hash =
3065+ 		lock_in_htlc_for_static_invoice ( & static_invoice_om,  peer_node_id,  sender,  sender_lsp) ; 
3066+ 
3067+ 	sender_lsp. node . process_pending_htlc_forwards ( ) ; 
3068+ 	let  ( peer_id,  held_htlc_om)  =
3069+ 		extract_held_htlc_available_oms ( sender,  & [ sender_lsp,  invoice_server,  recipient] ) 
3070+ 			. pop ( ) 
3071+ 			. unwrap ( ) ; 
3072+ 	recipient. onion_messenger . handle_onion_message ( peer_id,  & held_htlc_om) ; 
3073+ 
3074+ 	let  _ = extract_release_htlc_oms ( recipient,  & [ sender,  sender_lsp,  invoice_server] ) ; 
3075+ 
3076+ 	// Disconnect async sender <-> sender LSP 
3077+ 	sender. node . peer_disconnected ( sender_lsp. node . get_our_node_id ( ) ) ; 
3078+ 	sender_lsp. node . peer_disconnected ( sender. node . get_our_node_id ( ) ) ; 
3079+ 
3080+ 	// Connect blocks such that they cause the HTLC to timeout 
3081+ 	let  chan_id = chan. 0 . channel_id ; 
3082+ 	let  channel =
3083+ 		sender. node . list_channels ( ) . iter ( ) . find ( |c| c. channel_id  == chan_id) . unwrap ( ) . clone ( ) ; 
3084+ 	let  htlc_expiry = channel
3085+ 		. pending_outbound_htlcs 
3086+ 		. iter ( ) 
3087+ 		. find ( |htlc| htlc. payment_hash  == payment_hash) 
3088+ 		. unwrap ( ) 
3089+ 		. cltv_expiry ; 
3090+ 	let  blocks_to_connect = htlc_expiry - sender. best_block_info ( ) . 1  + 100 ; 
3091+ 	connect_blocks ( sender,  blocks_to_connect) ; 
3092+ 	connect_blocks ( sender_lsp,  blocks_to_connect) ; 
3093+ 
3094+ 	sender_lsp. node . process_pending_htlc_forwards ( ) ; 
3095+ 	let  mut  evs = sender_lsp. node . get_and_clear_pending_events ( ) ; 
3096+ 	assert_eq ! ( evs. len( ) ,  1 ) ; 
3097+ 	match  evs. pop ( ) . unwrap ( )  { 
3098+ 		Event :: HTLCHandlingFailed  {  failure_type,  failure_reason,  .. }  => { 
3099+ 			assert ! ( matches!( failure_type,  HTLCHandlingFailureType :: InvalidForward  {  .. } ) ) ; 
3100+ 			assert ! ( matches!( 
3101+ 				failure_reason, 
3102+ 				Some ( HTLCHandlingFailureReason :: Local  { 
3103+ 					reason:  LocalHTLCFailureReason :: ForwardExpiryBuffer 
3104+ 				} ) 
3105+ 			) ) ; 
3106+ 		} , 
3107+ 		_ => panic ! ( ) , 
3108+ 	} 
3109+ 
3110+ 	// After reconnecting, check that HTLC was failed and channel is open. 
3111+ 	let  mut  reconnect_args = ReconnectArgs :: new ( & sender,  & sender_lsp) ; 
3112+ 	reconnect_args. pending_cell_htlc_fails . 0  = 1 ; 
3113+ 	reconnect_nodes ( reconnect_args) ; 
3114+ 
3115+ 	expect_payment_failed ! ( sender,  payment_hash,  false ) ; 
3116+ 	assert_eq ! ( sender. node. list_channels( ) . len( ) ,  1 ) ; 
3117+ 	assert_eq ! ( sender_lsp. node. list_channels( ) . len( ) ,  2 ) ; 
3118+ } 
3119+ 
30343120#[ test]  
30353121fn  intercepted_hold_htlc ( )  { 
30363122	// Test a payment `sender --> LSP --> recipient` such that the HTLC is both a hold htlc and an 
0 commit comments