@@ -3285,6 +3285,90 @@ fn async_payment_mpp() {
32853285 claim_payment_along_route ( ClaimAlongRouteArgs :: new ( sender, expected_route, keysend_preimage) ) ;
32863286}
32873287
3288+ #[ test]
3289+ fn fallback_to_one_hop_release_htlc_path ( ) {
3290+ // Check that if the sender's LSP's message router fails to find a blinded path when creating a
3291+ // path for the release_held_htlc message, they will fall back to manually creating a 1-hop
3292+ // blinded path.
3293+ let chanmon_cfgs = create_chanmon_cfgs ( 4 ) ;
3294+ let node_cfgs = create_node_cfgs ( 4 , & chanmon_cfgs) ;
3295+
3296+ let ( sender_cfg, recipient_cfg) = ( often_offline_node_cfg ( ) , often_offline_node_cfg ( ) ) ;
3297+ let mut sender_lsp_cfg = test_default_channel_config ( ) ;
3298+ sender_lsp_cfg. enable_htlc_hold = true ;
3299+ let mut invoice_server_cfg = test_default_channel_config ( ) ;
3300+ invoice_server_cfg. accept_forwards_to_priv_channels = true ;
3301+
3302+ let node_chanmgrs = create_node_chanmgrs (
3303+ 4 ,
3304+ & node_cfgs,
3305+ & [ Some ( sender_cfg) , Some ( sender_lsp_cfg) , Some ( invoice_server_cfg) , Some ( recipient_cfg) ] ,
3306+ ) ;
3307+ let nodes = create_network ( 4 , & node_cfgs, & node_chanmgrs) ;
3308+ create_unannounced_chan_between_nodes_with_value ( & nodes, 0 , 1 , 1_000_000 , 0 ) ;
3309+ create_announced_chan_between_nodes_with_value ( & nodes, 1 , 2 , 1_000_000 , 0 ) ;
3310+ create_unannounced_chan_between_nodes_with_value ( & nodes, 2 , 3 , 1_000_000 , 0 ) ;
3311+ // Make sure all nodes are at the same block height
3312+ let node_max_height =
3313+ nodes. iter ( ) . map ( |node| node. blocks . lock ( ) . unwrap ( ) . len ( ) ) . max ( ) . unwrap ( ) as u32 ;
3314+ connect_blocks ( & nodes[ 0 ] , node_max_height - nodes[ 0 ] . best_block_info ( ) . 1 ) ;
3315+ connect_blocks ( & nodes[ 1 ] , node_max_height - nodes[ 1 ] . best_block_info ( ) . 1 ) ;
3316+ connect_blocks ( & nodes[ 2 ] , node_max_height - nodes[ 2 ] . best_block_info ( ) . 1 ) ;
3317+ connect_blocks ( & nodes[ 3 ] , node_max_height - nodes[ 3 ] . best_block_info ( ) . 1 ) ;
3318+ let sender = & nodes[ 0 ] ;
3319+ let sender_lsp = & nodes[ 1 ] ;
3320+ let invoice_server = & nodes[ 2 ] ;
3321+ let recipient = & nodes[ 3 ] ;
3322+
3323+ let amt_msat = 5000 ;
3324+ let ( static_invoice, peer_node_id, static_invoice_om) =
3325+ build_async_offer_and_init_payment ( amt_msat, & nodes) ;
3326+
3327+ // Force the sender_lsp's call to MessageRouter::create_blinded_paths to fail so it has to fall
3328+ // back to a 1-hop blinded path when creating the paths for its revoke_and_ack message.
3329+ sender_lsp. message_router . create_blinded_paths_res_override . lock ( ) . unwrap ( ) . 1 = Some ( Err ( ( ) ) ) ;
3330+
3331+ let payment_hash =
3332+ lock_in_htlc_for_static_invoice ( & static_invoice_om, peer_node_id, sender, sender_lsp) ;
3333+
3334+ // Check that we actually had to fall back to a 1-hop path.
3335+ assert ! ( sender_lsp. message_router. create_blinded_paths_res_override. lock( ) . unwrap( ) . 0 > 0 ) ;
3336+ sender_lsp. message_router . create_blinded_paths_res_override . lock ( ) . unwrap ( ) . 1 = None ;
3337+
3338+ sender_lsp. node . process_pending_htlc_forwards ( ) ;
3339+ let ( peer_id, held_htlc_om) =
3340+ extract_held_htlc_available_oms ( sender, & [ sender_lsp, invoice_server, recipient] )
3341+ . pop ( )
3342+ . unwrap ( ) ;
3343+ recipient. onion_messenger . handle_onion_message ( peer_id, & held_htlc_om) ;
3344+
3345+ // The release_htlc OM should go straight to the sender's LSP since they created a 1-hop blinded
3346+ // path to themselves for receiving it.
3347+ let release_htlc_om = recipient
3348+ . onion_messenger
3349+ . next_onion_message_for_peer ( sender_lsp. node . get_our_node_id ( ) )
3350+ . unwrap ( ) ;
3351+ sender_lsp
3352+ . onion_messenger
3353+ . handle_onion_message ( recipient. node . get_our_node_id ( ) , & release_htlc_om) ;
3354+
3355+ sender_lsp. node . process_pending_htlc_forwards ( ) ;
3356+ let mut events = sender_lsp. node . get_and_clear_pending_msg_events ( ) ;
3357+ assert_eq ! ( events. len( ) , 1 ) ;
3358+ let ev = remove_first_msg_event_to_node ( & invoice_server. node . get_our_node_id ( ) , & mut events) ;
3359+ check_added_monitors ! ( sender_lsp, 1 ) ;
3360+
3361+ let path: & [ & Node ] = & [ invoice_server, recipient] ;
3362+ let args = PassAlongPathArgs :: new ( sender_lsp, path, amt_msat, payment_hash, ev) ;
3363+ let claimable_ev = do_pass_along_path ( args) . unwrap ( ) ;
3364+
3365+ let route: & [ & [ & Node ] ] = & [ & [ sender_lsp, invoice_server, recipient] ] ;
3366+ let keysend_preimage = extract_payment_preimage ( & claimable_ev) ;
3367+ let ( res, _) =
3368+ claim_payment_along_route ( ClaimAlongRouteArgs :: new ( sender, route, keysend_preimage) ) ;
3369+ assert_eq ! ( res, Some ( PaidBolt12Invoice :: StaticInvoice ( static_invoice) ) ) ;
3370+ }
3371+
32883372#[ test]
32893373fn fail_held_htlcs_when_cfg_unset ( ) {
32903374 // Test that if we receive a held HTLC but `UserConfig::enable_htlc_hold` is unset, we will fail
0 commit comments