@@ -1374,9 +1374,15 @@ fn test_holding_cell_inflight_htlcs() {
13741374}
13751375
13761376#[ test]
1377- fn forward_intercepted_payment ( ) {
1377+ fn intercepted_payment ( ) {
13781378 // Test that detecting an intercept scid on payment forward will signal LDK to generate an
1379- // intercept event, which the LSP can then use to open a JIT channel to forward the payment.
1379+ // intercept event, which the LSP can then use to either (a) open a JIT channel to forward the
1380+ // payment or (b) fail the payment.
1381+ do_test_intercepted_payment ( false ) ;
1382+ do_test_intercepted_payment ( true ) ;
1383+ }
1384+
1385+ fn do_test_intercepted_payment ( fail_intercept : bool ) {
13801386 let chanmon_cfgs = create_chanmon_cfgs ( 3 ) ;
13811387 let node_cfgs = create_node_cfgs ( 3 , & chanmon_cfgs) ;
13821388 let mut chan_config = test_default_channel_config ( ) ;
@@ -1449,49 +1455,69 @@ fn forward_intercepted_payment() {
14491455 let unknown_chan_id_err = nodes[ 1 ] . node . forward_intercepted_htlc ( intercept_id, & [ 42 ; 32 ] , nodes[ 2 ] . node . get_our_node_id ( ) , expected_outbound_amount_msat) . unwrap_err ( ) ;
14501456 assert_eq ! ( unknown_chan_id_err , APIError :: APIMisuseError { err: format!( "Channel with id {:?} not found" , [ 42 ; 32 ] ) } ) ;
14511457
1452- // Open the just-in-time channel so the payment can then be forwarded.
1453- let ( _, channel_id) = open_zero_conf_channel ( & nodes[ 1 ] , & nodes[ 2 ] , None ) ;
1454-
1455- // Check for unknown intercept id error.
1456- let unknown_intercept_id = InterceptId ( [ 42 ; 32 ] ) ;
1457- let unknown_intercept_id_err = nodes[ 1 ] . node . forward_intercepted_htlc ( unknown_intercept_id, & channel_id, nodes[ 2 ] . node . get_our_node_id ( ) , expected_outbound_amount_msat) . unwrap_err ( ) ;
1458- assert_eq ! ( unknown_intercept_id_err , APIError :: APIMisuseError { err: format!( "Payment with intercept id {:?} not found" , unknown_intercept_id. 0 ) } ) ;
1459-
1460- // Finally, forward the intercepted payment through and claim it.
1461- nodes[ 1 ] . node . forward_intercepted_htlc ( intercept_id, & channel_id, nodes[ 2 ] . node . get_our_node_id ( ) , expected_outbound_amount_msat) . unwrap ( ) ;
1462- expect_pending_htlcs_forwardable ! ( nodes[ 1 ] ) ;
1463-
1464- let payment_event = {
1465- {
1466- let mut added_monitors = nodes[ 1 ] . chain_monitor . added_monitors . lock ( ) . unwrap ( ) ;
1467- assert_eq ! ( added_monitors. len( ) , 1 ) ;
1468- added_monitors. clear ( ) ;
1458+ if fail_intercept {
1459+ // Ensure we can fail the intercepted payment back.
1460+ nodes[ 1 ] . node . fail_intercepted_htlc ( intercept_id) . unwrap ( ) ;
1461+ expect_pending_htlcs_forwardable_and_htlc_handling_failed_ignore ! ( nodes[ 1 ] , vec![ HTLCDestination :: UnknownNextHop { requested_forward_scid: intercept_scid } ] ) ;
1462+ nodes[ 1 ] . node . process_pending_htlc_forwards ( ) ;
1463+ let update_fail = get_htlc_update_msgs ! ( nodes[ 1 ] , nodes[ 0 ] . node. get_our_node_id( ) ) ;
1464+ check_added_monitors ! ( & nodes[ 1 ] , 1 ) ;
1465+ assert ! ( update_fail. update_fail_htlcs. len( ) == 1 ) ;
1466+ let fail_msg = update_fail. update_fail_htlcs [ 0 ] . clone ( ) ;
1467+ nodes[ 0 ] . node . handle_update_fail_htlc ( & nodes[ 1 ] . node . get_our_node_id ( ) , & fail_msg) ;
1468+ commitment_signed_dance ! ( nodes[ 0 ] , nodes[ 1 ] , update_fail. commitment_signed, false ) ;
1469+
1470+ // Ensure the payment fails with the expected error.
1471+ let fail_conditions = PaymentFailedConditions :: new ( )
1472+ . blamed_scid ( intercept_scid)
1473+ . blamed_chan_closed ( true )
1474+ . expected_htlc_error_data ( 0x4000 | 10 , & [ ] ) ;
1475+ expect_payment_failed_conditions ( & nodes[ 0 ] , payment_hash, false , fail_conditions) ;
1476+ } else {
1477+ // Open the just-in-time channel so the payment can then be forwarded.
1478+ let ( _, channel_id) = open_zero_conf_channel ( & nodes[ 1 ] , & nodes[ 2 ] , None ) ;
1479+
1480+ // Check for unknown intercept id error.
1481+ let unknown_intercept_id = InterceptId ( [ 42 ; 32 ] ) ;
1482+ let unknown_intercept_id_err = nodes[ 1 ] . node . forward_intercepted_htlc ( unknown_intercept_id, & channel_id, nodes[ 2 ] . node . get_our_node_id ( ) , expected_outbound_amount_msat) . unwrap_err ( ) ;
1483+ assert_eq ! ( unknown_intercept_id_err , APIError :: APIMisuseError { err: format!( "Payment with intercept id {:?} not found" , unknown_intercept_id. 0 ) } ) ;
1484+
1485+ // Finally, forward the intercepted payment through and claim it.
1486+ nodes[ 1 ] . node . forward_intercepted_htlc ( intercept_id, & channel_id, nodes[ 2 ] . node . get_our_node_id ( ) , expected_outbound_amount_msat) . unwrap ( ) ;
1487+ expect_pending_htlcs_forwardable ! ( nodes[ 1 ] ) ;
1488+
1489+ let payment_event = {
1490+ {
1491+ let mut added_monitors = nodes[ 1 ] . chain_monitor . added_monitors . lock ( ) . unwrap ( ) ;
1492+ assert_eq ! ( added_monitors. len( ) , 1 ) ;
1493+ added_monitors. clear ( ) ;
1494+ }
1495+ let mut events = nodes[ 1 ] . node . get_and_clear_pending_msg_events ( ) ;
1496+ assert_eq ! ( events. len( ) , 1 ) ;
1497+ SendEvent :: from_event ( events. remove ( 0 ) )
1498+ } ;
1499+ nodes[ 2 ] . node . handle_update_add_htlc ( & nodes[ 1 ] . node . get_our_node_id ( ) , & payment_event. msgs [ 0 ] ) ;
1500+ commitment_signed_dance ! ( nodes[ 2 ] , nodes[ 1 ] , & payment_event. commitment_msg, false , true ) ;
1501+ expect_pending_htlcs_forwardable ! ( nodes[ 2 ] ) ;
1502+
1503+ let payment_preimage = nodes[ 2 ] . node . get_payment_preimage ( payment_hash, payment_secret) . unwrap ( ) ;
1504+ expect_payment_received ! ( & nodes[ 2 ] , payment_hash, payment_secret, amt_msat, Some ( payment_preimage) , nodes[ 2 ] . node. get_our_node_id( ) ) ;
1505+ do_claim_payment_along_route ( & nodes[ 0 ] , & vec ! ( & vec!( & nodes[ 1 ] , & nodes[ 2 ] ) [ ..] ) , false , payment_preimage) ;
1506+ let events = nodes[ 0 ] . node . get_and_clear_pending_events ( ) ;
1507+ assert_eq ! ( events. len( ) , 2 ) ;
1508+ match events[ 0 ] {
1509+ Event :: PaymentSent { payment_preimage : ref ev_preimage, payment_hash : ref ev_hash, ref fee_paid_msat, .. } => {
1510+ assert_eq ! ( payment_preimage, * ev_preimage) ;
1511+ assert_eq ! ( payment_hash, * ev_hash) ;
1512+ assert_eq ! ( fee_paid_msat, & Some ( 1000 ) ) ;
1513+ } ,
1514+ _ => panic ! ( "Unexpected event" )
1515+ }
1516+ match events[ 1 ] {
1517+ Event :: PaymentPathSuccessful { payment_hash : hash, .. } => {
1518+ assert_eq ! ( hash, Some ( payment_hash) ) ;
1519+ } ,
1520+ _ => panic ! ( "Unexpected event" )
14691521 }
1470- let mut events = nodes[ 1 ] . node . get_and_clear_pending_msg_events ( ) ;
1471- assert_eq ! ( events. len( ) , 1 ) ;
1472- SendEvent :: from_event ( events. remove ( 0 ) )
1473- } ;
1474- nodes[ 2 ] . node . handle_update_add_htlc ( & nodes[ 1 ] . node . get_our_node_id ( ) , & payment_event. msgs [ 0 ] ) ;
1475- commitment_signed_dance ! ( nodes[ 2 ] , nodes[ 1 ] , & payment_event. commitment_msg, false , true ) ;
1476- expect_pending_htlcs_forwardable ! ( nodes[ 2 ] ) ;
1477-
1478- let payment_preimage = nodes[ 2 ] . node . get_payment_preimage ( payment_hash, payment_secret) . unwrap ( ) ;
1479- expect_payment_received ! ( & nodes[ 2 ] , payment_hash, payment_secret, amt_msat, Some ( payment_preimage) , nodes[ 2 ] . node. get_our_node_id( ) ) ;
1480- do_claim_payment_along_route ( & nodes[ 0 ] , & vec ! ( & vec!( & nodes[ 1 ] , & nodes[ 2 ] ) [ ..] ) , false , payment_preimage) ;
1481- let events = nodes[ 0 ] . node . get_and_clear_pending_events ( ) ;
1482- assert_eq ! ( events. len( ) , 2 ) ;
1483- match events[ 0 ] {
1484- Event :: PaymentSent { payment_preimage : ref ev_preimage, payment_hash : ref ev_hash, ref fee_paid_msat, .. } => {
1485- assert_eq ! ( payment_preimage, * ev_preimage) ;
1486- assert_eq ! ( payment_hash, * ev_hash) ;
1487- assert_eq ! ( fee_paid_msat, & Some ( 1000 ) ) ;
1488- } ,
1489- _ => panic ! ( "Unexpected event" )
1490- }
1491- match events[ 1 ] {
1492- Event :: PaymentPathSuccessful { payment_hash : hash, .. } => {
1493- assert_eq ! ( hash, Some ( payment_hash) ) ;
1494- } ,
1495- _ => panic ! ( "Unexpected event" )
14961522 }
14971523}
0 commit comments