@@ -303,18 +303,19 @@ impl<T: sealed::Context> Features<T> {
303
303
}
304
304
}
305
305
306
- /// Takes the flags that we know how to interpret in an init-context features that are also
307
- /// relevant in a node-context features and creates a node-context features from them.
308
- /// Be sure to blank out features that are unknown to us.
309
- pub ( crate ) fn with_known_relevant_init_flags ( init_ctx : & InitFeatures ) -> Self {
310
- let byte_count = T :: KNOWN_FEATURE_MASK . len ( ) ;
306
+ /// Converts `Features<T>` to `Features<C>`. Only known `T` features relevant to context `C` are
307
+ /// included in the result.
308
+ pub ( crate ) fn to_context < C : sealed:: Context > ( & self ) -> Features < C > {
309
+ let byte_count = C :: KNOWN_FEATURE_MASK . len ( ) ;
311
310
let mut flags = Vec :: new ( ) ;
312
- for ( i, feature_byte ) in init_ctx . flags . iter ( ) . enumerate ( ) {
311
+ for ( i, byte ) in self . flags . iter ( ) . enumerate ( ) {
313
312
if i < byte_count {
314
- flags. push ( feature_byte & T :: KNOWN_FEATURE_MASK [ i] ) ;
313
+ let known_source_features = T :: KNOWN_FEATURE_MASK [ i] ;
314
+ let known_target_features = C :: KNOWN_FEATURE_MASK [ i] ;
315
+ flags. push ( byte & known_source_features & known_target_features) ;
315
316
}
316
317
}
317
- Self { flags, mark : PhantomData , }
318
+ Features :: < C > { flags, mark : PhantomData , }
318
319
}
319
320
320
321
#[ cfg( test) ]
@@ -399,8 +400,9 @@ impl<T: sealed::UpfrontShutdownScript> Features<T> {
399
400
<T as sealed:: UpfrontShutdownScript >:: supports_feature ( & self . flags )
400
401
}
401
402
#[ cfg( test) ]
402
- pub ( crate ) fn unset_upfront_shutdown_script ( & mut self ) {
403
- <T as sealed:: UpfrontShutdownScript >:: clear_bits ( & mut self . flags )
403
+ pub ( crate ) fn clear_upfront_shutdown_script ( mut self ) -> Self {
404
+ <T as sealed:: UpfrontShutdownScript >:: clear_bits ( & mut self . flags ) ;
405
+ self
404
406
}
405
407
}
406
408
@@ -461,7 +463,7 @@ impl<T: sealed::Context> Readable for Features<T> {
461
463
462
464
#[ cfg( test) ]
463
465
mod tests {
464
- use super :: { ChannelFeatures , InitFeatures , NodeFeatures , Features } ;
466
+ use super :: { ChannelFeatures , InitFeatures , NodeFeatures } ;
465
467
466
468
#[ test]
467
469
fn sanity_test_our_features ( ) {
@@ -503,26 +505,26 @@ mod tests {
503
505
}
504
506
505
507
#[ test]
506
- fn test_node_with_known_relevant_init_flags ( ) {
507
- // Create an InitFeatures with initial_routing_sync supported.
508
- let init_features = InitFeatures :: known ( ) ;
508
+ fn convert_to_context_with_relevant_flags ( ) {
509
+ let init_features = InitFeatures :: known ( ) . clear_upfront_shutdown_script ( ) ;
509
510
assert ! ( init_features. initial_routing_sync( ) ) ;
511
+ assert ! ( !init_features. supports_upfront_shutdown_script( ) ) ;
510
512
511
- // Attempt to pull out non-node-context feature flags from these InitFeatures.
512
- let res = NodeFeatures :: with_known_relevant_init_flags ( & init_features) ;
513
-
513
+ let node_features: NodeFeatures = init_features. to_context ( ) ;
514
514
{
515
- // Check that the flags are as expected: optional_data_loss_protect,
516
- // option_upfront_shutdown_script, var_onion_optin, payment_secret, and
517
- // basic_mpp.
518
- assert_eq ! ( res. flags. len( ) , 3 ) ;
519
- assert_eq ! ( res. flags[ 0 ] , 0b00100010 ) ;
520
- assert_eq ! ( res. flags[ 1 ] , 0b10000010 ) ;
521
- assert_eq ! ( res. flags[ 2 ] , 0b00000010 ) ;
515
+ // Check that the flags are as expected:
516
+ // - option_data_loss_protect
517
+ // - var_onion_optin | payment_secret
518
+ // - basic_mpp
519
+ assert_eq ! ( node_features. flags. len( ) , 3 ) ;
520
+ assert_eq ! ( node_features. flags[ 0 ] , 0b00000010 ) ;
521
+ assert_eq ! ( node_features. flags[ 1 ] , 0b10000010 ) ;
522
+ assert_eq ! ( node_features. flags[ 2 ] , 0b00000010 ) ;
522
523
}
523
524
524
- // Check that the initial_routing_sync feature was correctly blanked out.
525
- let new_features: InitFeatures = Features :: from_le_bytes ( res. flags ) ;
526
- assert ! ( !new_features. initial_routing_sync( ) ) ;
525
+ // Check that cleared flags are kept blank when converting back.
526
+ let features: InitFeatures = node_features. to_context ( ) ;
527
+ assert ! ( !features. initial_routing_sync( ) ) ;
528
+ assert ! ( !features. supports_upfront_shutdown_script( ) ) ;
527
529
}
528
530
}
0 commit comments