90
90
use core:: borrow:: Borrow ;
91
91
use core:: hash:: { Hash , Hasher } ;
92
92
use core:: marker:: PhantomData ;
93
+ use core:: ops:: { Deref , DerefMut } ;
93
94
use core:: { cmp, fmt} ;
94
95
95
96
use alloc:: vec:: Vec ;
96
97
97
98
mod sealed {
98
99
use super :: Features ;
99
100
100
- use alloc:: vec:: Vec ;
101
-
102
101
/// The context in which [`Features`] are applicable. Defines which features are known to the
103
102
/// implementation, though specification of them as required or optional is up to the code
104
103
/// constructing a features object.
@@ -297,68 +296,68 @@ mod sealed {
297
296
298
297
/// Returns whether the feature is required by the given flags.
299
298
#[ inline]
300
- fn requires_feature( flags: & Vec < u8 > ) -> bool {
299
+ fn requires_feature( flags: & [ u8 ] ) -> bool {
301
300
flags. len( ) > Self :: BYTE_OFFSET &&
302
301
( flags[ Self :: BYTE_OFFSET ] & Self :: REQUIRED_MASK ) != 0
303
302
}
304
303
305
304
/// Returns whether the feature is supported by the given flags.
306
305
#[ inline]
307
- fn supports_feature( flags: & Vec < u8 > ) -> bool {
306
+ fn supports_feature( flags: & [ u8 ] ) -> bool {
308
307
flags. len( ) > Self :: BYTE_OFFSET &&
309
308
( flags[ Self :: BYTE_OFFSET ] & ( Self :: REQUIRED_MASK | Self :: OPTIONAL_MASK ) ) != 0
310
309
}
311
310
312
311
/// Sets the feature's required (even) bit in the given flags.
313
312
#[ 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 ) ;
317
316
}
318
317
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 ;
321
320
}
322
321
323
322
/// Sets the feature's optional (odd) bit in the given flags.
324
323
#[ 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 ) ;
328
327
}
329
328
330
- flags[ Self :: BYTE_OFFSET ] |= Self :: OPTIONAL_MASK ;
329
+ obj . flags[ Self :: BYTE_OFFSET ] |= Self :: OPTIONAL_MASK ;
331
330
}
332
331
333
332
/// Clears the feature's required (even) and optional (odd) bits from the given
334
333
/// flags.
335
334
#[ 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 ;
340
339
}
341
340
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 ) ;
343
342
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 ) ;
345
344
}
346
345
}
347
346
348
347
impl <T : $feature> Features <T > {
349
348
/// Set this feature as optional.
350
349
pub fn $optional_setter( & mut self ) {
351
- <T as $feature>:: set_optional_bit( & mut self . flags ) ;
350
+ <T as $feature>:: set_optional_bit( self ) ;
352
351
}
353
352
354
353
/// Set this feature as required.
355
354
pub fn $required_setter( & mut self ) {
356
- <T as $feature>:: set_required_bit( & mut self . flags ) ;
355
+ <T as $feature>:: set_required_bit( self ) ;
357
356
}
358
357
359
358
/// Unsets this feature.
360
359
pub fn $clear( & mut self ) {
361
- <T as $feature>:: clear_bits( & mut self . flags ) ;
360
+ <T as $feature>:: clear_bits( self ) ;
362
361
}
363
362
364
363
/// Checks if this feature is supported.
@@ -661,6 +660,9 @@ mod sealed {
661
660
supports_trampoline_routing,
662
661
requires_trampoline_routing
663
662
) ;
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 ;
664
666
define_feature ! (
665
667
259 ,
666
668
DnsResolver ,
@@ -700,14 +702,138 @@ mod sealed {
700
702
const ANY_REQUIRED_FEATURES_MASK : u8 = 0b01_01_01_01 ;
701
703
const ANY_OPTIONAL_FEATURES_MASK : u8 = 0b10_10_10_10 ;
702
704
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
+
703
829
/// Tracks the set of features which a node implements, templated by the context in which it
704
830
/// appears.
705
831
///
706
832
/// This is not exported to bindings users as we map the concrete feature types below directly instead
707
833
#[ derive( Eq ) ]
708
- pub struct Features < T : sealed:: Context > {
834
+ pub struct Features < T : sealed:: Context + ? Sized > {
709
835
/// Note that, for convenience, flags is LITTLE endian (despite being big-endian on the wire)
710
- flags : Vec < u8 > ,
836
+ flags : FeatureFlags ,
711
837
mark : PhantomData < T > ,
712
838
}
713
839
@@ -744,7 +870,7 @@ impl<T: sealed::Context> Hash for Features<T> {
744
870
nonzero_flags. hash ( hasher) ;
745
871
}
746
872
}
747
- impl < T : sealed:: Context > PartialEq for Features < T > {
873
+ impl < T : sealed:: Context + ? Sized > PartialEq for Features < T > {
748
874
fn eq ( & self , o : & Self ) -> bool {
749
875
let mut o_iter = o. flags . iter ( ) ;
750
876
let mut self_iter = self . flags . iter ( ) ;
@@ -879,25 +1005,23 @@ impl ChannelTypeFeatures {
879
1005
/// Constructs a ChannelTypeFeatures with only static_remotekey set
880
1006
pub fn only_static_remote_key ( ) -> Self {
881
1007
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) ;
883
1009
ret
884
1010
}
885
1011
886
1012
/// Constructs a ChannelTypeFeatures with anchors support
887
1013
pub fn anchors_zero_htlc_fee_and_dependencies ( ) -> Self {
888
1014
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) ;
893
1017
ret
894
1018
}
895
1019
}
896
1020
897
1021
impl < T : sealed:: Context > Features < T > {
898
1022
/// Create a blank Features with no features set
899
1023
pub fn empty ( ) -> Self {
900
- Features { flags : Vec :: new ( ) , mark : PhantomData }
1024
+ Features { flags : FeatureFlags :: empty ( ) , mark : PhantomData }
901
1025
}
902
1026
903
1027
/// 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> {
910
1034
None
911
1035
}
912
1036
} ) ;
913
- let mut flags = Vec :: new ( ) ;
1037
+ let mut flags = FeatureFlags :: empty ( ) ;
914
1038
flags. resize ( flag_iter. clone ( ) . count ( ) , 0 ) ;
915
1039
for ( i, byte) in flag_iter {
916
1040
flags[ i] = byte;
@@ -923,7 +1047,7 @@ impl<T: sealed::Context> Features<T> {
923
1047
///
924
1048
/// This is not exported to bindings users as we don't support export across multiple T
925
1049
pub fn from_le_bytes ( flags : Vec < u8 > ) -> Features < T > {
926
- Features { flags, mark : PhantomData }
1050
+ Features { flags : FeatureFlags :: from ( flags ) , mark : PhantomData }
927
1051
}
928
1052
929
1053
/// 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> {
938
1062
/// This is not exported to bindings users as we don't support export across multiple T
939
1063
pub fn from_be_bytes ( mut flags : Vec < u8 > ) -> Features < T > {
940
1064
flags. reverse ( ) ; // Swap to little-endian
941
- Self { flags, mark : PhantomData }
1065
+ Self { flags : FeatureFlags :: from ( flags ) , mark : PhantomData }
942
1066
}
943
1067
944
1068
/// Returns true if this `Features` has any optional flags set
@@ -1331,7 +1455,7 @@ mod tests {
1331
1455
use std:: hash:: { Hash , Hasher } ;
1332
1456
1333
1457
let mut zerod_features = InitFeatures :: empty ( ) ;
1334
- zerod_features. flags = vec ! [ 0 ] ;
1458
+ zerod_features. flags = FeatureFlags :: Heap ( vec ! [ 0 ] ) ;
1335
1459
let empty_features = InitFeatures :: empty ( ) ;
1336
1460
assert ! ( empty_features. flags. is_empty( ) ) ;
1337
1461
@@ -1343,4 +1467,27 @@ mod tests {
1343
1467
empty_features. hash ( & mut empty_hash) ;
1344
1468
assert_eq ! ( zerod_hash. finish( ) , empty_hash. finish( ) ) ;
1345
1469
}
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
+ }
1346
1493
}
0 commit comments