@@ -679,6 +679,25 @@ impl<T: sealed::Context> Features<T> {
679679 self . flags . iter ( ) . any ( |& byte| ( byte & 0b10_10_10_10 ) != 0 )
680680 }
681681
682+ /// Returns true if this `Features` object contains required features unknown by `other`.
683+ pub fn requires_unknown_bits_from ( & self , other : & Features < T > ) -> bool {
684+ // Bitwise AND-ing with all even bits set except for known features will select required
685+ // unknown features.
686+ self . flags . iter ( ) . enumerate ( ) . any ( |( i, & byte) | {
687+ const REQUIRED_FEATURES : u8 = 0b01_01_01_01 ;
688+ const OPTIONAL_FEATURES : u8 = 0b10_10_10_10 ;
689+ let unknown_features = if i < other. flags . len ( ) {
690+ // Form a mask similar to !T::KNOWN_FEATURE_MASK only for `other`
691+ !( other. flags [ i]
692+ | ( ( other. flags [ i] >> 1 ) & REQUIRED_FEATURES )
693+ | ( ( other. flags [ i] << 1 ) & OPTIONAL_FEATURES ) )
694+ } else {
695+ 0b11_11_11_11
696+ } ;
697+ ( byte & ( REQUIRED_FEATURES & unknown_features) ) != 0
698+ } )
699+ }
700+
682701 /// Returns true if this `Features` object contains unknown feature flags which are set as
683702 /// "required".
684703 pub fn requires_unknown_bits ( & self ) -> bool {
@@ -852,6 +871,43 @@ mod tests {
852871 assert ! ( features. supports_unknown_bits( ) ) ;
853872 }
854873
874+ #[ test]
875+ fn requires_unknown_bits_from ( ) {
876+ let mut features1 = InitFeatures :: empty ( ) ;
877+ let mut features2 = InitFeatures :: empty ( ) ;
878+ assert ! ( !features1. requires_unknown_bits_from( & features2) ) ;
879+ assert ! ( !features2. requires_unknown_bits_from( & features1) ) ;
880+
881+ features1. set_data_loss_protect_required ( ) ;
882+ assert ! ( features1. requires_unknown_bits_from( & features2) ) ;
883+ assert ! ( !features2. requires_unknown_bits_from( & features1) ) ;
884+
885+ features2. set_data_loss_protect_optional ( ) ;
886+ assert ! ( !features1. requires_unknown_bits_from( & features2) ) ;
887+ assert ! ( !features2. requires_unknown_bits_from( & features1) ) ;
888+
889+ features2. set_gossip_queries_required ( ) ;
890+ assert ! ( !features1. requires_unknown_bits_from( & features2) ) ;
891+ assert ! ( features2. requires_unknown_bits_from( & features1) ) ;
892+
893+ features1. set_gossip_queries_optional ( ) ;
894+ assert ! ( !features1. requires_unknown_bits_from( & features2) ) ;
895+ assert ! ( !features2. requires_unknown_bits_from( & features1) ) ;
896+
897+ features1. set_variable_length_onion_required ( ) ;
898+ assert ! ( features1. requires_unknown_bits_from( & features2) ) ;
899+ assert ! ( !features2. requires_unknown_bits_from( & features1) ) ;
900+
901+ features2. set_variable_length_onion_optional ( ) ;
902+ assert ! ( !features1. requires_unknown_bits_from( & features2) ) ;
903+ assert ! ( !features2. requires_unknown_bits_from( & features1) ) ;
904+
905+ features1. set_basic_mpp_required ( ) ;
906+ features2. set_wumbo_required ( ) ;
907+ assert ! ( features1. requires_unknown_bits_from( & features2) ) ;
908+ assert ! ( features2. requires_unknown_bits_from( & features1) ) ;
909+ }
910+
855911 #[ test]
856912 fn convert_to_context_with_relevant_flags ( ) {
857913 let mut init_features = InitFeatures :: empty ( ) ;
0 commit comments