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