LCOV - code coverage report
Current view: top level - flamenco/features - fd_features.h (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 27 28 96.4 %
Date: 2026-10-22 04:28:21 Functions: 26 1494 1.7 %

          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 */

Generated by: LCOV version 1.14