Skip to content

Commit cfa782d

Browse files
authored
Merge pull request #3896 from elnosh/channel-type-required
Make channel_type required
2 parents 95ca0dc + e31df56 commit cfa782d

File tree

5 files changed

+150
-84
lines changed

5 files changed

+150
-84
lines changed

fuzz/src/full_stack.rs

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1066,8 +1066,8 @@ fn two_peer_forwarding_seed() -> Vec<u8> {
10661066
ext_from_hex("0010 03000000000000000000000000000000", &mut test);
10671067
// inbound read from peer id 0 of len 32
10681068
ext_from_hex("030020", &mut test);
1069-
// init message (type 16) with static_remotekey required, no channel_type/anchors/taproot, and other bits optional and mac
1070-
ext_from_hex("0010 00021aaa 0008aaa208aa2a0a9aaa 03000000000000000000000000000000", &mut test);
1069+
// init message (type 16) with static_remotekey required, no anchors/taproot, and other bits optional and mac
1070+
ext_from_hex("0010 00021aaa 0008aaa210aa2a0a9aaa 03000000000000000000000000000000", &mut test);
10711071

10721072
// inbound read from peer id 0 of len 18
10731073
ext_from_hex("030012", &mut test);
@@ -1167,8 +1167,8 @@ fn two_peer_forwarding_seed() -> Vec<u8> {
11671167
ext_from_hex("0010 01000000000000000000000000000000", &mut test);
11681168
// inbound read from peer id 1 of len 32
11691169
ext_from_hex("030120", &mut test);
1170-
// init message (type 16) with static_remotekey required, no channel_type/anchors/taproot, and other bits optional and mac
1171-
ext_from_hex("0010 00021aaa 0008aaa208aa2a0a9aaa 01000000000000000000000000000000", &mut test);
1170+
// init message (type 16) with static_remotekey required, no anchors/taproot, and other bits optional and mac
1171+
ext_from_hex("0010 00021aaa 0008aaa210aa2a0a9aaa 01000000000000000000000000000000", &mut test);
11721172

11731173
// create outbound channel to peer 1 for 50k sat
11741174
ext_from_hex(
@@ -1180,17 +1180,17 @@ fn two_peer_forwarding_seed() -> Vec<u8> {
11801180

11811181
// inbound read from peer id 1 of len 18
11821182
ext_from_hex("030112", &mut test);
1183-
// message header indicating message length 274
1184-
ext_from_hex("0112 01000000000000000000000000000000", &mut test);
1183+
// message header indicating message length 278
1184+
ext_from_hex("0116 01000000000000000000000000000000", &mut test);
11851185
// inbound read from peer id 1 of len 255
11861186
ext_from_hex("0301ff", &mut test);
11871187
// beginning of accept_channel
11881188
ext_from_hex("0021 0000000000000000000000000000000000000000000000000000000000000e12 0000000000000162 00000000004c4b40 00000000000003e8 00000000000003e8 00000002 03f0 0005 030000000000000000000000000000000000000000000000000000000000000100 030000000000000000000000000000000000000000000000000000000000000200 030000000000000000000000000000000000000000000000000000000000000300 030000000000000000000000000000000000000000000000000000000000000400 030000000000000000000000000000000000000000000000000000000000000500 02660000000000000000000000000000", &mut test);
1189-
// inbound read from peer id 1 of len 35
1190-
ext_from_hex("030123", &mut test);
1189+
// inbound read from peer id 1 of len 39
1190+
ext_from_hex("030127", &mut test);
11911191
// rest of accept_channel and mac
11921192
ext_from_hex(
1193-
"0000000000000000000000000000000000 0000 01000000000000000000000000000000",
1193+
"0000000000000000000000000000000000 0000 01021000 01000000000000000000000000000000",
11941194
&mut test,
11951195
);
11961196

@@ -1582,8 +1582,8 @@ fn gossip_exchange_seed() -> Vec<u8> {
15821582
ext_from_hex("0010 03000000000000000000000000000000", &mut test);
15831583
// inbound read from peer id 0 of len 32
15841584
ext_from_hex("030020", &mut test);
1585-
// init message (type 16) with static_remotekey required, no channel_type/anchors/taproot, and other bits optional and mac
1586-
ext_from_hex("0010 00021aaa 0008aaa20aaa2a0a9aaa 03000000000000000000000000000000", &mut test);
1585+
// init message (type 16) with static_remotekey required, no anchors/taproot, and other bits optional and mac
1586+
ext_from_hex("0010 00021aaa 0008aaa210aa2a0a9aaa 03000000000000000000000000000000", &mut test);
15871587

15881588
// new inbound connection with id 1
15891589
ext_from_hex("01", &mut test);
@@ -1602,8 +1602,8 @@ fn gossip_exchange_seed() -> Vec<u8> {
16021602
ext_from_hex("0010 01000000000000000000000000000000", &mut test);
16031603
// inbound read from peer id 1 of len 32
16041604
ext_from_hex("030120", &mut test);
1605-
// init message (type 16) with static_remotekey required, no channel_type/anchors/taproot, and other bits optional and mac
1606-
ext_from_hex("0010 00021aaa 0008aaa20aaa2a0a9aaa 01000000000000000000000000000000", &mut test);
1605+
// init message (type 16) with static_remotekey required, no anchors/taproot, and other bits optional and mac
1606+
ext_from_hex("0010 00021aaa 0008aaa210aa2a0a9aaa 01000000000000000000000000000000", &mut test);
16071607

16081608
// inbound read from peer id 0 of len 18
16091609
ext_from_hex("030012", &mut test);

lightning/src/ln/channel.rs

Lines changed: 28 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -3827,18 +3827,10 @@ where
38273827
return Err(ChannelError::close("Got an accept_channel message at a strange time".to_owned()));
38283828
}
38293829

3830-
if let Some(ty) = &common_fields.channel_type {
3831-
if ty != funding.get_channel_type() {
3832-
return Err(ChannelError::close("Channel Type in accept_channel didn't match the one sent in open_channel.".to_owned()));
3833-
}
3834-
} else if their_features.supports_channel_type() {
3835-
// Assume they've accepted the channel type as they said they understand it.
3836-
} else {
3837-
let channel_type = ChannelTypeFeatures::from_init(&their_features);
3838-
if channel_type != ChannelTypeFeatures::only_static_remote_key() {
3839-
return Err(ChannelError::close("Only static_remote_key is supported for non-negotiated channel types".to_owned()));
3840-
}
3841-
funding.channel_transaction_parameters.channel_type_features = channel_type;
3830+
let channel_type = common_fields.channel_type.as_ref()
3831+
.ok_or_else(|| ChannelError::close("option_channel_type assumed to be supported".to_owned()))?;
3832+
if channel_type != funding.get_channel_type() {
3833+
return Err(ChannelError::close("Channel Type in accept_channel didn't match the one sent in open_channel.".to_owned()));
38423834
}
38433835

38443836
if common_fields.dust_limit_satoshis > 21000000 * 100000000 {
@@ -11526,37 +11518,31 @@ where
1152611518
/// [`msgs::CommonOpenChannelFields`].
1152711519
#[rustfmt::skip]
1152811520
pub(super) fn channel_type_from_open_channel(
11529-
common_fields: &msgs::CommonOpenChannelFields, their_features: &InitFeatures,
11530-
our_supported_features: &ChannelTypeFeatures
11521+
common_fields: &msgs::CommonOpenChannelFields, our_supported_features: &ChannelTypeFeatures
1153111522
) -> Result<ChannelTypeFeatures, ChannelError> {
11532-
if let Some(channel_type) = &common_fields.channel_type {
11533-
if channel_type.supports_any_optional_bits() {
11534-
return Err(ChannelError::close("Channel Type field contained optional bits - this is not allowed".to_owned()));
11535-
}
11523+
let channel_type = common_fields.channel_type.as_ref()
11524+
.ok_or_else(|| ChannelError::close("option_channel_type assumed to be supported".to_owned()))?;
1153611525

11537-
// We only support the channel types defined by the `ChannelManager` in
11538-
// `provided_channel_type_features`. The channel type must always support
11539-
// `static_remote_key`, either implicitly with `option_zero_fee_commitments`
11540-
// or explicitly.
11541-
if !channel_type.requires_static_remote_key() && !channel_type.requires_anchor_zero_fee_commitments() {
11542-
return Err(ChannelError::close("Channel Type was not understood - we require static remote key".to_owned()));
11543-
}
11544-
// Make sure we support all of the features behind the channel type.
11545-
if channel_type.requires_unknown_bits_from(&our_supported_features) {
11546-
return Err(ChannelError::close("Channel Type contains unsupported features".to_owned()));
11547-
}
11548-
let announce_for_forwarding = if (common_fields.channel_flags & 1) == 1 { true } else { false };
11549-
if channel_type.requires_scid_privacy() && announce_for_forwarding {
11550-
return Err(ChannelError::close("SCID Alias/Privacy Channel Type cannot be set on a public channel".to_owned()));
11551-
}
11552-
Ok(channel_type.clone())
11553-
} else {
11554-
let channel_type = ChannelTypeFeatures::from_init(&their_features);
11555-
if channel_type != ChannelTypeFeatures::only_static_remote_key() {
11556-
return Err(ChannelError::close("Only static_remote_key is supported for non-negotiated channel types".to_owned()));
11557-
}
11558-
Ok(channel_type)
11526+
if channel_type.supports_any_optional_bits() {
11527+
return Err(ChannelError::close("Channel Type field contained optional bits - this is not allowed".to_owned()));
11528+
}
11529+
11530+
// We only support the channel types defined by the `ChannelManager` in
11531+
// `provided_channel_type_features`. The channel type must always support
11532+
// `static_remote_key`, either implicitly with `option_zero_fee_commitments`
11533+
// or explicitly.
11534+
if !channel_type.requires_static_remote_key() && !channel_type.requires_anchor_zero_fee_commitments() {
11535+
return Err(ChannelError::close("Channel Type was not understood - we require static remote key".to_owned()));
11536+
}
11537+
// Make sure we support all of the features behind the channel type.
11538+
if channel_type.requires_unknown_bits_from(&our_supported_features) {
11539+
return Err(ChannelError::close("Channel Type contains unsupported features".to_owned()));
1155911540
}
11541+
let announce_for_forwarding = if (common_fields.channel_flags & 1) == 1 { true } else { false };
11542+
if channel_type.requires_scid_privacy() && announce_for_forwarding {
11543+
return Err(ChannelError::close("SCID Alias/Privacy Channel Type cannot be set on a public channel".to_owned()));
11544+
}
11545+
Ok(channel_type.clone())
1156011546
}
1156111547

1156211548
impl<SP: Deref> InboundV1Channel<SP>
@@ -11580,7 +11566,7 @@ where
1158011566

1158111567
// First check the channel type is known, failing before we do anything else if we don't
1158211568
// support this channel type.
11583-
let channel_type = channel_type_from_open_channel(&msg.common_fields, their_features, our_supported_features)?;
11569+
let channel_type = channel_type_from_open_channel(&msg.common_fields, our_supported_features)?;
1158411570

1158511571
let holder_selected_channel_reserve_satoshis = get_holder_selected_channel_reserve_satoshis(msg.common_fields.funding_satoshis, config);
1158611572
let counterparty_pubkeys = ChannelPublicKeys {
@@ -11977,13 +11963,7 @@ where
1197711963
let holder_selected_channel_reserve_satoshis = get_v2_channel_reserve_satoshis(
1197811964
channel_value_satoshis, MIN_CHAN_DUST_LIMIT_SATOSHIS);
1197911965

11980-
// First check the channel type is known, failing before we do anything else if we don't
11981-
// support this channel type.
11982-
if msg.common_fields.channel_type.is_none() {
11983-
return Err(ChannelError::close(format!("Rejecting V2 channel {} missing channel_type",
11984-
msg.common_fields.temporary_channel_id)))
11985-
}
11986-
let channel_type = channel_type_from_open_channel(&msg.common_fields, their_features, our_supported_features)?;
11966+
let channel_type = channel_type_from_open_channel(&msg.common_fields, our_supported_features)?;
1198711967

1198811968
let counterparty_pubkeys = ChannelPublicKeys {
1198911969
funding_pubkey: msg.common_fields.funding_pubkey,

lightning/src/ln/channel_type_tests.rs

Lines changed: 103 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -295,9 +295,9 @@ fn do_test_supports_channel_type(config: UserConfig, expected_channel_type: Chan
295295
}
296296

297297
#[test]
298-
fn test_rejects_implicit_simple_anchors() {
299-
// Tests that if `option_anchors` is being negotiated implicitly through the intersection of
300-
// each side's `InitFeatures`, it is rejected.
298+
fn test_rejects_if_channel_type_not_set() {
299+
// Tests that if `channel_type` is not set in `open_channel` and `accept_channel`, it is
300+
// rejected.
301301
let secp_ctx = Secp256k1::new();
302302
let test_est = TestFeeEstimator::new(15000);
303303
let fee_estimator = LowerBoundedFeeEstimator::new(&test_est);
@@ -312,13 +312,6 @@ fn test_rejects_implicit_simple_anchors() {
312312

313313
let config = UserConfig::default();
314314

315-
// See feature bit assignments: https://github.com/lightning/bolts/blob/master/09-features.md
316-
let static_remote_key_required: u64 = 1 << 12;
317-
let simple_anchors_required: u64 = 1 << 20;
318-
let raw_init_features = static_remote_key_required | simple_anchors_required;
319-
let init_features_with_simple_anchors =
320-
InitFeatures::from_le_bytes(raw_init_features.to_le_bytes().to_vec());
321-
322315
let mut channel_a = OutboundV1Channel::<&TestKeysInterface>::new(
323316
&fee_estimator,
324317
&&keys_provider,
@@ -336,20 +329,18 @@ fn test_rejects_implicit_simple_anchors() {
336329
)
337330
.unwrap();
338331

339-
// Set `channel_type` to `None` to force the implicit feature negotiation.
332+
// Set `channel_type` to `None` to cause failure.
340333
let mut open_channel_msg =
341334
channel_a.get_open_channel(ChainHash::using_genesis_block(network), &&logger).unwrap();
342335
open_channel_msg.common_fields.channel_type = None;
343336

344-
// Since A supports both `static_remote_key` and `option_anchors`, but B only accepts
345-
// `static_remote_key`, it will fail the channel.
346337
let channel_b = InboundV1Channel::<&TestKeysInterface>::new(
347338
&fee_estimator,
348339
&&keys_provider,
349340
&&keys_provider,
350341
node_id_a,
351342
&channelmanager::provided_channel_type_features(&config),
352-
&init_features_with_simple_anchors,
343+
&channelmanager::provided_init_features(&config),
353344
&open_channel_msg,
354345
7,
355346
&config,
@@ -358,6 +349,104 @@ fn test_rejects_implicit_simple_anchors() {
358349
/*is_0conf=*/ false,
359350
);
360351
assert!(channel_b.is_err());
352+
353+
open_channel_msg.common_fields.channel_type =
354+
Some(channel_a.funding.get_channel_type().clone());
355+
let mut channel_b = InboundV1Channel::<&TestKeysInterface>::new(
356+
&fee_estimator,
357+
&&keys_provider,
358+
&&keys_provider,
359+
node_id_a,
360+
&channelmanager::provided_channel_type_features(&config),
361+
&channelmanager::provided_init_features(&config),
362+
&open_channel_msg,
363+
7,
364+
&config,
365+
0,
366+
&&logger,
367+
/*is_0conf=*/ false,
368+
)
369+
.unwrap();
370+
371+
// Set `channel_type` to `None` in `accept_channel` to cause failure.
372+
let mut accept_channel_msg = channel_b.get_accept_channel_message(&&logger).unwrap();
373+
accept_channel_msg.common_fields.channel_type = None;
374+
375+
let res = channel_a.accept_channel(
376+
&accept_channel_msg,
377+
&config.channel_handshake_limits,
378+
&channelmanager::provided_init_features(&config),
379+
);
380+
assert!(res.is_err());
381+
}
382+
383+
#[test]
384+
fn test_rejects_if_channel_type_differ() {
385+
// Tests that if the `channel_type` in `accept_channel` does not match the one set in
386+
// `open_channel` it rejects the channel.
387+
let secp_ctx = Secp256k1::new();
388+
let test_est = TestFeeEstimator::new(15000);
389+
let fee_estimator = LowerBoundedFeeEstimator::new(&test_est);
390+
let network = Network::Testnet;
391+
let keys_provider = TestKeysInterface::new(&[42; 32], network);
392+
let logger = TestLogger::new();
393+
394+
let node_id_a =
395+
PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[1; 32]).unwrap());
396+
let node_id_b =
397+
PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[2; 32]).unwrap());
398+
399+
let config = UserConfig::default();
400+
401+
let mut channel_a = OutboundV1Channel::<&TestKeysInterface>::new(
402+
&fee_estimator,
403+
&&keys_provider,
404+
&&keys_provider,
405+
node_id_b,
406+
&channelmanager::provided_init_features(&config),
407+
10000000,
408+
100000,
409+
42,
410+
&config,
411+
0,
412+
42,
413+
None,
414+
&logger,
415+
)
416+
.unwrap();
417+
418+
let open_channel_msg =
419+
channel_a.get_open_channel(ChainHash::using_genesis_block(network), &&logger).unwrap();
420+
421+
let mut channel_b = InboundV1Channel::<&TestKeysInterface>::new(
422+
&fee_estimator,
423+
&&keys_provider,
424+
&&keys_provider,
425+
node_id_a,
426+
&channelmanager::provided_channel_type_features(&config),
427+
&channelmanager::provided_init_features(&config),
428+
&open_channel_msg,
429+
7,
430+
&config,
431+
0,
432+
&&logger,
433+
/*is_0conf=*/ false,
434+
)
435+
.unwrap();
436+
437+
// Change the `channel_type` in `accept_channel` msg to make it different from the one set in
438+
// `open_channel` to cause failure.
439+
let mut accept_channel_msg = channel_b.get_accept_channel_message(&&logger).unwrap();
440+
let mut channel_type = channelmanager::provided_channel_type_features(&config);
441+
channel_type.set_zero_conf_required();
442+
accept_channel_msg.common_fields.channel_type = Some(channel_type.clone());
443+
444+
let res = channel_a.accept_channel(
445+
&accept_channel_msg,
446+
&config.channel_handshake_limits,
447+
&channelmanager::provided_init_features(&config),
448+
);
449+
assert!(res.is_err());
361450
}
362451

363452
#[test]

lightning/src/ln/channelmanager.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8860,7 +8860,7 @@ This indicates a bug inside LDK. Please report this error at https://github.com/
88608860
// We can get the channel type at this point already as we'll need it immediately in both the
88618861
// manual and the automatic acceptance cases.
88628862
let channel_type = channel::channel_type_from_open_channel(
8863-
common_fields, &peer_state.latest_features, &self.channel_type_features()
8863+
common_fields, &self.channel_type_features()
88648864
).map_err(|e| MsgHandleErrInternal::from_chan_no_close(e, common_fields.temporary_channel_id))?;
88658865

88668866
// If we're doing manual acceptance checks on the channel, then defer creation until we're sure we want to accept.
@@ -14106,7 +14106,7 @@ pub fn provided_init_features(config: &UserConfig) -> InitFeatures {
1410614106
features.set_basic_mpp_optional();
1410714107
features.set_wumbo_optional();
1410814108
features.set_shutdown_any_segwit_optional();
14109-
features.set_channel_type_optional();
14109+
features.set_channel_type_required();
1411014110
features.set_scid_privacy_optional();
1411114111
features.set_zero_conf_optional();
1411214112
features.set_route_blinding_optional();

lightning/src/ln/msgs.rs

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -242,10 +242,8 @@ pub struct CommonOpenChannelFields {
242242
/// Optionally, a request to pre-set the to-channel-initiator output's scriptPubkey for when we
243243
/// collaboratively close
244244
pub shutdown_scriptpubkey: Option<ScriptBuf>,
245-
/// The channel type that this channel will represent
246-
///
247-
/// If this is `None`, we derive the channel type from the intersection of our
248-
/// feature bits with our counterparty's feature bits from the [`Init`] message.
245+
/// The channel type that this channel will represent. As defined in the latest
246+
/// specification, this field is required. However, it is an `Option` for legacy reasons.
249247
pub channel_type: Option<ChannelTypeFeatures>,
250248
}
251249

@@ -356,9 +354,8 @@ pub struct CommonAcceptChannelFields {
356354
/// Optionally, a request to pre-set the to-channel-acceptor output's scriptPubkey for when we
357355
/// collaboratively close
358356
pub shutdown_scriptpubkey: Option<ScriptBuf>,
359-
/// The channel type that this channel will represent. If none is set, we derive the channel
360-
/// type from the intersection of our feature bits with our counterparty's feature bits from
361-
/// the Init message.
357+
/// The channel type that this channel will represent. As defined in the latest
358+
/// specification, this field is required. However, it is an `Option` for legacy reasons.
362359
///
363360
/// This is required to match the equivalent field in [`OpenChannel`] or [`OpenChannelV2`]'s
364361
/// [`CommonOpenChannelFields::channel_type`].

0 commit comments

Comments
 (0)