Line data Source code
1 : #ifndef HEADER_fd_src_flamenco_features_fd_features_h 2 : #define HEADER_fd_src_flamenco_features_fd_features_h 3 : 4 : #include "../fd_flamenco_base.h" 5 : #include "fd_features_generated.h" 6 : #include "../types/fd_types.h" 7 : /* Macro FEATURE_ID_CNT expands to the number of features in 8 : fd_features_t. */ 9 : 10 : //#define FD_FEATURE_ID_CNT (... see generated.h ...) 11 : 12 : /* FD_FEATURE_DISABLED is the sentinel value of the feature activation 13 : slot when the feature has not yet been activated. */ 14 : 15 1863333 : #define FD_FEATURE_DISABLED (ULONG_MAX) 16 : 17 : /* Convenience macros for checking features */ 18 : 19 8571 : #define FD_FEATURE_ACTIVE_(_slot, _features, _feature_name) ( _slot >= (_features)-> _feature_name ) 20 : #define FD_FEATURE_JUST_ACTIVATED_(_slot, _features, _feature_name) ( _slot == (_features). _feature_name ) 21 0 : #define FD_FEATURE_ACTIVE_OFFSET_(_slot, _features, _offset) ( _slot >= (_features).f[_offset>>3] ) 22 0 : #define FD_FEATURE_JUST_ACTIVATED_OFFSET_(_slot, _features, _offset) ( _slot == (_features).f[_offset>>3] ) 23 : 24 : #define FD_FEATURE_SET_ACTIVE(_features, _feature_name, _slot) ( (_features)-> _feature_name = _slot ) 25 0 : #define FD_FEATURE_ACTIVE_OFFSET(_slot, _features, _offset) FD_FEATURE_ACTIVE_OFFSET_( _slot, _features, _offset ) 26 0 : #define FD_FEATURE_JUST_ACTIVATED_OFFSET(_bank, _offset) FD_FEATURE_JUST_ACTIVATED_OFFSET_( fd_bank_slot_get( _bank ), fd_bank_features_get( _bank ), _offset ) 27 8463 : #define FD_FEATURE_ACTIVE(_slot, _features, _feature_name) FD_FEATURE_ACTIVE_( _slot, _features, _feature_name ) 28 0 : #define FD_FEATURE_ACTIVE_BANK(_bank, _feature_name) FD_FEATURE_ACTIVE_( fd_bank_slot_get( _bank ), fd_bank_features_query( _bank ), _feature_name ) 29 : 30 : 31 : /* fd_features_t is the current set of enabled feature flags. 32 : 33 : Each feature has a corresponding account in the account database, 34 : which are used to control activation. This structure contains an 35 : ulong of the activation slots of each feature for convenience (or 36 : FD_FEATURE_DISABLED if not yet activated). The feature params 37 : contained in this structure change over time, as activated features 38 : become default, and as new pending feature activations get added. 39 : 40 : Usage: 41 : 42 : fd_features_t * features; 43 : 44 : // Direct API 45 : ulong activation_slot = features->FEATURE_NAME; 46 : 47 : // Indirect API 48 : fd_feature_id_t const * id; 49 : ulong activation_slot = fd_features_get( id ); 50 : ... id->index safe in [0,FD_FEATURE_CNT) ... */ 51 : 52 : typedef union fd_features fd_features_t; 53 : 54 : /* fd_feature_id_t maps a feature ID (account address) to the byte 55 : offset in fd_features_t. */ 56 : 57 : struct fd_feature_id { 58 : ulong index; /* index of feature in fd_features_t */ 59 : fd_pubkey_t id; /* pubkey of feature */ 60 : char const * name; /* feature name cstr */ 61 : uint cleaned_up[3]; /* cleaned_up cluster version for feature */ 62 : uchar reverted; /* if the feature was reverted */ 63 : uchar hardcode_for_fuzzing; /* if the should be treated as hardcoded in the firedancer fuzzing harness */ 64 : }; 65 : typedef struct fd_feature_id fd_feature_id_t; 66 : 67 : FD_PROTOTYPES_BEGIN 68 : 69 : /* fd_feature_ids is the list of known feature IDs. 70 : The last element has offset==ULONG_MAX. */ 71 : extern fd_feature_id_t const ids[]; 72 : 73 : /* fd_features_disable_all disables all features (cleaned_up or not). */ 74 : 75 : void 76 : fd_features_disable_all( fd_features_t * f ); 77 : 78 : /* fd_features_enable_all enables all features (supported or not). */ 79 : 80 : void 81 : fd_features_enable_all( fd_features_t * ); 82 : 83 : /* fd_features_enable_cleaned_up enables all features marked as "hard 84 : coded". These are features that are baked into the current version 85 : of the Firedancer software and can't be disabled. */ 86 : 87 : void 88 : fd_features_enable_cleaned_up( fd_features_t *, fd_cluster_version_t const * ); 89 : 90 : /* fd_features_enable_one_offs enables all manually passed in features. */ 91 : 92 : void 93 : fd_features_enable_one_offs( fd_features_t * features, 94 : char const * * one_offs, 95 : uint one_offs_cnt, 96 : ulong slot ); 97 : 98 : /* fd_feature_iter_{...} is an iterator-style API over all supported 99 : features in this version of Firedancer. Usage: 100 : 101 : for( fd_feature_id_t const * id = fd_feature_iter_init(); 102 : !fd_feature_iter_done( id ); 103 : id = fd_feature_iter_next( id ) ) { 104 : ... 105 : } */ 106 : 107 : static inline fd_feature_id_t const * 108 7692 : fd_feature_iter_init( void ) { 109 7692 : return ids; 110 7692 : } 111 : 112 : static inline int 113 1876848 : fd_feature_iter_done( fd_feature_id_t const * id ) { 114 1876848 : return id->index == ULONG_MAX; 115 1876848 : } 116 : 117 : static inline fd_feature_id_t const * 118 1869156 : fd_feature_iter_next( fd_feature_id_t const * id ) { 119 1869156 : return id+1; 120 1869156 : } 121 : 122 : /* fd_features_set sets the activation slot of the given feature ID. */ 123 : 124 : static inline void 125 : fd_features_set( fd_features_t * features, 126 : fd_feature_id_t const * id, 127 1871718 : ulong slot ) { 128 1871718 : features->f[ id->index ] = slot; 129 1871718 : } 130 : 131 : /* fd_features_get returns the activation slot of the given feature ID. 132 : Returns ULONG_MAX if the feature is not scheduled for activation. */ 133 : 134 : static inline ulong 135 : fd_features_get( fd_features_t const * features, 136 729 : fd_feature_id_t const * id ) { 137 729 : return features->f[ id->index ]; 138 729 : } 139 : 140 : /* fd_feature_id_query queries a feature ID given the first 8 bytes of 141 : the feature address (little-endian order). Returns pointer to ID in 142 : `ids` array on success, or NULL on failure. */ 143 : 144 : FD_FN_CONST fd_feature_id_t const * 145 : fd_feature_id_query( ulong prefix ); 146 : 147 : FD_PROTOTYPES_END 148 : 149 : #endif /* HEADER_fd_src_flamenco_features_fd_features_h */