Line data Source code
1 : #ifndef HEADER_fd_src_flamenco_runtime_fd_runtime_helpers_h
2 : #define HEADER_fd_src_flamenco_runtime_fd_runtime_helpers_h
3 :
4 : #include "fd_runtime_err.h"
5 : #include "fd_acc_mgr.h"
6 : #include "fd_hashes.h"
7 : #include "fd_txncache.h"
8 : #include "fd_compute_budget_details.h"
9 : #include "fd_cost_tracker.h"
10 : #include "context/fd_exec_instr_ctx.h"
11 : #include "info/fd_instr_info.h"
12 : #include "../features/fd_features.h"
13 : #include "../capture/fd_capture_ctx.h"
14 : #include "../../disco/pack/fd_pack.h"
15 : #include "../../ballet/sbpf/fd_sbpf_loader.h"
16 : #include "program/vote/fd_vote_codec.h"
17 :
18 : /* Return data for syscalls */
19 : struct fd_txn_return_data {
20 : fd_pubkey_t program_id;
21 : ulong len;
22 : uchar data[1024];
23 : };
24 : typedef struct fd_txn_return_data fd_txn_return_data_t;
25 :
26 : /* fd_exec_txn_ctx_t is the context needed to execute a transaction. */
27 :
28 : FD_PROTOTYPES_BEGIN
29 :
30 : /* Returns 0 on success, and non zero otherwise. On failure, the out
31 : values will not be modified. */
32 : int
33 : fd_runtime_compute_max_tick_height( ulong ticks_per_slot,
34 : ulong slot,
35 : ulong * out_max_tick_height /* out */ );
36 :
37 : void
38 : fd_runtime_update_next_leaders( fd_bank_t * bank,
39 : fd_runtime_stack_t * runtime_stack );
40 :
41 : void
42 : fd_runtime_update_leaders( fd_bank_t * bank,
43 : fd_runtime_stack_t * runtime_stack );
44 :
45 : /* Load the accounts in the address lookup tables of txn into out_accts_alt */
46 : int
47 : fd_runtime_load_txn_address_lookup_tables( fd_txn_in_t const * txn_in,
48 : fd_txn_t const * txn,
49 : uchar const * payload,
50 : fd_accdb_user_t * accdb,
51 : fd_funk_txn_xid_t const * xid,
52 : ulong slot,
53 : fd_slot_hashes_t const * hashes,
54 : fd_acct_addr_t * out_accts_alt );
55 :
56 : /* fd_runtime_new_fee_rate_governor_derived updates the bank's
57 : FeeRateGovernor to a new derived value based on the parent bank's
58 : FeeRateGovernor and the latest_signatures_per_slot.
59 : https://github.com/anza-xyz/solana-sdk/blob/badc2c40071e6e7f7a8e8452b792b66613c5164c/fee-calculator/src/lib.rs#L97-L157
60 :
61 : latest_signatures_per_slot is typically obtained from the parent
62 : slot's signature count for the bank being processed.
63 :
64 : The fee rate governor is deprecated in favor of FeeStructure in
65 : transaction fee calculations but we still need to maintain the old
66 : logic for recent blockhashes sysvar (and nonce logic that relies on
67 : it). Thus, a separate bank field, `rbh_lamports_per_sig`, tracks the
68 : updates to the fee rate governor derived lamports-per-second value.
69 :
70 : Relevant links:
71 : - Deprecation issue tracker:
72 : https://github.com/anza-xyz/agave/issues/3303
73 : - PR that deals with disambiguation between FeeStructure and
74 : FeeRateGovernor in SVM: https://github.com/anza-xyz/agave/pull/3216
75 : */
76 : void
77 : fd_runtime_new_fee_rate_governor_derived( fd_bank_t * bank,
78 : ulong latest_signatures_per_slot );
79 :
80 : void
81 : fd_runtime_read_genesis( fd_banks_t * banks,
82 : fd_bank_t * bank,
83 : fd_accdb_user_t * accdb,
84 : fd_funk_txn_xid_t const * xid,
85 : fd_capture_ctx_t * capture_ctx,
86 : fd_hash_t const * genesis_hash,
87 : fd_lthash_value_t const * genesis_lthash,
88 : fd_genesis_t const * genesis,
89 : uchar const * genesis_blob,
90 : fd_runtime_stack_t * runtime_stack );
91 :
92 : /* Error logging handholding assertions */
93 :
94 : #ifdef FD_RUNTIME_ERR_HANDHOLDING
95 :
96 : /* Asserts that the error and error kind are not populated (zero) */
97 : #define FD_TXN_TEST_ERR_OVERWRITE( txn_out ) \
98 : FD_TEST( !txn_out->err.exec_err ); \
99 : FD_TEST( !txn_out->err.exec_err_kind )
100 :
101 : /* Used prior to a FD_TXN_ERR_FOR_LOG_INSTR call to deliberately
102 : bypass overwrite handholding checks.
103 : Only use this if you know what you're doing. */
104 : #define FD_TXN_PREPARE_ERR_OVERWRITE( txn_out ) \
105 : txn_out->err.exec_err = 0; \
106 : txn_out->err.exec_err_kind = 0
107 :
108 : #else
109 :
110 696 : #define FD_TXN_TEST_ERR_OVERWRITE( txn_out ) ( ( void )0 )
111 603 : #define FD_TXN_PREPARE_ERR_OVERWRITE( txn_out ) ( ( void )0 )
112 :
113 : #endif
114 :
115 696 : #define FD_TXN_ERR_FOR_LOG_INSTR( txn_out, err_, idx ) (__extension__({ \
116 696 : FD_TXN_TEST_ERR_OVERWRITE( txn_out ); \
117 696 : txn_out->err.exec_err = err_; \
118 696 : txn_out->err.exec_err_kind = FD_EXECUTOR_ERR_KIND_INSTR; \
119 696 : txn_out->err.exec_err_idx = idx; \
120 696 : }))
121 :
122 : int
123 : fd_runtime_find_index_of_account( fd_txn_out_t const * txn_out,
124 : fd_pubkey_t const * pubkey );
125 :
126 : typedef int fd_txn_account_condition_fn_t ( fd_txn_in_t const * txn_in,
127 : fd_txn_out_t * txn_out,
128 : ushort idx );
129 :
130 : /* Mirrors Agave function solana_sdk::transaction_context::get_account_at_index
131 :
132 : Takes a function pointer to a condition function to check pre-conditions on the
133 : obtained account. If the condition function is NULL, the account is returned without
134 : any pre-condition checks.
135 :
136 : https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L223-L230 */
137 :
138 : fd_accdb_ref_t *
139 : fd_runtime_get_account_at_index( fd_txn_in_t const * txn_in,
140 : fd_txn_out_t * txn_out,
141 : ushort idx,
142 : fd_txn_account_condition_fn_t * condition );
143 :
144 : /* A wrapper around fd_exec_txn_ctx_get_account_at_index that obtains an
145 : account from the transaction context by its pubkey. */
146 :
147 : fd_accdb_ref_t *
148 : fd_runtime_get_account_with_key( fd_txn_in_t const * txn_in,
149 : fd_txn_out_t * txn_out,
150 : fd_pubkey_t const * pubkey,
151 : int * index_out,
152 : fd_txn_account_condition_fn_t * condition );
153 :
154 : /* Gets an executable (program data) account via its pubkey. */
155 :
156 : fd_accdb_ro_t *
157 : fd_runtime_get_executable_account( fd_runtime_t * runtime,
158 : fd_txn_in_t const * txn_in,
159 : fd_txn_out_t * txn_out,
160 : fd_pubkey_t const * pubkey );
161 :
162 : /* Mirrors Agave function solana_sdk::transaction_context::get_key_of_account_at_index
163 :
164 : https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L212 */
165 :
166 : int
167 : fd_runtime_get_key_of_account_at_index( fd_txn_out_t * txn_out,
168 : ushort idx,
169 : fd_pubkey_t const * * key );
170 :
171 : /* In agave, the writable accounts cache is populated by this below function.
172 : This cache is then referenced to determine if a transaction account is
173 : writable or not.
174 :
175 : The overall logic is as follows: an account can be passed
176 : in as writable based on the signature and readonly signature as they are
177 : passed in by the transaction message. However, the account's writable
178 : status will be demoted if either of the two conditions are met:
179 : 1. If the account is in the set of reserved pubkeys
180 : 2. If the account is the program id AND the upgradeable loader account is in
181 : the set of transaction accounts. */
182 : /* https://github.com/anza-xyz/agave/blob/v2.1.1/sdk/program/src/message/versions/v0/loaded.rs#L137-L150 */
183 :
184 : int
185 : fd_runtime_account_is_writable_idx( fd_txn_in_t const * txn_in,
186 : fd_txn_out_t const * txn_out,
187 : ushort idx );
188 :
189 : /* Account pre-condition filtering functions
190 :
191 : Used to filter accounts based on pre-conditions such as existence, is_writable, etc.
192 : when obtaining accounts from the transaction context. Passed as a function pointer. */
193 :
194 : int
195 : fd_runtime_account_check_exists( fd_txn_in_t const * txn_in,
196 : fd_txn_out_t * txn_out,
197 : ushort idx );
198 :
199 : /* The fee payer is a valid modifiable account if it is passed in as writable
200 : in the message via a valid signature. We ignore if the account has been
201 : demoted or not (see fd_exec_txn_ctx_account_is_writable_idx) for more details.
202 : Agave and Firedancer will reject the fee payer if the transaction message
203 : doesn't have a writable signature. */
204 :
205 : int
206 : fd_runtime_account_check_fee_payer_writable( fd_txn_in_t const * txn_in,
207 : fd_txn_out_t * txn_out,
208 : ushort idx );
209 :
210 : int
211 : fd_account_meta_checked_sub_lamports( fd_account_meta_t * meta,
212 : ulong lamports );
213 :
214 : FD_FN_UNUSED static void
215 : fd_account_meta_resize( fd_account_meta_t * meta,
216 237 : ulong dlen ) {
217 237 : ulong old_sz = meta->dlen;
218 237 : ulong new_sz = dlen;
219 237 : ulong memset_sz = fd_ulong_sat_sub( new_sz, old_sz );
220 237 : fd_memset( fd_account_data( meta ) + old_sz, 0, memset_sz );
221 237 : meta->dlen = (uint)dlen;
222 237 : }
223 :
224 : FD_PROTOTYPES_END
225 :
226 : #endif /* HEADER_fd_src_flamenco_runtime_fd_runtime_helpers_h */
|