X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Fln%2Ffeatures.rs;h=51c608c1a6b47231762bbb35627032dcf33d19bc;hb=refs%2Fheads%2Fupstream%2Fmain;hp=9dcac57888a4dc6416660cb41eef35669dcae8e3;hpb=158ef6ffe3d347c1ea736d7ee1e1f8034b20725b;p=rust-lightning diff --git a/lightning/src/ln/features.rs b/lightning/src/ln/features.rs index 9dcac578..51c608c1 100644 --- a/lightning/src/ln/features.rs +++ b/lightning/src/ln/features.rs @@ -87,8 +87,7 @@ use core::borrow::Borrow; use core::hash::{Hash, Hasher}; use core::marker::PhantomData; -use bitcoin::bech32; -use bitcoin::bech32::{Base32Len, FromBase32, ToBase32, u5, WriteBase32}; +use bech32::{Base32Len, FromBase32, ToBase32, u5, WriteBase32}; use crate::ln::msgs::DecodeError; use crate::util::ser::{Readable, WithoutLength, Writeable, Writer}; @@ -443,6 +442,9 @@ mod sealed { set_unknown_feature_required, supports_unknown_test_feature, requires_unknown_test_feature); } +const ANY_REQUIRED_FEATURES_MASK: u8 = 0b01_01_01_01; +const ANY_OPTIONAL_FEATURES_MASK: u8 = 0b10_10_10_10; + /// Tracks the set of features which a node implements, templated by the context in which it /// appears. /// @@ -616,8 +618,8 @@ impl ChannelTypeFeatures { // ChannelTypeFeatures must only contain required bits, so we OR the required forms of all // optional bits and then AND out the optional ones. for byte in ret.flags.iter_mut() { - *byte |= (*byte & 0b10_10_10_10) >> 1; - *byte &= 0b01_01_01_01; + *byte |= (*byte & ANY_OPTIONAL_FEATURES_MASK) >> 1; + *byte &= ANY_REQUIRED_FEATURES_MASK; } ret } @@ -762,7 +764,7 @@ impl Features { } pub(crate) fn supports_any_optional_bits(&self) -> bool { - self.flags.iter().any(|&byte| (byte & 0b10_10_10_10) != 0) + self.flags.iter().any(|&byte| (byte & ANY_OPTIONAL_FEATURES_MASK) != 0) } /// Returns true if this `Features` object contains required features unknown by `other`. @@ -770,17 +772,8 @@ impl Features { // Bitwise AND-ing with all even bits set except for known features will select required // unknown features. self.flags.iter().enumerate().any(|(i, &byte)| { - const REQUIRED_FEATURES: u8 = 0b01_01_01_01; - const OPTIONAL_FEATURES: u8 = 0b10_10_10_10; - let unknown_features = if i < other.flags.len() { - // Form a mask similar to !T::KNOWN_FEATURE_MASK only for `other` - !(other.flags[i] - | ((other.flags[i] >> 1) & REQUIRED_FEATURES) - | ((other.flags[i] << 1) & OPTIONAL_FEATURES)) - } else { - 0b11_11_11_11 - }; - (byte & (REQUIRED_FEATURES & unknown_features)) != 0 + let unknown_features = unset_features_mask_at_position(other, i); + (byte & (ANY_REQUIRED_FEATURES_MASK & unknown_features)) != 0 }) } @@ -790,17 +783,7 @@ impl Features { // Bitwise AND-ing with all even bits set except for known features will select required // unknown features. self.flags.iter().enumerate().for_each(|(i, &byte)| { - const REQUIRED_FEATURES: u8 = 0b01_01_01_01; - const OPTIONAL_FEATURES: u8 = 0b10_10_10_10; - let unknown_features = if i < other.flags.len() { - // Form a mask similar to !T::KNOWN_FEATURE_MASK only for `other` - !(other.flags[i] - | ((other.flags[i] >> 1) & REQUIRED_FEATURES) - | ((other.flags[i] << 1) & OPTIONAL_FEATURES)) - } else { - 0b11_11_11_11 - }; - + let unknown_features = unset_features_mask_at_position(other, i); if byte & unknown_features != 0 { for bit in (0..8).step_by(2) { if ((byte & unknown_features) >> bit) & 1 == 1 { @@ -820,13 +803,12 @@ impl Features { // unknown features. let byte_count = T::KNOWN_FEATURE_MASK.len(); self.flags.iter().enumerate().any(|(i, &byte)| { - let required_features = 0b01_01_01_01; let unknown_features = if i < byte_count { !T::KNOWN_FEATURE_MASK[i] } else { 0b11_11_11_11 }; - (byte & (required_features & unknown_features)) != 0 + (byte & (ANY_REQUIRED_FEATURES_MASK & unknown_features)) != 0 }) } @@ -1047,10 +1029,21 @@ impl Readable for WithoutLength> { } } +pub(crate) fn unset_features_mask_at_position(other: &Features, index: usize) -> u8 { + if index < other.flags.len() { + // Form a mask similar to !T::KNOWN_FEATURE_MASK only for `other` + !(other.flags[index] + | ((other.flags[index] >> 1) & ANY_REQUIRED_FEATURES_MASK) + | ((other.flags[index] << 1) & ANY_OPTIONAL_FEATURES_MASK)) + } else { + 0b11_11_11_11 + } +} + #[cfg(test)] mod tests { use super::{ChannelFeatures, ChannelTypeFeatures, InitFeatures, Bolt11InvoiceFeatures, NodeFeatures, OfferFeatures, sealed}; - use bitcoin::bech32::{Base32Len, FromBase32, ToBase32, u5}; + use bech32::{Base32Len, FromBase32, ToBase32, u5}; use crate::util::ser::{Readable, WithoutLength, Writeable}; #[test]