@@ -743,6 +743,32 @@ impl<T: sealed::Context> Features<T> {
743
743
}
744
744
true
745
745
}
746
+
747
+ /// Sets a custom feature bit. Errors if `bit` is outside the custom range as defined by
748
+ /// [bLIP 2] or if it is a known `T` feature.
749
+ ///
750
+ /// [bLIP 2]: https://github.com/lightning/blips/blob/master/blip-0002.md#feature-bits
751
+ pub fn set_custom_bit ( & mut self , bit : usize ) -> Result < ( ) , ( ) > {
752
+ if bit < 256 {
753
+ return Err ( ( ) ) ;
754
+ }
755
+
756
+ let byte_offset = bit / 8 ;
757
+ let mask = 1 << ( bit - 8 * byte_offset) ;
758
+ if byte_offset < T :: KNOWN_FEATURE_MASK . len ( ) {
759
+ if ( T :: KNOWN_FEATURE_MASK [ byte_offset] & mask) != 0 {
760
+ return Err ( ( ) ) ;
761
+ }
762
+ }
763
+
764
+ if self . flags . len ( ) <= byte_offset {
765
+ self . flags . resize ( byte_offset + 1 , 0u8 ) ;
766
+ }
767
+
768
+ self . flags [ byte_offset] |= mask;
769
+
770
+ Ok ( ( ) )
771
+ }
746
772
}
747
773
748
774
impl < T : sealed:: UpfrontShutdownScript > Features < T > {
@@ -944,6 +970,26 @@ mod tests {
944
970
assert ! ( features. supports_payment_secret( ) ) ;
945
971
}
946
972
973
+ #[ test]
974
+ fn set_custom_bits ( ) {
975
+ let mut features = InvoiceFeatures :: empty ( ) ;
976
+ features. set_variable_length_onion_optional ( ) ;
977
+ assert_eq ! ( features. flags[ 1 ] , 0b00000010 ) ;
978
+
979
+ assert ! ( features. set_custom_bit( 255 ) . is_err( ) ) ;
980
+ assert ! ( features. set_custom_bit( 256 ) . is_ok( ) ) ;
981
+ assert ! ( features. set_custom_bit( 258 ) . is_ok( ) ) ;
982
+ assert_eq ! ( features. flags[ 31 ] , 0b00000000 ) ;
983
+ assert_eq ! ( features. flags[ 32 ] , 0b00000101 ) ;
984
+
985
+ let known_bit = <sealed:: InvoiceContext as sealed:: PaymentSecret >:: EVEN_BIT ;
986
+ let byte_offset = <sealed:: InvoiceContext as sealed:: PaymentSecret >:: BYTE_OFFSET ;
987
+ assert_eq ! ( byte_offset, 1 ) ;
988
+ assert_eq ! ( features. flags[ byte_offset] , 0b00000010 ) ;
989
+ assert ! ( features. set_custom_bit( known_bit) . is_err( ) ) ;
990
+ assert_eq ! ( features. flags[ byte_offset] , 0b00000010 ) ;
991
+ }
992
+
947
993
#[ test]
948
994
fn feature_difference ( ) {
949
995
let mut features1 = InitFeatures :: empty ( ) ;
0 commit comments