X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Fln%2Ffeatures.rs;h=d1f6b89db4f87e968e3624289331c00c476875fe;hb=8ec7cebc184ca706ccd34ad51518fec0c818b56e;hp=eb0100db675de8842e1d317d4a2b9c5c6e7b9ab1;hpb=0b4079df9a2d4fd7b178f7441c5fb89d79e40a4d;p=rust-lightning diff --git a/lightning/src/ln/features.rs b/lightning/src/ln/features.rs index eb0100db..d1f6b89d 100644 --- a/lightning/src/ln/features.rs +++ b/lightning/src/ln/features.rs @@ -22,8 +22,10 @@ //! [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::hash::{Hash, Hasher}; use core::marker::PhantomData; use bitcoin::bech32; @@ -89,6 +91,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" })) + } + } }; } @@ -339,6 +363,11 @@ impl Clone for Features { } } } +impl Hash for Features { + fn hash(&self, hasher: &mut H) { + self.flags.hash(hasher); + } +} impl PartialEq for Features { fn eq(&self, o: &Self) -> bool { self.flags.eq(&o.flags) @@ -361,7 +390,7 @@ pub type InvoiceFeatures = Features; impl InitFeatures { /// Writes all features present up to, and including, 13. - pub(crate) fn write_up_to_13(&self, w: &mut W) -> Result<(), ::std::io::Error> { + pub(crate) fn write_up_to_13(&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)?; @@ -525,7 +554,9 @@ impl Features { &self.flags } - pub(crate) fn requires_unknown_bits(&self) -> bool { + /// Returns true if this `Features` object contains unknown feature flags which are set as + /// "required". + pub fn requires_unknown_bits(&self) -> bool { // Bitwise AND-ing with all even bits set except for known features will select required // unknown features. let byte_count = T::KNOWN_FEATURE_MASK.len(); @@ -566,6 +597,7 @@ impl Features { pub(crate) fn requires_data_loss_protect(&self) -> bool { ::requires_feature(&self.flags) } + #[cfg(test)] pub(crate) fn supports_data_loss_protect(&self) -> bool { ::supports_feature(&self.flags) } @@ -669,7 +701,7 @@ impl Features { } impl Writeable for Features { - fn write(&self, w: &mut W) -> Result<(), ::std::io::Error> { + fn write(&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 @@ -680,7 +712,7 @@ impl Writeable for Features { } impl Readable for Features { - fn read(r: &mut R) -> Result { + fn read(r: &mut R) -> Result { let mut flags: Vec = Readable::read(r)?; flags.reverse(); // Swap to little-endian Ok(Self {