Skip to content

Commit daddd21

Browse files
committed
f add channeltypefeatures
1 parent 6ecb0d9 commit daddd21

File tree

1 file changed

+24
-2
lines changed

1 file changed

+24
-2
lines changed

lightning/src/ln/features.rs

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -482,7 +482,14 @@ impl ChannelTypeFeatures {
482482
/// Constructs the implicit channel type based on the common supported types between us and our
483483
/// counterparty
484484
pub(crate) fn from_counterparty_init(counterparty_init: &InitFeatures) -> Self {
485-
counterparty_init.to_context_internal()
485+
let mut ret = counterparty_init.to_context_internal();
486+
// ChannelTypeFeatures must only contain required bits, so we OR the required forms of all
487+
// optional bits and then AND out the optional ones.
488+
for byte in ret.flags.iter_mut() {
489+
*byte |= (*byte & 0b10_10_10_10) >> 1;
490+
*byte &= 0b01_01_01_01;
491+
}
492+
ret
486493
}
487494

488495
/// Constructs a ChannelTypeFeatures with only static_remotekey set
@@ -619,6 +626,10 @@ impl<T: sealed::Context> Features<T> {
619626
}
620627
}
621628

629+
pub(crate) fn supports_any_optional_bits(&self) -> bool {
630+
self.flags.iter().any(|&byte| (byte & 0b10_10_10_10) != 0)
631+
}
632+
622633
/// Returns true if this `Features` object contains unknown feature flags which are set as
623634
/// "required".
624635
pub fn requires_unknown_bits(&self) -> bool {
@@ -795,7 +806,7 @@ impl Readable for ChannelTypeFeatures {
795806

796807
#[cfg(test)]
797808
mod tests {
798-
use super::{ChannelFeatures, InitFeatures, InvoiceFeatures, NodeFeatures};
809+
use super::{ChannelFeatures, ChannelTypeFeatures, InitFeatures, InvoiceFeatures, NodeFeatures};
799810
use bitcoin::bech32::{Base32Len, FromBase32, ToBase32, u5};
800811

801812
#[test]
@@ -954,4 +965,15 @@ mod tests {
954965
let features_deserialized = InvoiceFeatures::from_base32(&features_as_u5s).unwrap();
955966
assert_eq!(features, features_deserialized);
956967
}
968+
969+
#[test]
970+
fn test_channel_type_mapping() {
971+
// If we map an InvoiceFeatures with StaticRemoteKey optional, it should map into a
972+
// required-StaticRemoteKey ChannelTypeFeatures.
973+
let init_features = InitFeatures::empty().set_static_remote_key_optional();
974+
let converted_features = ChannelTypeFeatures::from_counterparty_init(&init_features);
975+
assert_eq!(converted_features, ChannelTypeFeatures::only_static_remote_key());
976+
assert!(!converted_features.supports_any_optional_bits());
977+
assert!(converted_features.requires_static_remote_key());
978+
}
957979
}

0 commit comments

Comments
 (0)