supported_feature_set |= additional_permitted_features;
}
- if !features.is_subset(&supported_feature_set) {
+ if features.requires_unknown_bits_from(&supported_feature_set) {
return Err(DecodeError::UnknownRequiredFeature);
}
}
legacy_version_bit_set.set_scid_privacy_required();
legacy_version_bit_set.set_zero_conf_required();
- if features.is_subset(&legacy_version_bit_set) {
- None
- } else {
+ debug_assert!(!legacy_version_bit_set.supports_any_optional_bits());
+ debug_assert!(!features.supports_any_optional_bits());
+ if features.requires_unknown_bits_from(&legacy_version_bit_set) {
Some(())
+ } else {
+ None
}
}
}
let channel_type = get_initial_channel_type(&config, their_features);
- debug_assert!(channel_type.is_subset(&channelmanager::provided_channel_type_features(&config)));
+ debug_assert!(!channel_type.supports_any_optional_bits());
+ debug_assert!(!channel_type.requires_unknown_bits_from(&channelmanager::provided_channel_type_features(&config)));
let (commitment_conf_target, anchor_outputs_value_msat) = if channel_type.supports_anchors_zero_fee_htlc_tx() {
(ConfirmationTarget::AnchorChannelFee, ANCHOR_OUTPUT_VALUE_SATOSHI * 2 * 1000)
return Err(ChannelError::close("Channel Type was not understood - we require static remote key".to_owned()));
}
// Make sure we support all of the features behind the channel type.
- if !channel_type.is_subset(our_supported_features) {
+ if channel_type.requires_unknown_bits_from(&our_supported_features) {
return Err(ChannelError::close("Channel Type contains unsupported features".to_owned()));
}
let announced_channel = if (common_fields.channel_flags & 1) == 1 { true } else { false };
}
let chan_features = channel_type.as_ref().unwrap();
- if !chan_features.is_subset(our_supported_features) {
+ if chan_features.supports_any_optional_bits() || chan_features.requires_unknown_bits_from(&our_supported_features) {
// If the channel was written by a new version and negotiated with features we don't
// understand yet, refuse to read it.
return Err(DecodeError::UnknownRequiredFeature);
})
}
- // Returns true if the features within `self` are a subset of the features within `other`.
- pub(crate) fn is_subset(&self, other: &Self) -> bool {
- for (idx, byte) in self.flags.iter().enumerate() {
- if let Some(other_byte) = other.flags.get(idx) {
- if byte & other_byte != *byte {
- // `self` has bits set that `other` doesn't.
- return false;
- }
- } else {
- if *byte > 0 {
- // `self` has a non-zero byte that `other` doesn't.
- return false;
- }
- }
- }
- true
- }
-
/// Sets a required feature bit. Errors if `bit` is outside the feature range as defined
/// by [BOLT 9].
///