@@ -747,6 +747,239 @@ fn test_balances_on_local_commitment_htlcs() {
747
747
test_spendable_output ( & nodes[ 0 ] , & as_txn[ 1 ] ) ;
748
748
}
749
749
750
+ #[ test]
751
+ fn test_no_preimage_inbound_htlc_balances ( ) {
752
+ // Tests that MaybePreimageCLaimableHTLCAwaitingTImeouts are generated for inbound HTLCs for
753
+ // which we do not have a preimage.
754
+ let chanmon_cfgs = create_chanmon_cfgs ( 2 ) ;
755
+ let node_cfgs = create_node_cfgs ( 2 , & chanmon_cfgs) ;
756
+ let node_chanmgrs = create_node_chanmgrs ( 2 , & node_cfgs, & [ None , None ] ) ;
757
+ let mut nodes = create_network ( 2 , & node_cfgs, & node_chanmgrs) ;
758
+
759
+ let ( _, _, chan_id, funding_tx) = create_announced_chan_between_nodes_with_value ( & nodes, 0 , 1 , 1_000_000 , 500_000_000 , InitFeatures :: known ( ) , InitFeatures :: known ( ) ) ;
760
+ let funding_outpoint = OutPoint { txid : funding_tx. txid ( ) , index : 0 } ;
761
+
762
+ // Send two HTLCs, one from A to B, and one from B to C.
763
+ let to_b_failed_payment_hash = route_payment ( & nodes[ 0 ] , & [ & nodes[ 1 ] ] , 10_000_000 ) . 1 ;
764
+ let to_a_failed_payment_hash = route_payment ( & nodes[ 1 ] , & [ & nodes[ 0 ] ] , 20_000_000 ) . 1 ;
765
+ let htlc_cltv_timeout = nodes[ 0 ] . best_block_info ( ) . 1 + TEST_FINAL_CLTV + 1 ; // Note ChannelManager adds one to CLTV timeouts for safety
766
+
767
+ let chan_feerate = get_feerate ! ( nodes[ 0 ] , chan_id) as u64 ;
768
+ let opt_anchors = get_opt_anchors ! ( nodes[ 0 ] , chan_id) ;
769
+
770
+ // Both A and B will have an HTLC that's claimable on timeout and one that's claimable if they
771
+ // receive the preimage. These will remain the same through the channel closure and until the
772
+ // HTLC output is spent.
773
+
774
+ assert_eq ! ( sorted_vec( vec![ Balance :: ClaimableOnChannelClose {
775
+ claimable_amount_satoshis: 1_000_000 - 500_000 - 10_000 - chan_feerate *
776
+ ( channel:: commitment_tx_base_weight( opt_anchors) + 2 * channel:: COMMITMENT_TX_WEIGHT_PER_HTLC ) / 1000 ,
777
+ } , Balance :: MaybePreimageClaimableHTLCAwaitingTimeout {
778
+ claimable_amount_satoshis: 20_000 ,
779
+ expiry_height: htlc_cltv_timeout,
780
+ } , Balance :: MaybeClaimableHTLCAwaitingTimeout {
781
+ claimable_amount_satoshis: 10_000 ,
782
+ claimable_height: htlc_cltv_timeout,
783
+ } ] ) ,
784
+ sorted_vec( nodes[ 0 ] . chain_monitor. chain_monitor. get_monitor( funding_outpoint) . unwrap( ) . get_claimable_balances( ) ) ) ;
785
+
786
+ assert_eq ! ( sorted_vec( vec![ Balance :: ClaimableOnChannelClose {
787
+ claimable_amount_satoshis: 500_000 - 20_000 ,
788
+ } , Balance :: MaybePreimageClaimableHTLCAwaitingTimeout {
789
+ claimable_amount_satoshis: 10_000 ,
790
+ expiry_height: htlc_cltv_timeout,
791
+ } , Balance :: MaybeClaimableHTLCAwaitingTimeout {
792
+ claimable_amount_satoshis: 20_000 ,
793
+ claimable_height: htlc_cltv_timeout,
794
+ } ] ) ,
795
+ sorted_vec( nodes[ 1 ] . chain_monitor. chain_monitor. get_monitor( funding_outpoint) . unwrap( ) . get_claimable_balances( ) ) ) ;
796
+
797
+ // Get nodes[0]'s commitment transaction and HTLC-Timeout transaction
798
+ let as_txn = get_local_commitment_txn ! ( nodes[ 0 ] , chan_id) ;
799
+ assert_eq ! ( as_txn. len( ) , 2 ) ;
800
+ check_spends ! ( as_txn[ 1 ] , as_txn[ 0 ] ) ;
801
+ check_spends ! ( as_txn[ 0 ] , funding_tx) ;
802
+
803
+ // Now close the channel by confirming A's commitment transaction on both nodes, checking the
804
+ // claimable balances remain the same except for the non-HTLC balance changing variant.
805
+ let node_a_commitment_claimable = nodes[ 0 ] . best_block_info ( ) . 1 + BREAKDOWN_TIMEOUT as u32 ;
806
+ let as_pre_spend_claims = sorted_vec ( vec ! [ Balance :: ClaimableAwaitingConfirmations {
807
+ claimable_amount_satoshis: 1_000_000 - 500_000 - 10_000 - chan_feerate *
808
+ ( channel:: commitment_tx_base_weight( opt_anchors) + 2 * channel:: COMMITMENT_TX_WEIGHT_PER_HTLC ) / 1000 ,
809
+ confirmation_height: node_a_commitment_claimable,
810
+ } , Balance :: MaybePreimageClaimableHTLCAwaitingTimeout {
811
+ claimable_amount_satoshis: 20_000 ,
812
+ expiry_height: htlc_cltv_timeout,
813
+ } , Balance :: MaybeClaimableHTLCAwaitingTimeout {
814
+ claimable_amount_satoshis: 10_000 ,
815
+ claimable_height: htlc_cltv_timeout,
816
+ } ] ) ;
817
+
818
+ mine_transaction ( & nodes[ 0 ] , & as_txn[ 0 ] ) ;
819
+ nodes[ 0 ] . tx_broadcaster . txn_broadcasted . lock ( ) . unwrap ( ) . clear ( ) ;
820
+ check_added_monitors ! ( nodes[ 0 ] , 1 ) ;
821
+ check_closed_broadcast ! ( nodes[ 0 ] , true ) ;
822
+ check_closed_event ! ( nodes[ 0 ] , 1 , ClosureReason :: CommitmentTxConfirmed ) ;
823
+
824
+ assert_eq ! ( as_pre_spend_claims,
825
+ sorted_vec( nodes[ 0 ] . chain_monitor. chain_monitor. get_monitor( funding_outpoint) . unwrap( ) . get_claimable_balances( ) ) ) ;
826
+
827
+ mine_transaction ( & nodes[ 1 ] , & as_txn[ 0 ] ) ;
828
+ check_added_monitors ! ( nodes[ 1 ] , 1 ) ;
829
+ check_closed_broadcast ! ( nodes[ 1 ] , true ) ;
830
+ check_closed_event ! ( nodes[ 1 ] , 1 , ClosureReason :: CommitmentTxConfirmed ) ;
831
+
832
+ let node_b_commitment_claimable = nodes[ 1 ] . best_block_info ( ) . 1 + ANTI_REORG_DELAY - 1 ;
833
+ let mut bs_pre_spend_claims = sorted_vec ( vec ! [ Balance :: ClaimableAwaitingConfirmations {
834
+ claimable_amount_satoshis: 500_000 - 20_000 ,
835
+ confirmation_height: node_b_commitment_claimable,
836
+ } , Balance :: MaybePreimageClaimableHTLCAwaitingTimeout {
837
+ claimable_amount_satoshis: 10_000 ,
838
+ expiry_height: htlc_cltv_timeout,
839
+ } , Balance :: MaybeClaimableHTLCAwaitingTimeout {
840
+ claimable_amount_satoshis: 20_000 ,
841
+ claimable_height: htlc_cltv_timeout,
842
+ } ] ) ;
843
+ assert_eq ! ( bs_pre_spend_claims,
844
+ sorted_vec( nodes[ 1 ] . chain_monitor. chain_monitor. get_monitor( funding_outpoint) . unwrap( ) . get_claimable_balances( ) ) ) ;
845
+
846
+ // If we get one block prior to the HTLC expiring, we'll broadcast the HTLC-timeout transaction
847
+ // (as it is confirmable in the next block), but will still include the same claimable
848
+ // balances as no HTLC has been spent, even after the HTLC expires. We'll also fail the inbound
849
+ // HTLC, but it won't do anything as the channel is already closed.
850
+
851
+ connect_blocks ( & nodes[ 0 ] , TEST_FINAL_CLTV - 1 ) ;
852
+ let as_htlc_timeout_claim = nodes[ 0 ] . tx_broadcaster . txn_broadcasted . lock ( ) . unwrap ( ) . split_off ( 0 ) ;
853
+ assert_eq ! ( as_htlc_timeout_claim. len( ) , 1 ) ;
854
+ check_spends ! ( as_htlc_timeout_claim[ 0 ] , as_txn[ 0 ] ) ;
855
+ expect_pending_htlcs_forwardable_conditions ! ( nodes[ 0 ] ,
856
+ [ HTLCDestination :: FailedPayment { payment_hash: to_a_failed_payment_hash } ] ) ;
857
+
858
+ assert_eq ! ( as_pre_spend_claims,
859
+ sorted_vec( nodes[ 0 ] . chain_monitor. chain_monitor. get_monitor( funding_outpoint) . unwrap( ) . get_claimable_balances( ) ) ) ;
860
+
861
+ connect_blocks ( & nodes[ 0 ] , 1 ) ;
862
+ assert_eq ! ( as_pre_spend_claims,
863
+ sorted_vec( nodes[ 0 ] . chain_monitor. chain_monitor. get_monitor( funding_outpoint) . unwrap( ) . get_claimable_balances( ) ) ) ;
864
+
865
+ // For node B, we'll get the non-HTLC funds claimable after ANTI_REORG_DELAY confirmations
866
+ connect_blocks ( & nodes[ 1 ] , ANTI_REORG_DELAY - 1 ) ;
867
+ test_spendable_output ( & nodes[ 1 ] , & as_txn[ 0 ] ) ;
868
+ bs_pre_spend_claims. retain ( |e| if let Balance :: ClaimableAwaitingConfirmations { .. } = e { false } else { true } ) ;
869
+
870
+ // The next few blocks for B look the same as for A, though for the opposite HTLC
871
+ nodes[ 1 ] . tx_broadcaster . txn_broadcasted . lock ( ) . unwrap ( ) . clear ( ) ;
872
+ connect_blocks ( & nodes[ 1 ] , TEST_FINAL_CLTV - ( ANTI_REORG_DELAY - 1 ) - 1 ) ;
873
+ expect_pending_htlcs_forwardable_conditions ! ( nodes[ 1 ] ,
874
+ [ HTLCDestination :: FailedPayment { payment_hash: to_b_failed_payment_hash } ] ) ;
875
+ let bs_htlc_timeout_claim = nodes[ 1 ] . tx_broadcaster . txn_broadcasted . lock ( ) . unwrap ( ) . split_off ( 0 ) ;
876
+ assert_eq ! ( bs_htlc_timeout_claim. len( ) , 1 ) ;
877
+ check_spends ! ( bs_htlc_timeout_claim[ 0 ] , as_txn[ 0 ] ) ;
878
+
879
+ assert_eq ! ( bs_pre_spend_claims,
880
+ sorted_vec( nodes[ 1 ] . chain_monitor. chain_monitor. get_monitor( funding_outpoint) . unwrap( ) . get_claimable_balances( ) ) ) ;
881
+
882
+ connect_blocks ( & nodes[ 1 ] , 1 ) ;
883
+ assert_eq ! ( bs_pre_spend_claims,
884
+ sorted_vec( nodes[ 1 ] . chain_monitor. chain_monitor. get_monitor( funding_outpoint) . unwrap( ) . get_claimable_balances( ) ) ) ;
885
+
886
+ // Now confirm the two HTLC timeout transactions for A, checking that the inbound HTLC resolves
887
+ // after ANTI_REORG_DELAY confirmations and the other takes BREAKDOWN_TIMEOUT confirmations.
888
+ mine_transaction ( & nodes[ 0 ] , & as_htlc_timeout_claim[ 0 ] ) ;
889
+ let as_timeout_claimable_height = nodes[ 0 ] . best_block_info ( ) . 1 + ( BREAKDOWN_TIMEOUT as u32 ) - 1 ;
890
+ assert_eq ! ( sorted_vec( vec![ Balance :: ClaimableAwaitingConfirmations {
891
+ claimable_amount_satoshis: 1_000_000 - 500_000 - 10_000 - chan_feerate *
892
+ ( channel:: commitment_tx_base_weight( opt_anchors) + 2 * channel:: COMMITMENT_TX_WEIGHT_PER_HTLC ) / 1000 ,
893
+ confirmation_height: node_a_commitment_claimable,
894
+ } , Balance :: MaybePreimageClaimableHTLCAwaitingTimeout {
895
+ claimable_amount_satoshis: 20_000 ,
896
+ expiry_height: htlc_cltv_timeout,
897
+ } , Balance :: ClaimableAwaitingConfirmations {
898
+ claimable_amount_satoshis: 10_000 ,
899
+ confirmation_height: as_timeout_claimable_height,
900
+ } ] ) ,
901
+ sorted_vec( nodes[ 0 ] . chain_monitor. chain_monitor. get_monitor( funding_outpoint) . unwrap( ) . get_claimable_balances( ) ) ) ;
902
+ assert ! ( nodes[ 0 ] . node. get_and_clear_pending_events( ) . is_empty( ) ) ;
903
+
904
+ mine_transaction ( & nodes[ 0 ] , & bs_htlc_timeout_claim[ 0 ] ) ;
905
+ assert_eq ! ( sorted_vec( vec![ Balance :: ClaimableAwaitingConfirmations {
906
+ claimable_amount_satoshis: 1_000_000 - 500_000 - 10_000 - chan_feerate *
907
+ ( channel:: commitment_tx_base_weight( opt_anchors) + 2 * channel:: COMMITMENT_TX_WEIGHT_PER_HTLC ) / 1000 ,
908
+ confirmation_height: node_a_commitment_claimable,
909
+ } , Balance :: MaybePreimageClaimableHTLCAwaitingTimeout {
910
+ claimable_amount_satoshis: 20_000 ,
911
+ expiry_height: htlc_cltv_timeout,
912
+ } , Balance :: ClaimableAwaitingConfirmations {
913
+ claimable_amount_satoshis: 10_000 ,
914
+ confirmation_height: as_timeout_claimable_height,
915
+ } ] ) ,
916
+ sorted_vec( nodes[ 0 ] . chain_monitor. chain_monitor. get_monitor( funding_outpoint) . unwrap( ) . get_claimable_balances( ) ) ) ;
917
+
918
+ // Once as_htlc_timeout_claim[0] reaches ANTI_REORG_DELAY confirmations, we should get a
919
+ // payment failure event.
920
+ connect_blocks ( & nodes[ 0 ] , ANTI_REORG_DELAY - 2 ) ;
921
+ expect_payment_failed ! ( nodes[ 0 ] , to_b_failed_payment_hash, true ) ;
922
+
923
+ connect_blocks ( & nodes[ 0 ] , 1 ) ;
924
+ assert_eq ! ( sorted_vec( vec![ Balance :: ClaimableAwaitingConfirmations {
925
+ claimable_amount_satoshis: 1_000_000 - 500_000 - 10_000 - chan_feerate *
926
+ ( channel:: commitment_tx_base_weight( opt_anchors) + 2 * channel:: COMMITMENT_TX_WEIGHT_PER_HTLC ) / 1000 ,
927
+ confirmation_height: node_a_commitment_claimable,
928
+ } , Balance :: ClaimableAwaitingConfirmations {
929
+ claimable_amount_satoshis: 10_000 ,
930
+ confirmation_height: core:: cmp:: max( as_timeout_claimable_height, htlc_cltv_timeout) ,
931
+ } ] ) ,
932
+ sorted_vec( nodes[ 0 ] . chain_monitor. chain_monitor. get_monitor( funding_outpoint) . unwrap( ) . get_claimable_balances( ) ) ) ;
933
+
934
+ connect_blocks ( & nodes[ 0 ] , node_a_commitment_claimable - nodes[ 0 ] . best_block_info ( ) . 1 ) ;
935
+ assert_eq ! ( vec![ Balance :: ClaimableAwaitingConfirmations {
936
+ claimable_amount_satoshis: 10_000 ,
937
+ confirmation_height: core:: cmp:: max( as_timeout_claimable_height, htlc_cltv_timeout) ,
938
+ } ] ,
939
+ nodes[ 0 ] . chain_monitor. chain_monitor. get_monitor( funding_outpoint) . unwrap( ) . get_claimable_balances( ) ) ;
940
+ test_spendable_output ( & nodes[ 0 ] , & as_txn[ 0 ] ) ;
941
+
942
+ connect_blocks ( & nodes[ 0 ] , as_timeout_claimable_height - nodes[ 0 ] . best_block_info ( ) . 1 ) ;
943
+ assert ! ( nodes[ 0 ] . chain_monitor. chain_monitor. get_monitor( funding_outpoint) . unwrap( ) . get_claimable_balances( ) . is_empty( ) ) ;
944
+ test_spendable_output ( & nodes[ 0 ] , & as_htlc_timeout_claim[ 0 ] ) ;
945
+
946
+ // The process for B should be completely identical as well, noting that the non-HTLC-balance
947
+ // was already claimed.
948
+ mine_transaction ( & nodes[ 1 ] , & bs_htlc_timeout_claim[ 0 ] ) ;
949
+ let bs_timeout_claimable_height = nodes[ 1 ] . best_block_info ( ) . 1 + ANTI_REORG_DELAY - 1 ;
950
+ assert_eq ! ( sorted_vec( vec![ Balance :: MaybePreimageClaimableHTLCAwaitingTimeout {
951
+ claimable_amount_satoshis: 10_000 ,
952
+ expiry_height: htlc_cltv_timeout,
953
+ } , Balance :: ClaimableAwaitingConfirmations {
954
+ claimable_amount_satoshis: 20_000 ,
955
+ confirmation_height: bs_timeout_claimable_height,
956
+ } ] ) ,
957
+ sorted_vec( nodes[ 1 ] . chain_monitor. chain_monitor. get_monitor( funding_outpoint) . unwrap( ) . get_claimable_balances( ) ) ) ;
958
+
959
+ mine_transaction ( & nodes[ 1 ] , & as_htlc_timeout_claim[ 0 ] ) ;
960
+ assert_eq ! ( sorted_vec( vec![ Balance :: MaybePreimageClaimableHTLCAwaitingTimeout {
961
+ claimable_amount_satoshis: 10_000 ,
962
+ expiry_height: htlc_cltv_timeout,
963
+ } , Balance :: ClaimableAwaitingConfirmations {
964
+ claimable_amount_satoshis: 20_000 ,
965
+ confirmation_height: bs_timeout_claimable_height,
966
+ } ] ) ,
967
+ sorted_vec( nodes[ 1 ] . chain_monitor. chain_monitor. get_monitor( funding_outpoint) . unwrap( ) . get_claimable_balances( ) ) ) ;
968
+
969
+ connect_blocks ( & nodes[ 1 ] , ANTI_REORG_DELAY - 2 ) ;
970
+ expect_payment_failed ! ( nodes[ 1 ] , to_a_failed_payment_hash, true ) ;
971
+
972
+ assert_eq ! ( vec![ Balance :: MaybePreimageClaimableHTLCAwaitingTimeout {
973
+ claimable_amount_satoshis: 10_000 ,
974
+ expiry_height: htlc_cltv_timeout,
975
+ } ] ,
976
+ nodes[ 1 ] . chain_monitor. chain_monitor. get_monitor( funding_outpoint) . unwrap( ) . get_claimable_balances( ) ) ;
977
+ test_spendable_output ( & nodes[ 1 ] , & bs_htlc_timeout_claim[ 0 ] ) ;
978
+
979
+ connect_blocks ( & nodes[ 1 ] , 1 ) ;
980
+ assert ! ( nodes[ 1 ] . chain_monitor. chain_monitor. get_monitor( funding_outpoint) . unwrap( ) . get_claimable_balances( ) . is_empty( ) ) ;
981
+ }
982
+
750
983
fn sorted_vec_with_additions < T : Ord + Clone > ( v_orig : & Vec < T > , extra_ts : & [ & T ] ) -> Vec < T > {
751
984
let mut v = v_orig. clone ( ) ;
752
985
for t in extra_ts {
0 commit comments