Line data Source code
1 : #include "fd_sysvar_last_restart_slot.h" 2 : #include "fd_sysvar.h" 3 : #include "../fd_bank.h" 4 : #include "../fd_system_ids.h" 5 : #include "../../accdb/fd_accdb_sync.h" 6 : 7 : void 8 : fd_sysvar_last_restart_slot_write( 9 : fd_bank_t * bank, 10 : fd_accdb_user_t * accdb, 11 : fd_funk_txn_xid_t const * xid, 12 : fd_capture_ctx_t * capture_ctx, 13 : ulong slot 14 12 : ) { 15 12 : uchar enc[ 8 ]; 16 12 : FD_STORE( ulong, enc, slot ); 17 12 : fd_sysvar_account_update( bank, accdb, xid, capture_ctx, &fd_sysvar_last_restart_slot_id, enc, sizeof(enc) ); 18 12 : } 19 : 20 : void 21 : fd_sysvar_last_restart_slot_init( fd_bank_t * bank, 22 : fd_accdb_user_t * accdb, 23 : fd_funk_txn_xid_t const * xid, 24 0 : fd_capture_ctx_t * capture_ctx ) { 25 : 26 0 : if( !FD_FEATURE_ACTIVE_BANK( bank, last_restart_slot_sysvar ) ) return; 27 : 28 0 : fd_sysvar_last_restart_slot_write( bank, accdb, xid, capture_ctx, 0UL ); 29 0 : } 30 : 31 : ulong 32 : fd_sysvar_last_restart_slot_read( fd_accdb_user_t * accdb, 33 : fd_funk_txn_xid_t const * xid, 34 12 : ulong sentinel ) { 35 : 36 12 : fd_accdb_ro_t ro[1]; 37 12 : if( FD_UNLIKELY( !fd_accdb_open_ro( accdb, ro, xid, &fd_sysvar_last_restart_slot_id ) ) ) { 38 12 : return sentinel; 39 12 : } 40 : 41 : /* This check is needed as a quirk of the fuzzer. If a sysvar account 42 : exists in the accounts database, but doesn't have any lamports, 43 : this means that the account does not exist. This wouldn't happen 44 : in a real execution environment. */ 45 0 : if( FD_UNLIKELY( fd_accdb_ref_lamports( ro )==0UL ) ) { 46 0 : fd_accdb_close_ro( accdb, ro ); 47 0 : return sentinel; 48 0 : } 49 : 50 0 : ulong result = FD_LOAD( ulong, fd_accdb_ref_data_const( ro ) ); 51 0 : fd_accdb_close_ro( accdb, ro ); 52 0 : return result; 53 0 : } 54 : 55 : /* fd_sysvar_last_restart_slot_update is equivalent to 56 : Agave's solana_runtime::bank::Bank::update_last_restart_slot */ 57 : 58 : ulong 59 27 : fd_sysvar_last_restart_slot_derive( fd_bank_t const * bank ) { 60 27 : ulong slot = bank->f.slot; 61 27 : ulong last_restart_slot = 0UL; 62 : 63 63 : for( ulong i=0UL; i<bank->f.hard_fork_cnt; i++ ) { 64 36 : ulong hard_fork_slot = bank->f.hard_forks[ i ].slot; 65 36 : if( hard_fork_slot<=slot && hard_fork_slot>last_restart_slot ) { 66 24 : last_restart_slot = hard_fork_slot; 67 24 : } 68 36 : } 69 : 70 27 : return last_restart_slot; 71 27 : } 72 : 73 : void 74 : fd_sysvar_last_restart_slot_update( fd_bank_t * bank, 75 : fd_accdb_user_t * accdb, 76 : fd_funk_txn_xid_t const * xid, 77 3528 : fd_capture_ctx_t * capture_ctx ) { 78 : 79 : /* https://github.com/solana-labs/solana/blob/v1.18.18/runtime/src/bank.rs#L2093-L2095 */ 80 3528 : if( !FD_FEATURE_ACTIVE_BANK( bank, last_restart_slot_sysvar ) ) return; 81 : 82 12 : ulong last_restart_slot_want = fd_sysvar_last_restart_slot_derive( bank ); 83 12 : bank->f.last_restart_slot = last_restart_slot_want; 84 : 85 : /* https://github.com/solana-labs/solana/blob/v1.18.18/runtime/src/bank.rs#L2098-L2106 */ 86 12 : ulong last_restart_slot_have = fd_sysvar_last_restart_slot_read( accdb, xid, ULONG_MAX ); 87 : 88 : /* https://github.com/solana-labs/solana/blob/v1.18.18/runtime/src/bank.rs#L2122-L2130 */ 89 12 : if( last_restart_slot_have!=last_restart_slot_want ) { 90 12 : fd_sysvar_last_restart_slot_write( bank, accdb, xid, capture_ctx, last_restart_slot_want ); 91 12 : } 92 12 : }