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