@@ -644,8 +644,7 @@ fn test_claim_value_force_close() {
644644 do_test_claim_value_force_close ( true , false ) ;
645645}
646646
647- #[ test]
648- fn test_balances_on_local_commitment_htlcs ( ) {
647+ fn do_test_balances_on_local_commitment_htlcs ( anchors : bool ) {
649648 // Previously, when handling the broadcast of a local commitment transactions (with associated
650649 // CSV delays prior to spendability), we incorrectly handled the CSV delays on HTLC
651650 // transactions. This caused us to miss spendable outputs for HTLCs which were awaiting a CSV
@@ -657,9 +656,34 @@ fn test_balances_on_local_commitment_htlcs() {
657656 // claim by our counterparty).
658657 let chanmon_cfgs = create_chanmon_cfgs ( 2 ) ;
659658 let node_cfgs = create_node_cfgs ( 2 , & chanmon_cfgs) ;
660- let node_chanmgrs = create_node_chanmgrs ( 2 , & node_cfgs, & [ None , None ] ) ;
659+ let mut user_config = test_default_channel_config ( ) ;
660+ if anchors {
661+ user_config. channel_handshake_config . negotiate_anchors_zero_fee_htlc_tx = true ;
662+ user_config. manually_accept_inbound_channels = true ;
663+ }
664+ let node_chanmgrs = create_node_chanmgrs ( 2 , & node_cfgs, & [ Some ( user_config) , Some ( user_config) ] ) ;
661665 let mut nodes = create_network ( 2 , & node_cfgs, & node_chanmgrs) ;
662666
667+ let coinbase_tx = Transaction {
668+ version : 2 ,
669+ lock_time : PackedLockTime :: ZERO ,
670+ input : vec ! [ TxIn { ..Default :: default ( ) } ] ,
671+ output : vec ! [
672+ TxOut {
673+ value: Amount :: ONE_BTC . to_sat( ) ,
674+ script_pubkey: nodes[ 0 ] . wallet_source. get_change_script( ) . unwrap( ) ,
675+ } ,
676+ TxOut {
677+ value: Amount :: ONE_BTC . to_sat( ) ,
678+ script_pubkey: nodes[ 1 ] . wallet_source. get_change_script( ) . unwrap( ) ,
679+ } ,
680+ ] ,
681+ } ;
682+ if anchors {
683+ nodes[ 0 ] . wallet_source . add_utxo ( bitcoin:: OutPoint { txid : coinbase_tx. txid ( ) , vout : 0 } , coinbase_tx. output [ 0 ] . value ) ;
684+ nodes[ 1 ] . wallet_source . add_utxo ( bitcoin:: OutPoint { txid : coinbase_tx. txid ( ) , vout : 1 } , coinbase_tx. output [ 1 ] . value ) ;
685+ }
686+
663687 // Create a single channel with two pending HTLCs from nodes[0] to nodes[1], one which nodes[1]
664688 // knows the preimage for, one which it does not.
665689 let ( _, _, chan_id, funding_tx) = create_announced_chan_between_nodes_with_value ( & nodes, 0 , 1 , 1_000_000 , 0 ) ;
@@ -697,20 +721,26 @@ fn test_balances_on_local_commitment_htlcs() {
697721 let chan_feerate = get_feerate ! ( nodes[ 0 ] , nodes[ 1 ] , chan_id) as u64 ;
698722 let channel_type_features = get_channel_type_features ! ( nodes[ 0 ] , nodes[ 1 ] , chan_id) ;
699723
700- // Get nodes[0]'s commitment transaction and HTLC-Timeout transactions
701- let as_txn = get_local_commitment_txn ! ( nodes[ 0 ] , chan_id) ;
702- assert_eq ! ( as_txn. len( ) , 3 ) ;
703- check_spends ! ( as_txn[ 1 ] , as_txn[ 0 ] ) ;
704- check_spends ! ( as_txn[ 2 ] , as_txn[ 0 ] ) ;
705- check_spends ! ( as_txn[ 0 ] , funding_tx) ;
706-
707724 // First confirm the commitment transaction on nodes[0], which should leave us with three
708725 // claimable balances.
709726 let node_a_commitment_claimable = nodes[ 0 ] . best_block_info ( ) . 1 + BREAKDOWN_TIMEOUT as u32 ;
710- let commitment_tx_conf_height_a = block_from_scid ( & mine_transaction ( & nodes[ 0 ] , & as_txn [ 0 ] ) ) ;
727+ nodes[ 0 ] . node . force_close_broadcasting_latest_txn ( & chan_id , & nodes [ 1 ] . node . get_our_node_id ( ) ) . unwrap ( ) ;
711728 check_added_monitors ! ( nodes[ 0 ] , 1 ) ;
712729 check_closed_broadcast ! ( nodes[ 0 ] , true ) ;
713- check_closed_event ! ( nodes[ 0 ] , 1 , ClosureReason :: CommitmentTxConfirmed , [ nodes[ 1 ] . node. get_our_node_id( ) ] , 1000000 ) ;
730+ check_closed_event ! ( nodes[ 0 ] , 1 , ClosureReason :: HolderForceClosed , [ nodes[ 1 ] . node. get_our_node_id( ) ] , 1000000 ) ;
731+ let commitment_tx = {
732+ let mut txn = nodes[ 0 ] . tx_broadcaster . unique_txn_broadcast ( ) ;
733+ assert_eq ! ( txn. len( ) , 1 ) ;
734+ let commitment_tx = txn. pop ( ) . unwrap ( ) ;
735+ check_spends ! ( commitment_tx, funding_tx) ;
736+ commitment_tx
737+ } ;
738+ let commitment_tx_conf_height_a = block_from_scid ( & mine_transaction ( & nodes[ 0 ] , & commitment_tx) ) ;
739+ if anchors && nodes[ 0 ] . connect_style . borrow ( ) . updates_best_block_first ( ) {
740+ let mut txn = nodes[ 0 ] . tx_broadcaster . txn_broadcast ( ) ;
741+ assert_eq ! ( txn. len( ) , 1 ) ;
742+ assert_eq ! ( txn[ 0 ] . txid( ) , commitment_tx. txid( ) ) ;
743+ }
714744
715745 let htlc_balance_known_preimage = Balance :: MaybeTimeoutClaimableHTLC {
716746 amount_satoshis : 10_000 ,
@@ -723,43 +753,49 @@ fn test_balances_on_local_commitment_htlcs() {
723753 payment_hash : payment_hash_2,
724754 } ;
725755
756+ let commitment_tx_fee = chan_feerate *
757+ ( channel:: commitment_tx_base_weight ( & channel_type_features) + 2 * channel:: COMMITMENT_TX_WEIGHT_PER_HTLC ) / 1000 ;
758+ let anchor_outputs_value = if anchors { 2 * channel:: ANCHOR_OUTPUT_VALUE_SATOSHI } else { 0 } ;
726759 assert_eq ! ( sorted_vec( vec![ Balance :: ClaimableAwaitingConfirmations {
727- amount_satoshis: 1_000_000 - 10_000 - 20_000 - chan_feerate *
728- ( channel:: commitment_tx_base_weight( & channel_type_features) + 2 * channel:: COMMITMENT_TX_WEIGHT_PER_HTLC ) / 1000 ,
760+ amount_satoshis: 1_000_000 - 10_000 - 20_000 - commitment_tx_fee - anchor_outputs_value,
729761 confirmation_height: node_a_commitment_claimable,
730762 } , htlc_balance_known_preimage. clone( ) , htlc_balance_unknown_preimage. clone( ) ] ) ,
731763 sorted_vec( nodes[ 0 ] . chain_monitor. chain_monitor. get_monitor( funding_outpoint) . unwrap( ) . get_claimable_balances( ) ) ) ;
732764
733765 // Get nodes[1]'s HTLC claim tx for the second HTLC
734- mine_transaction ( & nodes[ 1 ] , & as_txn [ 0 ] ) ;
766+ mine_transaction ( & nodes[ 1 ] , & commitment_tx ) ;
735767 check_added_monitors ! ( nodes[ 1 ] , 1 ) ;
736768 check_closed_broadcast ! ( nodes[ 1 ] , true ) ;
737769 check_closed_event ! ( nodes[ 1 ] , 1 , ClosureReason :: CommitmentTxConfirmed , [ nodes[ 0 ] . node. get_our_node_id( ) ] , 1000000 ) ;
738770 let bs_htlc_claim_txn = nodes[ 1 ] . tx_broadcaster . txn_broadcasted . lock ( ) . unwrap ( ) . split_off ( 0 ) ;
739771 assert_eq ! ( bs_htlc_claim_txn. len( ) , 1 ) ;
740- check_spends ! ( bs_htlc_claim_txn[ 0 ] , as_txn [ 0 ] ) ;
772+ check_spends ! ( bs_htlc_claim_txn[ 0 ] , commitment_tx ) ;
741773
742774 // Connect blocks until the HTLCs expire, allowing us to (validly) broadcast the HTLC-Timeout
743775 // transaction.
744- connect_blocks ( & nodes[ 0 ] , TEST_FINAL_CLTV - 1 ) ;
776+ connect_blocks ( & nodes[ 0 ] , TEST_FINAL_CLTV ) ;
745777 assert_eq ! ( sorted_vec( vec![ Balance :: ClaimableAwaitingConfirmations {
746- amount_satoshis: 1_000_000 - 10_000 - 20_000 - chan_feerate *
747- ( channel:: commitment_tx_base_weight( & channel_type_features) + 2 * channel:: COMMITMENT_TX_WEIGHT_PER_HTLC ) / 1000 ,
778+ amount_satoshis: 1_000_000 - 10_000 - 20_000 - commitment_tx_fee - anchor_outputs_value,
748779 confirmation_height: node_a_commitment_claimable,
749780 } , htlc_balance_known_preimage. clone( ) , htlc_balance_unknown_preimage. clone( ) ] ) ,
750781 sorted_vec( nodes[ 0 ] . chain_monitor. chain_monitor. get_monitor( funding_outpoint) . unwrap( ) . get_claimable_balances( ) ) ) ;
751- assert_eq ! ( as_txn[ 1 ] . lock_time. 0 , nodes[ 0 ] . best_block_info( ) . 1 + 1 ) ; // as_txn[1] can be included in the next block
782+ if anchors {
783+ handle_bump_htlc_event ( & nodes[ 0 ] , 2 ) ;
784+ }
785+ let timeout_htlc_txn = nodes[ 0 ] . tx_broadcaster . unique_txn_broadcast ( ) ;
786+ assert_eq ! ( timeout_htlc_txn. len( ) , 2 ) ;
787+ check_spends ! ( timeout_htlc_txn[ 0 ] , commitment_tx, coinbase_tx) ;
788+ check_spends ! ( timeout_htlc_txn[ 1 ] , commitment_tx, coinbase_tx) ;
752789
753790 // Now confirm nodes[0]'s HTLC-Timeout transaction, which changes the claimable balance to an
754791 // "awaiting confirmations" one.
755792 let node_a_htlc_claimable = nodes[ 0 ] . best_block_info ( ) . 1 + BREAKDOWN_TIMEOUT as u32 ;
756- mine_transaction ( & nodes[ 0 ] , & as_txn [ 1 ] ) ;
793+ mine_transaction ( & nodes[ 0 ] , & timeout_htlc_txn [ 0 ] ) ;
757794 // Note that prior to the fix in the commit which introduced this test, this (and the next
758795 // balance) check failed. With this check removed, the code panicked in the `connect_blocks`
759796 // call, as described, two hunks down.
760797 assert_eq ! ( sorted_vec( vec![ Balance :: ClaimableAwaitingConfirmations {
761- amount_satoshis: 1_000_000 - 10_000 - 20_000 - chan_feerate *
762- ( channel:: commitment_tx_base_weight( & channel_type_features) + 2 * channel:: COMMITMENT_TX_WEIGHT_PER_HTLC ) / 1000 ,
798+ amount_satoshis: 1_000_000 - 10_000 - 20_000 - commitment_tx_fee - anchor_outputs_value,
763799 confirmation_height: node_a_commitment_claimable,
764800 } , Balance :: ClaimableAwaitingConfirmations {
765801 amount_satoshis: 10_000 ,
@@ -772,8 +808,7 @@ fn test_balances_on_local_commitment_htlcs() {
772808 mine_transaction ( & nodes[ 0 ] , & bs_htlc_claim_txn[ 0 ] ) ;
773809 expect_payment_sent ( & nodes[ 0 ] , payment_preimage_2, None , true , false ) ;
774810 assert_eq ! ( sorted_vec( vec![ Balance :: ClaimableAwaitingConfirmations {
775- amount_satoshis: 1_000_000 - 10_000 - 20_000 - chan_feerate *
776- ( channel:: commitment_tx_base_weight( & channel_type_features) + 2 * channel:: COMMITMENT_TX_WEIGHT_PER_HTLC ) / 1000 ,
811+ amount_satoshis: 1_000_000 - 10_000 - 20_000 - commitment_tx_fee - anchor_outputs_value,
777812 confirmation_height: node_a_commitment_claimable,
778813 } , Balance :: ClaimableAwaitingConfirmations {
779814 amount_satoshis: 10_000 ,
@@ -788,8 +823,7 @@ fn test_balances_on_local_commitment_htlcs() {
788823 expect_payment_failed ! ( nodes[ 0 ] , payment_hash, false ) ;
789824
790825 assert_eq ! ( sorted_vec( vec![ Balance :: ClaimableAwaitingConfirmations {
791- amount_satoshis: 1_000_000 - 10_000 - 20_000 - chan_feerate *
792- ( channel:: commitment_tx_base_weight( & channel_type_features) + 2 * channel:: COMMITMENT_TX_WEIGHT_PER_HTLC ) / 1000 ,
826+ amount_satoshis: 1_000_000 - 10_000 - 20_000 - commitment_tx_fee - anchor_outputs_value,
793827 confirmation_height: node_a_commitment_claimable,
794828 } , Balance :: ClaimableAwaitingConfirmations {
795829 amount_satoshis: 10_000 ,
@@ -801,16 +835,16 @@ fn test_balances_on_local_commitment_htlcs() {
801835 // `SpendableOutputs` event and removing the claimable balance entry.
802836 connect_blocks ( & nodes[ 0 ] , node_a_commitment_claimable - nodes[ 0 ] . best_block_info ( ) . 1 - 1 ) ;
803837 assert ! ( get_monitor!( nodes[ 0 ] , chan_id)
804- . get_spendable_outputs( & as_txn [ 0 ] , commitment_tx_conf_height_a) . is_empty( ) ) ;
838+ . get_spendable_outputs( & commitment_tx , commitment_tx_conf_height_a) . is_empty( ) ) ;
805839 connect_blocks ( & nodes[ 0 ] , 1 ) ;
806840 assert_eq ! ( vec![ Balance :: ClaimableAwaitingConfirmations {
807841 amount_satoshis: 10_000 ,
808842 confirmation_height: node_a_htlc_claimable,
809843 } ] ,
810844 nodes[ 0 ] . chain_monitor. chain_monitor. get_monitor( funding_outpoint) . unwrap( ) . get_claimable_balances( ) ) ;
811- let to_self_spendable_output = test_spendable_output ( & nodes[ 0 ] , & as_txn [ 0 ] , false ) ;
845+ let to_self_spendable_output = test_spendable_output ( & nodes[ 0 ] , & commitment_tx , false ) ;
812846 assert_eq ! (
813- get_monitor!( nodes[ 0 ] , chan_id) . get_spendable_outputs( & as_txn [ 0 ] , commitment_tx_conf_height_a) ,
847+ get_monitor!( nodes[ 0 ] , chan_id) . get_spendable_outputs( & commitment_tx , commitment_tx_conf_height_a) ,
814848 to_self_spendable_output
815849 ) ;
816850
@@ -829,6 +863,12 @@ fn test_balances_on_local_commitment_htlcs() {
829863 assert ! ( nodes[ 0 ] . chain_monitor. chain_monitor. get_monitor( funding_outpoint) . unwrap( ) . get_claimable_balances( ) . is_empty( ) ) ;
830864}
831865
866+ #[ test]
867+ fn test_balances_on_local_commitment_htlcs ( ) {
868+ do_test_balances_on_local_commitment_htlcs ( false ) ;
869+ do_test_balances_on_local_commitment_htlcs ( true ) ;
870+ }
871+
832872#[ test]
833873fn test_no_preimage_inbound_htlc_balances ( ) {
834874 // Tests that MaybePreimageClaimableHTLC are generated for inbound HTLCs for which we do not
0 commit comments