X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Fln%2Ffeatures.rs;h=fe879a5688fedc806a137231899327ffaa5620fd;hb=46fd7035b34de3035cec433558e27c823148fff1;hp=082890557d3fdbf20af0f22509258628fb6e6771;hpb=31a59629c4d309a8e023632508b11943c74fff33;p=rust-lightning diff --git a/lightning/src/ln/features.rs b/lightning/src/ln/features.rs index 08289055..fe879a56 100644 --- a/lightning/src/ln/features.rs +++ b/lightning/src/ln/features.rs @@ -512,10 +512,10 @@ impl InvoiceFeatures { } impl ChannelTypeFeatures { - /// Constructs the implicit channel type based on the common supported types between us and our - /// counterparty - pub(crate) fn from_counterparty_init(counterparty_init: &InitFeatures) -> Self { - let mut ret = counterparty_init.to_context_internal(); + // Maps the relevant `InitFeatures` to `ChannelTypeFeatures`. Any unknown features to + // `ChannelTypeFeatures` are not included in the result. + pub(crate) fn from_init(init: &InitFeatures) -> Self { + let mut ret = init.to_context_internal(); // ChannelTypeFeatures must only contain required bits, so we OR the required forms of all // optional bits and then AND out the optional ones. for byte in ret.flags.iter_mut() { @@ -685,6 +685,24 @@ impl Features { (byte & unknown_features) != 0 }) } + + // Returns true if the features within `self` are a subset of the features within `other`. + pub(crate) fn is_subset(&self, other: &Self) -> bool { + for (idx, byte) in self.flags.iter().enumerate() { + if let Some(other_byte) = other.flags.get(idx) { + if byte & other_byte != *byte { + // `self` has bits set that `other` doesn't. + return false; + } + } else { + if *byte > 0 { + // `self` has a non-zero byte that `other` doesn't. + return false; + } + } + } + true + } } impl Features { @@ -711,6 +729,18 @@ impl Features { } } +impl Features { + pub(crate) fn clear_scid_privacy(&mut self) { + ::clear_bits(&mut self.flags); + } +} + +impl Features { + pub(crate) fn clear_anchors_zero_fee_htlc_tx(&mut self) { + ::clear_bits(&mut self.flags); + } +} + #[cfg(test)] impl Features { pub(crate) fn unknown() -> Self { @@ -815,6 +845,7 @@ mod tests { init_features.set_channel_type_optional(); init_features.set_scid_privacy_optional(); init_features.set_zero_conf_optional(); + init_features.set_anchors_zero_fee_htlc_tx_optional(); assert!(init_features.initial_routing_sync()); assert!(!init_features.supports_upfront_shutdown_script()); @@ -924,7 +955,7 @@ mod tests { // required-StaticRemoteKey ChannelTypeFeatures. let mut init_features = InitFeatures::empty(); init_features.set_static_remote_key_optional(); - let converted_features = ChannelTypeFeatures::from_counterparty_init(&init_features); + let converted_features = ChannelTypeFeatures::from_init(&init_features); assert_eq!(converted_features, ChannelTypeFeatures::only_static_remote_key()); assert!(!converted_features.supports_any_optional_bits()); assert!(converted_features.requires_static_remote_key());