Merge pull request #2359 from domZippilli/2023-06-monitor-updating-persister
[rust-lightning] / lightning / src / ln / features.rs
index 5de383b1f4469273207441892a90d1d2c063494d..bcaa91ab266fe7f10ebbc8de710fc30d927365c3 100644 (file)
@@ -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);
@@ -795,6 +798,35 @@ impl<T: sealed::Context> Features<T> {
                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<T: sealed::Context> Features<T> {
                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]