Skip to content

Commit fb6970e

Browse files
carlaKCTheBlueMatt
andcommitted
ln: do not send and reject receive of update_fee for zero fee commits
Co-authored-by: Matt Corallo <[email protected]>
1 parent e5aadb7 commit fb6970e

File tree

3 files changed

+66
-0
lines changed

3 files changed

+66
-0
lines changed

lightning/src/chain/package.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,9 @@ pub(crate) fn verify_channel_type_features(channel_type_features: &Option<Channe
9999
supported_feature_set.set_scid_privacy_required();
100100
supported_feature_set.set_zero_conf_required();
101101

102+
#[cfg(test)]
103+
supported_feature_set.set_anchor_zero_fee_commitments_required();
104+
102105
// allow the passing of an additional necessary permitted flag
103106
if let Some(additional_permitted_features) = additional_permitted_features {
104107
supported_feature_set |= additional_permitted_features;

lightning/src/ln/channel.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4335,6 +4335,10 @@ where
43354335
F::Target: FeeEstimator,
43364336
L::Target: Logger,
43374337
{
4338+
if funding.get_channel_type().supports_anchor_zero_fee_commitments() {
4339+
return false;
4340+
}
4341+
43384342
// Before proposing a feerate update, check that we can actually afford the new fee.
43394343
let dust_exposure_limiting_feerate = self.get_dust_exposure_limiting_feerate(
43404344
&fee_estimator, funding.get_channel_type(),
@@ -8017,6 +8021,9 @@ where
80178021
if self.context.channel_state.is_remote_stfu_sent() || self.context.channel_state.is_quiescent() {
80188022
return Err(ChannelError::WarnAndDisconnect("Got fee update message while quiescent".to_owned()));
80198023
}
8024+
if self.funding.get_channel_type().supports_anchor_zero_fee_commitments() {
8025+
return Err(ChannelError::WarnAndDisconnect("Update fee message received for zero fee commitment channel".to_owned()));
8026+
}
80208027

80218028
core::iter::once(&self.funding)
80228029
.chain(self.pending_funding.iter())

lightning/src/ln/update_fee_tests.rs

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1375,3 +1375,59 @@ pub fn do_can_afford_given_trimmed_htlcs(inequality_regions: core::cmp::Ordering
13751375
nodes[0].logger.assert_log("lightning::ln::channel", err, 1);
13761376
}
13771377
}
1378+
1379+
#[test]
1380+
pub fn test_zero_fee_commiments_no_update_fee() {
1381+
// Tests that option_zero_fee_commitment channels do not sent update_fee messages, and that
1382+
// they'll disconnect and warn if they receive them.
1383+
let mut cfg = test_default_channel_config();
1384+
cfg.channel_handshake_config.negotiate_anchor_zero_fee_commitments = true;
1385+
cfg.manually_accept_inbound_channels = true;
1386+
1387+
let chanmon_cfgs = create_chanmon_cfgs(2);
1388+
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
1389+
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[Some(cfg.clone()), Some(cfg)]);
1390+
let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
1391+
1392+
let channel = create_chan_between_nodes(&nodes[0], &nodes[1]);
1393+
1394+
let assert_zero_fee = || {
1395+
for node in nodes.iter() {
1396+
let channels = node.node.list_channels();
1397+
assert_eq!(channels.len(), 1);
1398+
assert!(channels[0]
1399+
.channel_type
1400+
.as_ref()
1401+
.unwrap()
1402+
.supports_anchor_zero_fee_commitments());
1403+
assert_eq!(channels[0].feerate_sat_per_1000_weight.unwrap(), 0);
1404+
}
1405+
};
1406+
assert_zero_fee();
1407+
1408+
// Sender should not queue an update_fee message.
1409+
nodes[0].node.timer_tick_occurred();
1410+
let events_0 = nodes[0].node.get_and_clear_pending_msg_events();
1411+
assert_eq!(events_0.len(), 0);
1412+
1413+
// Receiver should ignore and warn if sent update_fee.
1414+
let channel_id = channel.3;
1415+
let update_fee_msg = msgs::UpdateFee { channel_id, feerate_per_kw: 5000 };
1416+
nodes[1].node.handle_update_fee(nodes[0].node.get_our_node_id(), &update_fee_msg);
1417+
1418+
let events_1 = nodes[1].node.get_and_clear_pending_msg_events();
1419+
assert_eq!(events_1.len(), 1);
1420+
match events_1[0] {
1421+
MessageSendEvent::HandleError { ref action, .. } => match action {
1422+
ErrorAction::DisconnectPeerWithWarning { ref msg, .. } => {
1423+
assert_eq!(msg.channel_id, channel_id);
1424+
assert!(msg
1425+
.data
1426+
.contains("Update fee message received for zero fee commitment channel"));
1427+
},
1428+
_ => panic!("Expected DisconnectPeerWithWarning, got {:?}", action),
1429+
},
1430+
_ => panic!("Expected HandleError event, got {:?}", events_1[0]),
1431+
}
1432+
assert_zero_fee();
1433+
}

0 commit comments

Comments
 (0)