@@ -763,6 +763,32 @@ impl<T: sealed::Context> Features<T> {
763
763
}
764
764
true
765
765
}
766
+
767
+ /// Sets a custom feature bit. Errors if `bit` is outside the custom range as defined by
768
+ /// [bLIP 2] or if it is a known `T` feature.
769
+ ///
770
+ /// [bLIP 2]: https://github.com/lightning/blips/blob/master/blip-0002.md#feature-bits
771
+ pub fn set_custom_bit ( & mut self , bit : usize ) -> Result < ( ) , ( ) > {
772
+ if bit < 256 {
773
+ return Err ( ( ) ) ;
774
+ }
775
+
776
+ let byte_offset = bit / 8 ;
777
+ let mask = 1 << ( bit - 8 * byte_offset) ;
778
+ if byte_offset < T :: KNOWN_FEATURE_MASK . len ( ) {
779
+ if ( T :: KNOWN_FEATURE_MASK [ byte_offset] & mask) != 0 {
780
+ return Err ( ( ) ) ;
781
+ }
782
+ }
783
+
784
+ if self . flags . len ( ) <= byte_offset {
785
+ self . flags . resize ( byte_offset + 1 , 0u8 ) ;
786
+ }
787
+
788
+ self . flags [ byte_offset] |= mask;
789
+
790
+ Ok ( ( ) )
791
+ }
766
792
}
767
793
768
794
impl < T : sealed:: UpfrontShutdownScript > Features < T > {
@@ -1001,6 +1027,26 @@ mod tests {
1001
1027
assert ! ( features. supports_payment_secret( ) ) ;
1002
1028
}
1003
1029
1030
+ #[ test]
1031
+ fn set_custom_bits ( ) {
1032
+ let mut features = InvoiceFeatures :: empty ( ) ;
1033
+ features. set_variable_length_onion_optional ( ) ;
1034
+ assert_eq ! ( features. flags[ 1 ] , 0b00000010 ) ;
1035
+
1036
+ assert ! ( features. set_custom_bit( 255 ) . is_err( ) ) ;
1037
+ assert ! ( features. set_custom_bit( 256 ) . is_ok( ) ) ;
1038
+ assert ! ( features. set_custom_bit( 258 ) . is_ok( ) ) ;
1039
+ assert_eq ! ( features. flags[ 31 ] , 0b00000000 ) ;
1040
+ assert_eq ! ( features. flags[ 32 ] , 0b00000101 ) ;
1041
+
1042
+ let known_bit = <sealed:: InvoiceContext as sealed:: PaymentSecret >:: EVEN_BIT ;
1043
+ let byte_offset = <sealed:: InvoiceContext as sealed:: PaymentSecret >:: BYTE_OFFSET ;
1044
+ assert_eq ! ( byte_offset, 1 ) ;
1045
+ assert_eq ! ( features. flags[ byte_offset] , 0b00000010 ) ;
1046
+ assert ! ( features. set_custom_bit( known_bit) . is_err( ) ) ;
1047
+ assert_eq ! ( features. flags[ byte_offset] , 0b00000010 ) ;
1048
+ }
1049
+
1004
1050
#[ test]
1005
1051
fn feature_difference ( ) {
1006
1052
let mut features1 = InitFeatures :: empty ( ) ;
0 commit comments