@@ -27,7 +27,7 @@ use bitcoin::util::bip143;
27
27
use bitcoin:: util:: address:: Address ;
28
28
use bitcoin:: util:: bip32:: { ChildNumber , ExtendedPubKey , ExtendedPrivKey } ;
29
29
use bitcoin:: blockdata:: block:: { Block , BlockHeader } ;
30
- use bitcoin:: blockdata:: transaction:: { Transaction , TxOut , TxIn , SigHashType } ;
30
+ use bitcoin:: blockdata:: transaction:: { Transaction , TxOut , TxIn , SigHashType , OutPoint as BitcoinOutPoint } ;
31
31
use bitcoin:: blockdata:: script:: { Builder , Script } ;
32
32
use bitcoin:: blockdata:: opcodes;
33
33
use bitcoin:: blockdata:: constants:: genesis_block;
@@ -5513,3 +5513,143 @@ fn test_update_fulfill_htlc_bolt2_after_malformed_htlc_message_must_forward_upda
5513
5513
5514
5514
check_added_monitors ! ( nodes[ 1 ] , 1 ) ;
5515
5515
}
5516
+
5517
+ fn do_test_failure_delay_dust_htlc_local_commitment ( announce_latest : bool ) {
5518
+ // Dust-HTLC failure updates must be delayed until failure-trigger tx (in this case local commitment) reach HTLC_FAIL_ANTI_REORG_DELAY
5519
+ // We can have at most two valid local commitment tx, so both cases must be covered, and both txs must be checked to get them all as
5520
+ // HTLC could have been removed from lastest local commitment tx but still valid until we get remote RAA
5521
+
5522
+ let nodes = create_network ( 2 ) ;
5523
+ let chan =create_announced_chan_between_nodes ( & nodes, 0 , 1 ) ;
5524
+
5525
+ let bs_dust_limit = nodes[ 1 ] . node . channel_state . lock ( ) . unwrap ( ) . by_id . get ( & chan. 2 ) . unwrap ( ) . our_dust_limit_satoshis ;
5526
+
5527
+ // We route 2 dust-HTLCs between A and B
5528
+ let ( _, payment_hash_1) = route_payment ( & nodes[ 0 ] , & [ & nodes[ 1 ] ] , bs_dust_limit* 1000 ) ;
5529
+ let ( _, payment_hash_2) = route_payment ( & nodes[ 0 ] , & [ & nodes[ 1 ] ] , bs_dust_limit* 1000 ) ;
5530
+ route_payment ( & nodes[ 0 ] , & [ & nodes[ 1 ] ] , 1000000 ) ;
5531
+
5532
+ // Cache one local commitment tx as previous
5533
+ let as_prev_commitment_tx = nodes[ 0 ] . node . channel_state . lock ( ) . unwrap ( ) . by_id . get ( & chan. 2 ) . unwrap ( ) . last_local_commitment_txn . clone ( ) ;
5534
+
5535
+ // Fail one HTLC to prune it in the will-be-latest-local commitment tx
5536
+ assert ! ( nodes[ 1 ] . node. fail_htlc_backwards( & payment_hash_2) ) ;
5537
+ check_added_monitors ! ( nodes[ 1 ] , 0 ) ;
5538
+ expect_pending_htlcs_forwardable ! ( nodes[ 1 ] ) ;
5539
+ check_added_monitors ! ( nodes[ 1 ] , 1 ) ;
5540
+
5541
+ let remove = get_htlc_update_msgs ! ( nodes[ 1 ] , nodes[ 0 ] . node. get_our_node_id( ) ) ;
5542
+ nodes[ 0 ] . node . handle_update_fail_htlc ( & nodes[ 1 ] . node . get_our_node_id ( ) , & remove. update_fail_htlcs [ 0 ] ) . unwrap ( ) ;
5543
+ nodes[ 0 ] . node . handle_commitment_signed ( & nodes[ 1 ] . node . get_our_node_id ( ) , & remove. commitment_signed ) . unwrap ( ) ;
5544
+ check_added_monitors ! ( nodes[ 0 ] , 1 ) ;
5545
+
5546
+ // Cache one local commitment tx as lastest
5547
+ let as_last_commitment_tx = nodes[ 0 ] . node . channel_state . lock ( ) . unwrap ( ) . by_id . get ( & chan. 2 ) . unwrap ( ) . last_local_commitment_txn . clone ( ) ;
5548
+
5549
+ let events = nodes[ 0 ] . node . get_and_clear_pending_msg_events ( ) ;
5550
+ match events[ 0 ] {
5551
+ MessageSendEvent :: SendRevokeAndACK { node_id, .. } => {
5552
+ assert_eq ! ( node_id, nodes[ 1 ] . node. get_our_node_id( ) ) ;
5553
+ } ,
5554
+ _ => panic ! ( "Unexpected event" ) ,
5555
+ }
5556
+ match events[ 1 ] {
5557
+ MessageSendEvent :: UpdateHTLCs { node_id, .. } => {
5558
+ assert_eq ! ( node_id, nodes[ 1 ] . node. get_our_node_id( ) ) ;
5559
+ } ,
5560
+ _ => panic ! ( "Unexpected event" ) ,
5561
+ }
5562
+
5563
+ assert_ne ! ( as_prev_commitment_tx, as_last_commitment_tx) ;
5564
+ // Fail the 2 dust-HTLCs, move their failure in maturation buffer (htlc_updated_waiting_threshold_conf)
5565
+ let header = BlockHeader { version : 0x20000000 , prev_blockhash : Default :: default ( ) , merkle_root : Default :: default ( ) , time : 42 , bits : 42 , nonce : 42 } ;
5566
+ if announce_latest {
5567
+ nodes[ 0 ] . chain_monitor . block_connected_checked ( & header, 1 , & [ & as_last_commitment_tx[ 0 ] ] , & [ 1 ; 1 ] ) ;
5568
+ } else {
5569
+ nodes[ 0 ] . chain_monitor . block_connected_checked ( & header, 1 , & [ & as_prev_commitment_tx[ 0 ] ] , & [ 1 ; 1 ] ) ;
5570
+ }
5571
+
5572
+ let events = nodes[ 0 ] . node . get_and_clear_pending_msg_events ( ) ;
5573
+ assert_eq ! ( events. len( ) , 1 ) ;
5574
+ match events[ 0 ] {
5575
+ MessageSendEvent :: BroadcastChannelUpdate { .. } => { } ,
5576
+ _ => panic ! ( "Unexpected event" ) ,
5577
+ }
5578
+
5579
+ assert_eq ! ( nodes[ 0 ] . node. get_and_clear_pending_events( ) . len( ) , 0 ) ;
5580
+ connect_blocks ( & nodes[ 0 ] . chain_monitor , HTLC_FAIL_ANTI_REORG_DELAY - 1 , 1 , true , header. bitcoin_hash ( ) ) ;
5581
+ let events = nodes[ 0 ] . node . get_and_clear_pending_events ( ) ;
5582
+ // Only 2 PaymentFailed events should show up, over-dust HTLC has to be failed by timeout tx
5583
+ assert_eq ! ( events. len( ) , 2 ) ;
5584
+ let mut first_failed = false ;
5585
+ for event in events {
5586
+ match event {
5587
+ Event :: PaymentFailed { payment_hash, .. } => {
5588
+ if payment_hash == payment_hash_1 {
5589
+ assert ! ( !first_failed) ;
5590
+ first_failed = true ;
5591
+ } else {
5592
+ assert_eq ! ( payment_hash, payment_hash_2) ;
5593
+ }
5594
+ }
5595
+ _ => panic ! ( "Unexpected event" ) ,
5596
+ }
5597
+ }
5598
+ }
5599
+
5600
+ #[ test]
5601
+ fn test_failure_delay_dust_htlc_local_commitment ( ) {
5602
+ do_test_failure_delay_dust_htlc_local_commitment ( true ) ;
5603
+ do_test_failure_delay_dust_htlc_local_commitment ( false ) ;
5604
+ }
5605
+
5606
+ #[ test]
5607
+ fn test_no_failure_dust_htlc_local_commitment ( ) {
5608
+ // Transaction filters for failing back dust htlc based on local commitment txn infos has been
5609
+ // prone to error, we test here that a dummy transaction don't fail them.
5610
+
5611
+ let nodes = create_network ( 2 ) ;
5612
+ let chan = create_announced_chan_between_nodes ( & nodes, 0 , 1 ) ;
5613
+
5614
+ // Rebalance a bit
5615
+ send_payment ( & nodes[ 0 ] , & vec ! ( & nodes[ 1 ] ) [ ..] , 8000000 ) ;
5616
+
5617
+ let as_dust_limit = nodes[ 0 ] . node . channel_state . lock ( ) . unwrap ( ) . by_id . get ( & chan. 2 ) . unwrap ( ) . our_dust_limit_satoshis ;
5618
+ let bs_dust_limit = nodes[ 1 ] . node . channel_state . lock ( ) . unwrap ( ) . by_id . get ( & chan. 2 ) . unwrap ( ) . our_dust_limit_satoshis ;
5619
+
5620
+ // We route 2 dust-HTLCs between A and B
5621
+ let ( preimage_1, _) = route_payment ( & nodes[ 0 ] , & [ & nodes[ 1 ] ] , bs_dust_limit* 1000 ) ;
5622
+ let ( preimage_2, _) = route_payment ( & nodes[ 1 ] , & [ & nodes[ 0 ] ] , as_dust_limit* 1000 ) ;
5623
+
5624
+ // Build a dummy invalid transaction trying to spend a commitment tx
5625
+ let input = TxIn {
5626
+ previous_output : BitcoinOutPoint { txid : chan. 3 . txid ( ) , vout : 0 } ,
5627
+ script_sig : Script :: new ( ) ,
5628
+ sequence : 0 ,
5629
+ witness : Vec :: new ( ) ,
5630
+ } ;
5631
+
5632
+ let outp = TxOut {
5633
+ script_pubkey : Builder :: new ( ) . push_opcode ( opcodes:: all:: OP_RETURN ) . into_script ( ) ,
5634
+ value : 10000 ,
5635
+ } ;
5636
+
5637
+ let dummy_tx = Transaction {
5638
+ version : 2 ,
5639
+ lock_time : 0 ,
5640
+ input : vec ! [ input] ,
5641
+ output : vec ! [ outp]
5642
+ } ;
5643
+
5644
+ let header = BlockHeader { version : 0x20000000 , prev_blockhash : Default :: default ( ) , merkle_root : Default :: default ( ) , time : 42 , bits : 42 , nonce : 42 } ;
5645
+ nodes[ 0 ] . chan_monitor . simple_monitor . block_connected ( & header, 1 , & [ & dummy_tx] , & [ 1 ; 1 ] ) ;
5646
+ assert_eq ! ( nodes[ 0 ] . node. get_and_clear_pending_events( ) . len( ) , 0 ) ;
5647
+ assert_eq ! ( nodes[ 0 ] . node. get_and_clear_pending_msg_events( ) . len( ) , 0 ) ;
5648
+ // We broadcast a few more block to check everything is all right
5649
+ connect_blocks ( & nodes[ 0 ] . chain_monitor , 20 , 1 , true , header. bitcoin_hash ( ) ) ;
5650
+ assert_eq ! ( nodes[ 0 ] . node. get_and_clear_pending_events( ) . len( ) , 0 ) ;
5651
+ assert_eq ! ( nodes[ 0 ] . node. get_and_clear_pending_msg_events( ) . len( ) , 0 ) ;
5652
+
5653
+ claim_payment ( & nodes[ 0 ] , & vec ! ( & nodes[ 1 ] ) [ ..] , preimage_1) ;
5654
+ claim_payment ( & nodes[ 1 ] , & vec ! ( & nodes[ 0 ] ) [ ..] , preimage_2) ;
5655
+ }
0 commit comments