Skip to content

Commit aba5092

Browse files
committed
Add Features::set_custom_bit
Custom message handlers may need to set feature bits that are unknown to LDK. Provide a Features::set_custom_bit to allow for this.
1 parent 6242c30 commit aba5092

File tree

1 file changed

+46
-0
lines changed

1 file changed

+46
-0
lines changed

lightning/src/ln/features.rs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -763,6 +763,32 @@ impl<T: sealed::Context> Features<T> {
763763
}
764764
true
765765
}
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+
}
766792
}
767793

768794
impl<T: sealed::UpfrontShutdownScript> Features<T> {
@@ -1001,6 +1027,26 @@ mod tests {
10011027
assert!(features.supports_payment_secret());
10021028
}
10031029

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+
10041050
#[test]
10051051
fn feature_difference() {
10061052
let mut features1 = InitFeatures::empty();

0 commit comments

Comments
 (0)