@@ -5483,3 +5483,71 @@ fn test_failure_delay_dust_htlc_local_commitment() {
5483
5483
do_test_failure_delay_dust_htlc_local_commitment ( true ) ;
5484
5484
do_test_failure_delay_dust_htlc_local_commitment ( false ) ;
5485
5485
}
5486
+
5487
+ fn do_test_sweep_outbound_htlc_failure_update ( revoked : bool , local : bool ) {
5488
+ // Outbound HTLC-failure updates must be cancelled if we get a reorg before we reach HTLC_FAIL_ANTI_REORG_DELAY.
5489
+ // Broadcast of revoked remote commitment tx, trigger failure-update of dust/non-dust HTLCs
5490
+ // Broadcast of remote commitment tx, trigger failure-update of dust-HTLCs
5491
+ // Broadcast of timeout tx on remote commitment tx, trigger failure-udate of non-dust HTLCs
5492
+ // Broadcast of local commitment tx, trigger failure-update of dust-HTLCs
5493
+ // Broadcast of HTLC-timeout tx on local commitment tx, trigger failure-update of non-dust HTLCs
5494
+
5495
+ let nodes = create_network ( 2 ) ;
5496
+ let chan = create_announced_chan_between_nodes ( & nodes, 0 , 1 ) ;
5497
+
5498
+ let bs_dust_limit = nodes[ 1 ] . node . channel_state . lock ( ) . unwrap ( ) . by_id . get ( & chan. 2 ) . unwrap ( ) . our_dust_limit_satoshis ;
5499
+
5500
+ let ( payment_preimage_1, _) = route_payment ( & nodes[ 0 ] , & [ & nodes[ 1 ] ] , bs_dust_limit* 1000 ) ;
5501
+ let ( payment_preimage_2, _) = route_payment ( & nodes[ 0 ] , & [ & nodes[ 1 ] ] , 1000000 ) ;
5502
+
5503
+ let as_commitment_tx = nodes[ 0 ] . node . channel_state . lock ( ) . unwrap ( ) . by_id . get ( & chan. 2 ) . unwrap ( ) . last_local_commitment_txn . clone ( ) ;
5504
+ let bs_commitment_tx = nodes[ 1 ] . node . channel_state . lock ( ) . unwrap ( ) . by_id . get ( & chan. 2 ) . unwrap ( ) . last_local_commitment_txn . clone ( ) ;
5505
+
5506
+ // We revoked bs_commitment_tx
5507
+ if revoked {
5508
+ let ( payment_preimage_3, _) = route_payment ( & nodes[ 0 ] , & [ & nodes[ 1 ] ] , 1000000 ) ;
5509
+ claim_payment ( & nodes[ 0 ] , & vec ! ( & nodes[ 1 ] ) [ ..] , payment_preimage_3) ;
5510
+ }
5511
+
5512
+ let header = BlockHeader { version : 0x20000000 , prev_blockhash : Default :: default ( ) , merkle_root : Default :: default ( ) , time : 42 , bits : 42 , nonce : 42 } ;
5513
+ let header_2 = BlockHeader { version : 0x20000000 , prev_blockhash : header. bitcoin_hash ( ) , merkle_root : Default :: default ( ) , time : 42 , bits : 42 , nonce : 42 } ;
5514
+ let mut timeout_tx = Vec :: new ( ) ;
5515
+ if local {
5516
+ // We fail dust-HTLC 1 by broadcast of local commitment tx
5517
+ nodes[ 0 ] . chain_monitor . block_connected_checked ( & header, 1 , & [ & as_commitment_tx[ 0 ] ] , & [ 1 ; 1 ] ) ;
5518
+ timeout_tx. push ( nodes[ 0 ] . tx_broadcaster . txn_broadcasted . lock ( ) . unwrap ( ) [ 0 ] . clone ( ) ) ;
5519
+ assert_eq ! ( timeout_tx[ 0 ] . input[ 0 ] . witness. last( ) . unwrap( ) . len( ) , OFFERED_HTLC_SCRIPT_WEIGHT ) ;
5520
+ // We fail dust-HTLC 2 by broadcast of local HTLC-timeout tx on local commitment tx
5521
+ nodes[ 0 ] . chain_monitor . block_connected_checked ( & header_2, 1 , & [ & timeout_tx[ 0 ] ] , & [ 1 ; 1 ] ) ;
5522
+ } else {
5523
+ // We fail dust-HTLC 1 by broadcast of remote commitment tx. If revoked, fail also non-dust HTLC
5524
+ nodes[ 0 ] . chain_monitor . block_connected_checked ( & header, 1 , & [ & bs_commitment_tx[ 0 ] ] , & [ 1 ; 1 ] ) ;
5525
+ if !revoked {
5526
+ timeout_tx. push ( nodes[ 0 ] . tx_broadcaster . txn_broadcasted . lock ( ) . unwrap ( ) [ 0 ] . clone ( ) ) ;
5527
+ assert_eq ! ( timeout_tx[ 0 ] . input[ 0 ] . witness. last( ) . unwrap( ) . len( ) , ACCEPTED_HTLC_SCRIPT_WEIGHT ) ;
5528
+ // We fail non-dust-HTLC 2 by broadcast of local timeout tx on remote commitment tx
5529
+ nodes[ 0 ] . chain_monitor . block_connected_checked ( & header_2, 1 , & [ & timeout_tx[ 0 ] ] , & [ 1 ; 1 ] ) ;
5530
+ }
5531
+ }
5532
+
5533
+ assert_eq ! ( nodes[ 0 ] . node. get_and_clear_pending_events( ) . len( ) , 0 ) ;
5534
+ // We connect 3 blocks, not enough to reach HTLC_FAIL_ANTI_REORG_DELAY
5535
+ connect_blocks ( & nodes[ 0 ] . chain_monitor , 3 , 2 , true , header. bitcoin_hash ( ) ) ;
5536
+ assert_eq ! ( nodes[ 0 ] . node. get_and_clear_pending_events( ) . len( ) , 0 ) ;
5537
+
5538
+ // We disconnect 5 blocks, updates should have been cancelled and HTLC still claimable
5539
+ disconnect_blocks ( & nodes[ 0 ] . chain_monitor , 3 , 5 , true , header. bitcoin_hash ( ) ) ;
5540
+ nodes[ 0 ] . chain_monitor . block_disconnected ( & Block { header : header_2, txdata : if !revoked { timeout_tx } else { vec ! [ ] } } , 2 ) ;
5541
+ nodes[ 0 ] . chain_monitor . block_disconnected ( & Block { header, txdata : vec ! [ if local { as_commitment_tx[ 0 ] . clone( ) } else { bs_commitment_tx[ 0 ] . clone( ) } ] } , 1 ) ;
5542
+ assert_eq ! ( nodes[ 0 ] . node. get_and_clear_pending_events( ) . len( ) , 0 ) ;
5543
+
5544
+ claim_payment ( & nodes[ 0 ] , & vec ! ( & nodes[ 1 ] ) [ ..] , payment_preimage_1) ;
5545
+ claim_payment ( & nodes[ 0 ] , & vec ! ( & nodes[ 1 ] ) [ ..] , payment_preimage_2) ;
5546
+ }
5547
+
5548
+ #[ test]
5549
+ fn test_sweep_outbound_htlc_failure_update ( ) {
5550
+ do_test_sweep_outbound_htlc_failure_update ( false , true ) ;
5551
+ do_test_sweep_outbound_htlc_failure_update ( false , false ) ;
5552
+ do_test_sweep_outbound_htlc_failure_update ( true , false ) ;
5553
+ }
0 commit comments