Line data Source code
1 : #include "fd_runtime_init.h" 2 : #include "fd_acc_mgr.h" 3 : #include "fd_bank.h" 4 : #include "../types/fd_types.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_bank_t * bank, 13 : fd_funk_t * funk, 14 : fd_funk_txn_xid_t const * xid, 15 : fd_feature_id_t const * id, 16 0 : fd_pubkey_t const * addr ) { 17 : 18 0 : fd_features_t * features = fd_bank_features_modify( bank ); 19 : 20 : /* Skip reverted features */ 21 0 : if( FD_UNLIKELY( id->reverted ) ) return; 22 : 23 0 : FD_TXN_ACCOUNT_DECL( acct_rec ); 24 0 : int err = fd_txn_account_init_from_funk_readonly( acct_rec, 25 0 : addr, 26 0 : funk, 27 0 : xid ); 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( fd_txn_account_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( fd_txn_account_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_feature_t feature[1]; 47 0 : if( FD_UNLIKELY( !fd_bincode_decode_static( 48 0 : feature, feature, 49 0 : fd_txn_account_get_data( acct_rec ), 50 0 : fd_txn_account_get_data_len( acct_rec ), 51 0 : NULL ) ) ) { 52 0 : return; 53 0 : } 54 : 55 0 : FD_BASE58_ENCODE_32_BYTES( addr->uc, addr_b58 ); 56 0 : if( feature->has_activated_at ) { 57 0 : FD_LOG_DEBUG(( "Feature %s activated at %lu", addr_b58, feature->activated_at )); 58 0 : fd_features_set( features, id, feature->activated_at ); 59 0 : } else { 60 0 : FD_LOG_DEBUG(( "Feature %s not activated at %lu", addr_b58, feature->activated_at )); 61 0 : } 62 0 : } 63 : 64 : void 65 : fd_features_restore( fd_bank_t * bank, 66 : fd_funk_t * funk, 67 0 : fd_funk_txn_xid_t const * xid ) { 68 : 69 0 : for( fd_feature_id_t const * id = fd_feature_iter_init(); 70 0 : !fd_feature_iter_done( id ); 71 0 : id = fd_feature_iter_next( id ) ) { 72 0 : fd_feature_restore( bank, funk, xid, id, &id->id ); 73 0 : } 74 0 : }