Skip to content

Commit d0a4441

Browse files
committed
Don't generate a commitment if we cannot afford a holding cell feerate
While an `update_fee` is in the holding cell, it is possible for HTLCs to get added to the commitment transaction such that when we release the holding cell, we can no longer afford this new feerate. In that case, we previously would drop the fee update, but still send a commitment (at the old feerate), which is a break of the specification. We now stop generating this lonely commitment when the fee update gets dropped upon release from the holding cell.
1 parent 6133a6c commit d0a4441

File tree

3 files changed

+146
-7
lines changed

3 files changed

+146
-7
lines changed

lightning/src/ln/channel.rs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6275,14 +6275,11 @@ impl<SP: Deref> FundedChannel<SP> where
62756275
}
62766276
}
62776277
}
6278-
if update_add_count == 0 && update_fulfill_count == 0 && update_fail_count == 0 && self.context.holding_cell_update_fee.is_none() {
6278+
let update_fee = self.context.holding_cell_update_fee.take().and_then(|feerate| self.send_update_fee(feerate, false, fee_estimator, logger));
6279+
6280+
if update_add_count == 0 && update_fulfill_count == 0 && update_fail_count == 0 && update_fee.is_none() {
62796281
return (None, htlcs_to_fail);
62806282
}
6281-
let update_fee = if let Some(feerate) = self.context.holding_cell_update_fee.take() {
6282-
self.send_update_fee(feerate, false, fee_estimator, logger)
6283-
} else {
6284-
None
6285-
};
62866283

62876284
let mut additional_update = self.build_commitment_no_status_check(logger);
62886285
// build_commitment_no_status_check and get_update_fulfill_htlc may bump latest_monitor_id

lightning/src/ln/channelmanager.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6586,7 +6586,7 @@ where
65866586
NotifyOption::DoPersist
65876587
}
65886588

6589-
#[cfg(fuzzing)]
6589+
#[cfg(any(test, fuzzing))]
65906590
/// In chanmon_consistency we want to sometimes do the channel fee updates done in
65916591
/// timer_tick_occurred, but we can't generate the disabled channel updates as it considers
65926592
/// these a fuzz failure (as they usually indicate a channel force-close, which is exactly what

lightning/src/ln/update_fee_tests.rs

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1009,3 +1009,145 @@ pub fn accept_busted_but_better_fee() {
10091009
_ => panic!("Unexpected event"),
10101010
};
10111011
}
1012+
1013+
#[xtest(feature = "_externalize_tests")]
1014+
pub fn cant_afford_on_holding_cell_release() {
1015+
do_cant_afford_on_holding_cell_release(true);
1016+
do_cant_afford_on_holding_cell_release(false);
1017+
}
1018+
1019+
pub fn do_cant_afford_on_holding_cell_release(can_afford: bool) {
1020+
// Test that if we can't afford a feerate update when releasing an
1021+
// update_fee from its holding cell, we do not generate any msg events
1022+
let chanmon_cfgs = create_chanmon_cfgs(2);
1023+
1024+
let mut default_config = test_default_channel_config();
1025+
default_config.channel_handshake_config.negotiate_anchors_zero_fee_htlc_tx = true;
1026+
default_config.manually_accept_inbound_channels = true;
1027+
default_config.channel_handshake_config.max_inbound_htlc_value_in_flight_percent_of_channel =
1028+
100;
1029+
1030+
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
1031+
let node_chanmgrs =
1032+
create_node_chanmgrs(2, &node_cfgs, &[Some(default_config.clone()), Some(default_config)]);
1033+
1034+
let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
1035+
1036+
let node_a_id = nodes[0].node.get_our_node_id();
1037+
let node_b_id = nodes[1].node.get_our_node_id();
1038+
1039+
let target_feerate = 257;
1040+
let channel_type = ChannelTypeFeatures::anchors_zero_htlc_fee_and_dependencies();
1041+
// This is the number of htlcs that `send_update_fee` will account for when checking whether
1042+
// it can afford the new feerate upon releasing an update_fee from its holding cell,
1043+
// ie the buffer + the inbound HTLC we will add while the update_fee is in the holding cell
1044+
let num_htlcs = crate::ln::channel::CONCURRENT_INBOUND_HTLC_FEE_BUFFER + 1;
1045+
let commit_tx_fee_sat =
1046+
chan_utils::commit_tx_fee_sat(target_feerate, num_htlcs as usize, &channel_type);
1047+
let anchor_value_satoshis = 2 * crate::ln::channel::ANCHOR_OUTPUT_VALUE_SATOSHI;
1048+
let channel_reserve_satoshis = 1000;
1049+
1050+
let channel_value_sat = 100_000;
1051+
let node_0_balance_sat = commit_tx_fee_sat + anchor_value_satoshis + channel_reserve_satoshis
1052+
- if can_afford { 0 } else { 1 };
1053+
let node_1_balance_sat = channel_value_sat - node_0_balance_sat;
1054+
1055+
let chan_id =
1056+
create_chan_between_nodes_with_value(&nodes[0], &nodes[1], channel_value_sat, 0).3;
1057+
1058+
// Set node 0's balance to the can/can't afford threshold
1059+
send_payment(&nodes[0], &[&nodes[1]], node_1_balance_sat * 1000);
1060+
1061+
{
1062+
// Sanity check the reserve
1063+
let per_peer_state_lock;
1064+
let mut peer_state_lock;
1065+
let chan =
1066+
get_channel_ref!(nodes[1], nodes[0], per_peer_state_lock, peer_state_lock, chan_id);
1067+
assert_eq!(
1068+
chan.funding().holder_selected_channel_reserve_satoshis,
1069+
channel_reserve_satoshis
1070+
);
1071+
}
1072+
1073+
{
1074+
// Bump the feerate
1075+
let mut feerate_lock = chanmon_cfgs[0].fee_estimator.sat_per_kw.lock().unwrap();
1076+
*feerate_lock += 4;
1077+
assert_eq!(*feerate_lock, target_feerate);
1078+
}
1079+
1080+
// Put the update fee into the holding cell of node 0
1081+
1082+
nodes[0].node.maybe_update_chan_fees();
1083+
1084+
// While the update_fee is in the holding cell, add an inbound HTLC
1085+
1086+
let (route, payment_hash, _, payment_secret) =
1087+
get_route_and_payment_hash!(nodes[1], nodes[0], 1000 * 1000);
1088+
let onion = RecipientOnionFields::secret_only(payment_secret);
1089+
let id = PaymentId(payment_hash.0);
1090+
nodes[1].node.send_payment_with_route(route, payment_hash, onion, id).unwrap();
1091+
check_added_monitors(&nodes[1], 1);
1092+
1093+
let payment_event = {
1094+
let mut events_1 = nodes[1].node.get_and_clear_pending_msg_events();
1095+
assert_eq!(events_1.len(), 1);
1096+
SendEvent::from_event(events_1.pop().unwrap())
1097+
};
1098+
assert_eq!(payment_event.node_id, node_a_id);
1099+
assert_eq!(payment_event.msgs.len(), 1);
1100+
1101+
nodes[0].node.handle_update_add_htlc(node_b_id, &payment_event.msgs[0]);
1102+
nodes[0].node.handle_commitment_signed(node_b_id, &payment_event.commitment_msg[0]);
1103+
check_added_monitors(&nodes[0], 1);
1104+
1105+
let (revoke_ack, commitment_signed) = get_revoke_commit_msgs!(nodes[0], node_b_id);
1106+
1107+
nodes[1].node.handle_revoke_and_ack(node_a_id, &revoke_ack);
1108+
check_added_monitors(&nodes[1], 1);
1109+
nodes[1].node.handle_commitment_signed(node_a_id, &commitment_signed[0]);
1110+
check_added_monitors(&nodes[1], 1);
1111+
1112+
let mut events = nodes[1].node.get_and_clear_pending_msg_events();
1113+
assert_eq!(events.len(), 1);
1114+
1115+
if let MessageSendEvent::SendRevokeAndACK { node_id, msg } = events.pop().unwrap() {
1116+
assert_eq!(node_id, node_a_id);
1117+
nodes[0].node.handle_revoke_and_ack(node_b_id, &msg);
1118+
check_added_monitors!(nodes[0], 1);
1119+
} else {
1120+
panic!();
1121+
}
1122+
1123+
let events = nodes[0].node.get_and_clear_pending_events();
1124+
assert_eq!(events.len(), 1);
1125+
assert!(matches!(events[0], Event::PendingHTLCsForwardable { .. }));
1126+
1127+
// Release the update_fee from its holding cell
1128+
1129+
let mut events = nodes[0].node.get_and_clear_pending_msg_events();
1130+
if can_afford {
1131+
// We could afford the update_fee, sanity check everything
1132+
if let MessageSendEvent::UpdateHTLCs { node_id, channel_id, updates } =
1133+
events.pop().unwrap()
1134+
{
1135+
assert_eq!(node_id, node_b_id);
1136+
assert_eq!(channel_id, chan_id);
1137+
assert_eq!(updates.commitment_signed.len(), 1);
1138+
assert_eq!(updates.commitment_signed[0].htlc_signatures.len(), 1);
1139+
assert_eq!(updates.update_add_htlcs.len(), 0);
1140+
assert_eq!(updates.update_fulfill_htlcs.len(), 0);
1141+
assert_eq!(updates.update_fail_htlcs.len(), 0);
1142+
assert_eq!(updates.update_fail_malformed_htlcs.len(), 0);
1143+
let update_fee = updates.update_fee.unwrap();
1144+
assert_eq!(update_fee.channel_id, chan_id);
1145+
assert_eq!(update_fee.feerate_per_kw, target_feerate);
1146+
} else {
1147+
panic!();
1148+
}
1149+
} else {
1150+
// We could not afford the update_fee, no events should be generated
1151+
assert_eq!(events.len(), 0);
1152+
}
1153+
}

0 commit comments

Comments
 (0)