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