9090use  core:: borrow:: Borrow ; 
9191use  core:: hash:: { Hash ,  Hasher } ; 
9292use  core:: marker:: PhantomData ; 
93+ use  core:: ops:: { Deref ,  DerefMut } ; 
9394use  core:: { cmp,  fmt} ; 
9495
9596use  alloc:: vec:: Vec ; 
9697
9798mod  sealed { 
98- 	use  super :: Features ; 
99- 
100- 	use  alloc:: vec:: Vec ; 
99+ 	use  super :: { FeatureFlags ,  Features } ; 
101100
102101	/// The context in which [`Features`] are applicable. Defines which features are known to the 
103102 	/// implementation, though specification of them as required or optional is up to the code 
@@ -297,21 +296,21 @@ mod sealed {
297296
298297				/// Returns whether the feature is required by the given flags. 
299298 				#[ inline] 
300- 				fn  requires_feature( flags:  & Vec < u8 > )  -> bool  { 
299+ 				fn  requires_feature( flags:  & [ u8 ] )  -> bool  { 
301300					flags. len( )  > Self :: BYTE_OFFSET  &&
302301						( flags[ Self :: BYTE_OFFSET ]  &  Self :: REQUIRED_MASK )  != 0 
303302				} 
304303
305304				/// Returns whether the feature is supported by the given flags. 
306305 				#[ inline] 
307- 				fn  supports_feature( flags:  & Vec < u8 > )  -> bool  { 
306+ 				fn  supports_feature( flags:  & [ u8 ] )  -> bool  { 
308307					flags. len( )  > Self :: BYTE_OFFSET  &&
309308						( flags[ Self :: BYTE_OFFSET ]  &  ( Self :: REQUIRED_MASK  | Self :: OPTIONAL_MASK ) )  != 0 
310309				} 
311310
312311				/// Sets the feature's required (even) bit in the given flags. 
313312 				#[ inline] 
314- 				fn  set_required_bit( flags:  & mut  Vec < u8 > )  { 
313+ 				fn  set_required_bit( flags:  & mut  FeatureFlags )  { 
315314					if  flags. len( )  <= Self :: BYTE_OFFSET  { 
316315						flags. resize( Self :: BYTE_OFFSET  + 1 ,  0u8 ) ; 
317316					} 
@@ -322,7 +321,7 @@ mod sealed {
322321
323322				/// Sets the feature's optional (odd) bit in the given flags. 
324323 				#[ inline] 
325- 				fn  set_optional_bit( flags:  & mut  Vec < u8 > )  { 
324+ 				fn  set_optional_bit( flags:  & mut  FeatureFlags )  { 
326325					if  flags. len( )  <= Self :: BYTE_OFFSET  { 
327326						flags. resize( Self :: BYTE_OFFSET  + 1 ,  0u8 ) ; 
328327					} 
@@ -333,7 +332,7 @@ mod sealed {
333332				/// Clears the feature's required (even) and optional (odd) bits from the given 
334333 				/// flags. 
335334 				#[ inline] 
336- 				fn  clear_bits( flags:  & mut  Vec < u8 > )  { 
335+ 				fn  clear_bits( flags:  & mut  FeatureFlags )  { 
337336					if  flags. len( )  > Self :: BYTE_OFFSET  { 
338337						flags[ Self :: BYTE_OFFSET ]  &= !Self :: REQUIRED_MASK ; 
339338						flags[ Self :: BYTE_OFFSET ]  &= !Self :: OPTIONAL_MASK ; 
@@ -661,6 +660,9 @@ mod sealed {
661660		supports_trampoline_routing, 
662661		requires_trampoline_routing
663662	) ; 
663+ 	// By default, allocate enough bytes to cover up to Trampoline. Update this as new features are 
664+ 	// added which we expect to appear commonly across contexts. 
665+ 	pub ( super )  const  MIN_FEATURES_ALLOCATION_BYTES :  usize  = ( 57  + 7 )  / 8 ; 
664666	define_feature ! ( 
665667		259 , 
666668		DnsResolver , 
@@ -700,14 +702,133 @@ mod sealed {
700702const  ANY_REQUIRED_FEATURES_MASK :  u8  = 0b01_01_01_01 ; 
701703const  ANY_OPTIONAL_FEATURES_MASK :  u8  = 0b10_10_10_10 ; 
702704
705+ // Vecs are always 3 pointers long, so `FeatureFlags` is never shorter than 24 bytes on 64-bit 
706+ // platforms no matter what we do. 
707+ // 
708+ // Luckily, because `Vec` uses a `NonNull` pointer to its buffer, the two-variant enum is free 
709+ // space-wise, but we only get the remaining 2 usizes in length available for our own stuff (as any 
710+ // other value is interpreted as the `Heap` variant). 
711+ // 
712+ // Thus, as long as we never use more than 16 bytes (15 bytes for the data and one byte for the 
713+ // length) for our Held variant `FeatureFlags` is the same length as a `Vec` in memory. 
714+ const  DIRECT_ALLOC_BYTES :  usize  = if  sealed:: MIN_FEATURES_ALLOCATION_BYTES  > 8  *  2  - 1  { 
715+ 	sealed:: MIN_FEATURES_ALLOCATION_BYTES 
716+ }  else  { 
717+ 	8  *  2  - 1 
718+ } ; 
719+ const  _ASSERT:  ( )  = assert ! ( DIRECT_ALLOC_BYTES  <= u8 :: MAX  as  usize ) ; 
720+ 
721+ /// The internal storage for feature flags. Public only for the [`sealed`] feature flag traits but 
722+ /// generally should never be used directly. 
723+ #[ derive( Clone ,  PartialEq ,  Eq ) ]  
724+ #[ doc( hidden) ]  
725+ pub  enum  FeatureFlags  { 
726+ 	Held  {  bytes :  [ u8 ;  DIRECT_ALLOC_BYTES ] ,  len :  u8  } , 
727+ 	Heap ( Vec < u8 > ) , 
728+ } 
729+ 
730+ impl  FeatureFlags  { 
731+ 	fn  empty ( )  -> Self  { 
732+ 		Self :: Held  {  bytes :  [ 0 ;  DIRECT_ALLOC_BYTES ] ,  len :  0  } 
733+ 	} 
734+ 
735+ 	fn  from ( vec :  Vec < u8 > )  -> Self  { 
736+ 		if  vec. len ( )  <= DIRECT_ALLOC_BYTES  { 
737+ 			let  mut  bytes = [ 0 ;  DIRECT_ALLOC_BYTES ] ; 
738+ 			bytes[ ..vec. len ( ) ] . copy_from_slice ( & vec) ; 
739+ 			Self :: Held  {  bytes,  len :  vec. len ( )  as  u8  } 
740+ 		}  else  { 
741+ 			Self :: Heap ( vec) 
742+ 		} 
743+ 	} 
744+ 
745+ 	fn  resize ( & mut  self ,  new_len :  usize ,  default :  u8 )  { 
746+ 		match  self  { 
747+ 			Self :: Held  {  bytes,  len }  => { 
748+ 				let  start_len = * len as  usize ; 
749+ 				if  new_len <= DIRECT_ALLOC_BYTES  { 
750+ 					bytes[ start_len..] . copy_from_slice ( & [ default;  DIRECT_ALLOC_BYTES ] [ start_len..] ) ; 
751+ 					* len = new_len as  u8 ; 
752+ 				}  else  { 
753+ 					let  mut  vec = Vec :: new ( ) ; 
754+ 					vec. resize ( new_len,  default) ; 
755+ 					vec[ ..start_len] . copy_from_slice ( & bytes[ ..start_len] ) ; 
756+ 					* self  = Self :: Heap ( vec) ; 
757+ 				} 
758+ 			} , 
759+ 			Self :: Heap ( vec)  => { 
760+ 				vec. resize ( new_len,  default) ; 
761+ 				if  new_len <= DIRECT_ALLOC_BYTES  { 
762+ 					let  mut  bytes = [ 0 ;  DIRECT_ALLOC_BYTES ] ; 
763+ 					bytes[ ..new_len] . copy_from_slice ( & vec[ ..new_len] ) ; 
764+ 					* self  = Self :: Held  {  bytes,  len :  new_len as  u8  } ; 
765+ 				} 
766+ 			} , 
767+ 		} 
768+ 	} 
769+ 
770+ 	fn  len ( & self )  -> usize  { 
771+ 		self . deref ( ) . len ( ) 
772+ 	} 
773+ 
774+ 	fn  iter ( 
775+ 		& self , 
776+ 	)  -> ( impl  Clone  + ExactSizeIterator < Item  = & u8 >  + DoubleEndedIterator < Item  = & u8 > )  { 
777+ 		let  slice = self . deref ( ) ; 
778+ 		slice. iter ( ) 
779+ 	} 
780+ 
781+ 	fn  iter_mut ( 
782+ 		& mut  self , 
783+ 	)  -> ( impl  ExactSizeIterator < Item  = & mut  u8 >  + DoubleEndedIterator < Item  = & mut  u8 > )  { 
784+ 		let  slice = self . deref_mut ( ) ; 
785+ 		slice. iter_mut ( ) 
786+ 	} 
787+ } 
788+ 
789+ impl  Deref  for  FeatureFlags  { 
790+ 	type  Target  = [ u8 ] ; 
791+ 	fn  deref ( & self )  -> & [ u8 ]  { 
792+ 		match  self  { 
793+ 			FeatureFlags :: Held  {  bytes,  len }  => & bytes[ ..* len as  usize ] , 
794+ 			FeatureFlags :: Heap ( vec)  => & vec, 
795+ 		} 
796+ 	} 
797+ } 
798+ 
799+ impl  DerefMut  for  FeatureFlags  { 
800+ 	fn  deref_mut ( & mut  self )  -> & mut  [ u8 ]  { 
801+ 		match  self  { 
802+ 			FeatureFlags :: Held  {  bytes,  len }  => & mut  bytes[ ..* len as  usize ] , 
803+ 			FeatureFlags :: Heap ( vec)  => & mut  vec[ ..] , 
804+ 		} 
805+ 	} 
806+ } 
807+ 
808+ impl  PartialOrd  for  FeatureFlags  { 
809+ 	fn  partial_cmp ( & self ,  other :  & Self )  -> Option < cmp:: Ordering >  { 
810+ 		self . deref ( ) . partial_cmp ( other. deref ( ) ) 
811+ 	} 
812+ } 
813+ impl  Ord  for  FeatureFlags  { 
814+ 	fn  cmp ( & self ,  other :  & Self )  -> cmp:: Ordering  { 
815+ 		self . deref ( ) . cmp ( other. deref ( ) ) 
816+ 	} 
817+ } 
818+ impl  fmt:: Debug  for  FeatureFlags  { 
819+ 	fn  fmt ( & self ,  fmt :  & mut  fmt:: Formatter )  -> Result < ( ) ,  fmt:: Error >  { 
820+ 		self . deref ( ) . fmt ( fmt) 
821+ 	} 
822+ } 
823+ 
703824/// Tracks the set of features which a node implements, templated by the context in which it 
704825/// appears. 
705826/// 
706827/// This is not exported to bindings users as we map the concrete feature types below directly instead 
707828#[ derive( Eq ) ]  
708829pub  struct  Features < T :  sealed:: Context >  { 
709830	/// Note that, for convenience, flags is LITTLE endian (despite being big-endian on the wire) 
710-  	flags :  Vec < u8 > , 
831+  	flags :  FeatureFlags , 
711832	mark :  PhantomData < T > , 
712833} 
713834
@@ -897,7 +1018,7 @@ impl ChannelTypeFeatures {
8971018impl < T :  sealed:: Context >  Features < T >  { 
8981019	/// Create a blank Features with no features set 
8991020 	pub  fn  empty ( )  -> Self  { 
900- 		Features  {  flags :  Vec :: new ( ) ,  mark :  PhantomData  } 
1021+ 		Features  {  flags :  FeatureFlags :: empty ( ) ,  mark :  PhantomData  } 
9011022	} 
9021023
9031024	/// Converts `Features<T>` to `Features<C>`. Only known `T` features relevant to context `C` are 
@@ -910,7 +1031,7 @@ impl<T: sealed::Context> Features<T> {
9101031				None 
9111032			} 
9121033		} ) ; 
913- 		let  mut  flags = Vec :: new ( ) ; 
1034+ 		let  mut  flags = FeatureFlags :: empty ( ) ; 
9141035		flags. resize ( flag_iter. clone ( ) . count ( ) ,  0 ) ; 
9151036		for  ( i,  byte)  in  flag_iter { 
9161037			flags[ i]  = byte; 
@@ -923,7 +1044,7 @@ impl<T: sealed::Context> Features<T> {
9231044 	/// 
9241045 	/// This is not exported to bindings users as we don't support export across multiple T 
9251046 	pub  fn  from_le_bytes ( flags :  Vec < u8 > )  -> Features < T >  { 
926- 		Features  {  flags,  mark :  PhantomData  } 
1047+ 		Features  {  flags :   FeatureFlags :: from ( flags ) ,  mark :  PhantomData  } 
9271048	} 
9281049
9291050	/// Returns the feature set as a list of bytes, in little-endian. This is in reverse byte order 
@@ -938,7 +1059,7 @@ impl<T: sealed::Context> Features<T> {
9381059 	/// This is not exported to bindings users as we don't support export across multiple T 
9391060 	pub  fn  from_be_bytes ( mut  flags :  Vec < u8 > )  -> Features < T >  { 
9401061		flags. reverse ( ) ;  // Swap to little-endian 
941- 		Self  {  flags,  mark :  PhantomData  } 
1062+ 		Self  {  flags :   FeatureFlags :: from ( flags ) ,  mark :  PhantomData  } 
9421063	} 
9431064
9441065	/// Returns true if this `Features` has any optional flags set 
@@ -1331,7 +1452,7 @@ mod tests {
13311452		use  std:: hash:: { Hash ,  Hasher } ; 
13321453
13331454		let  mut  zerod_features = InitFeatures :: empty ( ) ; 
1334- 		zerod_features. flags  = vec ! [ 0 ] ; 
1455+ 		zerod_features. flags  = FeatureFlags :: Heap ( vec ! [ 0 ] ) ; 
13351456		let  empty_features = InitFeatures :: empty ( ) ; 
13361457		assert ! ( empty_features. flags. is_empty( ) ) ; 
13371458
0 commit comments