@@ -5183,3 +5183,71 @@ fn test_failure_delay_dust_htlc_local_commitment() {
5183
5183
do_test_failure_delay_dust_htlc_local_commitment ( true ) ;
5184
5184
do_test_failure_delay_dust_htlc_local_commitment ( false ) ;
5185
5185
}
5186
+
5187
+ fn do_test_sweep_outbound_htlc_failure_update ( revoked : bool , local : bool ) {
5188
+ // Outbound HTLC-failure updates must be cancelled if we get a reorg before we reach HTLC_FAIL_ANTI_REORG_DELAY.
5189
+ // Broadcast of revoked remote commitment tx, trigger failure-update of dust/non-dust HTLCs
5190
+ // Broadcast of remote commitment tx, trigger failure-update of dust-HTLCs
5191
+ // Broadcast of timeout tx on remote commitment tx, trigger failure-udate of non-dust HTLCs
5192
+ // Broadcast of local commitment tx, trigger failure-update of dust-HTLCs
5193
+ // Broadcast of HTLC-timeout tx on local commitment tx, trigger failure-update of non-dust HTLCs
5194
+
5195
+ let nodes = create_network ( 2 ) ;
5196
+ let chan = create_announced_chan_between_nodes ( & nodes, 0 , 1 ) ;
5197
+
5198
+ let bs_dust_limit = nodes[ 1 ] . node . channel_state . lock ( ) . unwrap ( ) . by_id . get ( & chan. 2 ) . unwrap ( ) . our_dust_limit_satoshis ;
5199
+
5200
+ let ( payment_preimage_1, _) = route_payment ( & nodes[ 0 ] , & [ & nodes[ 1 ] ] , bs_dust_limit* 1000 ) ;
5201
+ let ( payment_preimage_2, _) = route_payment ( & nodes[ 0 ] , & [ & nodes[ 1 ] ] , 1000000 ) ;
5202
+
5203
+ let as_commitment_tx = nodes[ 0 ] . node . channel_state . lock ( ) . unwrap ( ) . by_id . get ( & chan. 2 ) . unwrap ( ) . last_local_commitment_txn . clone ( ) ;
5204
+ let bs_commitment_tx = nodes[ 1 ] . node . channel_state . lock ( ) . unwrap ( ) . by_id . get ( & chan. 2 ) . unwrap ( ) . last_local_commitment_txn . clone ( ) ;
5205
+
5206
+ // We revoked bs_commitment_tx
5207
+ if revoked {
5208
+ let ( payment_preimage_3, _) = route_payment ( & nodes[ 0 ] , & [ & nodes[ 1 ] ] , 1000000 ) ;
5209
+ claim_payment ( & nodes[ 0 ] , & vec ! ( & nodes[ 1 ] ) [ ..] , payment_preimage_3) ;
5210
+ }
5211
+
5212
+ let header = BlockHeader { version : 0x20000000 , prev_blockhash : Default :: default ( ) , merkle_root : Default :: default ( ) , time : 42 , bits : 42 , nonce : 42 } ;
5213
+ let header_2 = BlockHeader { version : 0x20000000 , prev_blockhash : header. bitcoin_hash ( ) , merkle_root : Default :: default ( ) , time : 42 , bits : 42 , nonce : 42 } ;
5214
+ let mut timeout_tx = Vec :: new ( ) ;
5215
+ if local {
5216
+ // We fail dust-HTLC 1 by broadcast of local commitment tx
5217
+ nodes[ 0 ] . chain_monitor . block_connected_checked ( & header, 1 , & [ & as_commitment_tx[ 0 ] ] , & [ 1 ; 1 ] ) ;
5218
+ timeout_tx. push ( nodes[ 0 ] . tx_broadcaster . txn_broadcasted . lock ( ) . unwrap ( ) [ 0 ] . clone ( ) ) ;
5219
+ assert_eq ! ( timeout_tx[ 0 ] . input[ 0 ] . witness. last( ) . unwrap( ) . len( ) , OFFERED_HTLC_SCRIPT_WEIGHT ) ;
5220
+ // We fail dust-HTLC 2 by broadcast of local HTLC-timeout tx on local commitment tx
5221
+ nodes[ 0 ] . chain_monitor . block_connected_checked ( & header_2, 1 , & [ & timeout_tx[ 0 ] ] , & [ 1 ; 1 ] ) ;
5222
+ } else {
5223
+ // We fail dust-HTLC 1 by broadcast of remote commitment tx. If revoked, fail also non-dust HTLC
5224
+ nodes[ 0 ] . chain_monitor . block_connected_checked ( & header, 1 , & [ & bs_commitment_tx[ 0 ] ] , & [ 1 ; 1 ] ) ;
5225
+ if !revoked {
5226
+ timeout_tx. push ( nodes[ 0 ] . tx_broadcaster . txn_broadcasted . lock ( ) . unwrap ( ) [ 0 ] . clone ( ) ) ;
5227
+ assert_eq ! ( timeout_tx[ 0 ] . input[ 0 ] . witness. last( ) . unwrap( ) . len( ) , ACCEPTED_HTLC_SCRIPT_WEIGHT ) ;
5228
+ // We fail non-dust-HTLC 2 by broadcast of local timeout tx on remote commitment tx
5229
+ nodes[ 0 ] . chain_monitor . block_connected_checked ( & header_2, 1 , & [ & timeout_tx[ 0 ] ] , & [ 1 ; 1 ] ) ;
5230
+ }
5231
+ }
5232
+
5233
+ assert_eq ! ( nodes[ 0 ] . node. get_and_clear_pending_events( ) . len( ) , 0 ) ;
5234
+ // We connect 3 blocks, not enough to reach HTLC_FAIL_ANTI_REORG_DELAY
5235
+ connect_blocks ( & nodes[ 0 ] . chain_monitor , 3 , 2 , true , header. bitcoin_hash ( ) ) ;
5236
+ assert_eq ! ( nodes[ 0 ] . node. get_and_clear_pending_events( ) . len( ) , 0 ) ;
5237
+
5238
+ // We disconnect 5 blocks, updates should have been cancelled and HTLC still claimable
5239
+ disconnect_blocks ( & nodes[ 0 ] . chain_monitor , 3 , 5 , true , header. bitcoin_hash ( ) ) ;
5240
+ nodes[ 0 ] . chain_monitor . block_disconnected ( & Block { header : header_2, txdata : if !revoked { timeout_tx } else { vec ! [ ] } } , 2 ) ;
5241
+ nodes[ 0 ] . chain_monitor . block_disconnected ( & Block { header, txdata : vec ! [ if local { as_commitment_tx[ 0 ] . clone( ) } else { bs_commitment_tx[ 0 ] . clone( ) } ] } , 1 ) ;
5242
+ assert_eq ! ( nodes[ 0 ] . node. get_and_clear_pending_events( ) . len( ) , 0 ) ;
5243
+
5244
+ claim_payment ( & nodes[ 0 ] , & vec ! ( & nodes[ 1 ] ) [ ..] , payment_preimage_1) ;
5245
+ claim_payment ( & nodes[ 0 ] , & vec ! ( & nodes[ 1 ] ) [ ..] , payment_preimage_2) ;
5246
+ }
5247
+
5248
+ #[ test]
5249
+ fn test_sweep_outbound_htlc_failure_update ( ) {
5250
+ do_test_sweep_outbound_htlc_failure_update ( false , true ) ;
5251
+ do_test_sweep_outbound_htlc_failure_update ( false , false ) ;
5252
+ do_test_sweep_outbound_htlc_failure_update ( true , false ) ;
5253
+ }
0 commit comments