@@ -16,13 +16,13 @@ use crate::chain::channelmonitor::{ANTI_REORG_DELAY, ChannelMonitor, LATENCY_GRA
1616use crate :: chain:: transaction:: OutPoint ;
1717use crate :: chain:: keysinterface:: KeysInterface ;
1818use crate :: ln:: channel:: EXPIRE_PREV_CONFIG_TICKS ;
19- use crate :: ln:: channelmanager:: { self , BREAKDOWN_TIMEOUT , ChannelManager , ChannelManagerReadArgs , InterceptId , MPP_TIMEOUT_TICKS , MIN_CLTV_EXPIRY_DELTA , PaymentId , PaymentSendFailure , IDEMPOTENCY_TIMEOUT_TICKS } ;
19+ use crate :: ln:: channelmanager:: { self , BREAKDOWN_TIMEOUT , ChannelManager , ChannelManagerReadArgs , MPP_TIMEOUT_TICKS , MIN_CLTV_EXPIRY_DELTA , PaymentId , PaymentSendFailure , IDEMPOTENCY_TIMEOUT_TICKS } ;
2020use crate :: ln:: msgs;
2121use crate :: ln:: msgs:: ChannelMessageHandler ;
2222use crate :: routing:: gossip:: RoutingFees ;
2323use crate :: routing:: router:: { find_route, get_route, PaymentParameters , RouteHint , RouteHintHop , RouteParameters } ;
2424use crate :: util:: events:: { ClosureReason , Event , HTLCDestination , MessageSendEvent , MessageSendEventsProvider } ;
25- use crate :: util:: test_utils;
25+ use crate :: util:: { byte_utils , test_utils} ;
2626use crate :: util:: errors:: APIError ;
2727use crate :: util:: enforcing_trait_impls:: EnforcingSigner ;
2828use crate :: util:: ser:: { ReadableArgs , Writeable } ;
@@ -1387,16 +1387,25 @@ fn abandoned_send_payment_idempotent() {
13871387 claim_payment ( & nodes[ 0 ] , & [ & nodes[ 1 ] ] , second_payment_preimage) ;
13881388}
13891389
1390+ #[ derive( PartialEq ) ]
1391+ enum InterceptTest {
1392+ Forward ,
1393+ Fail ,
1394+ Timeout ,
1395+ }
1396+
13901397#[ test]
13911398fn intercepted_payment ( ) {
13921399 // Test that detecting an intercept scid on payment forward will signal LDK to generate an
13931400 // intercept event, which the LSP can then use to either (a) open a JIT channel to forward the
13941401 // payment or (b) fail the payment.
1395- do_test_intercepted_payment ( false ) ;
1396- do_test_intercepted_payment ( true ) ;
1402+ do_test_intercepted_payment ( InterceptTest :: Forward ) ;
1403+ do_test_intercepted_payment ( InterceptTest :: Fail ) ;
1404+ // Make sure that intercepted payments will be automatically failed back if too many blocks pass.
1405+ do_test_intercepted_payment ( InterceptTest :: Timeout ) ;
13971406}
13981407
1399- fn do_test_intercepted_payment ( fail_intercept : bool ) {
1408+ fn do_test_intercepted_payment ( test : InterceptTest ) {
14001409 let chanmon_cfgs = create_chanmon_cfgs ( 3 ) ;
14011410 let node_cfgs = create_node_cfgs ( 3 , & chanmon_cfgs) ;
14021411
@@ -1471,7 +1480,7 @@ fn do_test_intercepted_payment(fail_intercept: bool) {
14711480 let unknown_scid_err = nodes[ 1 ] . node . forward_intercepted_htlc ( intercept_id, 4242 , nodes[ 2 ] . node . get_our_node_id ( ) , expected_outbound_amount_msat) . unwrap_err ( ) ;
14721481 assert_eq ! ( unknown_scid_err, APIError :: APIMisuseError { err: "Channel with short channel id 4242 not found" . to_string( ) } ) ;
14731482
1474- if fail_intercept {
1483+ if test == InterceptTest :: Fail {
14751484 // Ensure we can fail the intercepted payment back.
14761485 nodes[ 1 ] . node . fail_intercepted_htlc ( intercept_id) . unwrap ( ) ;
14771486 expect_pending_htlcs_forwardable_and_htlc_handling_failed_ignore ! ( nodes[ 1 ] , vec![ HTLCDestination :: UnknownNextHop { requested_forward_scid: intercept_scid } ] ) ;
@@ -1489,15 +1498,10 @@ fn do_test_intercepted_payment(fail_intercept: bool) {
14891498 . blamed_chan_closed ( true )
14901499 . expected_htlc_error_data ( 0x4000 | 10 , & [ ] ) ;
14911500 expect_payment_failed_conditions ( & nodes[ 0 ] , payment_hash, false , fail_conditions) ;
1492- } else {
1501+ } else if test == InterceptTest :: Forward {
14931502 // Open the just-in-time channel so the payment can then be forwarded.
14941503 let scid = create_announced_chan_between_nodes ( & nodes, 1 , 2 , channelmanager:: provided_init_features ( ) , channelmanager:: provided_init_features ( ) ) . 0 . contents . short_channel_id ;
14951504
1496- // Check for unknown intercept id error.
1497- let unknown_intercept_id = InterceptId ( [ 42 ; 32 ] ) ;
1498- let unknown_intercept_id_err = nodes[ 1 ] . node . forward_intercepted_htlc ( unknown_intercept_id, scid, nodes[ 2 ] . node . get_our_node_id ( ) , expected_outbound_amount_msat) . unwrap_err ( ) ;
1499- assert_eq ! ( unknown_intercept_id_err , APIError :: APIMisuseError { err: format!( "Payment with intercept id {:?} not found" , unknown_intercept_id. 0 ) } ) ;
1500-
15011505 // Finally, forward the intercepted payment through and claim it.
15021506 nodes[ 1 ] . node . forward_intercepted_htlc ( intercept_id, scid, nodes[ 2 ] . node . get_our_node_id ( ) , expected_outbound_amount_msat) . unwrap ( ) ;
15031507 expect_pending_htlcs_forwardable ! ( nodes[ 1 ] ) ;
@@ -1535,5 +1539,38 @@ fn do_test_intercepted_payment(fail_intercept: bool) {
15351539 } ,
15361540 _ => panic ! ( "Unexpected event" )
15371541 }
1542+ } else if test == InterceptTest :: Timeout {
1543+ let mut block = Block {
1544+ header : BlockHeader { version : 0x20000000 , prev_blockhash : nodes[ 0 ] . best_block_hash ( ) , merkle_root : TxMerkleNode :: all_zeros ( ) , time : 42 , bits : 42 , nonce : 42 } ,
1545+ txdata : vec ! [ ] ,
1546+ } ;
1547+ connect_block ( & nodes[ 0 ] , & block) ;
1548+ connect_block ( & nodes[ 1 ] , & block) ;
1549+ let block_count = 183 ; // find_route adds a random CLTV offset, so hardcode rather than summing consts
1550+ for _ in 0 ..block_count {
1551+ block. header . prev_blockhash = block. block_hash ( ) ;
1552+ connect_block ( & nodes[ 0 ] , & block) ;
1553+ connect_block ( & nodes[ 1 ] , & block) ;
1554+ }
1555+ expect_pending_htlcs_forwardable_and_htlc_handling_failed ! ( nodes[ 1 ] , vec![ HTLCDestination :: FailedPayment { payment_hash } ] ) ;
1556+ check_added_monitors ! ( nodes[ 1 ] , 1 ) ;
1557+ let htlc_timeout_updates = get_htlc_update_msgs ! ( nodes[ 1 ] , nodes[ 0 ] . node. get_our_node_id( ) ) ;
1558+ assert ! ( htlc_timeout_updates. update_add_htlcs. is_empty( ) ) ;
1559+ assert_eq ! ( htlc_timeout_updates. update_fail_htlcs. len( ) , 1 ) ;
1560+ assert ! ( htlc_timeout_updates. update_fail_malformed_htlcs. is_empty( ) ) ;
1561+ assert ! ( htlc_timeout_updates. update_fee. is_none( ) ) ;
1562+
1563+ nodes[ 0 ] . node . handle_update_fail_htlc ( & nodes[ 1 ] . node . get_our_node_id ( ) , & htlc_timeout_updates. update_fail_htlcs [ 0 ] ) ;
1564+ commitment_signed_dance ! ( nodes[ 0 ] , nodes[ 1 ] , htlc_timeout_updates. commitment_signed, false ) ;
1565+ // amt_msat as u64, followed by the height at which we failed back above
1566+ let mut expected_failure_data = byte_utils:: be64_to_array ( amt_msat) . to_vec ( ) ;
1567+ expected_failure_data. extend_from_slice ( & byte_utils:: be32_to_array ( block_count - 1 ) ) ;
1568+ expect_payment_failed ! ( nodes[ 0 ] , payment_hash, false , 0x4000 | 15 , & expected_failure_data[ ..] ) ;
1569+
1570+ let scid = create_announced_chan_between_nodes ( & nodes, 1 , 2 , channelmanager:: provided_init_features ( ) , channelmanager:: provided_init_features ( ) ) . 0 . contents . short_channel_id ;
1571+
1572+ // Check for unknown intercept id error.
1573+ let unknown_intercept_id_err = nodes[ 1 ] . node . forward_intercepted_htlc ( intercept_id, scid, nodes[ 2 ] . node . get_our_node_id ( ) , expected_outbound_amount_msat) . unwrap_err ( ) ;
1574+ assert_eq ! ( unknown_intercept_id_err , APIError :: APIMisuseError { err: format!( "Payment with intercept id {:?} not found" , intercept_id. 0 ) } ) ;
15381575 }
15391576}
0 commit comments