@@ -1193,3 +1193,185 @@ pub fn do_cannot_afford_on_holding_cell_release(
1193
1193
nodes[ 0 ] . logger . assert_log ( "lightning::ln::channel" , err, 1 ) ;
1194
1194
}
1195
1195
}
1196
+
1197
+ #[ xtest( feature = "_externalize_tests" ) ]
1198
+ pub fn can_afford_given_trimmed_htlcs ( ) {
1199
+ do_can_afford_given_trimmed_htlcs ( core:: cmp:: Ordering :: Equal ) ;
1200
+ do_can_afford_given_trimmed_htlcs ( core:: cmp:: Ordering :: Greater ) ;
1201
+ do_can_afford_given_trimmed_htlcs ( core:: cmp:: Ordering :: Less ) ;
1202
+ }
1203
+
1204
+ pub fn do_can_afford_given_trimmed_htlcs ( inequality_regions : core:: cmp:: Ordering ) {
1205
+ // Test that when we check whether we can afford a feerate update, we account for the
1206
+ // decrease in the weight of the commitment transaction due to newly trimmed HTLCs at the higher feerate.
1207
+ //
1208
+ // Place a non-dust HTLC on the transaction, increase the feerate such that the HTLC
1209
+ // gets trimmed, and finally check whether we were able to afford the new feerate.
1210
+
1211
+ let channel_type = ChannelTypeFeatures :: only_static_remote_key ( ) ;
1212
+ let can_afford = match inequality_regions {
1213
+ core:: cmp:: Ordering :: Less => false ,
1214
+ core:: cmp:: Ordering :: Equal => true ,
1215
+ core:: cmp:: Ordering :: Greater => true ,
1216
+ } ;
1217
+ let inequality_boundary_offset = match inequality_regions {
1218
+ core:: cmp:: Ordering :: Less => 0 ,
1219
+ core:: cmp:: Ordering :: Equal => 1 ,
1220
+ core:: cmp:: Ordering :: Greater => 2 ,
1221
+ } ;
1222
+
1223
+ let chanmon_cfgs = create_chanmon_cfgs ( 2 ) ;
1224
+
1225
+ let mut default_config = test_default_channel_config ( ) ;
1226
+ default_config. channel_handshake_config . max_inbound_htlc_value_in_flight_percent_of_channel =
1227
+ 100 ;
1228
+
1229
+ let node_cfgs = create_node_cfgs ( 2 , & chanmon_cfgs) ;
1230
+ let node_chanmgrs =
1231
+ create_node_chanmgrs ( 2 , & node_cfgs, & [ Some ( default_config. clone ( ) ) , Some ( default_config) ] ) ;
1232
+
1233
+ let mut nodes = create_network ( 2 , & node_cfgs, & node_chanmgrs) ;
1234
+
1235
+ let node_a_id = nodes[ 0 ] . node . get_our_node_id ( ) ;
1236
+ let node_b_id = nodes[ 1 ] . node . get_our_node_id ( ) ;
1237
+
1238
+ // We will update the feerate from 253sat/kw to 1000sat/kw
1239
+ let target_feerate = 1000 ;
1240
+ // Set a HTLC amount that is non-dust at 253sat/kw and dust at 1000sat/kw
1241
+ let node_0_inbound_htlc_amount_sat = 750 ;
1242
+
1243
+ // This is the number of HTLCs that `can_send_update_fee` will account for when checking
1244
+ // whether node 0 can afford the target feerate. We do not include the inbound HTLC we will send,
1245
+ // as that HTLC will be trimmed at the new feerate.
1246
+ let buffer_tx_fee_sat = chan_utils:: commit_tx_fee_sat (
1247
+ target_feerate,
1248
+ crate :: ln:: channel:: CONCURRENT_INBOUND_HTLC_FEE_BUFFER as usize ,
1249
+ & channel_type,
1250
+ ) ;
1251
+ let channel_reserve_satoshis = 1000 ;
1252
+
1253
+ let channel_value_sat = 100_000 ;
1254
+ let node_0_balance_sat =
1255
+ ( buffer_tx_fee_sat + channel_reserve_satoshis) - 1 + inequality_boundary_offset;
1256
+ let node_1_balance_sat = channel_value_sat - node_0_balance_sat;
1257
+
1258
+ let chan_id =
1259
+ create_chan_between_nodes_with_value ( & nodes[ 0 ] , & nodes[ 1 ] , channel_value_sat, 0 ) . 3 ;
1260
+ {
1261
+ // Double check the reserve here
1262
+ let per_peer_state_lock;
1263
+ let mut peer_state_lock;
1264
+ let chan =
1265
+ get_channel_ref ! ( nodes[ 1 ] , nodes[ 0 ] , per_peer_state_lock, peer_state_lock, chan_id) ;
1266
+ assert_eq ! (
1267
+ chan. funding( ) . holder_selected_channel_reserve_satoshis,
1268
+ channel_reserve_satoshis
1269
+ ) ;
1270
+ }
1271
+
1272
+ // Set node 0's balance at some offset from the inequality boundary
1273
+ send_payment ( & nodes[ 0 ] , & [ & nodes[ 1 ] ] , node_1_balance_sat * 1000 ) ;
1274
+
1275
+ // Route the HTLC from node 1 to node 0
1276
+ route_payment ( & nodes[ 1 ] , & [ & nodes[ 0 ] ] , node_0_inbound_htlc_amount_sat * 1000 ) ;
1277
+
1278
+ // Confirm the feerate on node 0's commitment transaction
1279
+ {
1280
+ let expected_tx_fee_sat = chan_utils:: commit_tx_fee_sat ( 253 , 1 , & channel_type) ;
1281
+ let commitment_tx = get_local_commitment_txn ! ( nodes[ 0 ] , chan_id) [ 0 ] . clone ( ) ;
1282
+
1283
+ let mut actual_fee = commitment_tx
1284
+ . output
1285
+ . iter ( )
1286
+ . map ( |output| output. value . to_sat ( ) )
1287
+ . reduce ( |acc, value| acc + value)
1288
+ . unwrap ( ) ;
1289
+ actual_fee = channel_value_sat - actual_fee;
1290
+ assert_eq ! ( expected_tx_fee_sat, actual_fee) ;
1291
+
1292
+ // The HTLC is non-dust...
1293
+ assert_eq ! ( commitment_tx. output. len( ) , 3 ) ;
1294
+ }
1295
+
1296
+ {
1297
+ // Bump the feerate
1298
+ let mut feerate_lock = chanmon_cfgs[ 0 ] . fee_estimator . sat_per_kw . lock ( ) . unwrap ( ) ;
1299
+ * feerate_lock = target_feerate;
1300
+ }
1301
+ nodes[ 0 ] . node . timer_tick_occurred ( ) ;
1302
+ check_added_monitors ( & nodes[ 0 ] , if can_afford { 1 } else { 0 } ) ;
1303
+ let mut events = nodes[ 0 ] . node . get_and_clear_pending_msg_events ( ) ;
1304
+
1305
+ if can_afford {
1306
+ // We could afford the target feerate, sanity check everything
1307
+ assert_eq ! ( events. len( ) , 1 ) ;
1308
+ if let MessageSendEvent :: UpdateHTLCs { node_id, channel_id, updates } =
1309
+ events. pop ( ) . unwrap ( )
1310
+ {
1311
+ assert_eq ! ( node_id, node_b_id) ;
1312
+ assert_eq ! ( channel_id, chan_id) ;
1313
+ assert_eq ! ( updates. commitment_signed. len( ) , 1 ) ;
1314
+ // The HTLC is now trimmed!
1315
+ assert_eq ! ( updates. commitment_signed[ 0 ] . htlc_signatures. len( ) , 0 ) ;
1316
+ assert_eq ! ( updates. update_add_htlcs. len( ) , 0 ) ;
1317
+ assert_eq ! ( updates. update_fulfill_htlcs. len( ) , 0 ) ;
1318
+ assert_eq ! ( updates. update_fail_htlcs. len( ) , 0 ) ;
1319
+ assert_eq ! ( updates. update_fail_malformed_htlcs. len( ) , 0 ) ;
1320
+ let update_fee = updates. update_fee . unwrap ( ) ;
1321
+ assert_eq ! ( update_fee. channel_id, chan_id) ;
1322
+ assert_eq ! ( update_fee. feerate_per_kw, target_feerate) ;
1323
+
1324
+ nodes[ 1 ] . node . handle_update_fee ( node_a_id, & update_fee) ;
1325
+ commitment_signed_dance ! ( nodes[ 1 ] , nodes[ 0 ] , updates. commitment_signed, false ) ;
1326
+
1327
+ // Confirm the feerate on node 0's commitment transaction
1328
+ {
1329
+ // Also add the trimmed HTLC to the fees
1330
+ let expected_tx_fee_sat =
1331
+ chan_utils:: commit_tx_fee_sat ( target_feerate, 0 , & channel_type)
1332
+ + node_0_inbound_htlc_amount_sat;
1333
+ let commitment_tx = get_local_commitment_txn ! ( nodes[ 0 ] , channel_id) [ 0 ] . clone ( ) ;
1334
+
1335
+ let mut actual_fee = commitment_tx
1336
+ . output
1337
+ . iter ( )
1338
+ . map ( |output| output. value . to_sat ( ) )
1339
+ . reduce ( |acc, value| acc + value)
1340
+ . unwrap ( ) ;
1341
+ actual_fee = channel_value_sat - actual_fee;
1342
+ assert_eq ! ( expected_tx_fee_sat, actual_fee) ;
1343
+
1344
+ // The HTLC is now trimmed!
1345
+ assert_eq ! ( commitment_tx. output. len( ) , 2 ) ;
1346
+ }
1347
+
1348
+ // Confirm the feerate on node 1's commitment transaction
1349
+ {
1350
+ // Also add the trimmed HTLC to the fees
1351
+ let expected_tx_fee_sat =
1352
+ chan_utils:: commit_tx_fee_sat ( target_feerate, 0 , & channel_type)
1353
+ + node_0_inbound_htlc_amount_sat;
1354
+ let commitment_tx = get_local_commitment_txn ! ( nodes[ 1 ] , channel_id) [ 0 ] . clone ( ) ;
1355
+
1356
+ let mut actual_fee = commitment_tx
1357
+ . output
1358
+ . iter ( )
1359
+ . map ( |output| output. value . to_sat ( ) )
1360
+ . reduce ( |acc, value| acc + value)
1361
+ . unwrap ( ) ;
1362
+ actual_fee = channel_value_sat - actual_fee;
1363
+ assert_eq ! ( expected_tx_fee_sat, actual_fee) ;
1364
+
1365
+ // The HTLC is now trimmed!
1366
+ assert_eq ! ( commitment_tx. output. len( ) , 2 ) ;
1367
+ }
1368
+ } else {
1369
+ panic ! ( ) ;
1370
+ }
1371
+ } else {
1372
+ // We could not afford the target feerate, no events should be generated
1373
+ assert_eq ! ( events. len( ) , 0 ) ;
1374
+ let err = format ! ( "Cannot afford to send new feerate at {}" , target_feerate) ;
1375
+ nodes[ 0 ] . logger . assert_log ( "lightning::ln::channel" , err, 1 ) ;
1376
+ }
1377
+ }
0 commit comments