@@ -2145,6 +2145,100 @@ fn test_revoked_counterparty_aggregated_claims() {
21452145 do_test_revoked_counterparty_aggregated_claims ( true ) ;
21462146}
21472147
2148+ fn do_test_claimable_balance_correct_while_payment_pending ( outbound_payment : bool , anchors : bool ) {
2149+ // Previously when a user fetched their balances via `get_claimable_balances` after forwarding a
2150+ // payment, but before it cleared, and summed up their balance using `Balance::claimable_amount_satoshis`
2151+ // neither the value of preimage claimable HTLC nor the timeout claimable HTLC would be included.
2152+ // This was incorrect as exactly one of these outcomes is true. This has been fixed by including the
2153+ // timeout claimable HTLC value in the balance as this excludes the routing fees and is the more
2154+ // prudent approach.
2155+ //
2156+ // In the case of the holder sending a payment, the above value will not be included while the payment
2157+ // is pending.
2158+ //
2159+ // This tests that we get the correct balance in either of the cases above.
2160+ let mut chanmon_cfgs = create_chanmon_cfgs ( 3 ) ;
2161+ let node_cfgs = create_node_cfgs ( 3 , & chanmon_cfgs) ;
2162+ let mut user_config = test_default_channel_config ( ) ;
2163+ if anchors {
2164+ user_config. channel_handshake_config . negotiate_anchors_zero_fee_htlc_tx = true ;
2165+ user_config. manually_accept_inbound_channels = true ;
2166+ }
2167+ let node_chanmgrs = create_node_chanmgrs ( 3 , & node_cfgs, & [ Some ( user_config) , Some ( user_config) , Some ( user_config) ] ) ;
2168+ let nodes = create_network ( 3 , & node_cfgs, & node_chanmgrs) ;
2169+
2170+ let coinbase_tx = Transaction {
2171+ version : Version :: TWO ,
2172+ lock_time : LockTime :: ZERO ,
2173+ input : vec ! [ TxIn { ..Default :: default ( ) } ] ,
2174+ output : vec ! [
2175+ TxOut {
2176+ value: Amount :: ONE_BTC ,
2177+ script_pubkey: nodes[ 0 ] . wallet_source. get_change_script( ) . unwrap( ) ,
2178+ } ,
2179+ TxOut {
2180+ value: Amount :: ONE_BTC ,
2181+ script_pubkey: nodes[ 1 ] . wallet_source. get_change_script( ) . unwrap( ) ,
2182+ } ,
2183+ ] ,
2184+ } ;
2185+ if anchors {
2186+ nodes[ 0 ] . wallet_source . add_utxo ( bitcoin:: OutPoint { txid : coinbase_tx. txid ( ) , vout : 0 } , coinbase_tx. output [ 0 ] . value ) ;
2187+ nodes[ 1 ] . wallet_source . add_utxo ( bitcoin:: OutPoint { txid : coinbase_tx. txid ( ) , vout : 1 } , coinbase_tx. output [ 1 ] . value ) ;
2188+ }
2189+
2190+ // Create a channel from A -> B
2191+ let ( _, _, chan_ab_id, funding_tx_ab) =
2192+ create_announced_chan_between_nodes_with_value ( & nodes, 0 , 1 , 1_000_000 /* channel_value (sat) */ , 0 /* push_msat */ ) ;
2193+ let funding_outpoint_ab = OutPoint { txid : funding_tx_ab. txid ( ) , index : 0 } ;
2194+ assert_eq ! ( ChannelId :: v1_from_funding_outpoint( funding_outpoint_ab) , chan_ab_id) ;
2195+ // Create a channel from B -> C
2196+ let ( _, _, chan_bc_id, funding_tx_bc) =
2197+ create_announced_chan_between_nodes_with_value ( & nodes, 1 , 2 , 1_000_000 /* channel_value (sat) */ , 0 /* push_msat */ ) ;
2198+ let funding_outpoint_bc = OutPoint { txid : funding_tx_bc. txid ( ) , index : 0 } ;
2199+ assert_eq ! ( ChannelId :: v1_from_funding_outpoint( funding_outpoint_bc) , chan_bc_id) ;
2200+
2201+ let ( chan_feerate, channel_type_features) = if outbound_payment {
2202+ let chan_ab_feerate = get_feerate ! ( nodes[ 0 ] , nodes[ 1 ] , chan_ab_id) ;
2203+ let channel_type_features_ab = get_channel_type_features ! ( nodes[ 0 ] , nodes[ 1 ] , chan_ab_id) ;
2204+ ( chan_ab_feerate, channel_type_features_ab)
2205+ } else {
2206+ let chan_bc_feerate = get_feerate ! ( nodes[ 1 ] , nodes[ 2 ] , chan_bc_id) ;
2207+ let channel_type_features_bc = get_channel_type_features ! ( nodes[ 1 ] , nodes[ 2 ] , chan_bc_id) ;
2208+ ( chan_bc_feerate, channel_type_features_bc)
2209+ } ;
2210+ let commitment_tx_fee = chan_feerate as u64 *
2211+ ( chan_utils:: commitment_tx_base_weight ( & channel_type_features) + chan_utils:: COMMITMENT_TX_WEIGHT_PER_HTLC ) / 1000 ;
2212+
2213+ // This HTLC will be forwarded by B from A -> C
2214+ let _ = route_payment ( & nodes[ 0 ] , & [ & nodes[ 1 ] , & nodes[ 2 ] ] , 4_000_000 ) ;
2215+ let anchor_outputs_value = if anchors { 2 * channel:: ANCHOR_OUTPUT_VALUE_SATOSHI } else { 0 } ;
2216+
2217+ if outbound_payment {
2218+ assert_eq ! (
2219+ 1_000_000 - commitment_tx_fee - anchor_outputs_value - 4_001 /* Note HTLC timeout amount of 4001 sats is excluded for outbound payment */ ,
2220+ nodes[ 0 ] . chain_monitor. chain_monitor. get_monitor( funding_outpoint_ab) . unwrap( ) . get_claimable_balances( ) . iter( ) . map(
2221+ |x| x. claimable_amount_satoshis( ) ) . sum( ) ) ;
2222+ } else {
2223+ assert_eq ! (
2224+ 0u64 ,
2225+ nodes[ 1 ] . chain_monitor. chain_monitor. get_monitor( funding_outpoint_ab) . unwrap( ) . get_claimable_balances( ) . iter( ) . map(
2226+ |x| x. claimable_amount_satoshis( ) ) . sum( ) ) ;
2227+ assert_eq ! (
2228+ 1_000_000 - commitment_tx_fee - anchor_outputs_value /* Note HTLC timeout amount of 4000 sats is included */ ,
2229+ nodes[ 1 ] . chain_monitor. chain_monitor. get_monitor( funding_outpoint_bc) . unwrap( ) . get_claimable_balances( ) . iter( ) . map(
2230+ |x| x. claimable_amount_satoshis( ) ) . sum( ) ) ;
2231+ }
2232+ }
2233+
2234+ #[ test]
2235+ fn test_claimable_balance_correct_while_payment_pending ( ) {
2236+ do_test_claimable_balance_correct_while_payment_pending ( false , false ) ;
2237+ do_test_claimable_balance_correct_while_payment_pending ( false , true ) ;
2238+ do_test_claimable_balance_correct_while_payment_pending ( true , false ) ;
2239+ do_test_claimable_balance_correct_while_payment_pending ( true , true ) ;
2240+ }
2241+
21482242fn do_test_restored_packages_retry ( check_old_monitor_retries_after_upgrade : bool ) {
21492243 // Tests that we'll retry packages that were previously timelocked after we've restored them.
21502244 let chanmon_cfgs = create_chanmon_cfgs ( 2 ) ;
0 commit comments