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 "../accdb/fd_accdb.h"
7 :
8 : /* Macro FEATURE_ID_CNT expands to the number of features in
9 : fd_features_t. */
10 :
11 : //#define FD_FEATURE_ID_CNT (... see generated.h ...)
12 :
13 : /* FD_FEATURE_DISABLED is the sentinel value of the feature activation
14 : slot when the feature has not yet been activated. */
15 :
16 3125079 : #define FD_FEATURE_DISABLED (ULONG_MAX)
17 :
18 : /* Convenience macros for checking features */
19 :
20 1114063 : #define FD_FEATURE_ACTIVE_(_slot, _features, _feature_name) ( _slot >= (_features)-> _feature_name )
21 : #define FD_FEATURE_JUST_ACTIVATED_(_slot, _features, _feature_name) ( _slot == (_features)-> _feature_name )
22 3456 : #define FD_FEATURE_ACTIVE_OFFSET_(_slot, _features, _offset) ( _slot >= (_features)->f[_offset>>3] )
23 909 : #define FD_FEATURE_JUST_ACTIVATED_OFFSET_(_slot, _features, _offset) ( _slot == (_features)->f[_offset>>3] )
24 :
25 2919 : #define FD_FEATURE_SET_ACTIVE(_features, _feature_name, _slot) ( (_features)-> _feature_name = _slot )
26 606 : #define FD_FEATURE_ACTIVE_OFFSET(_slot, _features, _offset) FD_FEATURE_ACTIVE_OFFSET_( _slot, _features, _offset )
27 909 : #define FD_FEATURE_JUST_ACTIVATED_OFFSET(_bank, _offset) FD_FEATURE_JUST_ACTIVATED_OFFSET_( (_bank)->f.slot, &(_bank)->f.features, _offset )
28 1088131 : #define FD_FEATURE_ACTIVE(_slot, _features, _feature_name) FD_FEATURE_ACTIVE_( _slot, _features, _feature_name )
29 25104 : #define FD_FEATURE_ACTIVE_BANK(_bank, _feature_name) FD_FEATURE_ACTIVE_( (_bank)->f.slot, &(_bank)->f.features, _feature_name )
30 0 : #define FD_FEATURE_ACTIVE_BANK_OFFSET(_bank, _offset) FD_FEATURE_ACTIVE_OFFSET_( (_bank)->f.slot, &(_bank)->f.features, _offset )
31 : #define FD_FEATURE_JUST_ACTIVATED_BANK(_bank, _feature_name) FD_FEATURE_JUST_ACTIVATED_( (_bank)->f.slot, &(_bank)->f.features, _feature_name )
32 :
33 : struct __attribute__((packed)) fd_feature {
34 : uchar is_active; /* 0 or 1 */
35 : ulong activation_slot;
36 : };
37 :
38 : typedef struct fd_feature fd_feature_t;
39 :
40 : /* fd_features_t is the current set of enabled feature flags.
41 :
42 : Each feature has a corresponding account in the account database,
43 : which are used to control activation. This structure contains an
44 : ulong of the activation slots of each feature for convenience (or
45 : FD_FEATURE_DISABLED if not yet activated). The feature params
46 : contained in this structure change over time, as activated features
47 : become default, and as new pending feature activations get added.
48 :
49 : Usage:
50 :
51 : fd_features_t * features;
52 :
53 : // Direct API
54 : ulong activation_slot = features->FEATURE_NAME;
55 :
56 : // Indirect API
57 : fd_feature_id_t const * id;
58 : ulong activation_slot = fd_features_get( id );
59 : ... id->index safe in [0,FD_FEATURE_CNT) ... */
60 :
61 : typedef union fd_features fd_features_t;
62 :
63 : /* fd_feature_id_t maps a feature ID (account address) to the byte
64 : offset in fd_features_t. */
65 :
66 : struct fd_feature_id {
67 : ulong index; /* index of feature in fd_features_t */
68 : fd_pubkey_t id; /* pubkey of feature */
69 : char const * name; /* feature name cstr */
70 : uchar implemented; /* 1 if the feature's behavior is implemented in firedancer, 0 otherwise */
71 : uchar cleaned_up; /* 1 if feature is cleaned up in firedancer, 0 otherwise */
72 : uchar reverted; /* if the feature was reverted */
73 : uchar hardcode_for_fuzzing; /* if the should be treated as hardcoded in the firedancer fuzzing harness */
74 : };
75 : typedef struct fd_feature_id fd_feature_id_t;
76 :
77 : FD_PROTOTYPES_BEGIN
78 :
79 : fd_feature_t *
80 : fd_feature_decode( fd_feature_t * feature,
81 : uchar const * data,
82 : ulong data_sz );
83 :
84 : /* fd_feature_ids is the list of known feature IDs.
85 : The last element has offset==ULONG_MAX. */
86 : extern fd_feature_id_t const ids[];
87 :
88 : /* fd_features_disable_all disables all features (cleaned_up or not). */
89 :
90 : void
91 : fd_features_disable_all( fd_features_t * f );
92 :
93 : /* fd_features_enable_all enables all features (supported or not). */
94 :
95 : void
96 : fd_features_enable_all( fd_features_t * );
97 :
98 : /* fd_features_enable_cleaned_up enables all features marked as "hard
99 : coded". These are features that are baked into the current version
100 : of the Firedancer software and can't be disabled. */
101 :
102 : void
103 : fd_features_enable_cleaned_up( fd_features_t * );
104 :
105 : /* fd_features_enable_one_offs forces all manually passed in features to
106 : activate at slot. The feature will always stay activated. */
107 :
108 : void
109 : fd_features_enable_one_offs( fd_features_t * features,
110 : char const * * one_offs,
111 : uint one_offs_cnt,
112 : ulong slot );
113 :
114 : /* fd_feature_iter_{...} is an iterator-style API over all supported
115 : features in this version of Firedancer. Usage:
116 :
117 : for( fd_feature_id_t const * id = fd_feature_iter_init();
118 : !fd_feature_iter_done( id );
119 : id = fd_feature_iter_next( id ) ) {
120 : ...
121 : } */
122 :
123 : static inline fd_feature_id_t const *
124 13635 : fd_feature_iter_init( void ) {
125 13635 : return ids;
126 13635 : }
127 :
128 : static inline int
129 4108566 : fd_feature_iter_done( fd_feature_id_t const * id ) {
130 4108566 : return id->index == ULONG_MAX;
131 4108566 : }
132 :
133 : static inline fd_feature_id_t const *
134 4094931 : fd_feature_iter_next( fd_feature_id_t const * id ) {
135 4094931 : return id+1;
136 4094931 : }
137 :
138 : /* fd_features_set sets the activation slot of the given feature ID. */
139 :
140 : static inline void
141 : fd_features_set( fd_features_t * features,
142 : fd_feature_id_t const * id,
143 4222275 : ulong slot ) {
144 4222275 : features->f[ id->index ] = slot;
145 4222275 : }
146 :
147 : /* fd_features_get returns the activation slot of the given feature ID.
148 : Returns ULONG_MAX if the feature is not scheduled for activation. */
149 :
150 : static inline ulong
151 : fd_features_get( fd_features_t const * features,
152 6375 : fd_feature_id_t const * id ) {
153 6375 : return features->f[ id->index ];
154 6375 : }
155 :
156 : /* fd_features_get_activation_slot_from_offset returns the
157 : activation slot of the feature at byte offset `offset` within
158 : fd_features_t.
159 :
160 : Returns ULONG_MAX if the feature is not scheduled for activation. */
161 :
162 : static inline ulong
163 : fd_features_get_activation_slot_from_offset( fd_features_t const * features,
164 126798 : ulong offset ) {
165 126798 : return features->f[ offset>>3 ];
166 126798 : }
167 :
168 : /* fd_feature_id_query queries a feature ID given the first 8 bytes of
169 : the feature address (little-endian order). Returns pointer to ID in
170 : `ids` array on success, or NULL on failure. */
171 :
172 : FD_FN_PURE fd_feature_id_t const *
173 : fd_feature_id_query( ulong prefix );
174 :
175 : /* fd_features_restore loads all known feature accounts from the given
176 : accounts database fork and populates the in-memory feature set with
177 : their activation slots. If slot is the last slot before an epoch
178 : boundary, any pending features (is_active==0) will also be populated
179 : with slot+1 as their activation slot. Features forced on by
180 : fd_features_enable_one_offs stay activated. */
181 :
182 : void
183 : fd_features_restore( fd_features_t * features,
184 : fd_accdb_t * accdb,
185 : fd_accdb_fork_id_t fork_id,
186 : ulong slot,
187 : fd_epoch_schedule_t const * epoch_schedule );
188 :
189 : /* fd_features_restore_chunk behaves like fd_features_restore but only
190 : restores one balanced, contiguous chunk of the known feature IDs.
191 : Assumes chunk_cnt>0 and chunk_idx<chunk_cnt. */
192 :
193 : void
194 : fd_features_restore_chunk( fd_features_t * features,
195 : fd_accdb_t * accdb,
196 : fd_accdb_fork_id_t fork_id,
197 : ulong slot,
198 : fd_epoch_schedule_t const * epoch_schedule,
199 : ulong chunk_idx,
200 : ulong chunk_cnt );
201 :
202 : FD_PROTOTYPES_END
203 :
204 : #endif /* HEADER_fd_src_flamenco_features_fd_features_h */
|