Line data Source code
1 : #include "fd_runtime_init.h" 2 : #include "fd_acc_mgr.h" 3 : #include "../types/fd_types.h" 4 : #include "context/fd_exec_slot_ctx.h" 5 : #include "fd_system_ids.h" 6 : 7 : /* fd_feature_restore loads a feature from the accounts database and 8 : updates the bank's feature activation state, given a feature account 9 : address. */ 10 : 11 : static void 12 : fd_feature_restore( fd_features_t * features, 13 : fd_exec_slot_ctx_t * slot_ctx, 14 : fd_feature_id_t const * id, 15 : uchar const acct[ static 32 ], 16 0 : fd_spad_t * runtime_spad ) { 17 : 18 : /* Skip reverted features */ 19 0 : if( FD_UNLIKELY( id->reverted ) ) { 20 0 : return; 21 0 : } 22 : 23 0 : FD_TXN_ACCOUNT_DECL( acct_rec ); 24 0 : int err = fd_txn_account_init_from_funk_readonly( acct_rec, 25 0 : (fd_pubkey_t *)acct, 26 0 : slot_ctx->funk, 27 0 : slot_ctx->funk_txn ); 28 0 : if( FD_UNLIKELY( err!=FD_ACC_MGR_SUCCESS ) ) { 29 0 : return; 30 0 : } 31 : 32 : /* Skip accounts that are not owned by the feature program 33 : https://github.com/anza-xyz/solana-sdk/blob/6512aca61167088ce10f2b545c35c9bcb1400e70/feature-gate-interface/src/lib.rs#L42-L44 */ 34 0 : if( FD_UNLIKELY( memcmp( acct_rec->vt->get_owner( acct_rec ), fd_solana_feature_program_id.key, sizeof(fd_pubkey_t) ) ) ) { 35 0 : return; 36 0 : } 37 : 38 : /* Account data size must be >= FD_FEATURE_SIZEOF (9 bytes) 39 : https://github.com/anza-xyz/solana-sdk/blob/6512aca61167088ce10f2b545c35c9bcb1400e70/feature-gate-interface/src/lib.rs#L45-L47 */ 40 0 : if( FD_UNLIKELY( acct_rec->vt->get_data_len( acct_rec )<FD_FEATURE_SIZEOF ) ) { 41 0 : return; 42 0 : } 43 : 44 : /* Deserialize the feature account data 45 : https://github.com/anza-xyz/solana-sdk/blob/6512aca61167088ce10f2b545c35c9bcb1400e70/feature-gate-interface/src/lib.rs#L48-L50 */ 46 0 : FD_SPAD_FRAME_BEGIN( runtime_spad ) { 47 0 : int decode_err; 48 0 : fd_feature_t * feature = fd_bincode_decode_spad( 49 0 : feature, runtime_spad, 50 0 : acct_rec->vt->get_data( acct_rec ), 51 0 : acct_rec->vt->get_data_len( acct_rec ), 52 0 : &decode_err ); 53 0 : if( FD_UNLIKELY( decode_err ) ) { 54 0 : return; 55 0 : } 56 : 57 0 : if( feature->has_activated_at ) { 58 0 : FD_LOG_INFO(( "Feature %s activated at %lu", FD_BASE58_ENC_32_ALLOCA( acct ), feature->activated_at )); 59 0 : fd_features_set( features, id, feature->activated_at ); 60 0 : } else { 61 0 : FD_LOG_DEBUG(( "Feature %s not activated at %lu", FD_BASE58_ENC_32_ALLOCA( acct ), feature->activated_at )); 62 0 : } 63 : /* No need to call destroy, since we are using fd_spad allocator. */ 64 0 : } FD_SPAD_FRAME_END; 65 0 : } 66 : 67 : void 68 0 : fd_features_restore( fd_exec_slot_ctx_t * slot_ctx, fd_spad_t * runtime_spad ) { 69 0 : fd_features_t * features = fd_bank_features_modify( slot_ctx->bank ); 70 : 71 0 : for( fd_feature_id_t const * id = fd_feature_iter_init(); 72 0 : !fd_feature_iter_done( id ); 73 0 : id = fd_feature_iter_next( id ) ) { 74 0 : fd_feature_restore( features, slot_ctx, id, id->id.key, runtime_spad ); 75 0 : } 76 0 : }