Line data Source code
1 : #ifndef HEADER_fd_src_flamenco_runtime_tests_fd_svm_mini_h
2 : #define HEADER_fd_src_flamenco_runtime_tests_fd_svm_mini_h
3 :
4 : /* fd_svm_mini.h is an API for creating Solana runtime test
5 : environments.
6 :
7 : Structurally, the API works as follows:
8 : - svm_mini provides an environment for block/transaction execution,
9 : including a fork-aware accounts DB, program cache, etc.
10 : - svm_mini_limits configures memory limits for the above
11 : - svm_mini_params fine-tunes default state to reduce setup
12 : boilerplate (e.g. set up vote/stake accounts, builtin programs)
13 : - forks are identified by the "bank index". some care is required to
14 : handle bank indexes, as they are reused after invalidation.
15 :
16 : This API optimizes for testing, not useful for production:
17 : - smaller runtime defaults (aims for 2 GiB memory reservations)
18 : - memory lazy paged / not pinned by default
19 : - memory 4K paged by default (simplify startup)
20 : - avoids use of privileged kernel calls */
21 :
22 : #include "../../accdb/fd_accdb_admin.h"
23 : #include "../../accdb/fd_accdb_user.h"
24 : #include "../../progcache/fd_progcache_user.h"
25 : #include "../../log_collector/fd_log_collector_base.h"
26 : #include "../fd_runtime.h"
27 : #include "../fd_runtime_stack.h"
28 : #include "../fd_acc_pool.h"
29 : #include "../../vm/fd_vm.h"
30 :
31 : /* fd_svm_mini_t holds handles to all relevant Firedancer runtime
32 : components for test environments. */
33 :
34 : struct fd_svm_mini {
35 : fd_wksp_t * wksp;
36 : fd_banks_t * banks;
37 : fd_runtime_t * runtime;
38 : fd_runtime_stack_t * runtime_stack;
39 : fd_acc_pool_t * acc_pool;
40 : fd_vm_t * vm;
41 :
42 : fd_accdb_user_t accdb[1];
43 : fd_accdb_admin_t accdb_admin[1];
44 : fd_progcache_t progcache[1];
45 : fd_log_collector_t log_collector[1];
46 : fd_features_t features[1];
47 : fd_sha256_t sha256[1]; /* FIXME this should not be separate */
48 : };
49 :
50 : typedef struct fd_svm_mini fd_svm_mini_t;
51 :
52 : /* fd_svm_mini_limits_t specifies memory allocation limits for runtime
53 : components. */
54 :
55 : struct fd_svm_mini_limits {
56 : /* fork management */
57 : ulong max_live_slots;
58 : ulong max_fork_width;
59 :
60 : /* consensus */
61 : ulong max_vote_accounts;
62 : ulong max_stake_accounts;
63 :
64 : /* accdb */
65 : ulong max_accounts;
66 : ulong max_account_space_bytes;
67 :
68 : /* progcache */
69 : ulong max_progcache_recs;
70 : ulong max_progcache_heap_bytes;
71 :
72 : /* txn executor */
73 : ulong max_txn_write_locks;
74 :
75 : /* wksp alloc tag (0 uses default) */
76 : ulong wksp_tag;
77 : };
78 :
79 : typedef struct fd_svm_mini_limits fd_svm_mini_limits_t;
80 :
81 : /* fd_svm_mini_params_t specifies defaults for initialization of an
82 : svm_mini object. */
83 :
84 : struct fd_svm_mini_params {
85 : ulong hash_seed;
86 : ulong root_slot;
87 : ulong slots_per_epoch;
88 :
89 : ulong init_sysvars : 1;
90 : ulong init_feature_accounts : 1;
91 : ulong init_builtins : 1;
92 :
93 : /* If non-zero, creates mock_validator_cnt validators with uniform
94 : stake and populates the epoch leader schedule. For each validator,
95 : creates identity, vote, and stake accounts in the accounts DB. */
96 : ulong mock_validator_cnt;
97 :
98 : /* Sysvar overrides */
99 : fd_sol_sysvar_clock_t const * clock;
100 : fd_epoch_schedule_t const * epoch_schedule;
101 : fd_rent_t const * rent;
102 : };
103 :
104 : typedef struct fd_svm_mini_params fd_svm_mini_params_t;
105 :
106 : FD_PROTOTYPES_BEGIN
107 :
108 : /* fd_svm_test_{boot,halt} do all-in-one setup for test executables.
109 : An important goal is rootless operation on a default Linux config for
110 : easy development.
111 :
112 : fd_svm_test_boot does the following steps:
113 : - standard command-line handling
114 : - creates an anonymous wksp / attaches to an existing wksp
115 : - creates various runtime objects
116 :
117 : Parses and strips the following arguments from pargc/pargv, or
118 : chooses sane defaults in the absence of these options.
119 :
120 : --page-sz <size> memory page size ("normal", "huge", "gigantic")
121 : if unspecified, uses lazy anonymous normal pages
122 : if specified, implies pinned/mlock() pages
123 : --page-cnt <count> number of memory pages to reserve (default derived from limits)
124 : --wksp <name> use existing wksp instead of allocating one
125 : --near-cpu <number> NUMA affinity hint for memory allocations
126 : (default: let kernel decide on first use/mlock)
127 :
128 : Terminates the process with FD_LOG_ERR (exit code 1) if svm_mini
129 : fails to boot.
130 :
131 : fd_svm_test_halt destroys the mini object and halts fd. Wksp
132 : cleanup is left to process termination. */
133 :
134 : fd_svm_mini_t *
135 : fd_svm_test_boot( int * pargc,
136 : char *** pargv,
137 : fd_svm_mini_limits_t const * limits );
138 :
139 : void
140 : fd_svm_test_halt( fd_svm_mini_t * mini );
141 :
142 : /* fd_svm_mini_limits_default populates minimal single-fork execution
143 : limits. */
144 :
145 : FD_FN_UNUSED static fd_svm_mini_limits_t *
146 24 : fd_svm_mini_limits_default( fd_svm_mini_limits_t * limits ) {
147 24 : *limits = (fd_svm_mini_limits_t) {
148 24 : .max_live_slots = 16UL,
149 24 : .max_fork_width = 4UL,
150 24 : .max_vote_accounts = 256UL,
151 24 : .max_stake_accounts = 256UL,
152 24 : .max_accounts = 128UL,
153 24 : .max_account_space_bytes = 32UL<<20,
154 24 : .max_progcache_recs = 256UL,
155 24 : .max_progcache_heap_bytes = 65536UL,
156 24 : .max_txn_write_locks = 0UL
157 24 : };
158 24 : return limits;
159 24 : }
160 :
161 : /* fd_svm_mini_wksp_data_max returns the recommended heap space in bytes
162 : for a given limits config. */
163 :
164 : ulong
165 : fd_svm_mini_wksp_data_max( fd_svm_mini_limits_t const * limits );
166 :
167 : /* fd_svm_mini_create allocates and constructs various Solana runtime
168 : environment objects and packs them into an svm_mini handle. The
169 : newly created svm_mini object is reset using default params. On
170 : failure terminates the app with FD_LOG_ERR (exit code 1). */
171 :
172 : fd_svm_mini_t *
173 : fd_svm_mini_create( fd_wksp_t * wksp,
174 : fd_svm_mini_limits_t const * limits );
175 :
176 : /* fd_svm_mini_destroy destroys all Solana runtime environment objects,
177 : accounts, blocks, etc, and frees them back to the wksp heap. */
178 :
179 : void
180 : fd_svm_mini_destroy( fd_svm_mini_t * mini );
181 :
182 : /* fd_svm_mini_params_default populates default execution state. */
183 :
184 : FD_FN_UNUSED static fd_svm_mini_params_t *
185 189 : fd_svm_mini_params_default( fd_svm_mini_params_t * params ) {
186 189 : *params = (fd_svm_mini_params_t) {
187 189 : .hash_seed = 1UL,
188 189 : .root_slot = 1UL,
189 189 : .slots_per_epoch = 16UL,
190 189 : .init_sysvars = 1,
191 189 : .init_feature_accounts = 0,
192 189 : .init_builtins = 1,
193 189 : .mock_validator_cnt = 1UL,
194 189 : .clock = NULL,
195 189 : .epoch_schedule = NULL,
196 : .rent = NULL,
197 189 : };
198 189 : return params;
199 189 : }
200 :
201 : /* fd_svm_mini_reset destroys all existing runtime state (banks, accdb,
202 : etc), and initializes them according to params. This operation
203 : invalidates any handle previously acquired through svm_mini. Returns
204 : the initial bank index (rooted). */
205 :
206 : ulong
207 : fd_svm_mini_reset( fd_svm_mini_t * mini,
208 : fd_svm_mini_params_t * params );
209 :
210 : /* Fork management API */
211 :
212 : /* fd_svm_mini_attach_child creates a fork node as a descendant of the
213 : node identified by parent_bank_idx. child_slot is the slot number of
214 : this node. Terminates the app with FD_LOG_ERR on failure. */
215 :
216 : ulong
217 : fd_svm_mini_attach_child( fd_svm_mini_t * mini,
218 : ulong parent_bank_idx,
219 : ulong child_slot );
220 :
221 : /* fd_svm_mini_freeze freezes the bank identified by bank_idx. Runs
222 : slot boundary logic (registers POH hash into blockhash queue, updates
223 : sysvars, settles fees, etc). */
224 :
225 : void
226 : fd_svm_mini_freeze( fd_svm_mini_t * mini,
227 : ulong bank_idx );
228 :
229 : /* fd_svm_mini_cancel_fork cancels the subtree of the fork graph
230 : identified by bank_idx (i.e. the bank_idx node and all its children,
231 : transitively). */
232 :
233 : void
234 : fd_svm_mini_cancel_fork( fd_svm_mini_t * mini,
235 : ulong bank_idx );
236 :
237 : /* fd_svm_mini_advance_root advances the fork graph root to the node
238 : identified by bank_idx. Cancels all siblings and uncles
239 : (transitively) of the rooted nodes. */
240 :
241 : void
242 : fd_svm_mini_advance_root( fd_svm_mini_t * mini,
243 : ulong bank_idx );
244 :
245 : fd_bank_t *
246 : fd_svm_mini_bank( fd_svm_mini_t * mini,
247 : ulong bank_idx );
248 :
249 : fd_xid_t
250 : fd_svm_mini_xid( fd_svm_mini_t * mini,
251 : ulong bank_idx );
252 :
253 : /* Mock/inject API */
254 :
255 : /* fd_svm_mini_put_account_rooted injects a copy of the account at ro
256 : into the rooted state. */
257 :
258 : void
259 : fd_svm_mini_put_account_rooted( fd_svm_mini_t * mini,
260 : fd_accdb_ro_t const * ro );
261 :
262 : /* fd_svm_mini_add_lamports_rooted increases the lamport balance of a
263 : rooted accounts. */
264 :
265 : void
266 : fd_svm_mini_add_lamports_rooted( fd_svm_mini_t * mini,
267 : fd_pubkey_t const * pubkey,
268 : ulong lamports );
269 :
270 : /* fd_svm_mini_add_lamports increases the lamport balance of an account. */
271 :
272 : void
273 : fd_svm_mini_add_lamports( fd_svm_mini_t * mini,
274 : fd_xid_t const * xid,
275 : fd_pubkey_t const * pubkey,
276 : ulong lamports );
277 :
278 : FD_PROTOTYPES_END
279 :
280 : #endif /* HEADER_fd_src_flamenco_runtime_tests_fd_svm_mini_h */
|