@@ -442,6 +442,9 @@ mod sealed {
442
442
set_unknown_feature_required, supports_unknown_test_feature, requires_unknown_test_feature) ;
443
443
}
444
444
445
+ const ANY_REQUIRED_FEATURES_MASK : u8 = 0b01_01_01_01 ;
446
+ const ANY_OPTIONAL_FEATURES_MASK : u8 = 0b10_10_10_10 ;
447
+
445
448
/// Tracks the set of features which a node implements, templated by the context in which it
446
449
/// appears.
447
450
///
@@ -615,8 +618,8 @@ impl ChannelTypeFeatures {
615
618
// ChannelTypeFeatures must only contain required bits, so we OR the required forms of all
616
619
// optional bits and then AND out the optional ones.
617
620
for byte in ret. flags . iter_mut ( ) {
618
- * byte |= ( * byte & 0b10_10_10_10 ) >> 1 ;
619
- * byte &= 0b01_01_01_01 ;
621
+ * byte |= ( * byte & ANY_OPTIONAL_FEATURES_MASK ) >> 1 ;
622
+ * byte &= ANY_REQUIRED_FEATURES_MASK ;
620
623
}
621
624
ret
622
625
}
@@ -761,42 +764,51 @@ impl<T: sealed::Context> Features<T> {
761
764
}
762
765
763
766
pub ( crate ) fn supports_any_optional_bits ( & self ) -> bool {
764
- self . flags . iter ( ) . any ( |& byte| ( byte & 0b10_10_10_10 ) != 0 )
767
+ self . flags . iter ( ) . any ( |& byte| ( byte & ANY_OPTIONAL_FEATURES_MASK ) != 0 )
765
768
}
766
769
767
770
/// Returns true if this `Features` object contains required features unknown by `other`.
768
771
pub fn requires_unknown_bits_from ( & self , other : & Self ) -> bool {
769
772
// Bitwise AND-ing with all even bits set except for known features will select required
770
773
// unknown features.
771
774
self . flags . iter ( ) . enumerate ( ) . any ( |( i, & byte) | {
772
- const REQUIRED_FEATURES : u8 = 0b01_01_01_01 ;
773
- const OPTIONAL_FEATURES : u8 = 0b10_10_10_10 ;
774
- let unknown_features = if i < other. flags . len ( ) {
775
- // Form a mask similar to !T::KNOWN_FEATURE_MASK only for `other`
776
- !( other. flags [ i]
777
- | ( ( other. flags [ i] >> 1 ) & REQUIRED_FEATURES )
778
- | ( ( other. flags [ i] << 1 ) & OPTIONAL_FEATURES ) )
779
- } else {
780
- 0b11_11_11_11
781
- } ;
782
- ( byte & ( REQUIRED_FEATURES & unknown_features) ) != 0
775
+ let unknown_features = unset_features_mask_at_position ( other, i) ;
776
+ ( byte & ( ANY_REQUIRED_FEATURES_MASK & unknown_features) ) != 0
783
777
} )
784
778
}
785
779
780
+ pub ( crate ) fn required_unknown_bits_from ( & self , other : & Self ) -> Vec < usize > {
781
+ let mut unknown_bits = Vec :: new ( ) ;
782
+
783
+ // Bitwise AND-ing with all even bits set except for known features will select required
784
+ // unknown features.
785
+ self . flags . iter ( ) . enumerate ( ) . for_each ( |( i, & byte) | {
786
+ let unknown_features = unset_features_mask_at_position ( other, i) ;
787
+ if byte & unknown_features != 0 {
788
+ for bit in ( 0 ..8 ) . step_by ( 2 ) {
789
+ if ( ( byte & unknown_features) >> bit) & 1 == 1 {
790
+ unknown_bits. push ( i * 8 + bit) ;
791
+ }
792
+ }
793
+ }
794
+ } ) ;
795
+
796
+ unknown_bits
797
+ }
798
+
786
799
/// Returns true if this `Features` object contains unknown feature flags which are set as
787
800
/// "required".
788
801
pub fn requires_unknown_bits ( & self ) -> bool {
789
802
// Bitwise AND-ing with all even bits set except for known features will select required
790
803
// unknown features.
791
804
let byte_count = T :: KNOWN_FEATURE_MASK . len ( ) ;
792
805
self . flags . iter ( ) . enumerate ( ) . any ( |( i, & byte) | {
793
- let required_features = 0b01_01_01_01 ;
794
806
let unknown_features = if i < byte_count {
795
807
!T :: KNOWN_FEATURE_MASK [ i]
796
808
} else {
797
809
0b11_11_11_11
798
810
} ;
799
- ( byte & ( required_features & unknown_features) ) != 0
811
+ ( byte & ( ANY_REQUIRED_FEATURES_MASK & unknown_features) ) != 0
800
812
} )
801
813
}
802
814
@@ -1017,6 +1029,17 @@ impl<T: sealed::Context> Readable for WithoutLength<Features<T>> {
1017
1029
}
1018
1030
}
1019
1031
1032
+ pub ( crate ) fn unset_features_mask_at_position < T : sealed:: Context > ( other : & Features < T > , index : usize ) -> u8 {
1033
+ if index < other. flags . len ( ) {
1034
+ // Form a mask similar to !T::KNOWN_FEATURE_MASK only for `other`
1035
+ !( other. flags [ index]
1036
+ | ( ( other. flags [ index] >> 1 ) & ANY_REQUIRED_FEATURES_MASK )
1037
+ | ( ( other. flags [ index] << 1 ) & ANY_OPTIONAL_FEATURES_MASK ) )
1038
+ } else {
1039
+ 0b11_11_11_11
1040
+ }
1041
+ }
1042
+
1020
1043
#[ cfg( test) ]
1021
1044
mod tests {
1022
1045
use super :: { ChannelFeatures , ChannelTypeFeatures , InitFeatures , Bolt11InvoiceFeatures , NodeFeatures , OfferFeatures , sealed} ;
@@ -1033,11 +1056,24 @@ mod tests {
1033
1056
features. set_unknown_feature_required ( ) ;
1034
1057
assert ! ( features. requires_unknown_bits( ) ) ;
1035
1058
assert ! ( features. supports_unknown_bits( ) ) ;
1059
+ assert_eq ! ( features. required_unknown_bits_from( & ChannelFeatures :: empty( ) ) , vec![ 123456788 ] ) ;
1036
1060
1037
1061
let mut features = ChannelFeatures :: empty ( ) ;
1038
1062
features. set_unknown_feature_optional ( ) ;
1039
1063
assert ! ( !features. requires_unknown_bits( ) ) ;
1040
1064
assert ! ( features. supports_unknown_bits( ) ) ;
1065
+ assert_eq ! ( features. required_unknown_bits_from( & ChannelFeatures :: empty( ) ) , vec![ ] ) ;
1066
+
1067
+ let mut features = ChannelFeatures :: empty ( ) ;
1068
+ features. set_unknown_feature_required ( ) ;
1069
+ features. set_custom_bit ( 123456786 ) . unwrap ( ) ;
1070
+ assert ! ( features. requires_unknown_bits( ) ) ;
1071
+ assert ! ( features. supports_unknown_bits( ) ) ;
1072
+ assert_eq ! ( features. required_unknown_bits_from( & ChannelFeatures :: empty( ) ) , vec![ 123456786 , 123456788 ] ) ;
1073
+
1074
+ let mut limiter = ChannelFeatures :: empty ( ) ;
1075
+ limiter. set_unknown_feature_optional ( ) ;
1076
+ assert_eq ! ( features. required_unknown_bits_from( & limiter) , vec![ 123456786 ] ) ;
1041
1077
}
1042
1078
1043
1079
#[ test]
0 commit comments