@@ -695,6 +695,26 @@ impl<T: sealed::Context> Features<T> {
695
695
self . flags . iter ( ) . any ( |& byte| ( byte & 0b10_10_10_10 ) != 0 )
696
696
}
697
697
698
+ /// Returns true if this `Features` object contains required features unknown by `other`.
699
+ pub fn requires_unknown_bits_from ( & self , other : & Features < T > ) -> bool {
700
+ // Bitwise AND-ing with all even bits set except for known features will select required
701
+ // unknown features.
702
+ let byte_count = other. flags . len ( ) ;
703
+ self . flags . iter ( ) . enumerate ( ) . any ( |( i, & byte) | {
704
+ let required_features = 0b01_01_01_01 ;
705
+ let optional_features = 0b10_10_10_10 ;
706
+ let unknown_features = if i < byte_count {
707
+ // Form a mask similar to !T::KNOWN_FEATURE_MASK only for `other`
708
+ !( other. flags [ i]
709
+ | ( ( other. flags [ i] >> 1 ) & required_features)
710
+ | ( ( other. flags [ i] << 1 ) & optional_features) )
711
+ } else {
712
+ 0b11_11_11_11
713
+ } ;
714
+ ( byte & ( required_features & unknown_features) ) != 0
715
+ } )
716
+ }
717
+
698
718
/// Returns true if this `Features` object contains unknown feature flags which are set as
699
719
/// "required".
700
720
pub fn requires_unknown_bits ( & self ) -> bool {
@@ -868,6 +888,43 @@ mod tests {
868
888
assert ! ( features. supports_unknown_bits( ) ) ;
869
889
}
870
890
891
+ #[ test]
892
+ fn requires_unknown_bits_from ( ) {
893
+ let mut features1 = InitFeatures :: empty ( ) ;
894
+ let mut features2 = InitFeatures :: empty ( ) ;
895
+ assert ! ( !features1. requires_unknown_bits_from( & features2) ) ;
896
+ assert ! ( !features2. requires_unknown_bits_from( & features1) ) ;
897
+
898
+ features1. set_data_loss_protect_required ( ) ;
899
+ assert ! ( features1. requires_unknown_bits_from( & features2) ) ;
900
+ assert ! ( !features2. requires_unknown_bits_from( & features1) ) ;
901
+
902
+ features2. set_data_loss_protect_optional ( ) ;
903
+ assert ! ( !features1. requires_unknown_bits_from( & features2) ) ;
904
+ assert ! ( !features2. requires_unknown_bits_from( & features1) ) ;
905
+
906
+ features2. set_gossip_queries_required ( ) ;
907
+ assert ! ( !features1. requires_unknown_bits_from( & features2) ) ;
908
+ assert ! ( features2. requires_unknown_bits_from( & features1) ) ;
909
+
910
+ features1. set_gossip_queries_optional ( ) ;
911
+ assert ! ( !features1. requires_unknown_bits_from( & features2) ) ;
912
+ assert ! ( !features2. requires_unknown_bits_from( & features1) ) ;
913
+
914
+ features1. set_variable_length_onion_required ( ) ;
915
+ assert ! ( features1. requires_unknown_bits_from( & features2) ) ;
916
+ assert ! ( !features2. requires_unknown_bits_from( & features1) ) ;
917
+
918
+ features2. set_variable_length_onion_optional ( ) ;
919
+ assert ! ( !features1. requires_unknown_bits_from( & features2) ) ;
920
+ assert ! ( !features2. requires_unknown_bits_from( & features1) ) ;
921
+
922
+ features1. set_basic_mpp_required ( ) ;
923
+ features2. set_wumbo_required ( ) ;
924
+ assert ! ( features1. requires_unknown_bits_from( & features2) ) ;
925
+ assert ! ( features2. requires_unknown_bits_from( & features1) ) ;
926
+ }
927
+
871
928
#[ test]
872
929
fn convert_to_context_with_relevant_flags ( ) {
873
930
let mut init_features = InitFeatures :: empty ( ) ;
0 commit comments