@@ -16,7 +16,7 @@ use crate::chain::channelmonitor::{ANTI_REORG_DELAY, LATENCY_GRACE_PERIOD_BLOCKS
16
16
use crate :: chain:: transaction:: OutPoint ;
17
17
use crate :: chain:: keysinterface:: KeysInterface ;
18
18
use crate :: ln:: channel:: EXPIRE_PREV_CONFIG_TICKS ;
19
- use crate :: ln:: channelmanager:: { self , BREAKDOWN_TIMEOUT , ChannelManager , InterceptId , MPP_TIMEOUT_TICKS , MIN_CLTV_EXPIRY_DELTA , PaymentId , PaymentSendFailure , IDEMPOTENCY_TIMEOUT_TICKS } ;
19
+ use crate :: ln:: channelmanager:: { self , BREAKDOWN_TIMEOUT , ChannelManager , MPP_TIMEOUT_TICKS , MIN_CLTV_EXPIRY_DELTA , PaymentId , PaymentSendFailure , IDEMPOTENCY_TIMEOUT_TICKS } ;
20
20
use crate :: ln:: msgs;
21
21
use crate :: ln:: msgs:: ChannelMessageHandler ;
22
22
use crate :: routing:: gossip:: RoutingFees ;
@@ -1243,6 +1243,13 @@ fn abandoned_send_payment_idempotent() {
1243
1243
claim_payment ( & nodes[ 0 ] , & [ & nodes[ 1 ] ] , second_payment_preimage) ;
1244
1244
}
1245
1245
1246
+ #[ derive( PartialEq ) ]
1247
+ enum InterceptTest {
1248
+ Forward ,
1249
+ Fail ,
1250
+ Timeout ,
1251
+ }
1252
+
1246
1253
#[ test]
1247
1254
fn test_trivial_inflight_htlc_tracking ( ) {
1248
1255
// In this test, we test three scenarios:
@@ -1378,11 +1385,13 @@ fn intercepted_payment() {
1378
1385
// Test that detecting an intercept scid on payment forward will signal LDK to generate an
1379
1386
// intercept event, which the LSP can then use to either (a) open a JIT channel to forward the
1380
1387
// payment or (b) fail the payment.
1381
- do_test_intercepted_payment ( false ) ;
1382
- do_test_intercepted_payment ( true ) ;
1388
+ do_test_intercepted_payment ( InterceptTest :: Forward ) ;
1389
+ do_test_intercepted_payment ( InterceptTest :: Fail ) ;
1390
+ // Make sure that intercepted payments will be automatically failed back if too many blocks pass.
1391
+ do_test_intercepted_payment ( InterceptTest :: Timeout ) ;
1383
1392
}
1384
1393
1385
- fn do_test_intercepted_payment ( fail_intercept : bool ) {
1394
+ fn do_test_intercepted_payment ( test : InterceptTest ) {
1386
1395
let chanmon_cfgs = create_chanmon_cfgs ( 3 ) ;
1387
1396
let node_cfgs = create_node_cfgs ( 3 , & chanmon_cfgs) ;
1388
1397
@@ -1459,7 +1468,7 @@ fn do_test_intercepted_payment(fail_intercept: bool) {
1459
1468
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 ( ) ;
1460
1469
assert_eq ! ( unknown_chan_id_err , APIError :: APIMisuseError { err: format!( "Channel with id {:?} not found" , [ 42 ; 32 ] ) } ) ;
1461
1470
1462
- if fail_intercept {
1471
+ if test == InterceptTest :: Fail {
1463
1472
// Ensure we can fail the intercepted payment back.
1464
1473
nodes[ 1 ] . node . fail_intercepted_htlc ( intercept_id) . unwrap ( ) ;
1465
1474
expect_pending_htlcs_forwardable_and_htlc_handling_failed_ignore ! ( nodes[ 1 ] , vec![ HTLCDestination :: UnknownNextHop { requested_forward_scid: intercept_scid } ] ) ;
@@ -1477,15 +1486,10 @@ fn do_test_intercepted_payment(fail_intercept: bool) {
1477
1486
. blamed_chan_closed ( true )
1478
1487
. expected_htlc_error_data ( 0x4000 | 10 , & [ ] ) ;
1479
1488
expect_payment_failed_conditions ( & nodes[ 0 ] , payment_hash, false , fail_conditions) ;
1480
- } else {
1489
+ } else if test == InterceptTest :: Forward {
1481
1490
// Open the just-in-time channel so the payment can then be forwarded.
1482
1491
let ( _, channel_id) = open_zero_conf_channel ( & nodes[ 1 ] , & nodes[ 2 ] , None ) ;
1483
1492
1484
- // Check for unknown intercept id error.
1485
- let unknown_intercept_id = InterceptId ( [ 42 ; 32 ] ) ;
1486
- 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 ( ) ;
1487
- assert_eq ! ( unknown_intercept_id_err , APIError :: APIMisuseError { err: format!( "Payment with intercept id {:?} not found" , unknown_intercept_id. 0 ) } ) ;
1488
-
1489
1493
// Finally, forward the intercepted payment through and claim it.
1490
1494
nodes[ 1 ] . node . forward_intercepted_htlc ( intercept_id, & channel_id, nodes[ 2 ] . node . get_our_node_id ( ) , expected_outbound_amount_msat) . unwrap ( ) ;
1491
1495
expect_pending_htlcs_forwardable ! ( nodes[ 1 ] ) ;
@@ -1523,5 +1527,34 @@ fn do_test_intercepted_payment(fail_intercept: bool) {
1523
1527
} ,
1524
1528
_ => panic ! ( "Unexpected event" )
1525
1529
}
1530
+ } else if test == InterceptTest :: Timeout {
1531
+ let mut block = Block {
1532
+ header : BlockHeader { version : 0x20000000 , prev_blockhash : nodes[ 0 ] . best_block_hash ( ) , merkle_root : TxMerkleNode :: all_zeros ( ) , time : 42 , bits : 42 , nonce : 42 } ,
1533
+ txdata : vec ! [ ] ,
1534
+ } ;
1535
+ connect_block ( & nodes[ 0 ] , & block) ;
1536
+ connect_block ( & nodes[ 1 ] , & block) ;
1537
+ let block_count = 183 ; // find_route adds a random CLTV offset, so hardcode rather than summing consts
1538
+ for _ in 0 ..block_count {
1539
+ block. header . prev_blockhash = block. block_hash ( ) ;
1540
+ connect_block ( & nodes[ 0 ] , & block) ;
1541
+ connect_block ( & nodes[ 1 ] , & block) ;
1542
+ }
1543
+ expect_pending_htlcs_forwardable_and_htlc_handling_failed ! ( nodes[ 1 ] , vec![ HTLCDestination :: InvalidForward { requested_forward_scid: intercept_scid } ] ) ;
1544
+ check_added_monitors ! ( nodes[ 1 ] , 1 ) ;
1545
+ let htlc_timeout_updates = get_htlc_update_msgs ! ( nodes[ 1 ] , nodes[ 0 ] . node. get_our_node_id( ) ) ;
1546
+ assert ! ( htlc_timeout_updates. update_add_htlcs. is_empty( ) ) ;
1547
+ assert_eq ! ( htlc_timeout_updates. update_fail_htlcs. len( ) , 1 ) ;
1548
+ assert ! ( htlc_timeout_updates. update_fail_malformed_htlcs. is_empty( ) ) ;
1549
+ assert ! ( htlc_timeout_updates. update_fee. is_none( ) ) ;
1550
+
1551
+ nodes[ 0 ] . node . handle_update_fail_htlc ( & nodes[ 1 ] . node . get_our_node_id ( ) , & htlc_timeout_updates. update_fail_htlcs [ 0 ] ) ;
1552
+ commitment_signed_dance ! ( nodes[ 0 ] , nodes[ 1 ] , htlc_timeout_updates. commitment_signed, false ) ;
1553
+ expect_payment_failed ! ( nodes[ 0 ] , payment_hash, false , 0x2000 | 2 , [ ] ) ;
1554
+
1555
+ // Check for unknown intercept id error.
1556
+ let ( _, channel_id) = open_zero_conf_channel ( & nodes[ 1 ] , & nodes[ 2 ] , None ) ;
1557
+ let unknown_intercept_id_err = nodes[ 1 ] . node . forward_intercepted_htlc ( intercept_id, & channel_id, nodes[ 2 ] . node . get_our_node_id ( ) , expected_outbound_amount_msat) . unwrap_err ( ) ;
1558
+ assert_eq ! ( unknown_intercept_id_err , APIError :: APIMisuseError { err: format!( "Payment with intercept id {:?} not found" , intercept_id. 0 ) } ) ;
1526
1559
}
1527
1560
}
0 commit comments