@@ -288,18 +288,19 @@ impl<T: sealed::Context> Features<T> {
288
288
}
289
289
}
290
290
291
- /// Takes the flags that we know how to interpret in an init-context features that are also
292
- /// relevant in a node-context features and creates a node-context features from them.
293
- /// Be sure to blank out features that are unknown to us.
294
- pub ( crate ) fn with_known_relevant_init_flags ( init_ctx : & InitFeatures ) -> Self {
295
- let byte_count = T :: KNOWN_FEATURE_MASK . len ( ) ;
291
+ /// Converts `Features<T>` to `Features<C>`. Only known `T` features relevant to `C` are
292
+ /// included in the result.
293
+ pub ( crate ) fn to_context < C : sealed:: Context > ( & self ) -> Features < C > {
294
+ let byte_count = C :: KNOWN_FEATURE_MASK . len ( ) ;
296
295
let mut flags = Vec :: new ( ) ;
297
- for ( i, feature_byte ) in init_ctx . flags . iter ( ) . enumerate ( ) {
296
+ for ( i, byte ) in self . flags . iter ( ) . enumerate ( ) {
298
297
if i < byte_count {
299
- flags. push ( feature_byte & T :: KNOWN_FEATURE_MASK [ i] ) ;
298
+ let known_source_features = T :: KNOWN_FEATURE_MASK [ i] ;
299
+ let known_target_features = C :: KNOWN_FEATURE_MASK [ i] ;
300
+ flags. push ( byte & known_source_features & known_target_features) ;
300
301
}
301
302
}
302
- Self { flags, mark : PhantomData , }
303
+ Features :: < C > { flags, mark : PhantomData , }
303
304
}
304
305
305
306
#[ cfg( test) ]
@@ -384,8 +385,9 @@ impl<T: sealed::UpfrontShutdownScript> Features<T> {
384
385
<T as sealed:: UpfrontShutdownScript >:: supports_feature ( & self . flags )
385
386
}
386
387
#[ cfg( test) ]
387
- pub ( crate ) fn unset_upfront_shutdown_script ( & mut self ) {
388
- <T as sealed:: UpfrontShutdownScript >:: clear_bits ( & mut self . flags )
388
+ pub ( crate ) fn clear_upfront_shutdown_script ( mut self ) -> Self {
389
+ <T as sealed:: UpfrontShutdownScript >:: clear_bits ( & mut self . flags ) ;
390
+ self
389
391
}
390
392
}
391
393
@@ -446,7 +448,7 @@ impl<T: sealed::Context> Readable for Features<T> {
446
448
447
449
#[ cfg( test) ]
448
450
mod tests {
449
- use super :: { ChannelFeatures , InitFeatures , NodeFeatures , Features } ;
451
+ use super :: { ChannelFeatures , InitFeatures , NodeFeatures } ;
450
452
451
453
#[ test]
452
454
fn sanity_test_our_features ( ) {
@@ -488,26 +490,26 @@ mod tests {
488
490
}
489
491
490
492
#[ test]
491
- fn test_node_with_known_relevant_init_flags ( ) {
492
- // Create an InitFeatures with initial_routing_sync supported.
493
- let init_features = InitFeatures :: known ( ) ;
493
+ fn convert_to_context_with_relevant_flags ( ) {
494
+ let init_features = InitFeatures :: known ( ) . clear_upfront_shutdown_script ( ) ;
494
495
assert ! ( init_features. initial_routing_sync( ) ) ;
496
+ assert ! ( !init_features. supports_upfront_shutdown_script( ) ) ;
495
497
496
- // Attempt to pull out non-node-context feature flags from these InitFeatures.
497
- let res = NodeFeatures :: with_known_relevant_init_flags ( & init_features) ;
498
-
498
+ let node_features: NodeFeatures = init_features. to_context ( ) ;
499
499
{
500
- // Check that the flags are as expected: optional_data_loss_protect,
501
- // option_upfront_shutdown_script, var_onion_optin, payment_secret, and
502
- // basic_mpp.
503
- assert_eq ! ( res. flags. len( ) , 3 ) ;
504
- assert_eq ! ( res. flags[ 0 ] , 0b00100010 ) ;
505
- assert_eq ! ( res. flags[ 1 ] , 0b10000010 ) ;
506
- assert_eq ! ( res. flags[ 2 ] , 0b00000010 ) ;
500
+ // Check that the flags are as expected:
501
+ // - option_data_loss_protect
502
+ // - var_onion_optin | payment_secret
503
+ // - basic_mpp
504
+ assert_eq ! ( node_features. flags. len( ) , 3 ) ;
505
+ assert_eq ! ( node_features. flags[ 0 ] , 0b00000010 ) ;
506
+ assert_eq ! ( node_features. flags[ 1 ] , 0b10000010 ) ;
507
+ assert_eq ! ( node_features. flags[ 2 ] , 0b00000010 ) ;
507
508
}
508
509
509
- // Check that the initial_routing_sync feature was correctly blanked out.
510
- let new_features: InitFeatures = Features :: from_le_bytes ( res. flags ) ;
511
- assert ! ( !new_features. initial_routing_sync( ) ) ;
510
+ // Check that cleared flags are kept blank when converting back.
511
+ let features: InitFeatures = node_features. to_context ( ) ;
512
+ assert ! ( !features. initial_routing_sync( ) ) ;
513
+ assert ! ( !features. supports_upfront_shutdown_script( ) ) ;
512
514
}
513
515
}
0 commit comments