@@ -747,11 +747,29 @@ impl<T: sealed::Context> Features<T> {
747747 true
748748 }
749749
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`).
752755 ///
753756 /// [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 < ( ) , ( ) > {
755773 if bit < 256 {
756774 return Err ( ( ) ) ;
757775 }
@@ -1016,18 +1034,28 @@ mod tests {
10161034 features. set_variable_length_onion_optional ( ) ;
10171035 assert_eq ! ( features. flags[ 1 ] , 0b00000010 ) ;
10181036
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( ) ) ;
10221040 assert_eq ! ( features. flags[ 31 ] , 0b00000000 ) ;
10231041 assert_eq ! ( features. flags[ 32 ] , 0b00000101 ) ;
10241042
10251043 let known_bit = <sealed:: InvoiceContext as sealed:: PaymentSecret >:: EVEN_BIT ;
10261044 let byte_offset = <sealed:: InvoiceContext as sealed:: PaymentSecret >:: BYTE_OFFSET ;
10271045 assert_eq ! ( byte_offset, 1 ) ;
10281046 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( ) ) ;
10301048 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 ) ;
10311059 }
10321060
10331061 #[ test]
0 commit comments