@@ -696,6 +696,126 @@ fn channel_open_abandoned() {
696696 assert ! ( result. is_err( ) ) ;
697697}
698698
699+ #[ test]
700+ fn channel_open_abandoned_releases_intercepted_htlcs ( ) {
701+ let chanmon_cfgs = create_chanmon_cfgs ( 3 ) ;
702+ let node_cfgs = create_node_cfgs ( 3 , & chanmon_cfgs) ;
703+ let mut service_node_config = test_default_channel_config ( ) ;
704+ service_node_config. accept_intercept_htlcs = true ;
705+
706+ let mut client_node_config = test_default_channel_config ( ) ;
707+ client_node_config. channel_config . accept_underpaying_htlcs = true ;
708+
709+ let node_chanmgrs = create_node_chanmgrs (
710+ 3 ,
711+ & node_cfgs,
712+ & [ Some ( service_node_config) , Some ( client_node_config) , None ] ,
713+ ) ;
714+ let nodes = create_network ( 3 , & node_cfgs, & node_chanmgrs) ;
715+ let ( lsps_nodes, promise_secret) = setup_test_lsps2_nodes_with_payer ( nodes) ;
716+ let LSPSNodesWithPayer { ref service_node, ref client_node, ref payer_node } = lsps_nodes;
717+
718+ let payer_node_id = payer_node. node . get_our_node_id ( ) ;
719+ let service_node_id = service_node. inner . node . get_our_node_id ( ) ;
720+ let client_node_id = client_node. inner . node . get_our_node_id ( ) ;
721+
722+ let service_handler = service_node. liquidity_manager . lsps2_service_handler ( ) . unwrap ( ) ;
723+ create_chan_between_nodes_with_value ( & payer_node, & service_node. inner , 2_000_000 , 100_000 ) ;
724+
725+ let intercept_scid = service_node. node . get_intercept_scid ( ) ;
726+ let user_channel_id = 42u128 ;
727+ let cltv_expiry_delta: u32 = 144 ;
728+ let payment_size_msat = Some ( 1_000_000 ) ;
729+ let fee_base_msat: u64 = 1_000 ;
730+
731+ execute_lsps2_dance (
732+ & lsps_nodes,
733+ intercept_scid,
734+ user_channel_id,
735+ cltv_expiry_delta,
736+ promise_secret,
737+ payment_size_msat,
738+ fee_base_msat,
739+ ) ;
740+
741+ let invoice = create_jit_invoice (
742+ & client_node,
743+ service_node_id,
744+ intercept_scid,
745+ cltv_expiry_delta,
746+ payment_size_msat,
747+ "channel-open-abandoned-cleanup" ,
748+ 3600 ,
749+ )
750+ . unwrap ( ) ;
751+
752+ payer_node
753+ . node
754+ . pay_for_bolt11_invoice (
755+ & invoice,
756+ PaymentId ( invoice. payment_hash ( ) . to_byte_array ( ) ) ,
757+ None ,
758+ Default :: default ( ) ,
759+ Retry :: Attempts ( 0 ) ,
760+ )
761+ . unwrap ( ) ;
762+
763+ check_added_monitors ! ( & payer_node, 1 ) ;
764+ let events = payer_node. node . get_and_clear_pending_msg_events ( ) ;
765+ let ev = SendEvent :: from_event ( events[ 0 ] . clone ( ) ) ;
766+ service_node. inner . node . handle_update_add_htlc ( payer_node_id, & ev. msgs [ 0 ] ) ;
767+ do_commitment_signed_dance ( & service_node. inner , & payer_node, & ev. commitment_msg , false , true ) ;
768+ service_node. inner . node . process_pending_htlc_forwards ( ) ;
769+
770+ let events = service_node. inner . node . get_and_clear_pending_events ( ) ;
771+ assert_eq ! ( events. len( ) , 1 ) ;
772+ let intercept_id = match & events[ 0 ] {
773+ Event :: HTLCIntercepted {
774+ intercept_id,
775+ requested_next_hop_scid,
776+ payment_hash,
777+ expected_outbound_amount_msat,
778+ ..
779+ } => {
780+ assert_eq ! ( * requested_next_hop_scid, intercept_scid) ;
781+ service_handler
782+ . htlc_intercepted (
783+ * requested_next_hop_scid,
784+ * intercept_id,
785+ * expected_outbound_amount_msat,
786+ * payment_hash,
787+ )
788+ . unwrap ( ) ;
789+ * intercept_id
790+ } ,
791+ other => panic ! ( "Expected HTLCIntercepted, got {:?}" , other) ,
792+ } ;
793+
794+ match service_node. liquidity_manager . next_event ( ) . unwrap ( ) {
795+ LiquidityEvent :: LSPS2Service ( LSPS2ServiceEvent :: OpenChannel { .. } ) => { } ,
796+ other => panic ! ( "Unexpected event: {:?}" , other) ,
797+ } ;
798+
799+ service_handler. channel_open_abandoned ( & client_node_id, user_channel_id) . unwrap ( ) ;
800+
801+ let res = service_node. inner . node . fail_intercepted_htlc ( intercept_id) ;
802+ assert ! (
803+ res. is_err( ) ,
804+ "channel_open_abandoned must release the intercepted HTLC via fail_intercepted_htlc, but the entry is still pending: {:?}" ,
805+ res,
806+ ) ;
807+
808+ let events = service_node. inner . node . get_and_clear_pending_events ( ) ;
809+ assert_eq ! ( events. len( ) , 1 ) ;
810+ match & events[ 0 ] {
811+ Event :: HTLCHandlingFailed {
812+ failure_type : HTLCHandlingFailureType :: InvalidForward { requested_forward_scid } ,
813+ ..
814+ } => assert_eq ! ( * requested_forward_scid, intercept_scid) ,
815+ other => panic ! ( "Expected HTLCHandlingFailed, got {:?}" , other) ,
816+ }
817+ }
818+
699819#[ test]
700820fn channel_open_abandoned_nonexistent_channel ( ) {
701821 let chanmon_cfgs = create_chanmon_cfgs ( 2 ) ;
0 commit comments