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