Line data Source code
1 : #include "fd_builtin_programs.h"
2 : #include "fd_precompiles.h"
3 : #include "../fd_runtime.h"
4 : #include "../fd_acc_mgr.h"
5 : #include "../fd_system_ids.h"
6 : #include "../fd_system_ids_pp.h"
7 :
8 : #define BUILTIN_PROGRAM(program_id, name, feature_offset, migration_config) \
9 : { \
10 : program_id, \
11 : name, \
12 : feature_offset, \
13 : migration_config \
14 : }
15 :
16 : #define STATELESS_BUILTIN(program_id, migration_config) \
17 : { \
18 : program_id, \
19 : migration_config \
20 : }
21 :
22 : #define CORE_BPF_MIGRATION_CONFIG(source_buffer_address, upgrade_authority_address, enable_feature_offset, builtin_program_id) \
23 : { \
24 : source_buffer_address, \
25 : upgrade_authority_address, \
26 : enable_feature_offset, \
27 : builtin_program_id \
28 : }
29 :
30 : #define PRECOMPILE(program_id, feature_offset, verify_fn) \
31 : { \
32 : program_id, \
33 : feature_offset, \
34 : verify_fn \
35 : }
36 :
37 : /* Core BPF migration configs */
38 : static const fd_core_bpf_migration_config_t BUILTIN_TO_CORE_BPF_STAKE_PROGRAM_CONFIG = {
39 : &fd_solana_stake_program_buffer_address,
40 : NULL,
41 : offsetof(fd_features_t, migrate_stake_program_to_core_bpf),
42 : FD_CORE_BPF_MIGRATION_TARGET_BUILTIN,
43 : &fd_solana_stake_program_id,
44 : NULL
45 : };
46 : static const fd_core_bpf_migration_config_t * const MIGRATE_BUILTIN_TO_CORE_BPF_STAKE_PROGRAM_CONFIG = &BUILTIN_TO_CORE_BPF_STAKE_PROGRAM_CONFIG;
47 :
48 : static const fd_core_bpf_migration_config_t BUILTIN_TO_CORE_BPF_CONFIG_PROGRAM_CONFIG = {
49 : &fd_solana_config_program_buffer_address,
50 : NULL,
51 : offsetof(fd_features_t, migrate_config_program_to_core_bpf),
52 : FD_CORE_BPF_MIGRATION_TARGET_BUILTIN,
53 : &fd_solana_config_program_id,
54 : NULL
55 : };
56 : static const fd_core_bpf_migration_config_t * const MIGRATE_BUILTIN_TO_CORE_BPF_CONFIG_PROGRAM_CONFIG = &BUILTIN_TO_CORE_BPF_CONFIG_PROGRAM_CONFIG;
57 :
58 : static const fd_core_bpf_migration_config_t BUILTIN_TO_CORE_BPF_ADDRESS_LOOKUP_TABLE_PROGRAM_CONFIG = {
59 : &fd_solana_address_lookup_table_program_buffer_address,
60 : NULL,
61 : offsetof(fd_features_t, migrate_address_lookup_table_program_to_core_bpf),
62 : FD_CORE_BPF_MIGRATION_TARGET_BUILTIN,
63 : &fd_solana_address_lookup_table_program_id,
64 : NULL
65 : };
66 : static const fd_core_bpf_migration_config_t * const MIGRATE_BUILTIN_TO_CORE_BPF_ADDRESS_LOOKUP_TABLE_PROGRAM_CONFIG = &BUILTIN_TO_CORE_BPF_ADDRESS_LOOKUP_TABLE_PROGRAM_CONFIG;
67 :
68 : static const fd_core_bpf_migration_config_t STATELESS_TO_CORE_BPF_FEATURE_GATE_PROGRAM_CONFIG = {
69 : &fd_solana_feature_program_buffer_address,
70 : NULL,
71 : offsetof(fd_features_t, migrate_feature_gate_program_to_core_bpf),
72 : FD_CORE_BPF_MIGRATION_TARGET_STATELESS,
73 : &fd_solana_feature_program_id,
74 : NULL
75 : };
76 : static const fd_core_bpf_migration_config_t * const MIGRATE_STATELESS_TO_CORE_BPF_FEATURE_GATE_PROGRAM_CONFIG = &STATELESS_TO_CORE_BPF_FEATURE_GATE_PROGRAM_CONFIG;
77 :
78 : /* 192ed727334abe822d5accba8b886e25f88b03c76973c2e7290cfb55b9e1115f */
79 : #define SLASHING_PROG_HASH_SIMD_204 0x19U,0x2eU,0xd7U,0x27U,0x33U,0x4aU,0xbeU,0x82U,0x2dU,0x5aU,0xccU,0xbaU,0x8bU,0x88U,0x6eU,0x25U, \
80 : 0xf8U,0x8bU,0x03U,0xc7U,0x69U,0x73U,0xc2U,0xe7U,0x29U,0x0cU,0xfbU,0x55U,0xb9U,0xe1U,0x11U,0x5fU
81 : const fd_hash_t fd_solana_slashing_program_verified_build_hash_simd_204 = { .uc = { SLASHING_PROG_HASH_SIMD_204 } };
82 : static const fd_core_bpf_migration_config_t STATELESS_TO_CORE_BPF_SLASHING_PROGRAM_CONFIG = {
83 : &fd_solana_slashing_program_buffer_address,
84 : NULL,
85 : offsetof(fd_features_t, enshrine_slashing_program),
86 : FD_CORE_BPF_MIGRATION_TARGET_STATELESS,
87 : &fd_solana_slashing_program_id,
88 : &fd_solana_slashing_program_verified_build_hash_simd_204
89 : };
90 : static const fd_core_bpf_migration_config_t * const MIGRATE_STATELESS_TO_CORE_BPF_SLASHING_PROGRAM_CONFIG = &STATELESS_TO_CORE_BPF_SLASHING_PROGRAM_CONFIG;
91 :
92 : #define SYSTEM_PROGRAM_BUILTIN BUILTIN_PROGRAM(&fd_solana_system_program_id, "system_program", NO_ENABLE_FEATURE_ID, NULL)
93 : #define VOTE_PROGRAM_BUILTIN BUILTIN_PROGRAM(&fd_solana_vote_program_id, "vote_program", NO_ENABLE_FEATURE_ID, NULL)
94 : #define STAKE_PROGRAM_BUILTIN BUILTIN_PROGRAM(&fd_solana_stake_program_id, "stake_program", NO_ENABLE_FEATURE_ID, MIGRATE_BUILTIN_TO_CORE_BPF_STAKE_PROGRAM_CONFIG)
95 : #define CONFIG_PROGRAM_BUILTIN BUILTIN_PROGRAM(&fd_solana_config_program_id, "config_program", NO_ENABLE_FEATURE_ID, MIGRATE_BUILTIN_TO_CORE_BPF_CONFIG_PROGRAM_CONFIG)
96 : #define LOADER_V4_BUILTIN BUILTIN_PROGRAM(&fd_solana_bpf_loader_v4_program_id, "loader_v4", offsetof(fd_features_t, enable_loader_v4), NULL)
97 : #define ADDRESS_LOOKUP_TABLE_PROGRAM_BUILTIN BUILTIN_PROGRAM(&fd_solana_address_lookup_table_program_id, "address_lookup_table_program", NO_ENABLE_FEATURE_ID, MIGRATE_BUILTIN_TO_CORE_BPF_ADDRESS_LOOKUP_TABLE_PROGRAM_CONFIG)
98 : #define BPF_LOADER_DEPRECATED_BUILTIN BUILTIN_PROGRAM(&fd_solana_bpf_loader_deprecated_program_id, "solana_bpf_loader_deprecated_program", NO_ENABLE_FEATURE_ID, NULL)
99 : #define BPF_LOADER_BUILTIN BUILTIN_PROGRAM(&fd_solana_bpf_loader_program_id, "solana_bpf_loader_program", NO_ENABLE_FEATURE_ID, NULL)
100 : #define BPF_LOADER_UPGRADEABLE_BUILTIN BUILTIN_PROGRAM(&fd_solana_bpf_loader_upgradeable_program_id, "solana_bpf_loader_upgradeable_program", NO_ENABLE_FEATURE_ID, NULL)
101 : #define COMPUTE_BUDGET_PROGRAM_BUILTIN BUILTIN_PROGRAM(&fd_solana_compute_budget_program_id, "compute_budget_program", NO_ENABLE_FEATURE_ID, NULL)
102 : #define ZK_TOKEN_PROOF_PROGRAM_BUILTIN BUILTIN_PROGRAM(&fd_solana_zk_token_proof_program_id, "zk_token_proof_program", offsetof(fd_features_t, zk_token_sdk_enabled), NULL)
103 : #define ZK_ELGAMAL_PROOF_PROGRAM_BUILTIN BUILTIN_PROGRAM(&fd_solana_zk_elgamal_proof_program_id, "zk_elgamal_proof_program", offsetof(fd_features_t, zk_elgamal_proof_program_enabled), NULL)
104 :
105 : #define FEATURE_PROGRAM_BUILTIN STATELESS_BUILTIN(&fd_solana_feature_program_id, MIGRATE_STATELESS_TO_CORE_BPF_FEATURE_GATE_PROGRAM_CONFIG)
106 : #define SLASHING_PROGRAM_BUILTIN STATELESS_BUILTIN(&fd_solana_slashing_program_id, MIGRATE_STATELESS_TO_CORE_BPF_SLASHING_PROGRAM_CONFIG)
107 :
108 : #define SECP256R1_PROGRAM_PRECOMPILE PRECOMPILE(&fd_solana_secp256r1_program_id, offsetof(fd_features_t, enable_secp256r1_precompile), fd_precompile_secp256r1_verify)
109 : #define KECCAK_SECP_PROGRAM_PRECOMPILE PRECOMPILE(&fd_solana_keccak_secp_256k_program_id, NO_ENABLE_FEATURE_ID, fd_precompile_secp256k1_verify)
110 : #define ED25519_SV_PROGRAM_PRECOMPILE PRECOMPILE(&fd_solana_ed25519_sig_verify_program_id, NO_ENABLE_FEATURE_ID, fd_precompile_ed25519_verify)
111 :
112 : /* https://github.com/anza-xyz/agave/blob/v2.1.0/runtime/src/bank/builtins/mod.rs#L133-L143 */
113 : static const fd_stateless_builtin_program_t stateless_programs_builtins[] = {
114 : FEATURE_PROGRAM_BUILTIN,
115 : SLASHING_PROGRAM_BUILTIN
116 : };
117 0 : #define STATELESS_BUILTINS_COUNT (sizeof(stateless_programs_builtins) / sizeof(fd_stateless_builtin_program_t))
118 :
119 : static const fd_precompile_program_t precompiles[] = {
120 : SECP256R1_PROGRAM_PRECOMPILE,
121 : KECCAK_SECP_PROGRAM_PRECOMPILE,
122 : ED25519_SV_PROGRAM_PRECOMPILE
123 : };
124 0 : #define PRECOMPILE_PROGRAMS_COUNT (sizeof(precompiles) / sizeof(fd_precompile_program_t))
125 :
126 : /* https://github.com/anza-xyz/agave/blob/v2.1.0/runtime/src/bank/builtins/mod.rs#L34-L131 */
127 : static fd_builtin_program_t const builtin_programs[] = {
128 : SYSTEM_PROGRAM_BUILTIN,
129 : VOTE_PROGRAM_BUILTIN,
130 : STAKE_PROGRAM_BUILTIN,
131 : CONFIG_PROGRAM_BUILTIN,
132 : LOADER_V4_BUILTIN,
133 : ADDRESS_LOOKUP_TABLE_PROGRAM_BUILTIN,
134 : BPF_LOADER_DEPRECATED_BUILTIN,
135 : BPF_LOADER_BUILTIN,
136 : BPF_LOADER_UPGRADEABLE_BUILTIN,
137 : COMPUTE_BUDGET_PROGRAM_BUILTIN,
138 : ZK_TOKEN_PROOF_PROGRAM_BUILTIN,
139 : ZK_ELGAMAL_PROOF_PROGRAM_BUILTIN
140 : };
141 0 : #define BUILTIN_PROGRAMS_COUNT (sizeof(builtin_programs) / sizeof(fd_builtin_program_t))
142 :
143 : /* Used by the compute budget program to determine how many CUs to deduct by default
144 : https://github.com/anza-xyz/agave/blob/v2.1.13/builtins-default-costs/src/lib.rs#L113-L139 */
145 : static fd_core_bpf_migration_config_t const * migrating_builtins[] = {
146 : MIGRATE_BUILTIN_TO_CORE_BPF_STAKE_PROGRAM_CONFIG,
147 : MIGRATE_BUILTIN_TO_CORE_BPF_CONFIG_PROGRAM_CONFIG,
148 : MIGRATE_BUILTIN_TO_CORE_BPF_ADDRESS_LOOKUP_TABLE_PROGRAM_CONFIG,
149 : };
150 0 : #define MIGRATING_BUILTINS_COUNT (sizeof(migrating_builtins) / sizeof(fd_core_bpf_migration_config_t const *))
151 :
152 : /* Using MAP_PERFECT instead of a list for optimization
153 : https://github.com/anza-xyz/agave/blob/v2.1.13/builtins-default-costs/src/lib.rs#L141-L193 */
154 : #define MAP_PERFECT_NAME fd_non_migrating_builtins_tbl
155 : #define MAP_PERFECT_LG_TBL_SZ 4
156 : #define MAP_PERFECT_T fd_pubkey_t
157 0 : #define MAP_PERFECT_HASH_C 146U
158 : #define MAP_PERFECT_KEY uc
159 : #define MAP_PERFECT_KEY_T fd_pubkey_t const *
160 : #define MAP_PERFECT_ZERO_KEY (0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0)
161 : #define MAP_PERFECT_COMPLEX_KEY 1
162 0 : #define MAP_PERFECT_KEYS_EQUAL(k1,k2) (!memcmp( (k1), (k2), 32UL ))
163 :
164 0 : #define PERFECT_HASH( u ) (((MAP_PERFECT_HASH_C*(u))>>28)&0x0FU)
165 :
166 : #define MAP_PERFECT_HASH_PP( a00,a01,a02,a03,a04,a05,a06,a07,a08,a09,a10,a11,a12,a13,a14,a15, \
167 : a16,a17,a18,a19,a20,a21,a22,a23,a24,a25,a26,a27,a28,a29,a30,a31) \
168 : PERFECT_HASH( (a08 | (a09<<8) | (a10<<16) | (a11<<24)) )
169 0 : #define MAP_PERFECT_HASH_R( ptr ) PERFECT_HASH( fd_uint_load_4( (uchar const *)ptr->uc + 8UL ) )
170 :
171 : #define MAP_PERFECT_0 ( VOTE_PROG_ID ),
172 : #define MAP_PERFECT_1 ( SYS_PROG_ID ),
173 : #define MAP_PERFECT_2 ( COMPUTE_BUDGET_PROG_ID ),
174 : #define MAP_PERFECT_3 ( BPF_UPGRADEABLE_PROG_ID ),
175 : #define MAP_PERFECT_4 ( BPF_LOADER_1_PROG_ID ),
176 : #define MAP_PERFECT_5 ( BPF_LOADER_2_PROG_ID ),
177 : #define MAP_PERFECT_6 ( LOADER_V4_PROG_ID ),
178 : #define MAP_PERFECT_7 ( KECCAK_SECP_PROG_ID ),
179 : #define MAP_PERFECT_8 ( ED25519_SV_PROG_ID ),
180 :
181 : #include "../../../util/tmpl/fd_map_perfect.c"
182 : #undef PERFECT_HASH
183 :
184 : // https://github.com/anza-xyz/agave/blob/v2.3.7/runtime/src/bank.rs#L4944
185 : static int
186 : fd_builtin_is_bpf( fd_funk_t * funk,
187 : fd_funk_txn_xid_t const * xid,
188 0 : fd_pubkey_t const * pubkey ) {
189 0 : FD_TXN_ACCOUNT_DECL( rec );
190 0 : int err = fd_txn_account_init_from_funk_readonly( rec, pubkey, funk, xid );
191 0 : if( !!err ) {
192 0 : return 0;
193 0 : }
194 :
195 0 : fd_pubkey_t const * owner = fd_txn_account_get_owner( rec );
196 0 : return memcmp( owner, &fd_solana_bpf_loader_upgradeable_program_id, sizeof(fd_solana_bpf_loader_upgradeable_program_id) )==0;
197 0 : }
198 :
199 :
200 : /* BuiltIn programs need "bogus" executable accounts to exist.
201 : These are loaded and ignored during execution.
202 :
203 : Bogus accounts are marked as "executable", but their data is a
204 : hardcoded ASCII string. */
205 :
206 : /* https://github.com/solana-labs/solana/blob/8f2c8b8388a495d2728909e30460aa40dcc5d733/sdk/src/native_loader.rs#L19 */
207 : void
208 : fd_write_builtin_account( fd_bank_t * bank,
209 : fd_funk_t * funk,
210 : fd_funk_txn_xid_t const * xid,
211 : fd_capture_ctx_t * capture_ctx,
212 : fd_pubkey_t const pubkey,
213 : char const * data,
214 0 : ulong sz ) {
215 :
216 0 : FD_TXN_ACCOUNT_DECL( rec );
217 0 : fd_funk_rec_prepare_t prepare = {0};
218 :
219 0 : int err = fd_txn_account_init_from_funk_mutable( rec, &pubkey, funk, xid, 1, sz, &prepare );
220 0 : FD_TEST( !err );
221 :
222 0 : fd_lthash_value_t prev_hash[1];
223 0 : fd_hashes_account_lthash(
224 0 : &pubkey,
225 0 : fd_txn_account_get_meta( rec ),
226 0 : fd_txn_account_get_data( rec ),
227 0 : prev_hash );
228 :
229 0 : fd_txn_account_set_data( rec, data, sz );
230 0 : fd_txn_account_set_lamports( rec, 1UL );
231 0 : fd_txn_account_set_executable( rec, 1 );
232 0 : fd_txn_account_set_owner( rec, &fd_solana_native_loader_id );
233 :
234 0 : fd_hashes_update_lthash( rec, prev_hash, bank, capture_ctx );
235 :
236 0 : fd_txn_account_mutable_fini( rec, funk, &prepare );
237 :
238 0 : fd_bank_capitalization_set( bank, fd_bank_capitalization_get( bank ) + 1UL );
239 :
240 0 : FD_TEST( !err );
241 0 : }
242 :
243 : /* https://github.com/solana-labs/solana/blob/8f2c8b8388a495d2728909e30460aa40dcc5d733/runtime/src/inline_spl_token.rs#L74 */
244 : /* TODO: move this somewhere more appropiate */
245 : static void
246 : write_inline_spl_native_mint_program_account( fd_funk_t * funk,
247 0 : fd_funk_txn_xid_t const * xid ) {
248 :
249 0 : if( true ) {
250 : /* FIXME: This is a hack that corresponds to the cluster type field
251 : in Agave. This needs to get implemented properly in Firedancer. */
252 0 : return;
253 0 : }
254 :
255 0 : fd_pubkey_t const * key = (fd_pubkey_t const *)&fd_solana_spl_native_mint_id;
256 0 : FD_TXN_ACCOUNT_DECL( rec );
257 :
258 : /* https://github.com/solana-labs/solana/blob/8f2c8b8388a495d2728909e30460aa40dcc5d733/runtime/src/inline_spl_token.rs#L86-L90 */
259 0 : static uchar const data[] = {
260 0 : 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
261 0 : 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
262 0 : 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
263 :
264 0 : fd_funk_rec_prepare_t prepare = {0};
265 0 : int err = fd_txn_account_init_from_funk_mutable( rec, key, funk, xid, 1, sizeof(data), &prepare );
266 0 : FD_TEST( !err );
267 :
268 0 : fd_txn_account_set_lamports( rec, 1000000000UL );
269 0 : fd_txn_account_set_executable( rec, 0 );
270 0 : fd_txn_account_set_owner( rec, &fd_solana_spl_token_id );
271 0 : fd_txn_account_set_data( rec, data, sizeof(data) );
272 :
273 0 : fd_txn_account_mutable_fini( rec, funk, &prepare );
274 :
275 0 : FD_TEST( !err );
276 0 : }
277 :
278 : // <rant> Why are these not in the genesis block themselves?! the hackery to deal with subtle solana variants
279 : // because of the "special knowledge" required for these accounts is counter productive... </rant>
280 :
281 : void
282 : fd_builtin_programs_init( fd_bank_t * bank,
283 : fd_funk_t * funk,
284 : fd_funk_txn_xid_t const * xid,
285 0 : fd_capture_ctx_t * capture_ctx ) {
286 : /* https://github.com/anza-xyz/agave/blob/v2.3.7/builtins/src/lib.rs#L52 */
287 0 : fd_builtin_program_t const * builtins = fd_builtins();
288 :
289 0 : for( ulong i=0UL; i<fd_num_builtins(); i++ ) {
290 : /** https://github.com/anza-xyz/agave/blob/v2.3.7/runtime/src/bank.rs#L4949 */
291 0 : if( fd_bank_slot_get( bank )==0UL && builtins[i].enable_feature_offset==NO_ENABLE_FEATURE_ID && !fd_builtin_is_bpf( funk, xid, builtins[i].pubkey ) ) {
292 0 : fd_write_builtin_account( bank, funk, xid, capture_ctx, *builtins[i].pubkey, builtins[i].data, strlen( builtins[i].data ) );
293 0 : } else if( builtins[i].core_bpf_migration_config && FD_FEATURE_ACTIVE_OFFSET( fd_bank_slot_get( bank ), fd_bank_features_get( bank ), builtins[i].core_bpf_migration_config->enable_feature_offset ) ) {
294 0 : continue;
295 0 : } else if( builtins[i].enable_feature_offset!=NO_ENABLE_FEATURE_ID && !FD_FEATURE_ACTIVE_OFFSET( fd_bank_slot_get( bank ), fd_bank_features_get( bank ), builtins[i].enable_feature_offset ) ) {
296 0 : continue;
297 0 : } else {
298 0 : fd_write_builtin_account( bank, funk, xid, capture_ctx, *builtins[i].pubkey, builtins[i].data, strlen(builtins[i].data) );
299 0 : }
300 0 : }
301 :
302 : /* Precompiles have empty account data */
303 0 : if( fd_bank_cluster_version_get( bank ).major == 1 ) {
304 0 : char data[1] = {1};
305 0 : fd_write_builtin_account( bank, funk, xid, capture_ctx, fd_solana_keccak_secp_256k_program_id, data, 1 );
306 0 : fd_write_builtin_account( bank, funk, xid, capture_ctx, fd_solana_ed25519_sig_verify_program_id, data, 1 );
307 0 : if( FD_FEATURE_ACTIVE_BANK( bank, enable_secp256r1_precompile ) )
308 0 : fd_write_builtin_account( bank, funk, xid, capture_ctx, fd_solana_secp256r1_program_id, data, 1 );
309 0 : } else {
310 0 : fd_write_builtin_account( bank, funk, xid, capture_ctx, fd_solana_keccak_secp_256k_program_id, "", 0 );
311 0 : fd_write_builtin_account( bank, funk, xid, capture_ctx, fd_solana_ed25519_sig_verify_program_id, "", 0 );
312 0 : if( FD_FEATURE_ACTIVE_BANK( bank, enable_secp256r1_precompile ) )
313 0 : fd_write_builtin_account( bank, funk, xid, capture_ctx, fd_solana_secp256r1_program_id, "", 0 );
314 0 : }
315 :
316 : /* Inline SPL token mint program ("inlined to avoid an external dependency on the spl-token crate") */
317 0 : write_inline_spl_native_mint_program_account( funk, xid );
318 0 : }
319 :
320 : fd_builtin_program_t const *
321 0 : fd_builtins( void ) {
322 0 : return builtin_programs;
323 0 : }
324 :
325 : ulong
326 0 : fd_num_builtins( void ) {
327 0 : return BUILTIN_PROGRAMS_COUNT;
328 0 : }
329 :
330 : fd_stateless_builtin_program_t const *
331 0 : fd_stateless_builtins( void ) {
332 0 : return stateless_programs_builtins;
333 0 : }
334 :
335 : ulong
336 0 : fd_num_stateless_builtins( void ) {
337 0 : return STATELESS_BUILTINS_COUNT;
338 0 : }
339 :
340 : fd_precompile_program_t const *
341 0 : fd_precompiles( void ) {
342 0 : return precompiles;
343 0 : }
344 :
345 : ulong
346 0 : fd_num_precompiles( void ) {
347 0 : return PRECOMPILE_PROGRAMS_COUNT;
348 0 : }
349 :
350 : uchar
351 : fd_is_migrating_builtin_program( fd_exec_txn_ctx_t const * txn_ctx,
352 : fd_pubkey_t const * pubkey,
353 0 : uchar * migrated_yet ) {
354 0 : *migrated_yet = 0;
355 :
356 0 : for( ulong i=0; i<MIGRATING_BUILTINS_COUNT; i++ ) {
357 0 : fd_core_bpf_migration_config_t const * config = migrating_builtins[i];
358 0 : if( !memcmp( pubkey->uc, config->builtin_program_id->key, sizeof(fd_pubkey_t) ) ) {
359 0 : if( config->enable_feature_offset!=NO_ENABLE_FEATURE_ID &&
360 0 : FD_FEATURE_ACTIVE_OFFSET( txn_ctx->slot, txn_ctx->features, config->enable_feature_offset ) ) {
361 : /* The program has been migrated to BPF. */
362 0 : *migrated_yet = 1;
363 0 : }
364 :
365 0 : return 1;
366 0 : }
367 0 : }
368 :
369 : /* No migration config exists for this program */
370 0 : return 0;
371 0 : }
372 :
373 : FD_FN_PURE uchar
374 0 : fd_is_non_migrating_builtin_program( fd_pubkey_t const * pubkey ) {
375 0 : return !!( fd_non_migrating_builtins_tbl_contains( pubkey ) );
376 0 : }
|