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 "../../accdb/fd_accdb_sync.h"
5 :
6 : void
7 : fd_sysvar_last_restart_slot_write(
8 : fd_bank_t * bank,
9 : fd_accdb_user_t * accdb,
10 : fd_funk_txn_xid_t const * xid,
11 : fd_capture_ctx_t * capture_ctx,
12 : fd_sol_sysvar_last_restart_slot_t const * sysvar
13 75 : ) {
14 75 : uchar enc[ 8 ];
15 75 : FD_STORE( ulong, enc, sysvar->slot );
16 75 : fd_sysvar_account_update( bank, accdb, xid, capture_ctx, &fd_sysvar_last_restart_slot_id, enc, sizeof(enc) );
17 75 : }
18 :
19 : void
20 : fd_sysvar_last_restart_slot_init( fd_bank_t * bank,
21 : fd_accdb_user_t * accdb,
22 : fd_funk_txn_xid_t const * xid,
23 0 : fd_capture_ctx_t * capture_ctx ) {
24 :
25 0 : if( !FD_FEATURE_ACTIVE_BANK( bank, last_restart_slot_sysvar ) ) {
26 0 : return;
27 0 : }
28 :
29 0 : fd_sol_sysvar_last_restart_slot_t sysvar = {0};
30 0 : fd_sysvar_last_restart_slot_write( bank, accdb, xid, capture_ctx, &sysvar );
31 0 : }
32 :
33 : /* https://github.com/anza-xyz/agave/blob/v2.3.2/runtime/src/bank.rs#L2217 */
34 :
35 : ulong
36 : fd_sysvar_last_restart_slot_derive(
37 : fd_hard_forks_global_t const * hard_forks,
38 : ulong current_slot
39 0 : ) {
40 :
41 0 : if( FD_UNLIKELY( hard_forks->hard_forks_len == 0 ) ) {
42 : /* SIMD-0047: The first restart slot should be `0` */
43 0 : return 0UL;
44 0 : }
45 :
46 0 : fd_slot_pair_t const * head = fd_hard_forks_hard_forks_join( (fd_hard_forks_global_t *)hard_forks );
47 0 : fd_slot_pair_t const * tail = head + hard_forks->hard_forks_len - 1UL;
48 :
49 0 : for( fd_slot_pair_t const *pair = tail; pair >= head; pair-- ) {
50 0 : if( pair->slot <= current_slot ) {
51 0 : return pair->slot;
52 0 : }
53 0 : }
54 :
55 0 : return 0UL;
56 0 : }
57 :
58 : fd_sol_sysvar_last_restart_slot_t *
59 : fd_sysvar_last_restart_slot_read(
60 : fd_accdb_user_t * accdb,
61 : fd_funk_txn_xid_t const * xid,
62 : fd_sol_sysvar_last_restart_slot_t * out
63 75 : ) {
64 :
65 75 : fd_accdb_ro_t ro[1];
66 75 : if( FD_UNLIKELY( !fd_accdb_open_ro( accdb, ro, xid, &fd_sysvar_last_restart_slot_id ) ) ) {
67 75 : return NULL;
68 75 : }
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_accdb_ref_lamports( ro )==0UL ) ) {
75 0 : fd_accdb_close_ro( accdb, ro );
76 0 : return NULL;
77 0 : }
78 :
79 0 : out = fd_bincode_decode_static(
80 0 : sol_sysvar_last_restart_slot, out,
81 0 : fd_accdb_ref_data_const( ro ),
82 0 : fd_accdb_ref_data_sz ( ro ) );
83 0 : fd_accdb_close_ro( accdb, ro );
84 0 : return out;
85 0 : }
86 :
87 : /* fd_sysvar_last_restart_slot_update is equivalent to
88 : Agave's solana_runtime::bank::Bank::update_last_restart_slot */
89 :
90 : void
91 : fd_sysvar_last_restart_slot_update(
92 : fd_bank_t * bank,
93 : fd_accdb_user_t * accdb,
94 : fd_funk_txn_xid_t const * xid,
95 : fd_capture_ctx_t * capture_ctx,
96 : ulong last_restart_slot_want
97 108 : ) {
98 :
99 : /* https://github.com/solana-labs/solana/blob/v1.18.18/runtime/src/bank.rs#L2093-L2095 */
100 108 : if( !FD_FEATURE_ACTIVE_BANK( bank, last_restart_slot_sysvar ) ) return;
101 :
102 : /* https://github.com/solana-labs/solana/blob/v1.18.18/runtime/src/bank.rs#L2098-L2106 */
103 75 : ulong last_restart_slot_have = ULONG_MAX;
104 75 : fd_sol_sysvar_last_restart_slot_t sysvar;
105 75 : if( FD_LIKELY( fd_sysvar_last_restart_slot_read( accdb, xid, &sysvar ) ) ) {
106 0 : last_restart_slot_have = sysvar.slot;
107 0 : }
108 :
109 : /* https://github.com/solana-labs/solana/blob/v1.18.18/runtime/src/bank.rs#L2122-L2130 */
110 75 : if( last_restart_slot_have != last_restart_slot_want ) {
111 75 : sysvar.slot = last_restart_slot_want;
112 75 : fd_sysvar_last_restart_slot_write( bank, accdb, xid, capture_ctx, &sysvar );
113 75 : }
114 75 : }
|