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 {
9899 use super :: Features ;
99100
100- use alloc:: vec:: Vec ;
101-
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
104103 /// constructing a features object.
@@ -297,68 +296,68 @@ 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 >) {
315- if flags. len( ) <= Self :: BYTE_OFFSET {
316- flags. resize( Self :: BYTE_OFFSET + 1 , 0u8 ) ;
313+ fn set_required_bit( obj : & mut Features < Self >) {
314+ if obj . flags. len( ) <= Self :: BYTE_OFFSET {
315+ obj . flags. resize( Self :: BYTE_OFFSET + 1 , 0u8 ) ;
317316 }
318317
319- flags[ Self :: BYTE_OFFSET ] |= Self :: REQUIRED_MASK ;
320- flags[ Self :: BYTE_OFFSET ] &= !Self :: OPTIONAL_MASK ;
318+ obj . flags[ Self :: BYTE_OFFSET ] |= Self :: REQUIRED_MASK ;
319+ obj . flags[ Self :: BYTE_OFFSET ] &= !Self :: OPTIONAL_MASK ;
321320 }
322321
323322 /// Sets the feature's optional (odd) bit in the given flags.
324323 #[ inline]
325- fn set_optional_bit( flags : & mut Vec < u8 >) {
326- if flags. len( ) <= Self :: BYTE_OFFSET {
327- flags. resize( Self :: BYTE_OFFSET + 1 , 0u8 ) ;
324+ fn set_optional_bit( obj : & mut Features < Self >) {
325+ if obj . flags. len( ) <= Self :: BYTE_OFFSET {
326+ obj . flags. resize( Self :: BYTE_OFFSET + 1 , 0u8 ) ;
328327 }
329328
330- flags[ Self :: BYTE_OFFSET ] |= Self :: OPTIONAL_MASK ;
329+ obj . flags[ Self :: BYTE_OFFSET ] |= Self :: OPTIONAL_MASK ;
331330 }
332331
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 >) {
337- if flags. len( ) > Self :: BYTE_OFFSET {
338- flags[ Self :: BYTE_OFFSET ] &= !Self :: REQUIRED_MASK ;
339- flags[ Self :: BYTE_OFFSET ] &= !Self :: OPTIONAL_MASK ;
335+ fn clear_bits( obj : & mut Features < Self >) {
336+ if obj . flags. len( ) > Self :: BYTE_OFFSET {
337+ obj . flags[ Self :: BYTE_OFFSET ] &= !Self :: REQUIRED_MASK ;
338+ obj . flags[ Self :: BYTE_OFFSET ] &= !Self :: OPTIONAL_MASK ;
340339 }
341340
342- let last_non_zero_byte = flags. iter( ) . rposition( |& byte| byte != 0 ) ;
341+ let last_non_zero_byte = obj . flags. iter( ) . rposition( |& byte| byte != 0 ) ;
343342 let size = if let Some ( offset) = last_non_zero_byte { offset + 1 } else { 0 } ;
344- flags. resize( size, 0u8 ) ;
343+ obj . flags. resize( size, 0u8 ) ;
345344 }
346345 }
347346
348347 impl <T : $feature> Features <T > {
349348 /// Set this feature as optional.
350349 pub fn $optional_setter( & mut self ) {
351- <T as $feature>:: set_optional_bit( & mut self . flags ) ;
350+ <T as $feature>:: set_optional_bit( self ) ;
352351 }
353352
354353 /// Set this feature as required.
355354 pub fn $required_setter( & mut self ) {
356- <T as $feature>:: set_required_bit( & mut self . flags ) ;
355+ <T as $feature>:: set_required_bit( self ) ;
357356 }
358357
359358 /// Unsets this feature.
360359 pub fn $clear( & mut self ) {
361- <T as $feature>:: clear_bits( & mut self . flags ) ;
360+ <T as $feature>:: clear_bits( self ) ;
362361 }
363362
364363 /// Checks if this feature is supported.
@@ -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,138 @@ 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+ #[ cfg( fuzzing) ]
722+ #[ derive( Clone , PartialEq , Eq ) ]
723+ pub enum FeatureFlags {
724+ Held { bytes : [ u8 ; DIRECT_ALLOC_BYTES ] , len : u8 } ,
725+ Heap ( Vec < u8 > ) ,
726+ }
727+
728+ #[ cfg( not( fuzzing) ) ]
729+ #[ derive( Clone , PartialEq , Eq ) ]
730+ enum FeatureFlags {
731+ Held { bytes : [ u8 ; DIRECT_ALLOC_BYTES ] , len : u8 } ,
732+ Heap ( Vec < u8 > ) ,
733+ }
734+
735+ impl FeatureFlags {
736+ fn empty ( ) -> Self {
737+ Self :: Held { bytes : [ 0 ; DIRECT_ALLOC_BYTES ] , len : 0 }
738+ }
739+
740+ fn from ( vec : Vec < u8 > ) -> Self {
741+ if vec. len ( ) <= DIRECT_ALLOC_BYTES {
742+ let mut bytes = [ 0 ; DIRECT_ALLOC_BYTES ] ;
743+ bytes[ ..vec. len ( ) ] . copy_from_slice ( & vec) ;
744+ Self :: Held { bytes, len : vec. len ( ) as u8 }
745+ } else {
746+ Self :: Heap ( vec)
747+ }
748+ }
749+
750+ fn resize ( & mut self , new_len : usize , default : u8 ) {
751+ match self {
752+ Self :: Held { bytes, len } => {
753+ let start_len = * len as usize ;
754+ if new_len <= DIRECT_ALLOC_BYTES {
755+ bytes[ start_len..] . copy_from_slice ( & [ default; DIRECT_ALLOC_BYTES ] [ start_len..] ) ;
756+ * len = new_len as u8 ;
757+ } else {
758+ let mut vec = Vec :: new ( ) ;
759+ vec. resize ( new_len, default) ;
760+ vec[ ..start_len] . copy_from_slice ( & bytes[ ..start_len] ) ;
761+ * self = Self :: Heap ( vec) ;
762+ }
763+ } ,
764+ Self :: Heap ( vec) => {
765+ vec. resize ( new_len, default) ;
766+ if new_len <= DIRECT_ALLOC_BYTES {
767+ let mut bytes = [ 0 ; DIRECT_ALLOC_BYTES ] ;
768+ bytes[ ..new_len] . copy_from_slice ( & vec[ ..new_len] ) ;
769+ * self = Self :: Held { bytes, len : new_len as u8 } ;
770+ }
771+ } ,
772+ }
773+ }
774+
775+ fn len ( & self ) -> usize {
776+ self . deref ( ) . len ( )
777+ }
778+
779+ fn iter (
780+ & self ,
781+ ) -> ( impl Clone + ExactSizeIterator < Item = & u8 > + DoubleEndedIterator < Item = & u8 > ) {
782+ let slice = self . deref ( ) ;
783+ slice. iter ( )
784+ }
785+
786+ fn iter_mut (
787+ & mut self ,
788+ ) -> ( impl ExactSizeIterator < Item = & mut u8 > + DoubleEndedIterator < Item = & mut u8 > ) {
789+ let slice = self . deref_mut ( ) ;
790+ slice. iter_mut ( )
791+ }
792+ }
793+
794+ impl Deref for FeatureFlags {
795+ type Target = [ u8 ] ;
796+ fn deref ( & self ) -> & [ u8 ] {
797+ match self {
798+ FeatureFlags :: Held { bytes, len } => & bytes[ ..* len as usize ] ,
799+ FeatureFlags :: Heap ( vec) => & vec,
800+ }
801+ }
802+ }
803+
804+ impl DerefMut for FeatureFlags {
805+ fn deref_mut ( & mut self ) -> & mut [ u8 ] {
806+ match self {
807+ FeatureFlags :: Held { bytes, len } => & mut bytes[ ..* len as usize ] ,
808+ FeatureFlags :: Heap ( vec) => & mut vec[ ..] ,
809+ }
810+ }
811+ }
812+
813+ impl PartialOrd for FeatureFlags {
814+ fn partial_cmp ( & self , other : & Self ) -> Option < cmp:: Ordering > {
815+ Some ( self . cmp ( other) )
816+ }
817+ }
818+ impl Ord for FeatureFlags {
819+ fn cmp ( & self , other : & Self ) -> cmp:: Ordering {
820+ self . deref ( ) . cmp ( other. deref ( ) )
821+ }
822+ }
823+ impl fmt:: Debug for FeatureFlags {
824+ fn fmt ( & self , fmt : & mut fmt:: Formatter ) -> Result < ( ) , fmt:: Error > {
825+ self . deref ( ) . fmt ( fmt)
826+ }
827+ }
828+
703829/// Tracks the set of features which a node implements, templated by the context in which it
704830/// appears.
705831///
706832/// This is not exported to bindings users as we map the concrete feature types below directly instead
707833#[ derive( Eq ) ]
708- pub struct Features < T : sealed:: Context > {
834+ pub struct Features < T : sealed:: Context + ? Sized > {
709835 /// Note that, for convenience, flags is LITTLE endian (despite being big-endian on the wire)
710- flags : Vec < u8 > ,
836+ flags : FeatureFlags ,
711837 mark : PhantomData < T > ,
712838}
713839
@@ -744,7 +870,7 @@ impl<T: sealed::Context> Hash for Features<T> {
744870 nonzero_flags. hash ( hasher) ;
745871 }
746872}
747- impl < T : sealed:: Context > PartialEq for Features < T > {
873+ impl < T : sealed:: Context + ? Sized > PartialEq for Features < T > {
748874 fn eq ( & self , o : & Self ) -> bool {
749875 let mut o_iter = o. flags . iter ( ) ;
750876 let mut self_iter = self . flags . iter ( ) ;
@@ -879,25 +1005,23 @@ impl ChannelTypeFeatures {
8791005 /// Constructs a ChannelTypeFeatures with only static_remotekey set
8801006 pub fn only_static_remote_key ( ) -> Self {
8811007 let mut ret = Self :: empty ( ) ;
882- <sealed:: ChannelTypeContext as sealed:: StaticRemoteKey >:: set_required_bit ( & mut ret. flags ) ;
1008+ <sealed:: ChannelTypeContext as sealed:: StaticRemoteKey >:: set_required_bit ( & mut ret) ;
8831009 ret
8841010 }
8851011
8861012 /// Constructs a ChannelTypeFeatures with anchors support
8871013 pub fn anchors_zero_htlc_fee_and_dependencies ( ) -> Self {
8881014 let mut ret = Self :: empty ( ) ;
889- <sealed:: ChannelTypeContext as sealed:: StaticRemoteKey >:: set_required_bit ( & mut ret. flags ) ;
890- <sealed:: ChannelTypeContext as sealed:: AnchorsZeroFeeHtlcTx >:: set_required_bit (
891- & mut ret. flags ,
892- ) ;
1015+ <sealed:: ChannelTypeContext as sealed:: StaticRemoteKey >:: set_required_bit ( & mut ret) ;
1016+ <sealed:: ChannelTypeContext as sealed:: AnchorsZeroFeeHtlcTx >:: set_required_bit ( & mut ret) ;
8931017 ret
8941018 }
8951019}
8961020
8971021impl < T : sealed:: Context > Features < T > {
8981022 /// Create a blank Features with no features set
8991023 pub fn empty ( ) -> Self {
900- Features { flags : Vec :: new ( ) , mark : PhantomData }
1024+ Features { flags : FeatureFlags :: empty ( ) , mark : PhantomData }
9011025 }
9021026
9031027 /// Converts `Features<T>` to `Features<C>`. Only known `T` features relevant to context `C` are
@@ -910,7 +1034,7 @@ impl<T: sealed::Context> Features<T> {
9101034 None
9111035 }
9121036 } ) ;
913- let mut flags = Vec :: new ( ) ;
1037+ let mut flags = FeatureFlags :: empty ( ) ;
9141038 flags. resize ( flag_iter. clone ( ) . count ( ) , 0 ) ;
9151039 for ( i, byte) in flag_iter {
9161040 flags[ i] = byte;
@@ -923,7 +1047,7 @@ impl<T: sealed::Context> Features<T> {
9231047 ///
9241048 /// This is not exported to bindings users as we don't support export across multiple T
9251049 pub fn from_le_bytes ( flags : Vec < u8 > ) -> Features < T > {
926- Features { flags, mark : PhantomData }
1050+ Features { flags : FeatureFlags :: from ( flags ) , mark : PhantomData }
9271051 }
9281052
9291053 /// Returns the feature set as a list of bytes, in little-endian. This is in reverse byte order
@@ -938,7 +1062,7 @@ impl<T: sealed::Context> Features<T> {
9381062 /// This is not exported to bindings users as we don't support export across multiple T
9391063 pub fn from_be_bytes ( mut flags : Vec < u8 > ) -> Features < T > {
9401064 flags. reverse ( ) ; // Swap to little-endian
941- Self { flags, mark : PhantomData }
1065+ Self { flags : FeatureFlags :: from ( flags ) , mark : PhantomData }
9421066 }
9431067
9441068 /// Returns true if this `Features` has any optional flags set
@@ -1331,7 +1455,7 @@ mod tests {
13311455 use std:: hash:: { Hash , Hasher } ;
13321456
13331457 let mut zerod_features = InitFeatures :: empty ( ) ;
1334- zerod_features. flags = vec ! [ 0 ] ;
1458+ zerod_features. flags = FeatureFlags :: Heap ( vec ! [ 0 ] ) ;
13351459 let empty_features = InitFeatures :: empty ( ) ;
13361460 assert ! ( empty_features. flags. is_empty( ) ) ;
13371461
@@ -1343,4 +1467,27 @@ mod tests {
13431467 empty_features. hash ( & mut empty_hash) ;
13441468 assert_eq ! ( zerod_hash. finish( ) , empty_hash. finish( ) ) ;
13451469 }
1470+
1471+ #[ test]
1472+ fn test_feature_flags_transitions ( ) {
1473+ // Tests transitions from stack to heap and back in `FeatureFlags`
1474+ let mut flags = FeatureFlags :: empty ( ) ;
1475+ assert ! ( matches!( flags, FeatureFlags :: Held { .. } ) ) ;
1476+
1477+ flags. resize ( DIRECT_ALLOC_BYTES , 42 ) ;
1478+ assert_eq ! ( flags. len( ) , DIRECT_ALLOC_BYTES ) ;
1479+ assert ! ( flags. iter( ) . take( DIRECT_ALLOC_BYTES ) . all( |b| * b == 42 ) ) ;
1480+ assert ! ( matches!( flags, FeatureFlags :: Held { .. } ) ) ;
1481+
1482+ flags. resize ( DIRECT_ALLOC_BYTES * 2 , 43 ) ;
1483+ assert_eq ! ( flags. len( ) , DIRECT_ALLOC_BYTES * 2 ) ;
1484+ assert ! ( flags. iter( ) . take( DIRECT_ALLOC_BYTES ) . all( |b| * b == 42 ) ) ;
1485+ assert ! ( flags. iter( ) . skip( DIRECT_ALLOC_BYTES ) . all( |b| * b == 43 ) ) ;
1486+ assert ! ( matches!( flags, FeatureFlags :: Heap ( _) ) ) ;
1487+
1488+ flags. resize ( DIRECT_ALLOC_BYTES , 0 ) ;
1489+ assert_eq ! ( flags. len( ) , DIRECT_ALLOC_BYTES ) ;
1490+ assert ! ( flags. iter( ) . take( DIRECT_ALLOC_BYTES ) . all( |b| * b == 42 ) ) ;
1491+ assert ! ( matches!( flags, FeatureFlags :: Held { .. } ) ) ;
1492+ }
13461493}
0 commit comments