@@ -482,7 +482,14 @@ impl ChannelTypeFeatures {
482
482
/// Constructs the implicit channel type based on the common supported types between us and our
483
483
/// counterparty
484
484
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
486
493
}
487
494
488
495
/// Constructs a ChannelTypeFeatures with only static_remotekey set
@@ -619,6 +626,10 @@ impl<T: sealed::Context> Features<T> {
619
626
}
620
627
}
621
628
629
+ pub ( crate ) fn supports_any_optional_bits ( & self ) -> bool {
630
+ self . flags . iter ( ) . any ( |& byte| ( byte & 0b10_10_10_10 ) != 0 )
631
+ }
632
+
622
633
/// Returns true if this `Features` object contains unknown feature flags which are set as
623
634
/// "required".
624
635
pub fn requires_unknown_bits ( & self ) -> bool {
@@ -795,7 +806,7 @@ impl Readable for ChannelTypeFeatures {
795
806
796
807
#[ cfg( test) ]
797
808
mod tests {
798
- use super :: { ChannelFeatures , InitFeatures , InvoiceFeatures , NodeFeatures } ;
809
+ use super :: { ChannelFeatures , ChannelTypeFeatures , InitFeatures , InvoiceFeatures , NodeFeatures } ;
799
810
use bitcoin:: bech32:: { Base32Len , FromBase32 , ToBase32 , u5} ;
800
811
801
812
#[ test]
@@ -954,4 +965,15 @@ mod tests {
954
965
let features_deserialized = InvoiceFeatures :: from_base32 ( & features_as_u5s) . unwrap ( ) ;
955
966
assert_eq ! ( features, features_deserialized) ;
956
967
}
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
+ }
957
979
}
0 commit comments