@@ -5631,3 +5631,71 @@ fn test_failure_delay_dust_htlc_local_commitment() {
5631
5631
do_test_failure_delay_dust_htlc_local_commitment ( true ) ;
5632
5632
do_test_failure_delay_dust_htlc_local_commitment ( false ) ;
5633
5633
}
5634
+
5635
+ fn do_test_sweep_outbound_htlc_failure_update ( revoked : bool , local : bool ) {
5636
+ // Outbound HTLC-failure updates must be cancelled if we get a reorg before we reach HTLC_FAIL_ANTI_REORG_DELAY.
5637
+ // Broadcast of revoked remote commitment tx, trigger failure-update of dust/non-dust HTLCs
5638
+ // Broadcast of remote commitment tx, trigger failure-update of dust-HTLCs
5639
+ // Broadcast of timeout tx on remote commitment tx, trigger failure-udate of non-dust HTLCs
5640
+ // Broadcast of local commitment tx, trigger failure-update of dust-HTLCs
5641
+ // Broadcast of HTLC-timeout tx on local commitment tx, trigger failure-update of non-dust HTLCs
5642
+
5643
+ let nodes = create_network ( 2 ) ;
5644
+ let chan = create_announced_chan_between_nodes ( & nodes, 0 , 1 ) ;
5645
+
5646
+ let bs_dust_limit = nodes[ 1 ] . node . channel_state . lock ( ) . unwrap ( ) . by_id . get ( & chan. 2 ) . unwrap ( ) . our_dust_limit_satoshis ;
5647
+
5648
+ let ( payment_preimage_1, _) = route_payment ( & nodes[ 0 ] , & [ & nodes[ 1 ] ] , bs_dust_limit* 1000 ) ;
5649
+ let ( payment_preimage_2, _) = route_payment ( & nodes[ 0 ] , & [ & nodes[ 1 ] ] , 1000000 ) ;
5650
+
5651
+ let as_commitment_tx = nodes[ 0 ] . node . channel_state . lock ( ) . unwrap ( ) . by_id . get ( & chan. 2 ) . unwrap ( ) . last_local_commitment_txn . clone ( ) ;
5652
+ let bs_commitment_tx = nodes[ 1 ] . node . channel_state . lock ( ) . unwrap ( ) . by_id . get ( & chan. 2 ) . unwrap ( ) . last_local_commitment_txn . clone ( ) ;
5653
+
5654
+ // We revoked bs_commitment_tx
5655
+ if revoked {
5656
+ let ( payment_preimage_3, _) = route_payment ( & nodes[ 0 ] , & [ & nodes[ 1 ] ] , 1000000 ) ;
5657
+ claim_payment ( & nodes[ 0 ] , & vec ! ( & nodes[ 1 ] ) [ ..] , payment_preimage_3) ;
5658
+ }
5659
+
5660
+ let header = BlockHeader { version : 0x20000000 , prev_blockhash : Default :: default ( ) , merkle_root : Default :: default ( ) , time : 42 , bits : 42 , nonce : 42 } ;
5661
+ let header_2 = BlockHeader { version : 0x20000000 , prev_blockhash : header. bitcoin_hash ( ) , merkle_root : Default :: default ( ) , time : 42 , bits : 42 , nonce : 42 } ;
5662
+ let mut timeout_tx = Vec :: new ( ) ;
5663
+ if local {
5664
+ // We fail dust-HTLC 1 by broadcast of local commitment tx
5665
+ nodes[ 0 ] . chain_monitor . block_connected_checked ( & header, 1 , & [ & as_commitment_tx[ 0 ] ] , & [ 1 ; 1 ] ) ;
5666
+ timeout_tx. push ( nodes[ 0 ] . tx_broadcaster . txn_broadcasted . lock ( ) . unwrap ( ) [ 0 ] . clone ( ) ) ;
5667
+ assert_eq ! ( timeout_tx[ 0 ] . input[ 0 ] . witness. last( ) . unwrap( ) . len( ) , OFFERED_HTLC_SCRIPT_WEIGHT ) ;
5668
+ // We fail dust-HTLC 2 by broadcast of local HTLC-timeout tx on local commitment tx
5669
+ nodes[ 0 ] . chain_monitor . block_connected_checked ( & header_2, 1 , & [ & timeout_tx[ 0 ] ] , & [ 1 ; 1 ] ) ;
5670
+ } else {
5671
+ // We fail dust-HTLC 1 by broadcast of remote commitment tx. If revoked, fail also non-dust HTLC
5672
+ nodes[ 0 ] . chain_monitor . block_connected_checked ( & header, 1 , & [ & bs_commitment_tx[ 0 ] ] , & [ 1 ; 1 ] ) ;
5673
+ if !revoked {
5674
+ timeout_tx. push ( nodes[ 0 ] . tx_broadcaster . txn_broadcasted . lock ( ) . unwrap ( ) [ 0 ] . clone ( ) ) ;
5675
+ assert_eq ! ( timeout_tx[ 0 ] . input[ 0 ] . witness. last( ) . unwrap( ) . len( ) , ACCEPTED_HTLC_SCRIPT_WEIGHT ) ;
5676
+ // We fail non-dust-HTLC 2 by broadcast of local timeout tx on remote commitment tx
5677
+ nodes[ 0 ] . chain_monitor . block_connected_checked ( & header_2, 1 , & [ & timeout_tx[ 0 ] ] , & [ 1 ; 1 ] ) ;
5678
+ }
5679
+ }
5680
+
5681
+ assert_eq ! ( nodes[ 0 ] . node. get_and_clear_pending_events( ) . len( ) , 0 ) ;
5682
+ // We connect 3 blocks, not enough to reach HTLC_FAIL_ANTI_REORG_DELAY
5683
+ connect_blocks ( & nodes[ 0 ] . chain_monitor , 3 , 2 , true , header. bitcoin_hash ( ) ) ;
5684
+ assert_eq ! ( nodes[ 0 ] . node. get_and_clear_pending_events( ) . len( ) , 0 ) ;
5685
+
5686
+ // We disconnect 5 blocks, updates should have been cancelled and HTLC still claimable
5687
+ disconnect_blocks ( & nodes[ 0 ] . chain_monitor , 3 , 5 , true , header. bitcoin_hash ( ) ) ;
5688
+ nodes[ 0 ] . chain_monitor . block_disconnected ( & Block { header : header_2, txdata : if !revoked { timeout_tx } else { vec ! [ ] } } , 2 ) ;
5689
+ nodes[ 0 ] . chain_monitor . block_disconnected ( & Block { header, txdata : vec ! [ if local { as_commitment_tx[ 0 ] . clone( ) } else { bs_commitment_tx[ 0 ] . clone( ) } ] } , 1 ) ;
5690
+ assert_eq ! ( nodes[ 0 ] . node. get_and_clear_pending_events( ) . len( ) , 0 ) ;
5691
+
5692
+ claim_payment ( & nodes[ 0 ] , & vec ! ( & nodes[ 1 ] ) [ ..] , payment_preimage_1) ;
5693
+ claim_payment ( & nodes[ 0 ] , & vec ! ( & nodes[ 1 ] ) [ ..] , payment_preimage_2) ;
5694
+ }
5695
+
5696
+ #[ test]
5697
+ fn test_sweep_outbound_htlc_failure_update ( ) {
5698
+ do_test_sweep_outbound_htlc_failure_update ( false , true ) ;
5699
+ do_test_sweep_outbound_htlc_failure_update ( false , false ) ;
5700
+ do_test_sweep_outbound_htlc_failure_update ( true , false ) ;
5701
+ }
0 commit comments