Line data Source code
1 : #include "fd_sysvar_last_restart_slot.h" 2 : #include "fd_sysvar.h" 3 : #include "../fd_system_ids.h" 4 : #include "../fd_runtime.h" 5 : #include "../context/fd_exec_slot_ctx.h" 6 : 7 : void 8 : fd_sysvar_last_restart_slot_write( 9 : fd_exec_slot_ctx_t * slot_ctx, 10 : fd_sol_sysvar_last_restart_slot_t const * sysvar 11 0 : ) { 12 0 : uchar enc[ 8 ]; 13 0 : FD_STORE( ulong, enc, sysvar->slot ); 14 0 : fd_sysvar_account_update( slot_ctx, &fd_sysvar_last_restart_slot_id, enc, sizeof(enc) ); 15 0 : } 16 : 17 : void 18 0 : fd_sysvar_last_restart_slot_init( fd_exec_slot_ctx_t * slot_ctx ) { 19 : 20 0 : if( !FD_FEATURE_ACTIVE_BANK( slot_ctx->bank, last_restart_slot_sysvar ) ) { 21 0 : return; 22 0 : } 23 : 24 0 : fd_sol_sysvar_last_restart_slot_t sysvar = {0}; 25 0 : fd_sysvar_last_restart_slot_write( slot_ctx, &sysvar ); 26 0 : } 27 : 28 : /* https://github.com/anza-xyz/agave/blob/v2.3.2/runtime/src/bank.rs#L2217 */ 29 : 30 : ulong 31 : fd_sysvar_last_restart_slot_derive( 32 : fd_hard_forks_global_t const * hard_forks, 33 : ulong current_slot 34 0 : ) { 35 : 36 0 : if( FD_UNLIKELY( hard_forks->hard_forks_len == 0 ) ) { 37 : /* SIMD-0047: The first restart slot should be `0` */ 38 0 : return 0UL; 39 0 : } 40 : 41 0 : fd_slot_pair_t const * head = fd_hard_forks_hard_forks_join( (fd_hard_forks_global_t *)hard_forks ); 42 0 : fd_slot_pair_t const * tail = head + hard_forks->hard_forks_len - 1UL; 43 : 44 0 : for( fd_slot_pair_t const *pair = tail; pair >= head; pair-- ) { 45 0 : if( pair->slot <= current_slot ) { 46 0 : return pair->slot; 47 0 : } 48 0 : } 49 : 50 0 : return 0UL; 51 0 : } 52 : 53 : fd_sol_sysvar_last_restart_slot_t * 54 : fd_sysvar_last_restart_slot_read( 55 : fd_funk_t * funk, 56 : fd_funk_txn_t * funk_txn, 57 : fd_sol_sysvar_last_restart_slot_t * out 58 0 : ) { 59 : 60 0 : FD_TXN_ACCOUNT_DECL( acc ); 61 0 : int err = fd_txn_account_init_from_funk_readonly( acc, &fd_sysvar_last_restart_slot_id, funk, funk_txn ); 62 0 : if( FD_UNLIKELY( err!=FD_ACC_MGR_SUCCESS ) ) return NULL; 63 : 64 : /* This check is needed as a quirk of the fuzzer. If a sysvar account 65 : exists in the accounts database, but doesn't have any lamports, 66 : this means that the account does not exist. This wouldn't happen 67 : in a real execution environment. */ 68 0 : if( FD_UNLIKELY( acc->vt->get_lamports( acc )==0 ) ) return NULL; 69 : 70 0 : return fd_bincode_decode_static( 71 0 : sol_sysvar_last_restart_slot, out, 72 0 : acc->vt->get_data( acc ), 73 0 : acc->vt->get_data_len( acc ), 74 0 : &err ); 75 0 : } 76 : 77 : /* fd_sysvar_last_restart_slot_update is equivalent to 78 : Agave's solana_runtime::bank::Bank::update_last_restart_slot */ 79 : 80 : void 81 : fd_sysvar_last_restart_slot_update( 82 : fd_exec_slot_ctx_t * slot_ctx, 83 : ulong last_restart_slot_want 84 0 : ) { 85 : 86 : /* https://github.com/solana-labs/solana/blob/v1.18.18/runtime/src/bank.rs#L2093-L2095 */ 87 0 : if( !FD_FEATURE_ACTIVE_BANK( slot_ctx->bank, last_restart_slot_sysvar ) ) return; 88 : 89 : /* https://github.com/solana-labs/solana/blob/v1.18.18/runtime/src/bank.rs#L2098-L2106 */ 90 0 : ulong last_restart_slot_have = ULONG_MAX; 91 0 : fd_sol_sysvar_last_restart_slot_t sysvar; 92 0 : if( FD_LIKELY( fd_sysvar_last_restart_slot_read( slot_ctx->funk, slot_ctx->funk_txn, &sysvar ) ) ) { 93 0 : last_restart_slot_have = sysvar.slot; 94 0 : } 95 : 96 : /* https://github.com/solana-labs/solana/blob/v1.18.18/runtime/src/bank.rs#L2122-L2130 */ 97 0 : if( last_restart_slot_have != last_restart_slot_want ) { 98 0 : sysvar.slot = last_restart_slot_want; 99 0 : fd_sysvar_last_restart_slot_write( slot_ctx, &sysvar ); 100 0 : } 101 0 : }