@@ -1193,3 +1193,185 @@ pub fn do_cannot_afford_on_holding_cell_release(
11931193 nodes[ 0 ] . logger . assert_log ( "lightning::ln::channel" , err, 1 ) ;
11941194 }
11951195}
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