Skip to content

Commit e9d9711

Browse files
authored
Merge pull request #2522 from sr-gi/202308-set-feature
Adds a set of convenience methods to set non-custom features
2 parents ef8945e + 992f102 commit e9d9711

File tree

1 file changed

+40
-1
lines changed

1 file changed

+40
-1
lines changed

lightning/src/ln/features.rs

+40-1
Original file line numberDiff line numberDiff line change
@@ -798,6 +798,35 @@ impl<T: sealed::Context> Features<T> {
798798
true
799799
}
800800

801+
/// Sets a required feature bit. Errors if `bit` is outside the feature range as defined
802+
/// by [BOLT 9].
803+
///
804+
/// Note: Required bits are even. If an odd bit is given, then the corresponding even bit will
805+
/// be set instead (i.e., `bit - 1`).
806+
///
807+
/// [BOLT 9]: https://github.com/lightning/bolts/blob/master/09-features.md
808+
pub fn set_required_feature_bit(&mut self, bit: usize) -> Result<(), ()> {
809+
self.set_feature_bit(bit - (bit % 2))
810+
}
811+
812+
/// Sets an optional feature bit. Errors if `bit` is outside the feature range as defined
813+
/// by [BOLT 9].
814+
///
815+
/// Note: Optional bits are odd. If an even bit is given, then the corresponding odd bit will be
816+
/// set instead (i.e., `bit + 1`).
817+
///
818+
/// [BOLT 9]: https://github.com/lightning/bolts/blob/master/09-features.md
819+
pub fn set_optional_feature_bit(&mut self, bit: usize) -> Result<(), ()> {
820+
self.set_feature_bit(bit + (1 - (bit % 2)))
821+
}
822+
823+
fn set_feature_bit(&mut self, bit: usize) -> Result<(), ()> {
824+
if bit > 255 {
825+
return Err(());
826+
}
827+
self.set_bit(bit, false)
828+
}
829+
801830
/// Sets a required custom feature bit. Errors if `bit` is outside the custom range as defined
802831
/// by [bLIP 2] or if it is a known `T` feature.
803832
///
@@ -824,10 +853,13 @@ impl<T: sealed::Context> Features<T> {
824853
if bit < 256 {
825854
return Err(());
826855
}
856+
self.set_bit(bit, true)
857+
}
827858

859+
fn set_bit(&mut self, bit: usize, custom: bool) -> Result<(), ()> {
828860
let byte_offset = bit / 8;
829861
let mask = 1 << (bit - 8 * byte_offset);
830-
if byte_offset < T::KNOWN_FEATURE_MASK.len() {
862+
if byte_offset < T::KNOWN_FEATURE_MASK.len() && custom {
831863
if (T::KNOWN_FEATURE_MASK[byte_offset] & mask) != 0 {
832864
return Err(());
833865
}
@@ -1078,6 +1110,13 @@ mod tests {
10781110
assert!(!features.requires_basic_mpp());
10791111
assert!(features.requires_payment_secret());
10801112
assert!(features.supports_payment_secret());
1113+
1114+
// Set flags manually
1115+
let mut features = NodeFeatures::empty();
1116+
assert!(features.set_optional_feature_bit(55).is_ok());
1117+
assert!(features.supports_keysend());
1118+
assert!(features.set_optional_feature_bit(255).is_ok());
1119+
assert!(features.set_required_feature_bit(256).is_err());
10811120
}
10821121

10831122
#[test]

0 commit comments

Comments
 (0)