@@ -2078,3 +2078,302 @@ pub fn test_update_fulfill_htlc_bolt2_missing_badonion_bit_for_malformed_htlc_me
2078
2078
let reason = ClosureReason :: ProcessingError { err : err_msg. data } ;
2079
2079
check_closed_event ! ( nodes[ 0 ] , 1 , reason, [ node_b_id] , 1000000 ) ;
2080
2080
}
2081
+
2082
+ #[ xtest( feature = "_externalize_tests" ) ]
2083
+ pub fn test_dust_limit_fee_accounting ( ) {
2084
+ do_test_dust_limit_fee_accounting ( false ) ;
2085
+ do_test_dust_limit_fee_accounting ( true ) ;
2086
+ }
2087
+
2088
+ pub fn do_test_dust_limit_fee_accounting ( can_afford : bool ) {
2089
+ // Test that when a channel funder sends HTLCs exactly on the dust limit
2090
+ // of the funder, the fundee correctly accounts for the additional fee on the
2091
+ // funder's commitment transaction due to those additional non-dust HTLCs when
2092
+ // checking for any infrigements on the funder's reserve.
2093
+
2094
+ let channel_type = ChannelTypeFeatures :: anchors_zero_htlc_fee_and_dependencies ( ) ;
2095
+
2096
+ let chanmon_cfgs = create_chanmon_cfgs ( 2 ) ;
2097
+
2098
+ let mut default_config = test_default_channel_config ( ) ;
2099
+ default_config. channel_handshake_config . negotiate_anchors_zero_fee_htlc_tx = true ;
2100
+ default_config. manually_accept_inbound_channels = true ;
2101
+
2102
+ let node_cfgs = create_node_cfgs ( 2 , & chanmon_cfgs) ;
2103
+ let node_chanmgrs =
2104
+ create_node_chanmgrs ( 2 , & node_cfgs, & [ Some ( default_config. clone ( ) ) , Some ( default_config) ] ) ;
2105
+
2106
+ let mut nodes = create_network ( 2 , & node_cfgs, & node_chanmgrs) ;
2107
+
2108
+ let node_a_id = nodes[ 0 ] . node . get_our_node_id ( ) ;
2109
+ let node_b_id = nodes[ 1 ] . node . get_our_node_id ( ) ;
2110
+
2111
+ // Set a HTLC amount that is equal to the dust limit of the funder
2112
+ const HTLC_AMT_SAT : u64 = 354 ;
2113
+
2114
+ const CHANNEL_VALUE_SAT : u64 = 100_000 ;
2115
+
2116
+ const FEERATE_PER_KW : u32 = 253 ;
2117
+
2118
+ let commit_tx_fee_sat =
2119
+ chan_utils:: commit_tx_fee_sat ( FEERATE_PER_KW , MIN_AFFORDABLE_HTLC_COUNT , & channel_type) ;
2120
+
2121
+ // By default the reserve is set to 1% or 1000sat, whichever is higher
2122
+ let channel_reserve_satoshis = 1_000 ;
2123
+
2124
+ // Set node 0's balance to pay for exactly MIN_AFFORDABLE_HTLC_COUNT non-dust HTLCs on the channel, minus some offset
2125
+ let node_0_balance_sat = commit_tx_fee_sat
2126
+ + channel_reserve_satoshis
2127
+ + 2 * crate :: ln:: channel:: ANCHOR_OUTPUT_VALUE_SATOSHI
2128
+ + MIN_AFFORDABLE_HTLC_COUNT as u64 * HTLC_AMT_SAT
2129
+ - if can_afford { 0 } else { 1 } ;
2130
+ let mut node_1_balance_sat = CHANNEL_VALUE_SAT - node_0_balance_sat;
2131
+
2132
+ let chan_id = create_chan_between_nodes_with_value (
2133
+ & nodes[ 0 ] ,
2134
+ & nodes[ 1 ] ,
2135
+ CHANNEL_VALUE_SAT ,
2136
+ node_1_balance_sat * 1000 ,
2137
+ )
2138
+ . 3 ;
2139
+
2140
+ {
2141
+ // Double check the reserve that node 0 has to maintain here
2142
+ let per_peer_state_lock;
2143
+ let mut peer_state_lock;
2144
+ let chan =
2145
+ get_channel_ref ! ( nodes[ 1 ] , nodes[ 0 ] , per_peer_state_lock, peer_state_lock, chan_id) ;
2146
+ assert_eq ! (
2147
+ chan. funding( ) . holder_selected_channel_reserve_satoshis,
2148
+ channel_reserve_satoshis
2149
+ ) ;
2150
+ }
2151
+ {
2152
+ // Double check the dust limit on node 0's commitment transactions; when node 0
2153
+ // adds a HTLC, node 1 will check that the fee on node 0's commitment transaction
2154
+ // does not dip under the node 1 selected reserve.
2155
+ let per_peer_state_lock;
2156
+ let mut peer_state_lock;
2157
+ let chan =
2158
+ get_channel_ref ! ( nodes[ 0 ] , nodes[ 1 ] , per_peer_state_lock, peer_state_lock, chan_id) ;
2159
+ assert_eq ! ( chan. context( ) . holder_dust_limit_satoshis, HTLC_AMT_SAT ) ;
2160
+ }
2161
+
2162
+ // Precompute the route to skip any router complaints when sending the last HTLC
2163
+ let ( route_0_1, payment_hash_0_1, _, payment_secret_0_1) =
2164
+ get_route_and_payment_hash ! ( nodes[ 0 ] , nodes[ 1 ] , HTLC_AMT_SAT * 1000 ) ;
2165
+
2166
+ let mut htlcs = Vec :: new ( ) ;
2167
+ for _ in 0 ..MIN_AFFORDABLE_HTLC_COUNT - 1 {
2168
+ let ( _payment_preimage, payment_hash, ..) =
2169
+ route_payment ( & nodes[ 0 ] , & [ & nodes[ 1 ] ] , HTLC_AMT_SAT * 1000 ) ;
2170
+ // Grab a snapshot of these HTLCs to manually build the commitment transaction later...
2171
+ let accepted_htlc = chan_utils:: HTLCOutputInCommitment {
2172
+ offered : false ,
2173
+ amount_msat : HTLC_AMT_SAT * 1000 ,
2174
+ // Hard-coded to match the expected value
2175
+ cltv_expiry : 81 ,
2176
+ payment_hash,
2177
+ transaction_output_index : None ,
2178
+ } ;
2179
+ htlcs. push ( accepted_htlc) ;
2180
+ }
2181
+
2182
+ // Need to manually create the update_add_htlc message to go around the channel reserve check in send_htlc()
2183
+ let secp_ctx = Secp256k1 :: new ( ) ;
2184
+ let session_priv = SecretKey :: from_slice ( & [ 42 ; 32 ] ) . expect ( "RNG is bad!" ) ;
2185
+
2186
+ let cur_height = nodes[ 1 ] . node . best_block . read ( ) . unwrap ( ) . height + 1 ;
2187
+
2188
+ let onion_keys =
2189
+ onion_utils:: construct_onion_keys ( & secp_ctx, & route_0_1. paths [ 0 ] , & session_priv) ;
2190
+ let recipient_onion_fields = RecipientOnionFields :: secret_only ( payment_secret_0_1) ;
2191
+ let ( onion_payloads, amount_msat, cltv_expiry) = onion_utils:: build_onion_payloads (
2192
+ & route_0_1. paths [ 0 ] ,
2193
+ HTLC_AMT_SAT * 1000 ,
2194
+ & recipient_onion_fields,
2195
+ cur_height,
2196
+ & None ,
2197
+ None ,
2198
+ None ,
2199
+ )
2200
+ . unwrap ( ) ;
2201
+ let onion_routing_packet =
2202
+ onion_utils:: construct_onion_packet ( onion_payloads, onion_keys, [ 0 ; 32 ] , & payment_hash_0_1)
2203
+ . unwrap ( ) ;
2204
+ // Double check the hard-coded value
2205
+ assert_eq ! ( cltv_expiry, 81 ) ;
2206
+ let msg = msgs:: UpdateAddHTLC {
2207
+ channel_id : chan_id,
2208
+ htlc_id : MIN_AFFORDABLE_HTLC_COUNT as u64 - 1 ,
2209
+ amount_msat,
2210
+ payment_hash : payment_hash_0_1,
2211
+ cltv_expiry,
2212
+ onion_routing_packet,
2213
+ skimmed_fee_msat : None ,
2214
+ blinding_point : None ,
2215
+ } ;
2216
+
2217
+ nodes[ 1 ] . node . handle_update_add_htlc ( node_a_id, & msg) ;
2218
+
2219
+ if !can_afford {
2220
+ let err = "Remote HTLC add would put them under remote reserve value" . to_string ( ) ;
2221
+ nodes[ 1 ] . logger . assert_log_contains ( "lightning::ln::channelmanager" , & err, 3 ) ;
2222
+ let events = nodes[ 1 ] . node . get_and_clear_pending_msg_events ( ) ;
2223
+ assert_eq ! ( events. len( ) , 2 ) ;
2224
+ let reason = ClosureReason :: ProcessingError { err } ;
2225
+ check_closed_event ( & nodes[ 1 ] , 1 , reason, false , & [ node_a_id] , CHANNEL_VALUE_SAT ) ;
2226
+ check_added_monitors ( & nodes[ 1 ] , 1 ) ;
2227
+ } else {
2228
+ // Now manually create the commitment_signed message corresponding to the update_add
2229
+ // nodes[0] just sent. In the code for construction of this message, "local" refers
2230
+ // to the sender of the message, and "remote" refers to the receiver.
2231
+
2232
+ const INITIAL_COMMITMENT_NUMBER : u64 = ( 1 << 48 ) - 1 ;
2233
+
2234
+ let ( local_secret, next_local_point) = {
2235
+ let per_peer_state = nodes[ 0 ] . node . per_peer_state . read ( ) . unwrap ( ) ;
2236
+ let chan_lock = per_peer_state. get ( & node_b_id) . unwrap ( ) . lock ( ) . unwrap ( ) ;
2237
+ let local_chan =
2238
+ chan_lock. channel_by_id . get ( & chan_id) . and_then ( Channel :: as_funded) . unwrap ( ) ;
2239
+ let chan_signer = local_chan. get_signer ( ) ;
2240
+ // Make the signer believe we validated another commitment, so we can release the secret
2241
+ chan_signer. as_ecdsa ( ) . unwrap ( ) . get_enforcement_state ( ) . last_holder_commitment -= 1 ;
2242
+
2243
+ (
2244
+ chan_signer
2245
+ . as_ref ( )
2246
+ . release_commitment_secret (
2247
+ INITIAL_COMMITMENT_NUMBER - MIN_AFFORDABLE_HTLC_COUNT as u64 + 1 ,
2248
+ )
2249
+ . unwrap ( ) ,
2250
+ chan_signer
2251
+ . as_ref ( )
2252
+ . get_per_commitment_point (
2253
+ INITIAL_COMMITMENT_NUMBER - MIN_AFFORDABLE_HTLC_COUNT as u64 ,
2254
+ & secp_ctx,
2255
+ )
2256
+ . unwrap ( ) ,
2257
+ )
2258
+ } ;
2259
+ let remote_point = {
2260
+ let per_peer_lock;
2261
+ let mut peer_state_lock;
2262
+
2263
+ let channel =
2264
+ get_channel_ref ! ( nodes[ 1 ] , nodes[ 0 ] , per_peer_lock, peer_state_lock, chan_id) ;
2265
+ let chan_signer = channel. as_funded ( ) . unwrap ( ) . get_signer ( ) ;
2266
+ chan_signer
2267
+ . as_ref ( )
2268
+ . get_per_commitment_point (
2269
+ INITIAL_COMMITMENT_NUMBER - MIN_AFFORDABLE_HTLC_COUNT as u64 ,
2270
+ & secp_ctx,
2271
+ )
2272
+ . unwrap ( )
2273
+ } ;
2274
+
2275
+ // Build the remote commitment transaction so we can sign it, and then later use the
2276
+ // signature for the commitment_signed message.
2277
+ let local_chan_balance = node_0_balance_sat
2278
+ - HTLC_AMT_SAT * MIN_AFFORDABLE_HTLC_COUNT as u64
2279
+ - 2 * crate :: ln:: channel:: ANCHOR_OUTPUT_VALUE_SATOSHI
2280
+ - chan_utils:: commit_tx_fee_sat (
2281
+ FEERATE_PER_KW ,
2282
+ MIN_AFFORDABLE_HTLC_COUNT ,
2283
+ & channel_type,
2284
+ ) ;
2285
+
2286
+ let accepted_htlc_info = chan_utils:: HTLCOutputInCommitment {
2287
+ offered : false ,
2288
+ amount_msat : HTLC_AMT_SAT * 1000 ,
2289
+ cltv_expiry,
2290
+ payment_hash : payment_hash_0_1,
2291
+ transaction_output_index : None ,
2292
+ } ;
2293
+ htlcs. push ( accepted_htlc_info) ;
2294
+
2295
+ let commitment_number = INITIAL_COMMITMENT_NUMBER - MIN_AFFORDABLE_HTLC_COUNT as u64 ;
2296
+
2297
+ let res = {
2298
+ let per_peer_lock;
2299
+ let mut peer_state_lock;
2300
+
2301
+ let channel =
2302
+ get_channel_ref ! ( nodes[ 0 ] , nodes[ 1 ] , per_peer_lock, peer_state_lock, chan_id) ;
2303
+ let chan_signer = channel. as_funded ( ) . unwrap ( ) . get_signer ( ) ;
2304
+
2305
+ let commitment_tx = CommitmentTransaction :: new (
2306
+ commitment_number,
2307
+ & remote_point,
2308
+ node_1_balance_sat,
2309
+ local_chan_balance,
2310
+ FEERATE_PER_KW ,
2311
+ htlcs,
2312
+ & channel. funding ( ) . channel_transaction_parameters . as_counterparty_broadcastable ( ) ,
2313
+ & secp_ctx,
2314
+ ) ;
2315
+ let params = & channel. funding ( ) . channel_transaction_parameters ;
2316
+ chan_signer
2317
+ . as_ecdsa ( )
2318
+ . unwrap ( )
2319
+ . sign_counterparty_commitment (
2320
+ params,
2321
+ & commitment_tx,
2322
+ Vec :: new ( ) ,
2323
+ Vec :: new ( ) ,
2324
+ & secp_ctx,
2325
+ )
2326
+ . unwrap ( )
2327
+ } ;
2328
+
2329
+ let commit_signed_msg = msgs:: CommitmentSigned {
2330
+ channel_id : chan_id,
2331
+ signature : res. 0 ,
2332
+ htlc_signatures : res. 1 ,
2333
+ funding_txid : None ,
2334
+ #[ cfg( taproot) ]
2335
+ partial_signature_with_nonce : None ,
2336
+ } ;
2337
+
2338
+ // Send the commitment_signed message to the nodes[1].
2339
+ nodes[ 1 ] . node . handle_commitment_signed ( node_a_id, & commit_signed_msg) ;
2340
+ let _ = nodes[ 1 ] . node . get_and_clear_pending_msg_events ( ) ;
2341
+
2342
+ // Send the RAA to nodes[1].
2343
+ let raa_msg = msgs:: RevokeAndACK {
2344
+ channel_id : chan_id,
2345
+ per_commitment_secret : local_secret,
2346
+ next_per_commitment_point : next_local_point,
2347
+ #[ cfg( taproot) ]
2348
+ next_local_nonce : None ,
2349
+ } ;
2350
+ nodes[ 1 ] . node . handle_revoke_and_ack ( node_a_id, & raa_msg) ;
2351
+
2352
+ // The HTLC actually fails here in `fn validate_commitment_signed` due to a fee spike buffer
2353
+ // violation. It nonetheless passed all checks in `fn validate_update_add_htlc`.
2354
+
2355
+ expect_pending_htlcs_forwardable ! ( nodes[ 1 ] ) ;
2356
+ expect_htlc_handling_failed_destinations ! (
2357
+ nodes[ 1 ] . node. get_and_clear_pending_events( ) ,
2358
+ & [ HTLCHandlingFailureType :: Receive { payment_hash: payment_hash_0_1 } ]
2359
+ ) ;
2360
+
2361
+ let events = nodes[ 1 ] . node . get_and_clear_pending_msg_events ( ) ;
2362
+ assert_eq ! ( events. len( ) , 1 ) ;
2363
+ // Make sure the HTLC failed in the way we expect.
2364
+ match events[ 0 ] {
2365
+ MessageSendEvent :: UpdateHTLCs {
2366
+ updates : msgs:: CommitmentUpdate { ref update_fail_htlcs, .. } ,
2367
+ ..
2368
+ } => {
2369
+ assert_eq ! ( update_fail_htlcs. len( ) , 1 ) ;
2370
+ update_fail_htlcs[ 0 ] . clone ( )
2371
+ } ,
2372
+ _ => panic ! ( "Unexpected event" ) ,
2373
+ } ;
2374
+ nodes[ 1 ] . logger . assert_log ( "lightning::ln::channel" ,
2375
+ format ! ( "Attempting to fail HTLC due to fee spike buffer violation in channel {}. Rebalancing is required." , raa_msg. channel_id) , 1 ) ;
2376
+
2377
+ check_added_monitors ( & nodes[ 1 ] , 3 ) ;
2378
+ }
2379
+ }
0 commit comments