Actual no_std support
[rust-lightning] / lightning / src / ln / features.rs
index b459baf06580bff8414715b82c1845e7334c23ee..e78fa3d50d2d05c5bfcafe1fd58eb1b654c167f7 100644 (file)
@@ -22,6 +22,7 @@
 //! [BOLT #9]: https://github.com/lightningnetwork/lightning-rfc/blob/master/09-features.md
 //! [messages]: crate::ln::msgs
 
+use io;
 use prelude::*;
 use core::{cmp, fmt};
 use core::marker::PhantomData;
@@ -89,6 +90,28 @@ mod sealed {
                                        )*
                                ];
                        }
+
+                       impl alloc::fmt::Display for Features<$context> {
+                               fn fmt(&self, fmt: &mut alloc::fmt::Formatter) -> Result<(), alloc::fmt::Error> {
+                                       $(
+                                               $(
+                                                       fmt.write_fmt(format_args!("{}: {}, ", stringify!($required_feature),
+                                                               if <$context as $required_feature>::requires_feature(&self.flags) { "required" }
+                                                               else if <$context as $required_feature>::supports_feature(&self.flags) { "supported" }
+                                                               else { "not supported" }))?;
+                                               )*
+                                               $(
+                                                       fmt.write_fmt(format_args!("{}: {}, ", stringify!($optional_feature),
+                                                               if <$context as $optional_feature>::requires_feature(&self.flags) { "required" }
+                                                               else if <$context as $optional_feature>::supports_feature(&self.flags) { "supported" }
+                                                               else { "not supported" }))?;
+                                               )*
+                                       )*
+                                       fmt.write_fmt(format_args!("unknown flags: {}",
+                                               if self.requires_unknown_bits() { "required" }
+                                               else if self.supports_unknown_bits() { "supported" } else { "none" }))
+                               }
+                       }
                };
        }
 
@@ -124,6 +147,12 @@ mod sealed {
                        ,
                        // Byte 3
                        ,
+                       // Byte 4
+                       ,
+                       // Byte 5
+                       ,
+                       // Byte 6
+                       ,
                ],
                optional_features: [
                        // Byte 0
@@ -134,6 +163,12 @@ mod sealed {
                        BasicMPP,
                        // Byte 3
                        ShutdownAnySegwit,
+                       // Byte 4
+                       ,
+                       // Byte 5
+                       ,
+                       // Byte 6
+                       Keysend,
                ],
        });
        define_context!(ChannelContext {
@@ -299,29 +334,11 @@ mod sealed {
        define_feature!(27, ShutdownAnySegwit, [InitContext, NodeContext],
                "Feature flags for `opt_shutdown_anysegwit`.", set_shutdown_any_segwit_optional,
                set_shutdown_any_segwit_required);
+       define_feature!(55, Keysend, [NodeContext],
+               "Feature flags for keysend payments.", set_keysend_optional, set_keysend_required);
 
        #[cfg(test)]
-       define_context!(TestingContext {
-               required_features: [
-                       // Byte 0
-                       ,
-                       // Byte 1
-                       ,
-                       // Byte 2
-                       UnknownFeature,
-               ],
-               optional_features: [
-                       // Byte 0
-                       ,
-                       // Byte 1
-                       ,
-                       // Byte 2
-                       ,
-               ],
-       });
-
-       #[cfg(test)]
-       define_feature!(23, UnknownFeature, [TestingContext],
+       define_feature!(123456789, UnknownFeature, [NodeContext, ChannelContext, InvoiceContext],
                "Feature flags for an unknown feature used in testing.", set_unknown_feature_optional,
                set_unknown_feature_required);
 }
@@ -367,7 +384,7 @@ pub type InvoiceFeatures = Features<sealed::InvoiceContext>;
 
 impl InitFeatures {
        /// Writes all features present up to, and including, 13.
-       pub(crate) fn write_up_to_13<W: Writer>(&self, w: &mut W) -> Result<(), ::std::io::Error> {
+       pub(crate) fn write_up_to_13<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
                let len = cmp::min(2, self.flags.len());
                w.size_hint(len + 2);
                (len as u16).write(w)?;
@@ -406,6 +423,18 @@ impl InvoiceFeatures {
        pub(crate) fn to_context<C: sealed::Context>(&self) -> Features<C> {
                self.to_context_internal()
        }
+
+       /// Getting a route for a keysend payment to a private node requires providing the payee's
+       /// features (since they were not announced in a node announcement). However, keysend payments
+       /// don't have an invoice to pull the payee's features from, so this method is provided for use in
+       /// [`get_keysend_route`], thus omitting the need for payers to manually construct an
+       /// `InvoiceFeatures` for [`get_route`].
+       ///
+       /// [`get_keysend_route`]: crate::routing::router::get_keysend_route
+       /// [`get_route`]: crate::routing::router::get_route
+       pub(crate) fn for_keysend() -> InvoiceFeatures {
+               InvoiceFeatures::empty().set_variable_length_onion_optional()
+       }
 }
 
 impl ToBase32 for InvoiceFeatures {
@@ -490,13 +519,14 @@ impl<T: sealed::Context> Features<T> {
        /// Converts `Features<T>` to `Features<C>`. Only known `T` features relevant to context `C` are
        /// included in the result.
        fn to_context_internal<C: sealed::Context>(&self) -> Features<C> {
-               let byte_count = C::KNOWN_FEATURE_MASK.len();
+               let from_byte_count = T::KNOWN_FEATURE_MASK.len();
+               let to_byte_count = C::KNOWN_FEATURE_MASK.len();
                let mut flags = Vec::new();
                for (i, byte) in self.flags.iter().enumerate() {
-                       if i < byte_count {
-                               let known_source_features = T::KNOWN_FEATURE_MASK[i];
-                               let known_target_features = C::KNOWN_FEATURE_MASK[i];
-                               flags.push(byte & known_source_features & known_target_features);
+                       if i < from_byte_count && i < to_byte_count {
+                               let from_known_features = T::KNOWN_FEATURE_MASK[i];
+                               let to_known_features = C::KNOWN_FEATURE_MASK[i];
+                               flags.push(byte & from_known_features & to_known_features);
                        }
                }
                Features::<C> { flags, mark: PhantomData, }
@@ -552,21 +582,6 @@ impl<T: sealed::Context> Features<T> {
        pub(crate) fn byte_count(&self) -> usize {
                self.flags.len()
        }
-
-       #[cfg(test)]
-       pub(crate) fn set_required_unknown_bits(&mut self) {
-               <sealed::TestingContext as sealed::UnknownFeature>::set_required_bit(&mut self.flags);
-       }
-
-       #[cfg(test)]
-       pub(crate) fn set_optional_unknown_bits(&mut self) {
-               <sealed::TestingContext as sealed::UnknownFeature>::set_optional_bit(&mut self.flags);
-       }
-
-       #[cfg(test)]
-       pub(crate) fn clear_unknown_bits(&mut self) {
-               <sealed::TestingContext as sealed::UnknownFeature>::clear_bits(&mut self.flags);
-       }
 }
 
 impl<T: sealed::DataLossProtect> Features<T> {
@@ -574,6 +589,7 @@ impl<T: sealed::DataLossProtect> Features<T> {
        pub(crate) fn requires_data_loss_protect(&self) -> bool {
                <T as sealed::DataLossProtect>::requires_feature(&self.flags)
        }
+       #[cfg(test)]
        pub(crate) fn supports_data_loss_protect(&self) -> bool {
                <T as sealed::DataLossProtect>::supports_feature(&self.flags)
        }
@@ -677,7 +693,7 @@ impl<T: sealed::ShutdownAnySegwit> Features<T> {
 }
 
 impl<T: sealed::Context> Writeable for Features<T> {
-       fn write<W: Writer>(&self, w: &mut W) -> Result<(), ::std::io::Error> {
+       fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
                w.size_hint(self.flags.len() + 2);
                (self.flags.len() as u16).write(w)?;
                for f in self.flags.iter().rev() { // Swap back to big-endian
@@ -688,7 +704,7 @@ impl<T: sealed::Context> Writeable for Features<T> {
 }
 
 impl<T: sealed::Context> Readable for Features<T> {
-       fn read<R: ::std::io::Read>(r: &mut R) -> Result<Self, DecodeError> {
+       fn read<R: io::Read>(r: &mut R) -> Result<Self, DecodeError> {
                let mut flags: Vec<u8> = Readable::read(r)?;
                flags.reverse(); // Swap to little-endian
                Ok(Self {
@@ -764,19 +780,15 @@ mod tests {
 
        #[test]
        fn sanity_test_unknown_bits() {
-               let mut features = ChannelFeatures::empty();
+               let features = ChannelFeatures::empty();
                assert!(!features.requires_unknown_bits());
                assert!(!features.supports_unknown_bits());
 
-               features.set_required_unknown_bits();
+               let features = ChannelFeatures::empty().set_unknown_feature_required();
                assert!(features.requires_unknown_bits());
                assert!(features.supports_unknown_bits());
 
-               features.clear_unknown_bits();
-               assert!(!features.requires_unknown_bits());
-               assert!(!features.supports_unknown_bits());
-
-               features.set_optional_unknown_bits();
+               let features = ChannelFeatures::empty().set_unknown_feature_optional();
                assert!(!features.requires_unknown_bits());
                assert!(features.supports_unknown_bits());
        }
@@ -812,6 +824,16 @@ mod tests {
                assert!(!init_features.supports_gossip_queries());
        }
 
+       #[test]
+       fn convert_to_context_with_unknown_flags() {
+               // Ensure the `from` context has fewer known feature bytes than the `to` context.
+               assert!(InvoiceFeatures::known().byte_count() < NodeFeatures::known().byte_count());
+               let invoice_features = InvoiceFeatures::known().set_unknown_feature_optional();
+               assert!(invoice_features.supports_unknown_bits());
+               let node_features: NodeFeatures = invoice_features.to_context();
+               assert!(!node_features.supports_unknown_bits());
+       }
+
        #[test]
        fn set_feature_bits() {
                let features = InvoiceFeatures::empty()