Line data Source code
1 : #include "fd_sysvar_cache.h"
2 : #include "../fd_acc_mgr.h"
3 : #include "../fd_executor.h"
4 : #include "../fd_system_ids.h"
5 : #include "../context/fd_exec_instr_ctx.h"
6 : #include "../context/fd_exec_txn_ctx.h"
7 :
8 0 : #define FD_SYSVAR_CACHE_MAGIC (0x195a0e78828cacd5UL)
9 :
10 : ulong
11 0 : fd_sysvar_cache_align( void ) {
12 0 : return alignof(fd_sysvar_cache_t);
13 0 : }
14 :
15 : ulong
16 0 : fd_sysvar_cache_footprint( void ) {
17 0 : return sizeof(fd_sysvar_cache_t);
18 0 : }
19 :
20 : fd_sysvar_cache_t *
21 0 : fd_sysvar_cache_new( void * mem ) {
22 :
23 0 : if( FD_UNLIKELY( !mem ) ) {
24 0 : FD_LOG_WARNING(( "NULL mem" ));
25 0 : return NULL;
26 0 : }
27 :
28 0 : fd_sysvar_cache_t * cache = (fd_sysvar_cache_t *)mem;
29 0 : fd_memset( cache, 0, sizeof(fd_sysvar_cache_t) );
30 :
31 0 : FD_COMPILER_MFENCE();
32 0 : cache->magic = FD_SYSVAR_CACHE_MAGIC;
33 0 : FD_COMPILER_MFENCE();
34 0 : return cache;
35 0 : }
36 :
37 : void *
38 0 : fd_sysvar_cache_delete( fd_sysvar_cache_t * cache ) {
39 :
40 0 : if( FD_UNLIKELY( !cache ) ) {
41 0 : FD_LOG_WARNING(( "NULL cache" ));
42 0 : return NULL;
43 0 : }
44 :
45 0 : if( FD_UNLIKELY( cache->magic != FD_SYSVAR_CACHE_MAGIC ) ) {
46 0 : FD_LOG_WARNING(( "bad magic" ));
47 0 : return NULL;
48 0 : }
49 :
50 0 : FD_COMPILER_MFENCE();
51 0 : cache->magic = 0UL;
52 0 : FD_COMPILER_MFENCE();
53 :
54 : /* Call destroy on all objects.
55 : This is safe even if these objects logically don't exist
56 : (destroy is safe on zero-initialized values and is idempotent) */
57 0 : # define X( type, name ) \
58 : //type##_destroy( cache->val_##name );
59 0 : FD_SYSVAR_CACHE_ITER(X)
60 0 : # undef X
61 :
62 0 : return (void *)cache;
63 0 : }
64 :
65 : /* Provide accessor methods */
66 :
67 : #define X( type, name ) \
68 : type##_global_t const * \
69 0 : fd_sysvar_cache_##name( fd_sysvar_cache_t const * cache ) { \
70 0 : type##_global_t const * val = cache->val_##name; \
71 0 : return (cache->has_##name) ? val : NULL; \
72 0 : }
73 : FD_SYSVAR_CACHE_ITER(X)
74 : #undef X
75 :
76 : /* Restore sysvars */
77 :
78 : # define X( type, name ) \
79 : void \
80 : fd_sysvar_cache_restore_##name( \
81 : fd_sysvar_cache_t * cache, \
82 : fd_acc_mgr_t * acc_mgr, \
83 : fd_funk_txn_t * funk_txn, \
84 : fd_spad_t * runtime_spad, \
85 0 : fd_wksp_t * wksp ) { \
86 0 : do { \
87 0 : fd_pubkey_t const * pubkey = &fd_sysvar_##name##_id; \
88 0 : FD_TXN_ACCOUNT_DECL( account ); \
89 0 : int view_err = fd_acc_mgr_view( acc_mgr, funk_txn, pubkey, account ); \
90 0 : if( view_err==FD_ACC_MGR_ERR_UNKNOWN_ACCOUNT ) break; \
91 0 : \
92 0 : if( view_err!=FD_ACC_MGR_SUCCESS ) { \
93 0 : char pubkey_cstr[ FD_BASE58_ENCODED_32_SZ ]; \
94 0 : FD_LOG_ERR(( "fd_acc_mgr_view(%s) failed (%d-%s)", \
95 0 : fd_acct_addr_cstr( pubkey_cstr, pubkey->key ), \
96 0 : view_err, fd_acc_mgr_strerror( view_err ) )); \
97 0 : } \
98 0 : \
99 0 : if( account->const_meta->info.lamports == 0UL ) break; \
100 0 : \
101 0 : /* Decode new value \
102 0 : type##_decode() does not do heap allocations on failure */ \
103 0 : fd_bincode_decode_ctx_t decode = { \
104 0 : .data = account->const_data, \
105 0 : .dataend = account->const_data + account->const_meta->dlen, \
106 0 : .wksp = wksp \
107 0 : }; \
108 0 : ulong total_sz = 0UL; \
109 0 : int err = type##_decode_footprint( &decode, &total_sz ); \
110 0 : cache->has_##name = (err==FD_BINCODE_SUCCESS); \
111 0 : if( FD_UNLIKELY( err ) ) { \
112 0 : break; \
113 0 : } \
114 0 : \
115 0 : type##_global_t * mem = fd_spad_alloc( runtime_spad, \
116 0 : type##_align(), \
117 0 : total_sz ); \
118 0 : if( FD_UNLIKELY( !mem ) ) { \
119 0 : FD_LOG_ERR(( "memory allocation failed" )); \
120 0 : } \
121 0 : type##_decode_global( mem, &decode ); \
122 0 : fd_memcpy( cache->val_##name, mem, sizeof(type##_global_t) ); \
123 0 : } while(0); \
124 0 : }
125 : FD_SYSVAR_CACHE_ITER(X)
126 : # undef X
127 :
128 : void
129 : fd_sysvar_cache_restore( fd_sysvar_cache_t * cache,
130 : fd_acc_mgr_t * acc_mgr,
131 : fd_funk_txn_t * funk_txn,
132 : fd_spad_t * runtime_spad,
133 0 : fd_wksp_t * wksp ) {
134 0 : # define X( type, name ) \
135 0 : fd_sysvar_cache_restore_##name( cache, acc_mgr, funk_txn, runtime_spad, wksp );
136 0 : FD_SYSVAR_CACHE_ITER(X)
137 0 : # undef X
138 0 : }
139 :
140 : # define X( type, name ) \
141 : type##_global_t const * \
142 : fd_sysvar_from_instr_acct_##name( fd_exec_instr_ctx_t const * ctx, \
143 : ulong idx, \
144 0 : int * err ) {\
145 0 : \
146 0 : if( FD_UNLIKELY( idx >= ctx->instr->acct_cnt ) ) { \
147 0 : *err = FD_EXECUTOR_INSTR_ERR_NOT_ENOUGH_ACC_KEYS; \
148 0 : return NULL; \
149 0 : } \
150 0 : \
151 0 : fd_sysvar_cache_t const * cache = ctx->txn_ctx->sysvar_cache; \
152 0 : type##_global_t const * val = fd_sysvar_cache_##name ( cache ); \
153 0 : \
154 0 : fd_pubkey_t const * addr_have = &ctx->instr->acct_pubkeys[idx]; \
155 0 : fd_pubkey_t const * addr_want = &fd_sysvar_##name##_id; \
156 0 : if( 0!=memcmp( addr_have, addr_want, sizeof(fd_pubkey_t) ) ) { \
157 0 : *err = FD_EXECUTOR_INSTR_ERR_INVALID_ARG; \
158 0 : return NULL; \
159 0 : } \
160 0 : \
161 0 : *err = val ? \
162 0 : FD_EXECUTOR_INSTR_SUCCESS : \
163 0 : FD_EXECUTOR_INSTR_ERR_UNSUPPORTED_SYSVAR; \
164 0 : return val; \
165 0 : \
166 0 : }
167 : FD_SYSVAR_CACHE_ITER(X)
168 : # undef X
169 :
170 : /* https://github.com/anza-xyz/agave/blob/77daab497df191ef485a7ad36ed291c1874596e5/program-runtime/src/sysvar_cache.rs#L223-L234 */
171 : int
172 : fd_check_sysvar_account( fd_exec_instr_ctx_t const * ctx,
173 : ulong insn_acc_idx,
174 0 : fd_pubkey_t const * expected_id ) {
175 0 : uchar const * instr_acc_idxs = ctx->instr->acct_txn_idxs;
176 0 : fd_pubkey_t const * txn_accs = ctx->txn_ctx->account_keys;
177 :
178 0 : if( insn_acc_idx>=ctx->instr->acct_cnt ) {
179 0 : return FD_EXECUTOR_INSTR_ERR_NOT_ENOUGH_ACC_KEYS;
180 0 : }
181 :
182 0 : fd_pubkey_t const * insn_acc_key = &txn_accs[ instr_acc_idxs[ insn_acc_idx ] ];
183 :
184 0 : if( memcmp( expected_id, insn_acc_key, sizeof(fd_pubkey_t) ) ) {
185 0 : return FD_EXECUTOR_INSTR_ERR_INVALID_ARG;
186 0 : }
187 0 : return FD_EXECUTOR_INSTR_SUCCESS;
188 0 : }
|