X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Fln%2Ffeatures.rs;h=bcaa91ab266fe7f10ebbc8de710fc30d927365c3;hb=bf9144039cccb30d269c899f69de6a0c366f041f;hp=6309eea413adb4d913c45379baad6eca16bdeb83;hpb=8c4a85b35700d0e4b254c31a8d3171b14140038a;p=rust-lightning diff --git a/lightning/src/ln/features.rs b/lightning/src/ln/features.rs index 6309eea4..bcaa91ab 100644 --- a/lightning/src/ln/features.rs +++ b/lightning/src/ln/features.rs @@ -143,7 +143,7 @@ mod sealed { // Byte 2 BasicMPP | Wumbo | AnchorsNonzeroFeeHtlcTx | AnchorsZeroFeeHtlcTx, // Byte 3 - ShutdownAnySegwit, + ShutdownAnySegwit | Taproot, // Byte 4 OnionMessages, // Byte 5 @@ -159,7 +159,7 @@ mod sealed { // Byte 2 BasicMPP | Wumbo | AnchorsNonzeroFeeHtlcTx | AnchorsZeroFeeHtlcTx, // Byte 3 - ShutdownAnySegwit, + ShutdownAnySegwit | Taproot, // Byte 4 OnionMessages, // Byte 5 @@ -205,7 +205,7 @@ mod sealed { // Byte 2 AnchorsNonzeroFeeHtlcTx | AnchorsZeroFeeHtlcTx, // Byte 3 - , + Taproot, // Byte 4 , // Byte 5 @@ -394,6 +394,9 @@ mod sealed { define_feature!(27, ShutdownAnySegwit, [InitContext, NodeContext], "Feature flags for `opt_shutdown_anysegwit`.", set_shutdown_any_segwit_optional, set_shutdown_any_segwit_required, supports_shutdown_anysegwit, requires_shutdown_anysegwit); + define_feature!(31, Taproot, [InitContext, NodeContext, ChannelTypeContext], + "Feature flags for `option_taproot`.", set_taproot_optional, + set_taproot_required, supports_taproot, requires_taproot); define_feature!(39, OnionMessages, [InitContext, NodeContext], "Feature flags for `option_onion_messages`.", set_onion_messages_optional, set_onion_messages_required, supports_onion_messages, requires_onion_messages); @@ -728,7 +731,7 @@ impl Features { } /// Returns true if this `Features` object contains required features unknown by `other`. - pub fn requires_unknown_bits_from(&self, other: &Features) -> bool { + pub fn requires_unknown_bits_from(&self, other: &Self) -> bool { // Bitwise AND-ing with all even bits set except for known features will select required // unknown features. self.flags.iter().enumerate().any(|(i, &byte)| { @@ -795,6 +798,35 @@ impl Features { true } + /// Sets a required feature bit. Errors if `bit` is outside the feature range as defined + /// by [BOLT 9]. + /// + /// Note: Required bits are even. If an odd bit is given, then the corresponding even bit will + /// be set instead (i.e., `bit - 1`). + /// + /// [BOLT 9]: https://github.com/lightning/bolts/blob/master/09-features.md + pub fn set_required_feature_bit(&mut self, bit: usize) -> Result<(), ()> { + self.set_feature_bit(bit - (bit % 2)) + } + + /// Sets an optional feature bit. Errors if `bit` is outside the feature range as defined + /// by [BOLT 9]. + /// + /// Note: Optional bits are odd. If an even bit is given, then the corresponding odd bit will be + /// set instead (i.e., `bit + 1`). + /// + /// [BOLT 9]: https://github.com/lightning/bolts/blob/master/09-features.md + pub fn set_optional_feature_bit(&mut self, bit: usize) -> Result<(), ()> { + self.set_feature_bit(bit + (1 - (bit % 2))) + } + + fn set_feature_bit(&mut self, bit: usize) -> Result<(), ()> { + if bit > 255 { + return Err(()); + } + self.set_bit(bit, false) + } + /// Sets a required custom feature bit. Errors if `bit` is outside the custom range as defined /// by [bLIP 2] or if it is a known `T` feature. /// @@ -821,10 +853,13 @@ impl Features { if bit < 256 { return Err(()); } + self.set_bit(bit, true) + } + fn set_bit(&mut self, bit: usize, custom: bool) -> Result<(), ()> { let byte_offset = bit / 8; let mask = 1 << (bit - 8 * byte_offset); - if byte_offset < T::KNOWN_FEATURE_MASK.len() { + if byte_offset < T::KNOWN_FEATURE_MASK.len() && custom { if (T::KNOWN_FEATURE_MASK[byte_offset] & mask) != 0 { return Err(()); } @@ -1075,6 +1110,13 @@ mod tests { assert!(!features.requires_basic_mpp()); assert!(features.requires_payment_secret()); assert!(features.supports_payment_secret()); + + // Set flags manually + let mut features = NodeFeatures::empty(); + assert!(features.set_optional_feature_bit(55).is_ok()); + assert!(features.supports_keysend()); + assert!(features.set_optional_feature_bit(255).is_ok()); + assert!(features.set_required_feature_bit(256).is_err()); } #[test]