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