Line data Source code
1 : #ifndef HEADER_fd_src_flamenco_runtime_fd_runtime_h
2 : #define HEADER_fd_src_flamenco_runtime_fd_runtime_h
3 :
4 : #include "../fd_flamenco_base.h"
5 : #include "fd_runtime_err.h"
6 : #include "fd_runtime_init.h"
7 : #include "fd_rocksdb.h"
8 : #include "fd_acc_mgr.h"
9 : #include "../features/fd_features.h"
10 : #include "fd_rent_lists.h"
11 : #include "../../ballet/poh/fd_poh.h"
12 : #include "../leaders/fd_leaders.h"
13 : #include "context/fd_exec_epoch_ctx.h"
14 : #include "context/fd_exec_slot_ctx.h"
15 : #include "context/fd_capture_ctx.h"
16 : #include "context/fd_exec_txn_ctx.h"
17 : #include "info/fd_runtime_block_info.h"
18 : #include "info/fd_instr_info.h"
19 : #include "../gossip/fd_gossip.h"
20 : #include "../repair/fd_repair.h"
21 : #include "../../disco/pack/fd_microblock.h"
22 : #include "info/fd_microblock_info.h"
23 : #include "../../ballet/bmtree/fd_wbmtree.h"
24 : #include "../../ballet/sbpf/fd_sbpf_loader.h"
25 : /* Various constant values used by the runtime. */
26 :
27 0 : #define MICRO_LAMPORTS_PER_LAMPORT (1000000UL)
28 :
29 : #define DEFAULT_HASHES_PER_TICK (12500)
30 0 : #define UPDATED_HASHES_PER_TICK2 (17500)
31 0 : #define UPDATED_HASHES_PER_TICK3 (27500)
32 0 : #define UPDATED_HASHES_PER_TICK4 (47500)
33 0 : #define UPDATED_HASHES_PER_TICK5 (57500)
34 0 : #define UPDATED_HASHES_PER_TICK6 (62500)
35 :
36 : #define FD_RUNTIME_TRACE_NONE (0)
37 : #define FD_RUNTIME_TRACE_SAVE (1)
38 : #define FD_RUNTIME_TRACE_REPLAY (2)
39 :
40 0 : #define FD_RUNTIME_NUM_ROOT_BLOCKS (32UL)
41 :
42 23898 : #define FD_FEATURE_ACTIVE_(_slot, _features, _feature_name) (_slot >= (_features). _feature_name)
43 0 : #define FD_FEATURE_JUST_ACTIVATED_(_slot, _features, _feature_name) (_slot == (_features). _feature_name)
44 0 : #define FD_FEATURE_ACTIVE_OFFSET_(_slot, _features, _offset) (_slot >= (_features).f[_offset>>3])
45 0 : #define FD_FEATURE_JUST_ACTIVATED_OFFSET_(_slot, _features, _offset) (_slot == (_features).f[_offset>>3] )
46 :
47 15873 : #define FD_FEATURE_ACTIVE(_slot,_features,_feature_name) FD_FEATURE_ACTIVE_( _slot,_features,_feature_name )
48 0 : #define FD_FEATURE_JUST_ACTIVATED(_slot_ctx, _feature_name) FD_FEATURE_JUST_ACTIVATED_( _slot_ctx->slot_bank.slot, _slot_ctx->epoch_ctx->features, _feature_name )
49 0 : #define FD_FEATURE_ACTIVE_OFFSET(_slot, _features, _offset) FD_FEATURE_ACTIVE_OFFSET_( _slot, _features, _offset )
50 0 : #define FD_FEATURE_JUST_ACTIVATED_OFFSET(_slot_ctx, _offset) FD_FEATURE_JUST_ACTIVATED_OFFSET_( _slot_ctx->slot_bank.slot, _slot_ctx->epoch_ctx->features, _offset )
51 :
52 0 : #define FD_BLOCKHASH_QUEUE_MAX_ENTRIES (300UL)
53 0 : #define FD_RECENT_BLOCKHASHES_MAX_ENTRIES (150UL)
54 :
55 3 : #define FD_RENT_EXEMPT_RENT_EPOCH (ULONG_MAX)
56 :
57 0 : #define SECONDS_PER_YEAR ((double)(365.242199 * 24.0 * 60.0 * 60.0))
58 :
59 : /* TODO: increase this to default once we have enough memory to support a 95G status cache. */
60 0 : #define MAX_CACHE_TXNS_PER_SLOT (FD_TXNCACHE_DEFAULT_MAX_TRANSACTIONS_PER_SLOT / 8)
61 :
62 : /* This is the reasonably tight upper bound for the number of writable
63 : accounts in a slot. This is because a block has a limit of 48 million
64 : compute units. Each writable account lock costs 300 CUs. That means there
65 : can be up to 48M/300 writable accounts in a block. */
66 0 : #define FD_WRITABLE_ACCS_IN_SLOT (160000UL)
67 :
68 : struct fd_execute_txn_task_info {
69 : fd_spad_t * * spads;
70 : fd_spad_t * spad;
71 : fd_exec_txn_ctx_t * txn_ctx;
72 : fd_txn_p_t * txn;
73 : int exec_res;
74 : };
75 : typedef struct fd_execute_txn_task_info fd_execute_txn_task_info_t;
76 :
77 : struct fd_raw_block_txn_iter {
78 : fd_block_entry_batch_t const * curr_batch;
79 : uchar const * orig_data;
80 : ulong remaining_batches;
81 : ulong remaining_microblocks;
82 : ulong remaining_txns;
83 : ulong curr_offset;
84 :
85 : ulong curr_txn_sz;
86 : };
87 :
88 : typedef struct fd_raw_block_txn_iter fd_raw_block_txn_iter_t;
89 :
90 : struct fd_poh_verifier {
91 : union {
92 : fd_microblock_hdr_t const * hdr;
93 : uchar * raw;
94 : } microblock;
95 : fd_hash_t const * in_poh_hash;
96 : ulong microblk_max_sz;
97 : fd_spad_t * spad;
98 : int success;
99 : };
100 : typedef struct fd_poh_verifier fd_poh_verifier_t;
101 :
102 : /* The below logic is used to size out the memory footprint generated by the
103 : runtime during transaction execution. */
104 :
105 : /* The prevailing layout we have in the runtime is the meta followed by
106 : the account's data. This struct encodes that layout and asserts that
107 : the alignment requirements of the constituents are satisfied. */
108 : // TODO: Use this struct at allocation sites so it's clear we use this layout
109 : struct __attribute__((packed)) fd_account_rec {
110 : fd_account_meta_t meta;
111 : uchar data[];
112 : };
113 : typedef struct fd_account_rec fd_account_rec_t;
114 0 : #define FD_ACCOUNT_REC_ALIGN (8UL)
115 : #define FD_ACCOUNT_REC_DATA_ALIGN (8UL)
116 : FD_STATIC_ASSERT( FD_ACCOUNT_REC_ALIGN>=FD_ACCOUNT_META_ALIGN, account_rec_meta_align );
117 : FD_STATIC_ASSERT( FD_ACCOUNT_REC_ALIGN>=FD_ACCOUNT_REC_DATA_ALIGN, account_rec_data_align );
118 : FD_STATIC_ASSERT( (offsetof(fd_account_rec_t, meta)%FD_ACCOUNT_META_ALIGN)==0, account_rec_meta_offset );
119 : FD_STATIC_ASSERT( (offsetof(fd_account_rec_t, data)%FD_ACCOUNT_REC_DATA_ALIGN)==0, account_rec_data_offset );
120 :
121 0 : #define MAX_PERMITTED_DATA_INCREASE (10240UL) // 10KB
122 0 : #define FD_BPF_ALIGN_OF_U128 (8UL )
123 : FD_STATIC_ASSERT( FD_BPF_ALIGN_OF_U128==FD_ACCOUNT_REC_DATA_ALIGN, input_data_align );
124 0 : #define FD_RUNTIME_INPUT_REGION_ALLOC_ALIGN_UP (16UL)
125 :
126 : /******** These macros bound out memory footprint ********/
127 :
128 : /* The tight upper bound on borrowed account footprint over the
129 : execution of a single transaction. */
130 0 : #define FD_RUNTIME_BORROWED_ACCOUNT_FOOTPRINT (MAX_TX_ACCOUNT_LOCKS * FD_ULONG_ALIGN_UP( FD_ACC_TOT_SZ_MAX, FD_ACCOUNT_REC_ALIGN ))
131 :
132 : /* The tight-ish upper bound on input region footprint over the
133 : execution of a single transaction. See input serialization code for
134 : reference: fd_bpf_loader_serialization.c
135 :
136 : This bound is based off of the transaction MTU. We consider the
137 : question of what kind of transaction one would construct to
138 : maximally bloat the input region.
139 : The worst case scenario is when every nested instruction references
140 : all unique accounts in the transaction. A transaction can lock a max
141 : of MAX_TX_ACCOUNT_LOCKS accounts. Then all remaining input account
142 : references are going to be duplicates, which cost 1 byte to specify
143 : offset in payload, and which cost 8 bytes during serialization. Then
144 : there would be 0 bytes of instruction data, because they exist byte
145 : for byte in the raw payload, which is not a worthwhile bloat factor.
146 : */
147 : #define FD_RUNTIME_INPUT_REGION_UNIQUE_ACCOUNT_FOOTPRINT(direct_mapping) \
148 : (1UL /* dup byte */ + \
149 : sizeof(uchar) /* is_signer */ + \
150 : sizeof(uchar) /* is_writable */ + \
151 : sizeof(uchar) /* executable */ + \
152 : sizeof(uint) /* original_data_len */ + \
153 : sizeof(fd_pubkey_t) /* key */ + \
154 : sizeof(fd_pubkey_t) /* owner */ + \
155 : sizeof(ulong) /* lamports */ + \
156 : sizeof(ulong) /* data len */ + \
157 : (direct_mapping ? FD_BPF_ALIGN_OF_U128 : FD_ULONG_ALIGN_UP( FD_ACC_SZ_MAX, FD_BPF_ALIGN_OF_U128 )) + \
158 : MAX_PERMITTED_DATA_INCREASE + \
159 : sizeof(ulong)) /* rent_epoch */
160 :
161 : #define FD_RUNTIME_INPUT_REGION_INSN_FOOTPRINT(account_lock_limit, direct_mapping) \
162 0 : (FD_ULONG_ALIGN_UP( (sizeof(ulong) /* acct_cnt */ + \
163 0 : account_lock_limit*FD_RUNTIME_INPUT_REGION_UNIQUE_ACCOUNT_FOOTPRINT(direct_mapping) + \
164 0 : sizeof(ulong) /* instr data len */ + \
165 0 : /* No instr data */ \
166 0 : sizeof(fd_pubkey_t)), /* program id */ \
167 0 : FD_RUNTIME_INPUT_REGION_ALLOC_ALIGN_UP ) + FD_BPF_ALIGN_OF_U128)
168 :
169 : #define FD_RUNTIME_INPUT_REGION_TXN_FOOTPRINT(account_lock_limit, direct_mapping) \
170 0 : ((FD_MAX_INSTRUCTION_STACK_DEPTH*FD_RUNTIME_INPUT_REGION_INSN_FOOTPRINT(account_lock_limit, direct_mapping)) + \
171 0 : ((FD_TXN_MTU-FD_TXN_MIN_SERIALIZED_SZ-account_lock_limit)*8UL)) /* We can have roughly this much duplicate offsets */
172 :
173 : /* Bincode valloc footprint over the execution of a single transaction.
174 : As well as other footprint specific to each native program type.
175 :
176 : N.B. We know that bincode valloc footprint is bounded, because
177 : whenever we alloc something, we advance our pointer into the binary
178 : buffer, so eventually we are gonna reach the end of the buffer.
179 : This buffer is usually backed by and ultimately bounded in size by
180 : either accounts data or the transaction MTU.
181 :
182 : That being said, it's not obvious what the tight upper bound would
183 : be for allocations across all possible execution paths of all native
184 : programs, including possible CPIs from native programs. The
185 : footprint estimate here is based on a manual review of our native
186 : program implementation. Note that even if the possible paths remain
187 : steady at the Solana protocol level, the footprint is subject to
188 : change when we change our implementation.
189 :
190 : ### Native programs
191 : ALUT (migrated to BPF)
192 : Loader
193 : - rodata for bpf program relocation and validation
194 : Compute budget (0 allocations)
195 : Config (migrated to BPF)
196 : Precompile (0 allocations)
197 : Stake
198 : - The instruction with the largest footprint is deactivate_delinquent
199 : - During instruction decode, no allocations
200 : - During execution, this is (vote account get_state() + vote convert_to_current()) times 2, once for delinquent_vote_account, and once for reference_vote_account
201 : System
202 : - system_program_instruction_decode seed
203 : Vote
204 : - The instruction with the largest footprint is compact vote state update
205 : - During instruction decode, this is 9*lockouts_len bytes, MTU bounded
206 : - During execution, this is vote account get_state() + vote convert_to_current() + 12*lockouts_len bytes + lockouts_len ulong + deq_fd_landed_vote_t_alloc(lockouts_len)
207 : Zk Elgamal (0 allocations)
208 :
209 : The largest footprint is hence deactivate_delinquent, in which the
210 : two get_state() calls dominate the footprint. In particular, the
211 : authorized_voters treaps bloat 40 bytes (epoch+pubkey) in a vote
212 : account to 72 bytes (sizeof(fd_vote_authorized_voter_t)) in memory.
213 : */
214 0 : #define FD_RUNTIME_BINCODE_AND_NATIVE_FOOTPRINT (2UL*FD_ACC_SZ_MAX*72UL/40UL)
215 :
216 : /* Misc other footprint. */
217 0 : #define FD_RUNTIME_SYSCALL_TABLE_FOOTPRINT (FD_MAX_INSTRUCTION_STACK_DEPTH*FD_ULONG_ALIGN_UP(FD_SBPF_SYSCALLS_FOOTPRINT, FD_SBPF_SYSCALLS_ALIGN))
218 :
219 : #ifdef FD_DEBUG_SBPF_TRACES
220 : #define FD_RUNTIME_VM_TRACE_EVENT_MAX (1UL<<30)
221 : #define FD_RUNTIME_VM_TRACE_EVENT_DATA_MAX (2048UL)
222 : #define FD_RUNTIME_VM_TRACE_FOOTPRINT (FD_MAX_INSTRUCTION_STACK_DEPTH*fd_ulong_align_up( fd_vm_trace_footprint( FD_RUNTIME_VM_TRACE_EVENT_MAX, FD_RUNTIME_VM_TRACE_EVENT_DATA_MAX ), fd_vm_trace_align() ))
223 : #else
224 0 : #define FD_RUNTIME_VM_TRACE_FOOTPRINT (0UL)
225 : #endif
226 :
227 0 : #define FD_RUNTIME_MISC_FOOTPRINT (FD_RUNTIME_SYSCALL_TABLE_FOOTPRINT+FD_RUNTIME_VM_TRACE_FOOTPRINT)
228 :
229 : /* Now finally, we bound out the footprint of transaction execution. */
230 : #define FD_RUNTIME_TRANSACTION_EXECUTION_FOOTPRINT(account_lock_limit, direct_mapping) \
231 0 : (FD_RUNTIME_BORROWED_ACCOUNT_FOOTPRINT + \
232 0 : FD_RUNTIME_INPUT_REGION_TXN_FOOTPRINT(account_lock_limit, direct_mapping) + \
233 0 : FD_RUNTIME_BINCODE_AND_NATIVE_FOOTPRINT + \
234 0 : FD_RUNTIME_MISC_FOOTPRINT)
235 :
236 : /* Convenience macros for common use cases.
237 :
238 : TODO: If account lock limits are increased to 128, this macro will need to be updated. */
239 0 : #define FD_RUNTIME_TRANSACTION_EXECUTION_FOOTPRINT_FUZZ FD_RUNTIME_TRANSACTION_EXECUTION_FOOTPRINT(64UL, 0)
240 0 : #define FD_RUNTIME_TRANSACTION_EXECUTION_FOOTPRINT_DEFAULT FD_RUNTIME_TRANSACTION_EXECUTION_FOOTPRINT(64UL, 0)
241 : /* TODO: Update this value once the bound is calculated correctly. */
242 0 : #define FD_RUNTIME_BLOCK_EXECUTION_FOOTPRINT (45000000000UL)
243 :
244 : /* The below macros aren't used anywhere, but since the spads are used for PoH tick verification,
245 : we ensure that the default spad size is large enough for the wbmtree and leaves */
246 :
247 : #define FD_RUNTIME_MERKLE_LEAF_CNT_MAX (FD_TXN_MAX_PER_SLOT * FD_TXN_ACTUAL_SIG_MAX)
248 :
249 : #define FD_RUNTIME_MERKLE_VERIFICATION_FOOTPRINT FD_RUNTIME_MERKLE_LEAF_CNT_MAX * sizeof(fd_wbmtree32_leaf_t) /* leaves */ \
250 : + sizeof(fd_wbmtree32_t) + sizeof(fd_wbmtree32_node_t)*(FD_RUNTIME_MERKLE_LEAF_CNT_MAX + (FD_RUNTIME_MERKLE_LEAF_CNT_MAX/2)) /* tree footprint */ \
251 : + FD_RUNTIME_MERKLE_LEAF_CNT_MAX * (sizeof(fd_ed25519_sig_t) + 1) /* sig mbuf */ \
252 : + 1UL + FD_WBMTREE32_ALIGN + alignof(fd_wbmtree32_leaf_t) /* aligns */
253 :
254 : FD_STATIC_ASSERT( FD_RUNTIME_MERKLE_VERIFICATION_FOOTPRINT <= FD_RUNTIME_TRANSACTION_EXECUTION_FOOTPRINT_DEFAULT, merkle verify footprint exceeds txn execution footprint );
255 :
256 : /* definition of the public/readable workspace */
257 : struct fd_runtime_public {
258 : // FIXME: This is a non-fork-aware copy of the currently active
259 : // features. Once the epoch_ctx and the slot_ctx get moved into
260 : // this workspace AND we make the epoch_ctx properly fork aware at
261 : // the epoch boundary, we can remove this copy of the features map
262 : // and just use the epoch_ctx (or slot_ctx) copy directly.
263 : fd_features_t features;
264 : };
265 : typedef struct fd_runtime_public fd_runtime_public_t;
266 :
267 : /* Helpers for runtime public frame management. */
268 :
269 : /* Helpers for runtime spad frame management. */
270 : struct fd_runtime_spad_verify_handle_private {
271 : fd_spad_t * spad;
272 : fd_exec_txn_ctx_t * txn_ctx;
273 : };
274 : typedef struct fd_runtime_spad_verify_handle_private fd_runtime_spad_verify_handle_private_t;
275 :
276 : static inline void
277 0 : fd_runtime_spad_private_frame_end( fd_runtime_spad_verify_handle_private_t * _spad_handle ) {
278 : /* fd_spad_verify() returns 0 if everything looks good, and non-zero
279 : otherwise.
280 :
281 : Since the fast spad alloc API doesn't check for or indicate an OOM
282 : situation and is going to happily permit an OOB alloc, we need
283 : some way of detecting that. Moreover, we would also like to detect
284 : unbalanced frame push/pop or usage of more frames than allowed.
285 : While surrounding the spad with guard regions will help detect the
286 : former, it won't necessarily catch the latter.
287 :
288 : On compliant transactions, fd_spad_verify() isn't all that
289 : expensive. Nonetheless, We invoke fd_spad_verify() only at the
290 : peak of memory usage, and not gratuitously everywhere. One peak
291 : would be right before we do the most deeply nested spad frame pop.
292 : However, we do pops through compiler-inserted cleanup functions
293 : that take only a single pointer, so we define this helper function
294 : to access the needed context info. The end result is that we do
295 : super fast spad calls everywhere in the runtime, and every now and
296 : then we invoke verify to check things. */
297 : /* -1UL because spad pop is called after instr stack pop. */
298 0 : if( FD_UNLIKELY( _spad_handle->txn_ctx->instr_stack_sz>=FD_MAX_INSTRUCTION_STACK_DEPTH-1UL && fd_spad_verify( _spad_handle->txn_ctx->spad ) ) ) {
299 0 : uchar const * txn_signature = (uchar const *)fd_txn_get_signatures( _spad_handle->txn_ctx->txn_descriptor, _spad_handle->txn_ctx->_txn_raw->raw );
300 0 : FD_BASE58_ENCODE_64_BYTES( txn_signature, sig );
301 0 : FD_LOG_ERR(( "spad corrupted or overflown on transaction %s", sig ));
302 0 : }
303 0 : fd_spad_pop( _spad_handle->spad );
304 0 : }
305 :
306 0 : #define FD_RUNTIME_TXN_SPAD_FRAME_BEGIN(_spad, _txn_ctx) do { \
307 0 : fd_runtime_spad_verify_handle_private_t _spad_handle __attribute__((cleanup(fd_runtime_spad_private_frame_end))) = \
308 0 : (fd_runtime_spad_verify_handle_private_t) { .spad = _spad, .txn_ctx = _txn_ctx }; \
309 0 : fd_spad_push( _spad_handle.spad ); \
310 0 : do
311 :
312 0 : #define FD_RUNTIME_TXN_SPAD_FRAME_END while(0); } while(0)
313 :
314 : FD_PROTOTYPES_BEGIN
315 :
316 : /* Runtime Helpers ************************************************************/
317 :
318 : /*
319 : Returns 0 on success, and non zero otherwise. On failure, the
320 : out values will not be modified.
321 : */
322 : int
323 : fd_runtime_compute_max_tick_height( ulong ticks_per_slot,
324 : ulong slot,
325 : ulong * out_max_tick_height /* out */ );
326 :
327 : void
328 : fd_runtime_update_leaders( fd_exec_slot_ctx_t * slot_ctx,
329 : ulong slot,
330 : fd_spad_t * runtime_spad );
331 :
332 : int
333 : fd_runtime_sysvar_cache_load( fd_exec_slot_ctx_t * slot_ctx,
334 : fd_spad_t * runtime_spad );
335 :
336 : /* TODO: Invoked by fd_executor: layering violation. Rent logic is deprecated
337 : and will be torn out entirely very soon. */
338 : ulong
339 : fd_runtime_collect_rent_from_account( ulong slot,
340 : fd_epoch_schedule_t const * schedule,
341 : fd_rent_t const * rent,
342 : double slots_per_year,
343 : fd_features_t * features,
344 : fd_account_meta_t * acc,
345 : fd_pubkey_t const * key,
346 : ulong epoch );
347 :
348 : void
349 : fd_runtime_update_slots_per_epoch( fd_exec_slot_ctx_t * slot_ctx,
350 : ulong slots_per_epoch,
351 : fd_spad_t * runtime_spad );
352 :
353 : void
354 : fd_runtime_register_new_fresh_account( fd_exec_slot_ctx_t * slot_ctx,
355 : fd_pubkey_t const * pubkey );
356 :
357 : /* Block Level Execution Prep/Finalize ****************************************/
358 :
359 0 : #define FD_BLOCK_OK (0UL)
360 : #define FD_BLOCK_ERR_INCOMPLETE (1UL)
361 : #define FD_BLOCK_ERR_INVALID_ENTRY_HASH (2UL)
362 : #define FD_BLOCK_ERR_INVALID_LAST_TICK (3UL)
363 0 : #define FD_BLOCK_ERR_TOO_FEW_TICKS (4UL)
364 0 : #define FD_BLOCK_ERR_TOO_MANY_TICKS (5UL)
365 0 : #define FD_BLOCK_ERR_INVALID_TICK_HASH_COUNT (6UL)
366 0 : #define FD_BLOCK_ERR_TRAILING_ENTRY (7UL)
367 : #define FD_BLOCK_ERR_DUPLICATE_BLOCK (8UL)
368 :
369 : /*
370 : https://github.com/anza-xyz/agave/blob/v2.1.0/ledger/src/blockstore_processor.rs#L1096
371 : This function assumes a full block.
372 : This needs to be called after epoch processing to get the up to date
373 : hashes_per_tick.
374 :
375 : Provide scratch memory >= the max size of a batch to use. This is because we can only
376 : assemble shreds by batch, so we iterate and assemble shreds by batch in this function
377 : without needing the caller to do so.
378 : */
379 : ulong
380 : fd_runtime_block_verify_ticks( fd_blockstore_t * blockstore,
381 : ulong slot,
382 : uchar * block_data_mem,
383 : ulong block_data_sz,
384 : ulong tick_height,
385 : ulong max_tick_height,
386 : ulong hashes_per_tick );
387 :
388 : /* The following microblock-level functions are exposed and non-static due to also being used for fd_replay.
389 : The block-level equivalent functions, on the other hand, are mostly static as they are only used
390 : for offline replay */
391 :
392 : /* extra fine-grained streaming tick verification */
393 : int
394 : fd_runtime_microblock_verify_ticks( fd_exec_slot_ctx_t * slot_ctx,
395 : ulong slot,
396 : fd_microblock_hdr_t const * hdr,
397 : bool slot_complete,
398 : ulong tick_height,
399 : ulong max_tick_height,
400 : ulong hashes_per_tick );
401 :
402 : /* fd_runtime_poh_verify is responsible for verifying poh hashes while
403 : streaming in microblocks. */
404 :
405 : void
406 : fd_runtime_poh_verify( fd_poh_verifier_t * poh_info );
407 :
408 : int
409 : fd_runtime_block_execute_prepare( fd_exec_slot_ctx_t * slot_ctx,
410 : fd_spad_t * runtime_spad );
411 :
412 : int
413 : fd_runtime_block_execute_finalize_tpool( fd_exec_slot_ctx_t * slot_ctx,
414 : fd_capture_ctx_t * capture_ctx,
415 : fd_runtime_block_info_t const * block_info,
416 : fd_tpool_t * tpool,
417 : fd_spad_t * runtime_spad );
418 :
419 : /* Transaction Level Execution Management *************************************/
420 :
421 : /* fd_runtime_prepare_txns_start and fd_runtime_pre_execute_check are only
422 : publicly exposed for the fuzzing harnesses. These functions are responsible
423 : for various transaction sanitization checks. */
424 :
425 : int
426 : fd_runtime_prepare_txns_start( fd_exec_slot_ctx_t * slot_ctx,
427 : fd_execute_txn_task_info_t * task_info,
428 : fd_txn_p_t * txns,
429 : ulong txn_cnt,
430 : fd_spad_t * runtime_spad );
431 :
432 : void
433 : fd_runtime_pre_execute_check( fd_execute_txn_task_info_t * task_info );
434 :
435 : /* fd_runtime_process_txns is responsible for end-to-end preparing, executing,
436 : and finalizing a list of transactions. It will execute all of the
437 : transactions on a single core. */
438 : int
439 : fd_runtime_process_txns( fd_exec_slot_ctx_t * slot_ctx,
440 : fd_capture_ctx_t * capture_ctx,
441 : fd_txn_p_t * txns,
442 : ulong txn_cnt,
443 : fd_spad_t * exec_spad,
444 : fd_spad_t * runtime_spad );
445 :
446 : /* fd_runtime_execute_txns_in_microblock_stream is responsible for end-to-end
447 : preparing, executing and finalizng a list of transactions. It assumes that
448 : all transactions are conflict-free. */
449 :
450 : int
451 : fd_runtime_process_txns_in_microblock_stream( fd_exec_slot_ctx_t * slot_ctx,
452 : fd_capture_ctx_t * capture_ctx,
453 : fd_txn_p_t * all_txns,
454 : ulong total_txn_cnt,
455 : fd_tpool_t * tpool,
456 : fd_spad_t * * exec_spads,
457 : ulong exec_spad_cnt,
458 : fd_spad_t * runtime_spad,
459 : fd_cost_tracker_t * cost_tracker_opt );
460 :
461 : /* fd_runtime_process_txns and fd_runtime_execute_txns_in_waves_tpool are
462 : both entrypoints for executing transactions. Currently, the former is used
463 : in the leader pipeline as conflict-free microblocks are streamed in from the
464 : pack tile. The latter is used for replaying non-leader blocks. Currently the
465 : entire block must be recieved to start replaying. This allows us to scheedule
466 : out all of the transactions. Eventually, transactions will be executed in
467 : a streamed fashion.*/
468 :
469 : /* Epoch Boundary *************************************************************/
470 :
471 : uint
472 : fd_runtime_is_epoch_boundary( fd_epoch_bank_t * epoch_bank,
473 : ulong curr_slot,
474 : ulong prev_slot );
475 :
476 : /*
477 : This is roughly Agave's process_new_epoch() which gets called from
478 : new_from_parent() for every slot.
479 : https://github.com/anza-xyz/agave/blob/v1.18.26/runtime/src/bank.rs#L1483
480 : This needs to be called after funk_txn_prepare() because the accounts
481 : that we modify when processing a new epoch need to be hashed into
482 : the bank hash.
483 : */
484 : void
485 : fd_runtime_block_pre_execute_process_new_epoch( fd_exec_slot_ctx_t * slot_ctx,
486 : fd_tpool_t * tpool,
487 : fd_spad_t * * exec_spads,
488 : ulong exec_spad_cnt,
489 : fd_spad_t * runtime_spad );
490 :
491 : /* Debugging Tools ************************************************************/
492 :
493 : void
494 : fd_runtime_checkpt( fd_capture_ctx_t * capture_ctx,
495 : fd_exec_slot_ctx_t * slot_ctx,
496 : ulong slot );
497 :
498 : /* Block Parsing **************************************************************/
499 :
500 : /* Live Replay APIs */
501 :
502 : fd_raw_block_txn_iter_t
503 : fd_raw_block_txn_iter_init( uchar const * orig_data,
504 : fd_block_entry_batch_t const * batches,
505 : ulong batch_cnt );
506 :
507 : ulong
508 : fd_raw_block_txn_iter_done( fd_raw_block_txn_iter_t iter );
509 :
510 : fd_raw_block_txn_iter_t
511 : fd_raw_block_txn_iter_next( fd_raw_block_txn_iter_t iter );
512 :
513 : void
514 : fd_raw_block_txn_iter_ele( fd_raw_block_txn_iter_t iter, fd_txn_p_t * out_txn );
515 :
516 : /* Offline Replay *************************************************************/
517 :
518 : int
519 : fd_runtime_block_eval_tpool( fd_exec_slot_ctx_t * slot_ctx,
520 : fd_block_t * block,
521 : fd_capture_ctx_t * capture_ctx,
522 : fd_tpool_t * tpool,
523 : ulong scheduler,
524 : ulong * txn_cnt,
525 : fd_spad_t * * spads,
526 : ulong spads_cnt,
527 : fd_spad_t * runtime_spad );
528 :
529 : int
530 : fd_runtime_block_execute_tpool( fd_exec_slot_ctx_t * slot_ctx,
531 : fd_capture_ctx_t * capture_ctx,
532 : fd_runtime_block_info_t const * block_info,
533 : fd_tpool_t * tpool,
534 : fd_spad_t * * exec_spads,
535 : ulong exec_spad_cnt,
536 : fd_spad_t * runtime_spad );
537 :
538 : /* Genesis ********************************************************************/
539 :
540 : void
541 : fd_runtime_read_genesis( fd_exec_slot_ctx_t * slot_ctx,
542 : char const * genesis_filepath,
543 : uchar is_snapshot,
544 : fd_capture_ctx_t * capture_ctx,
545 : fd_tpool_t * tpool,
546 : fd_spad_t * spad );
547 :
548 : ulong
549 : fd_runtime_public_footprint ( void );
550 :
551 : fd_runtime_public_t *
552 : fd_runtime_public_join ( void * ptr ) ;
553 :
554 : void *
555 : fd_runtime_public_new ( void * ptr ) ;
556 :
557 : FD_FN_CONST static inline ulong
558 0 : fd_runtime_public_align( void ) {
559 0 : return alignof(fd_runtime_public_t);
560 0 : }
561 :
562 : FD_PROTOTYPES_END
563 :
564 : #endif /* HEADER_fd_src_flamenco_runtime_fd_runtime_h */
|