@@ -747,11 +747,29 @@ impl<T: sealed::Context> Features<T> {
747
747
true
748
748
}
749
749
750
- /// Sets a custom feature bit. Errors if `bit` is outside the custom range as defined by
751
- /// [bLIP 2] or if it is a known `T` feature.
750
+ /// Sets a required custom feature bit. Errors if `bit` is outside the custom range as defined
751
+ /// by [bLIP 2] or if it is a known `T` feature.
752
+ ///
753
+ /// Note: Required bits are even. If an odd bit is given, then the corresponding even bit will
754
+ /// be set instead (i.e., `bit - 1`).
752
755
///
753
756
/// [bLIP 2]: https://github.com/lightning/blips/blob/master/blip-0002.md#feature-bits
754
- pub fn set_custom_bit ( & mut self , bit : usize ) -> Result < ( ) , ( ) > {
757
+ pub fn set_required_custom_bit ( & mut self , bit : usize ) -> Result < ( ) , ( ) > {
758
+ self . set_custom_bit ( bit - ( bit % 2 ) )
759
+ }
760
+
761
+ /// Sets an optional custom feature bit. Errors if `bit` is outside the custom range as defined
762
+ /// by [bLIP 2] or if it is a known `T` feature.
763
+ ///
764
+ /// Note: Optional bits are odd. If an even bit is given, then the corresponding odd bit will be
765
+ /// set instead (i.e., `bit + 1`).
766
+ ///
767
+ /// [bLIP 2]: https://github.com/lightning/blips/blob/master/blip-0002.md#feature-bits
768
+ pub fn set_optional_custom_bit ( & mut self , bit : usize ) -> Result < ( ) , ( ) > {
769
+ self . set_custom_bit ( bit + ( 1 - ( bit % 2 ) ) )
770
+ }
771
+
772
+ fn set_custom_bit ( & mut self , bit : usize ) -> Result < ( ) , ( ) > {
755
773
if bit < 256 {
756
774
return Err ( ( ) ) ;
757
775
}
@@ -1016,18 +1034,28 @@ mod tests {
1016
1034
features. set_variable_length_onion_optional ( ) ;
1017
1035
assert_eq ! ( features. flags[ 1 ] , 0b00000010 ) ;
1018
1036
1019
- assert ! ( features. set_custom_bit ( 255 ) . is_err( ) ) ;
1020
- assert ! ( features. set_custom_bit ( 256 ) . is_ok( ) ) ;
1021
- assert ! ( features. set_custom_bit ( 258 ) . is_ok( ) ) ;
1037
+ assert ! ( features. set_optional_custom_bit ( 255 ) . is_err( ) ) ;
1038
+ assert ! ( features. set_required_custom_bit ( 256 ) . is_ok( ) ) ;
1039
+ assert ! ( features. set_required_custom_bit ( 258 ) . is_ok( ) ) ;
1022
1040
assert_eq ! ( features. flags[ 31 ] , 0b00000000 ) ;
1023
1041
assert_eq ! ( features. flags[ 32 ] , 0b00000101 ) ;
1024
1042
1025
1043
let known_bit = <sealed:: InvoiceContext as sealed:: PaymentSecret >:: EVEN_BIT ;
1026
1044
let byte_offset = <sealed:: InvoiceContext as sealed:: PaymentSecret >:: BYTE_OFFSET ;
1027
1045
assert_eq ! ( byte_offset, 1 ) ;
1028
1046
assert_eq ! ( features. flags[ byte_offset] , 0b00000010 ) ;
1029
- assert ! ( features. set_custom_bit ( known_bit) . is_err( ) ) ;
1047
+ assert ! ( features. set_required_custom_bit ( known_bit) . is_err( ) ) ;
1030
1048
assert_eq ! ( features. flags[ byte_offset] , 0b00000010 ) ;
1049
+
1050
+ let mut features = InvoiceFeatures :: empty ( ) ;
1051
+ assert ! ( features. set_optional_custom_bit( 256 ) . is_ok( ) ) ;
1052
+ assert ! ( features. set_optional_custom_bit( 259 ) . is_ok( ) ) ;
1053
+ assert_eq ! ( features. flags[ 32 ] , 0b00001010 ) ;
1054
+
1055
+ let mut features = InvoiceFeatures :: empty ( ) ;
1056
+ assert ! ( features. set_required_custom_bit( 257 ) . is_ok( ) ) ;
1057
+ assert ! ( features. set_required_custom_bit( 258 ) . is_ok( ) ) ;
1058
+ assert_eq ! ( features. flags[ 32 ] , 0b00000101 ) ;
1031
1059
}
1032
1060
1033
1061
#[ test]
0 commit comments