@@ -288,10 +288,16 @@ fn do_test_claim_value_force_close(prev_commitment_tx: bool) {
288288 claimable_height: htlc_cltv_timeout,
289289 } ] ) ,
290290 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 {
292292 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( ) ) ) ;
295301
296302 nodes[ 1 ] . node . claim_funds ( payment_preimage) ;
297303 check_added_monitors ! ( nodes[ 1 ] , 1 ) ;
@@ -747,6 +753,239 @@ fn test_balances_on_local_commitment_htlcs() {
747753 test_spendable_output ( & nodes[ 0 ] , & as_txn[ 1 ] ) ;
748754}
749755
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+
750989fn sorted_vec_with_additions < T : Ord + Clone > ( v_orig : & Vec < T > , extra_ts : & [ & T ] ) -> Vec < T > {
751990 let mut v = v_orig. clone ( ) ;
752991 for t in extra_ts {
0 commit comments