LCOV - code coverage report
Current view: top level - flamenco/features - fd_features.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 25 82 30.5 %
Date: 2025-12-05 04:49:52 Functions: 3 6 50.0 %

          Line data    Source code
       1             : #include "fd_features.h"
       2             : #include "../runtime/fd_bank.h"
       3             : #include "../runtime/fd_acc_mgr.h"
       4             : #include "../runtime/fd_system_ids.h"
       5             : 
       6             : void
       7           6 : fd_features_enable_all( fd_features_t * f ) {
       8           6 :   for( fd_feature_id_t const * id = fd_feature_iter_init();
       9        1500 :        !fd_feature_iter_done( id );
      10        1494 :        id = fd_feature_iter_next( id ) ) {
      11        1494 :     fd_features_set( f, id, 0UL );
      12        1494 :   }
      13           6 : }
      14             : 
      15             : void
      16        7668 : fd_features_disable_all( fd_features_t * f ) {
      17        7668 :   for( fd_feature_id_t const * id = fd_feature_iter_init();
      18     1917000 :        !fd_feature_iter_done( id );
      19     1909332 :        id = fd_feature_iter_next( id ) ) {
      20     1909332 :     fd_features_set( f, id, FD_FEATURE_DISABLED );
      21     1909332 :   }
      22        7668 : }
      23             : 
      24             : void
      25           0 : fd_features_enable_cleaned_up( fd_features_t * f, fd_cluster_version_t const * cluster_version ) {
      26           0 :   for( fd_feature_id_t const * id = fd_feature_iter_init();
      27           0 :        !fd_feature_iter_done( id );
      28           0 :        id = fd_feature_iter_next( id ) ) {
      29           0 :     if( ( id->cleaned_up[0]<cluster_version->major ) ||
      30           0 :         ( id->cleaned_up[0]==cluster_version->major && id->cleaned_up[1]<cluster_version->minor ) ||
      31           0 :         ( id->cleaned_up[0]==cluster_version->major && id->cleaned_up[1]==cluster_version->minor && id->cleaned_up[2]<=cluster_version->patch ) ) {
      32           0 :       fd_features_set( f, id, 0UL );
      33           0 :     } else {
      34           0 :       fd_features_set( f, id, FD_FEATURE_DISABLED );
      35           0 :     }
      36           0 :   }
      37           0 : }
      38             : 
      39             : void
      40          18 : fd_features_enable_one_offs( fd_features_t * f, char const * * one_offs, uint one_offs_cnt, ulong slot ) {
      41          18 :   uchar pubkey[32];
      42          36 :   for( uint i=0U; i<one_offs_cnt; i++ ) {
      43          18 :     fd_base58_decode_32( one_offs[i], pubkey );
      44          18 :     for( fd_feature_id_t const * id = fd_feature_iter_init();
      45        4500 :          !fd_feature_iter_done( id );
      46        4482 :          id = fd_feature_iter_next( id ) ) {
      47        4482 :       if( !memcmp( &id->id, pubkey, sizeof(fd_pubkey_t) ) ) {
      48           0 :         fd_features_set( f, id, slot );
      49           0 :         break;
      50           0 :       }
      51        4482 :     }
      52          18 :   }
      53          18 : }
      54             : 
      55             : static void
      56             : fd_feature_restore( fd_bank_t *               bank,
      57             :                     fd_funk_t *               funk,
      58             :                     fd_funk_txn_xid_t const * xid,
      59             :                     fd_feature_id_t const *   id,
      60           0 :                     fd_pubkey_t const *       addr ) {
      61             : 
      62           0 :   fd_features_t * features = fd_bank_features_modify( bank );
      63             : 
      64             :   /* https://github.com/anza-xyz/solana-sdk/blob/6512aca61167088ce10f2b545c35c9bcb1400e70/feature-gate-interface/src/lib.rs#L36-L38 */
      65           0 :   #define FD_FEATURE_SIZEOF      (9UL)
      66             : 
      67             :   /* Skip reverted features */
      68           0 :   if( FD_UNLIKELY( id->reverted ) ) return;
      69             : 
      70           0 :   fd_txn_account_t acct_rec[1];
      71           0 :   int err = fd_txn_account_init_from_funk_readonly( acct_rec,
      72           0 :                                                     addr,
      73           0 :                                                     funk,
      74           0 :                                                     xid );
      75           0 :   if( FD_UNLIKELY( err!=FD_ACC_MGR_SUCCESS ) ) {
      76           0 :     return;
      77           0 :   }
      78             : 
      79             :   /* Skip accounts that are not owned by the feature program
      80             :      https://github.com/anza-xyz/solana-sdk/blob/6512aca61167088ce10f2b545c35c9bcb1400e70/feature-gate-interface/src/lib.rs#L42-L44 */
      81           0 :   if( FD_UNLIKELY( memcmp( fd_txn_account_get_owner( acct_rec ), fd_solana_feature_program_id.key, sizeof(fd_pubkey_t) ) ) ) {
      82           0 :     return;
      83           0 :   }
      84             : 
      85             :   /* Account data size must be >= FD_FEATURE_SIZEOF (9 bytes)
      86             :      https://github.com/anza-xyz/solana-sdk/blob/6512aca61167088ce10f2b545c35c9bcb1400e70/feature-gate-interface/src/lib.rs#L45-L47 */
      87           0 :   if( FD_UNLIKELY( fd_txn_account_get_data_len( acct_rec )<FD_FEATURE_SIZEOF ) ) {
      88           0 :     return;
      89           0 :   }
      90             : 
      91             :   /* Deserialize the feature account data
      92             :      https://github.com/anza-xyz/solana-sdk/blob/6512aca61167088ce10f2b545c35c9bcb1400e70/feature-gate-interface/src/lib.rs#L48-L50 */
      93           0 :   fd_feature_t feature[1];
      94           0 :   if( FD_UNLIKELY( !fd_bincode_decode_static(
      95           0 :       feature, feature,
      96           0 :       fd_txn_account_get_data( acct_rec ),
      97           0 :       fd_txn_account_get_data_len( acct_rec ),
      98           0 :       NULL ) ) ) {
      99           0 :     return;
     100           0 :   }
     101             : 
     102           0 :   FD_BASE58_ENCODE_32_BYTES( addr->uc, addr_b58 );
     103           0 :   if( feature->has_activated_at ) {
     104           0 :     FD_LOG_DEBUG(( "Feature %s activated at %lu", addr_b58, feature->activated_at ));
     105           0 :     fd_features_set( features, id, feature->activated_at );
     106           0 :   } else {
     107           0 :     FD_LOG_DEBUG(( "Feature %s not activated at %lu", addr_b58, feature->activated_at ));
     108           0 :   }
     109           0 : }
     110             : 
     111             : void
     112             : fd_features_restore( fd_bank_t *               bank,
     113             :                      fd_funk_t *               funk,
     114           0 :                      fd_funk_txn_xid_t const * xid ) {
     115             : 
     116           0 :   for( fd_feature_id_t const * id = fd_feature_iter_init();
     117           0 :                                    !fd_feature_iter_done( id );
     118           0 :                                id = fd_feature_iter_next( id ) ) {
     119           0 :     fd_feature_restore( bank, funk, xid, id, &id->id );
     120           0 :   }
     121           0 : }

Generated by: LCOV version 1.14