@@ -2187,6 +2187,15 @@ fn claim_htlc_outputs_single_tx() {
2187
2187
let header = BlockHeader { version : 0x20000000 , prev_blockhash : Default :: default ( ) , merkle_root : Default :: default ( ) , time : 42 , bits : 42 , nonce : 42 } ;
2188
2188
nodes[ 0 ] . block_notifier . block_connected ( & Block { header, txdata : vec ! [ revoked_local_txn[ 0 ] . clone( ) ] } , 200 ) ;
2189
2189
nodes[ 1 ] . block_notifier . block_connected ( & Block { header, txdata : vec ! [ revoked_local_txn[ 0 ] . clone( ) ] } , 200 ) ;
2190
+
2191
+ // Expect pending failures, but we don't bother trying to update the channel state with them.
2192
+ let events = nodes[ 0 ] . node . get_and_clear_pending_events ( ) ;
2193
+ assert_eq ! ( events. len( ) , 1 ) ;
2194
+ match events[ 0 ] {
2195
+ Event :: PendingHTLCsForwardable { .. } => { } ,
2196
+ _ => panic ! ( "Unexpected event" ) ,
2197
+ } ;
2198
+
2190
2199
connect_blocks ( & nodes[ 1 ] . block_notifier , ANTI_REORG_DELAY - 1 , 200 , true , header. bitcoin_hash ( ) ) ;
2191
2200
2192
2201
let events = nodes[ 1 ] . node . get_and_clear_pending_events ( ) ;
@@ -3441,6 +3450,48 @@ fn test_drop_messages_peer_disconnect_dual_htlc() {
3441
3450
claim_payment ( & nodes[ 0 ] , & [ & nodes[ 1 ] ] , payment_preimage_2, 1_000_000 ) ;
3442
3451
}
3443
3452
3453
+ #[ test]
3454
+ fn test_htlc_timeout ( ) {
3455
+ // If the user fails to claim/fail an HTLC within the HTLC CLTV timeout we fail it for them
3456
+ // to avoid our counterparty failing the channel.
3457
+ let node_cfgs = create_node_cfgs ( 2 ) ;
3458
+ let node_chanmgrs = create_node_chanmgrs ( 2 , & node_cfgs, & [ None , None ] ) ;
3459
+ let nodes = create_network ( 2 , & node_cfgs, & node_chanmgrs) ;
3460
+
3461
+ create_announced_chan_between_nodes ( & nodes, 0 , 1 , InitFeatures :: supported ( ) , InitFeatures :: supported ( ) ) ;
3462
+ let ( _, our_payment_hash) = route_payment ( & nodes[ 0 ] , & [ & nodes[ 1 ] ] , 100000 ) ;
3463
+
3464
+ let mut header = BlockHeader { version : 0x20000000 , prev_blockhash : Default :: default ( ) , merkle_root : Default :: default ( ) , time : 42 , bits : 42 , nonce : 42 } ;
3465
+ nodes[ 0 ] . block_notifier . block_connected_checked ( & header, 101 , & [ ] , & [ ] ) ;
3466
+ nodes[ 1 ] . block_notifier . block_connected_checked ( & header, 101 , & [ ] , & [ ] ) ;
3467
+ for i in 102 ..TEST_FINAL_CLTV + 100 + 1 - CLTV_CLAIM_BUFFER - LATENCY_GRACE_PERIOD_BLOCKS {
3468
+ header. prev_blockhash = header. bitcoin_hash ( ) ;
3469
+ nodes[ 0 ] . block_notifier . block_connected_checked ( & header, i, & [ ] , & [ ] ) ;
3470
+ nodes[ 1 ] . block_notifier . block_connected_checked ( & header, i, & [ ] , & [ ] ) ;
3471
+ }
3472
+
3473
+ expect_pending_htlcs_forwardable ! ( nodes[ 1 ] ) ;
3474
+
3475
+ check_added_monitors ! ( nodes[ 1 ] , 1 ) ;
3476
+ let htlc_timeout_updates = get_htlc_update_msgs ! ( nodes[ 1 ] , nodes[ 0 ] . node. get_our_node_id( ) ) ;
3477
+ assert ! ( htlc_timeout_updates. update_add_htlcs. is_empty( ) ) ;
3478
+ assert_eq ! ( htlc_timeout_updates. update_fail_htlcs. len( ) , 1 ) ;
3479
+ assert ! ( htlc_timeout_updates. update_fail_malformed_htlcs. is_empty( ) ) ;
3480
+ assert ! ( htlc_timeout_updates. update_fee. is_none( ) ) ;
3481
+
3482
+ nodes[ 0 ] . node . handle_update_fail_htlc ( & nodes[ 1 ] . node . get_our_node_id ( ) , & htlc_timeout_updates. update_fail_htlcs [ 0 ] ) ;
3483
+ commitment_signed_dance ! ( nodes[ 0 ] , nodes[ 1 ] , htlc_timeout_updates. commitment_signed, false ) ;
3484
+ let events = nodes[ 0 ] . node . get_and_clear_pending_events ( ) ;
3485
+ match events[ 0 ] {
3486
+ Event :: PaymentFailed { payment_hash, rejected_by_dest, error_code } => {
3487
+ assert_eq ! ( payment_hash, our_payment_hash) ;
3488
+ assert ! ( rejected_by_dest) ;
3489
+ assert_eq ! ( error_code. unwrap( ) , 0x4000 | 15 ) ;
3490
+ } ,
3491
+ _ => panic ! ( "Unexpected event" ) ,
3492
+ }
3493
+ }
3494
+
3444
3495
#[ test]
3445
3496
fn test_invalid_channel_announcement ( ) {
3446
3497
//Test BOLT 7 channel_announcement msg requirement for final node, gather data to build customed channel_announcement msgs
@@ -6698,6 +6749,15 @@ fn test_bump_penalty_txn_on_revoked_htlcs() {
6698
6749
6699
6750
// Broadcast set of revoked txn on A
6700
6751
let header_128 = connect_blocks ( & nodes[ 0 ] . block_notifier , 128 , 0 , true , header. bitcoin_hash ( ) ) ;
6752
+
6753
+ // Expect pending failures, but we don't bother trying to update the channel state with them.
6754
+ let events = nodes[ 0 ] . node . get_and_clear_pending_events ( ) ;
6755
+ assert_eq ! ( events. len( ) , 1 ) ;
6756
+ match events[ 0 ] {
6757
+ Event :: PendingHTLCsForwardable { .. } => { } ,
6758
+ _ => panic ! ( "Unexpected event" ) ,
6759
+ } ;
6760
+
6701
6761
let header_129 = BlockHeader { version : 0x20000000 , prev_blockhash : header_128, merkle_root : Default :: default ( ) , time : 42 , bits : 42 , nonce : 42 } ;
6702
6762
nodes[ 0 ] . block_notifier . block_connected ( & Block { header : header_129, txdata : vec ! [ revoked_local_txn[ 0 ] . clone( ) , revoked_htlc_txn[ 0 ] . clone( ) , revoked_htlc_txn[ 1 ] . clone( ) ] } , 129 ) ;
6703
6763
let first;
@@ -7055,6 +7115,15 @@ fn test_bump_txn_sanitize_tracking_maps() {
7055
7115
7056
7116
// Broadcast set of revoked txn on A
7057
7117
let header_128 = connect_blocks ( & nodes[ 0 ] . block_notifier , 128 , 0 , false , Default :: default ( ) ) ;
7118
+
7119
+ // Expect pending failures, but we don't bother trying to update the channel state with them.
7120
+ let events = nodes[ 0 ] . node . get_and_clear_pending_events ( ) ;
7121
+ assert_eq ! ( events. len( ) , 1 ) ;
7122
+ match events[ 0 ] {
7123
+ Event :: PendingHTLCsForwardable { .. } => { } ,
7124
+ _ => panic ! ( "Unexpected event" ) ,
7125
+ } ;
7126
+
7058
7127
let header_129 = BlockHeader { version : 0x20000000 , prev_blockhash : header_128, merkle_root : Default :: default ( ) , time : 42 , bits : 42 , nonce : 42 } ;
7059
7128
nodes[ 0 ] . block_notifier . block_connected ( & Block { header : header_129, txdata : vec ! [ revoked_local_txn[ 0 ] . clone( ) ] } , 129 ) ;
7060
7129
check_closed_broadcast ! ( nodes[ 0 ] , false ) ;
0 commit comments