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 : }