miraland_sdk/
feature_set.rs

1//! Collection of all runtime features.
2//!
3//! Steps to add a new feature are outlined below. Note that these steps only cover
4//! the process of getting a feature into the core Miraland code.
5//! - For features that are unambiguously good (ie bug fixes), these steps are sufficient.
6//! - For features that should go up for community vote (ie fee structure changes), more
7//!   information on the additional steps to follow can be found at:
8//!   <https://spl.solana.com/feature-proposal#feature-proposal-life-cycle>
9//!
10//! 1. Generate a new keypair with `miraland-keygen new --outfile feature.json --no-passphrase`
11//!    - Keypairs should be held by core contributors only. If you're a non-core contributor going
12//!      through these steps, the PR process will facilitate a keypair holder being picked. That
13//!      person will generate the keypair, provide pubkey for PR, and ultimately enable the feature.
14//! 2. Add a public module for the feature, specifying keypair pubkey as the id with
15//!    `miraland_sdk::declare_id!()` within the module.
16//!    Additionally, add an entry to `FEATURE_NAMES` map.
17//! 3. Add desired logic to check for and switch on feature availability.
18//!
19//! For more information on how features are picked up, see comments for `Feature`.
20
21use {
22    lazy_static::lazy_static,
23    miraland_program::{epoch_schedule::EpochSchedule, stake_history::Epoch},
24    miraland_sdk::{
25        clock::Slot,
26        hash::{Hash, Hasher},
27        pubkey::Pubkey,
28    },
29    std::collections::{HashMap, HashSet},
30};
31
32pub mod deprecate_rewards_sysvar {
33    miraland_sdk::declare_id!("2c1LfwhtrnYYUTADd7jNfw2v25C9wdD7TxaNNeBL26Uo");
34}
35
36pub mod pico_inflation {
37    miraland_sdk::declare_id!("79Rx9u8bp61qVXfgU77ConTZusQrJAVCLHKX12fXQFLM");
38}
39
40pub mod full_inflation {
41    pub mod devnet_and_testnet {
42        miraland_sdk::declare_id!("4SLokfWfRfEdgc9LTQPeqVSTKp1yT9EGxkvunw2kyRYk");
43    }
44
45    pub mod mainnet {
46        pub mod certusone {
47            pub mod vote {
48                miraland_sdk::declare_id!("6LAz8hDNfU2wZQNvU5A486aLb4uMqMP71VJuLeqa8VH1");
49            }
50            pub mod enable {
51                miraland_sdk::declare_id!("APxJq5bJDVHvXvxgnSzynG4fcrnjBftgiHqryr8HGzeZ");
52            }
53        }
54    }
55}
56
57pub mod secp256k1_program_enabled {
58    miraland_sdk::declare_id!("7jUAsmg1aiq7KUFJmgTbonwB7o1UkcPwhaxyvtoK6aLv");
59}
60
61pub mod spl_token_v2_multisig_fix {
62    miraland_sdk::declare_id!("9UeP8WVfxerQVsvS7CKPocQb3SicYhzeJdfPxbbw3Xba");
63}
64
65pub mod no_overflow_rent_distribution {
66    miraland_sdk::declare_id!("28yzxUrgESLBv8MLCq7HHWt69PqQm8qEFfdN9niqLx1n");
67}
68
69pub mod filter_stake_delegation_accounts {
70    miraland_sdk::declare_id!("2pjiimKVUKEgnc79asiV1SQLQ4jtHziCw8RzXtjHgfz5");
71}
72
73pub mod require_custodian_for_locked_stake_authorize {
74    miraland_sdk::declare_id!("BoSRYC39THTKeiGzUAfBJUJTUBpmvprqMdqbSaPmKf79");
75}
76
77pub mod spl_token_v2_self_transfer_fix {
78    miraland_sdk::declare_id!("BXTRt14DE2ogunj5E3KTU3Gp5aYJVNJAiswq8ocSbDnc");
79}
80
81pub mod warp_timestamp_again {
82    miraland_sdk::declare_id!("7jj4R75Y3zUvdfLSDcx4FXnWSPauxA3e5ajdxwGSq9HM");
83}
84
85pub mod check_init_vote_data {
86    miraland_sdk::declare_id!("8uSS6mrHnYcFF9xdLEuJBQ2zvePVtHmeoPnewXy6EzH1");
87}
88
89pub mod secp256k1_recover_syscall_enabled {
90    miraland_sdk::declare_id!("8bsFk18mhd2R81MkdXaWYNQGiDcDWDHcXxEnc3wmaPJ9");
91}
92
93pub mod system_transfer_zero_check {
94    miraland_sdk::declare_id!("F2VaF6pkmUnPUE92Pv6sephEWBkoUUi5evPUtNtxEDo9");
95}
96
97pub mod blake3_syscall_enabled {
98    miraland_sdk::declare_id!("4jNWNYf2uHsZ7DmP6RizeC9m5WiffkyGTtj6BehjBsbJ");
99}
100
101pub mod dedupe_config_program_signers {
102    miraland_sdk::declare_id!("7oQw7GQWdsUSbVqMqP42nTntnDkKJPPSM3ydrMSLCWAY");
103}
104
105pub mod verify_tx_signatures_len {
106    miraland_sdk::declare_id!("2V95BUaoS7mUgd4e6LCXtAd5WLuDyYFP5u9AuXfSZFHQ");
107}
108
109pub mod vote_stake_checked_instructions {
110    miraland_sdk::declare_id!("FBgh8jqxHJWJG9Rrc59gWb1bQq6PHFg675QVVitZtXMt");
111}
112
113pub mod rent_for_sysvars {
114    miraland_sdk::declare_id!("D2UrJpLDUzjSC7F7U3ZZpAw4UvZkSLybteeyL2Soa6AL");
115}
116
117pub mod libsecp256k1_0_5_upgrade_enabled {
118    miraland_sdk::declare_id!("2Tf8EAMRjo8Z9kEmSL5JLbf33Q2tjCSieP4FBZGrdHQZ");
119}
120
121pub mod tx_wide_compute_cap {
122    miraland_sdk::declare_id!("4AdEYJECdV8Zve71m7xLimhgdL3qi2tvqEy6r1VZm4ih");
123}
124
125pub mod spl_token_v2_set_authority_fix {
126    miraland_sdk::declare_id!("N2UX7hfPmEUQrmTKUqUqX3fspnsehrbAqyDzY5JFkcc");
127}
128
129pub mod merge_nonce_error_into_system_error {
130    miraland_sdk::declare_id!("5rgeSmE17s1tbUSDmmcqXL26A9SqaLNUmgDzKbDKY3af");
131}
132
133pub mod disable_fees_sysvar {
134    miraland_sdk::declare_id!("28GpzueRzsKyPd2vmkwhXKdr174viqEaMPoUaFBRXXRo");
135}
136
137pub mod stake_merge_with_unmatched_credits_observed {
138    miraland_sdk::declare_id!("5Y4VcaQSoUj4j9ZeLjq3fH2WRc8mbk3H5BH6Vf578wfF");
139}
140
141pub mod zk_token_sdk_enabled {
142    miraland_sdk::declare_id!("FNEsWEdUNGbyWVxiJrSmf1SbmypFJPtPURAGgcUiE7Xf");
143}
144
145pub mod curve25519_syscall_enabled {
146    miraland_sdk::declare_id!("8rd1cN2QwtAMR5BV4fEZGxyUfWJtSB2AihHhctPGc4Ya");
147}
148
149pub mod curve25519_restrict_msm_length {
150    miraland_sdk::declare_id!("9FjsWJGJrtCiaR6wWiwxJHyWdSSjj2E5E3VYhKJDXXLU");
151}
152
153pub mod versioned_tx_message_enabled {
154    miraland_sdk::declare_id!("4R9FuBD4tN3rzYnGL6VLtehzuVXSbxgUSor4sRqYfxQD");
155}
156
157pub mod libsecp256k1_fail_on_bad_count {
158    miraland_sdk::declare_id!("ADf1p7q3ZHsmNuCn5SHh2AFdhrvP6UVBphsnURGy94eJ");
159}
160
161pub mod libsecp256k1_fail_on_bad_count2 {
162    miraland_sdk::declare_id!("4EBpJoi9YamhAY9hgPxFL3N2xk7GbiRWpfEcXgJZCzVx");
163}
164
165pub mod instructions_sysvar_owned_by_sysvar {
166    miraland_sdk::declare_id!("83x8QZSPCDqiCrfVhTPn4j6ML4iTSG6DgD1THk8rDnHJ");
167}
168
169pub mod stake_program_advance_activating_credits_observed {
170    miraland_sdk::declare_id!("ExSUs7m2qv6d4TYb72EuaKEBqcA8TktnRNm2GEeWWFP3");
171}
172
173pub mod credits_auto_rewind {
174    miraland_sdk::declare_id!("7iCvJnUS8kmC2gXARop5SV4TWgEu9VW3HCjPCX3aH6ap");
175}
176
177pub mod demote_program_write_locks {
178    miraland_sdk::declare_id!("EzXHe4N1ezMU1mAXkEbTxz6bT7NT8nZrD3yWaTdm5nKi");
179}
180
181pub mod ed25519_program_enabled {
182    miraland_sdk::declare_id!("8N6nBvvMTnC5FFNgBnFagpLo1ecNoCpvfkgFJVhVRHFY");
183}
184
185pub mod return_data_syscall_enabled {
186    miraland_sdk::declare_id!("6WTDFppf83DMNejYPQpFfniJSUocgNfyF6KDeriGy8be");
187}
188
189pub mod reduce_required_deploy_balance {
190    miraland_sdk::declare_id!("6V5vr414z1BXCJo9MXXArJNVKbkqtAH7HE32U6rcZESx");
191}
192
193pub mod sol_log_data_syscall_enabled {
194    miraland_sdk::declare_id!("3nsrptKRNefv1f7yHUAg9hbnf28GAkVGajaR42XEDV9Q");
195}
196
197pub mod stakes_remove_delegation_if_inactive {
198    miraland_sdk::declare_id!("9ryFTNZjt9eiGxPxZP9vmu1o7MTP432F4Deu3CBr8Fuf");
199}
200
201pub mod do_support_realloc {
202    miraland_sdk::declare_id!("DM4TyMJkUYN6YXVaeFpWTDGBdWo5sbhk82RDScK7ptjU");
203}
204
205pub mod prevent_calling_precompiles_as_programs {
206    miraland_sdk::declare_id!("9EmqPEbM54LjSwHwNFBvF5G5ePmyc9vtYDdeafAXcUAB");
207}
208
209pub mod optimize_epoch_boundary_updates {
210    miraland_sdk::declare_id!("DkLJm8F8bXJJt4PjrXYRTrdvqJfrV9nKRWbLvKqBpTVV");
211}
212
213pub mod remove_native_loader {
214    miraland_sdk::declare_id!("7RtzXKHPtYjVLxG4Si7P28rB5eFtFA96ruZFCbSRMZjW");
215}
216
217pub mod send_to_tpu_vote_port {
218    miraland_sdk::declare_id!("EfZQW1z4UugTsjpL4q7kXEhM2cuokXAyx3xNimAX96hh");
219}
220
221pub mod requestable_heap_size {
222    miraland_sdk::declare_id!("2uWChP7zecD9mCWRN671u9RQBppxaJUvey1tbS5gEGJh");
223}
224
225pub mod disable_fee_calculator {
226    miraland_sdk::declare_id!("G7qQS6VDvdrGX2t9n8WGLKEXorCEFjdepyTWVc5FNPBp");
227}
228
229pub mod add_compute_budget_program {
230    miraland_sdk::declare_id!("35BUe4UVLer2dwHQyBn6EgRSwc2yfbvy9TQxD7vYRExU");
231}
232
233pub mod nonce_must_be_writable {
234    miraland_sdk::declare_id!("6z5xsisAAiauaE9cHiHrZAxajJyxFMkwTtaPsLGhCfNg");
235}
236
237pub mod spl_token_v3_3_0_release {
238    miraland_sdk::declare_id!("A3VfsyhcwZKkfTXN1a4Z1dSMQxWiaqjymPMBky2Lh5Mq");
239}
240
241pub mod leave_nonce_on_success {
242    miraland_sdk::declare_id!("CFtA7BGeyWgqh3y5EmgGsdHBCVqDrfAxC8Tm2mBuYox");
243}
244
245pub mod reject_empty_instruction_without_program {
246    miraland_sdk::declare_id!("CVnCWV9rZrdK9gawJ5DPXUggLufqzkiYpe7V8ewHv2gX");
247}
248
249pub mod fixed_memcpy_nonoverlapping_check {
250    miraland_sdk::declare_id!("3SxofBxWgtdYHEKnVEfcuCfmFqmFLiMeD7j4aE7NGJLg");
251}
252
253pub mod reject_non_rent_exempt_vote_withdraws {
254    miraland_sdk::declare_id!("5at3F6XAWJRSdURRrhcPKMsWUu7jpErffQvhbudAG91p");
255}
256
257pub mod evict_invalid_stakes_cache_entries {
258    miraland_sdk::declare_id!("Dj5KYGDEE6XNZ2uuQxH1c9pDwhRS9X3kC7uTvXJnUtbC");
259}
260
261pub mod allow_votes_to_directly_update_vote_state {
262    miraland_sdk::declare_id!("9NQbXmRjHa4LnJVcmCYCQxTAEmgWASZB6dyR8ujmPift");
263}
264
265pub mod cap_accounts_data_len {
266    miraland_sdk::declare_id!("7qx6TcurUwSt6mRkwLjDrJDSxsMnNXsqcrCNzZeNq236");
267}
268
269pub mod max_tx_account_locks {
270    miraland_sdk::declare_id!("56EYkVzpWjvvrVjdmCXSTxFSSK3HUVFKavLyB3H9HvpK");
271}
272
273pub mod require_rent_exempt_accounts {
274    miraland_sdk::declare_id!("FRJstrV5EAhseibFSAXm5ZmPnHdBNAqaT1sDyy9jsoma");
275}
276
277pub mod filter_votes_outside_slot_hashes {
278    miraland_sdk::declare_id!("5izPfs14BkNSkjBBuuQxHbEZomzzF8tvXcbnfqX2Exwn");
279}
280
281pub mod update_syscall_base_costs {
282    miraland_sdk::declare_id!("HmoYBViLHHKw9tqxjGq7Vy8kXzTxzw7RmbBkvcnJfxR8");
283}
284
285pub mod stake_deactivate_delinquent_instruction {
286    miraland_sdk::declare_id!("5NU3DmTjfbtGZ7gsUWFE8TzxZ7PRF5EvbHCuGJhqUh4B");
287}
288
289pub mod stake_redelegate_instruction {
290    miraland_sdk::declare_id!("HD2vR1ZZzjqTXzUyWoUjL5ZAVBpe4wNo1ToR2ogEbbgc");
291}
292
293pub mod vote_withdraw_authority_may_change_authorized_voter {
294    miraland_sdk::declare_id!("97DV3qAzqqPpiqQuZjf3GvKcwgTZwsSLjWnP5naoYhkF");
295}
296
297pub mod spl_associated_token_account_v1_0_4 {
298    miraland_sdk::declare_id!("J3V6Rmm8dFmcZBadzGLLdU7Rrg2rNKWkfmYsTdkeBvmu");
299}
300
301pub mod reject_vote_account_close_unless_zero_credit_epoch {
302    miraland_sdk::declare_id!("9Xn27E7PdcE8rHwkB79MknuoydhVNkEbZFvQMVDchjwq");
303}
304
305pub mod add_get_processed_sibling_instruction_syscall {
306    miraland_sdk::declare_id!("1XCfEQcYXoakjx6ULrMeidyvSozjT3gu1ee38u8ofEu");
307}
308
309pub mod bank_transaction_count_fix {
310    miraland_sdk::declare_id!("9nFiWjLxyKFRTidASf7pgMFCYPHiXQ2oLmD4h6hpRWCA");
311}
312
313pub mod disable_bpf_deprecated_load_instructions {
314    miraland_sdk::declare_id!("CvqsVybTcwM9yi99UGALDtyQ3FxkmsiSzRGLTwwoiow9");
315}
316
317pub mod disable_bpf_unresolved_symbols_at_runtime {
318    miraland_sdk::declare_id!("FmksuagiZ2tXDWoa8o6Cjs3bTFU7vmqhyaYdRbuJdgwM");
319}
320
321pub mod record_instruction_in_transaction_context_push {
322    miraland_sdk::declare_id!("Eg3fSoHWFweKmwpbJnrdMmbebHZ5QpYrprcYtAhNpjmt");
323}
324
325pub mod syscall_saturated_math {
326    miraland_sdk::declare_id!("HHPC2xVx7S1Lxf2pMK3JySKJZurt5CLpNj6c9LRSyuwz");
327}
328
329pub mod check_physical_overlapping {
330    miraland_sdk::declare_id!("Cyx9FW417wQbNC3GLE9jDuqtUiHVysfUP2siU9cXkFLn");
331}
332
333pub mod limit_secp256k1_recovery_id {
334    miraland_sdk::declare_id!("Dt84qqvdFBVppTdxwTLFtRSBLMfBgbHbxbxEYeX5bpBC");
335}
336
337pub mod disable_deprecated_loader {
338    miraland_sdk::declare_id!("768MU43todZ97n7PnYVmJr8ygUnpHhygaXgWbGmHxFTR");
339}
340
341pub mod check_slice_translation_size {
342    miraland_sdk::declare_id!("FPVk8r4grQQkiwMfcMM2PUjccDWTQCMKKM4cE1ndQsfZ");
343}
344
345pub mod stake_split_uses_rent_sysvar {
346    miraland_sdk::declare_id!("3Fq7Z2QBbuwhQGjeTuN2dNSzRKv38rjQaoVjpZZ9CW62");
347}
348
349pub mod add_get_minimum_delegation_instruction_to_stake_program {
350    miraland_sdk::declare_id!("2JeJcFD1ZNriXcwZegot6ACsbZYqWLKpTYdsLwNEhAkX");
351}
352
353pub mod error_on_syscall_bpf_function_hash_collisions {
354    miraland_sdk::declare_id!("9vJtwctZZ1Cd7rdQcLYV8ogxz2KeA4bBkoAf1Yr6kcLE");
355}
356
357pub mod reject_callx_r10 {
358    miraland_sdk::declare_id!("2rDQ1Vm1SSaRmtHThDobnZy79e76br63UUN8Cp6NXZne");
359}
360
361pub mod drop_redundant_turbine_path {
362    miraland_sdk::declare_id!("9EWKPkuSrpx4XXc2UEQrXqHpwmCEjSa3iUkT4GDTAorz");
363}
364
365pub mod executables_incur_cpi_data_cost {
366    miraland_sdk::declare_id!("7utHb3vm2xqUQwEKGF8Kq3CRov8CaPp68hurBNJDFb7C");
367}
368
369pub mod fix_recent_blockhashes {
370    miraland_sdk::declare_id!("CGwzrUUcPSo72h2QViC6UcCNXFv2iM1DkudKW7M3JsM5");
371}
372
373pub mod update_rewards_from_cached_accounts {
374    miraland_sdk::declare_id!("2kdPn3Ey5ECDh3VqpM7EGugJqLDxBoJx6SKPCcoCsEJr");
375}
376pub mod enable_partitioned_epoch_reward {
377    miraland_sdk::declare_id!("38g8VJePWcPHYVJDnj14uEvzM3n6vnuao9dvprLC94UM");
378}
379
380pub mod spl_token_v3_4_0 {
381    miraland_sdk::declare_id!("3fMW2T88f8HGUyknyyNWYCVTo95pEvZQTmRMvLFujfBK");
382}
383
384pub mod spl_associated_token_account_v1_1_0 {
385    miraland_sdk::declare_id!("oBYHRgUwkLQM9eZCXzBRTpazWgGJAx1WtHysQaxcQ84");
386}
387
388pub mod default_units_per_instruction {
389    miraland_sdk::declare_id!("79ZUd4LQuuMSWS1Tg84E1RJV9Dd3C2zjqiAsmVrZ94uu");
390}
391
392pub mod stake_allow_zero_undelegated_amount {
393    miraland_sdk::declare_id!("oar3YgmoDYExbEBWEZEjw753eo2NfskRkBcFG5yAuEA");
394}
395
396pub mod require_static_program_ids_in_transaction {
397    miraland_sdk::declare_id!("oGKc7zccts79GHrWwf3ndumuC6FxxCBaoHM3BbqQgBs");
398}
399
400pub mod stake_raise_minimum_delegation_to_1_mln {
401    // This is a feature-proposal *feature id*.  The feature keypair address is `GQXzC7YiSNkje6FFUk6sc2p53XRvKoaZ9VMktYzUMnpL`.
402    miraland_sdk::declare_id!("GDUQPY5WH24nccKtcHtpNMPQp6cP1SSnjePsMHCjEEcs");
403}
404
405pub mod stake_minimum_delegation_for_rewards {
406    miraland_sdk::declare_id!("YcGYaDrMhbhPMoAt5gj4zKGkRYgNndFSXksoyJx8dUR");
407}
408
409pub mod add_set_compute_unit_price_ix {
410    miraland_sdk::declare_id!("4EVwLByjgirSfFFfEFboeK17YGrUBxRXTw3jwdxpDhah");
411}
412
413pub mod disable_deploy_of_alloc_free_syscall {
414    miraland_sdk::declare_id!("5og3u9Vg5sLtUiVC5cdP9PJfrZeRgazzw1zpxGvePLfh");
415}
416
417pub mod include_account_index_in_rent_error {
418    miraland_sdk::declare_id!("5NhMbTH7XQssZHEAJergVacuTnUws6A5ntt524uFpBWx");
419}
420
421pub mod add_shred_type_to_shred_seed {
422    miraland_sdk::declare_id!("AXD9UhsXbQAsAXtBQYJYfrdpQyhZWEtvAAvnm8twWjeg");
423}
424
425pub mod warp_timestamp_with_a_vengeance {
426    miraland_sdk::declare_id!("48WKpfA7e9x2L6o5NkteqvaJs1njoFZHZtH3YL3Avh1X");
427}
428
429pub mod separate_nonce_from_blockhash {
430    miraland_sdk::declare_id!("9xsusmw7MBtYSEkL8essFbQrvr5GdxLSbj1YoqYUKo5J");
431}
432
433pub mod enable_durable_nonce {
434    miraland_sdk::declare_id!("B18WzS8UncGJQzEm772JLbJfYfJ2DfLCqiVgdbYERzCz");
435}
436
437pub mod vote_state_update_credit_per_dequeue {
438    miraland_sdk::declare_id!("3AoE6v4MSmMsBHX7ukSC8xuw4vGccrqpMxbHDEmcmYBD");
439}
440
441pub mod quick_bail_on_panic {
442    miraland_sdk::declare_id!("6Ns8qHyGbv4udAqvhboD9Hn5QLfuT4rXqGE7pU5m28tH");
443}
444
445pub mod nonce_must_be_authorized {
446    miraland_sdk::declare_id!("24kYbqnGtXiyGj23cdWML1gn37SbyQwsi1fmoo8uCExU");
447}
448
449pub mod nonce_must_be_advanceable {
450    miraland_sdk::declare_id!("4fvFevcmNCFH6iivotrNDvCXzLwSNZEnHXNNCZDJBbgu");
451}
452
453pub mod vote_authorize_with_seed {
454    miraland_sdk::declare_id!("GS1diGxAwxQdZxt5WroA6DGc3QgLZzsc2r7Lwd4HTk8H");
455}
456
457pub mod cap_accounts_data_size_per_block {
458    miraland_sdk::declare_id!("FiHSf24BgV6screxfQ8JDNJorfayyTE1WULfWQa5zeEB");
459}
460
461pub mod preserve_rent_epoch_for_rent_exempt_accounts {
462    miraland_sdk::declare_id!("2gTPWYyesH2ReNq3d637Ug49UAV4toUU1Rqz3uXcLze5");
463}
464
465pub mod enable_bpf_loader_extend_program_ix {
466    miraland_sdk::declare_id!("CM3tFB8SCkq6b4Y2wpWwoxu7qnW9B5dRT7chof69FYUM");
467}
468
469pub mod enable_early_verification_of_account_modifications {
470    miraland_sdk::declare_id!("BkKuJQrZUByC2TCrC3b4GBnsCDN468w1e8FkMxe9SEZE");
471}
472
473pub mod skip_rent_rewrites {
474    miraland_sdk::declare_id!("5FLf2rN66eUhxtRbRBjGNv6SA8HeYeHJSuZdi9T3gUGp");
475}
476
477pub mod prevent_crediting_accounts_that_end_rent_paying {
478    miraland_sdk::declare_id!("7JFYPcNdT1AkfDJu9j5uX5toJE1wVvVF3EjopTDRrxM1");
479}
480
481pub mod cap_bpf_program_instruction_accounts {
482    miraland_sdk::declare_id!("E5PVPzbMMBRTVheoCnsfDHdhVt65ByjKwpc6qWjqsgEP");
483}
484
485pub mod loosen_cpi_size_restriction {
486    miraland_sdk::declare_id!("HeMgEi3umaAii72TP2Vd7Q9cjLYihzMs99ZMMVm1Hetc");
487}
488
489pub mod use_default_units_in_fee_calculation {
490    miraland_sdk::declare_id!("FxxuxT6Qa6qGwUhnCJJ9vBYHXa8v8oFbcVMKd7tR92fH");
491}
492
493pub mod compact_vote_state_updates {
494    miraland_sdk::declare_id!("D81C628sHgkTy8bFoSaTFKR8rtFpBgAZpXrwWvjGN2B1");
495}
496
497pub mod incremental_snapshot_only_incremental_hash_calculation {
498    miraland_sdk::declare_id!("2ot2vmSkdBsHZzx7192NwSk9vkTdKwU9WudDR8yHXLR4");
499}
500
501pub mod disable_cpi_setting_executable_and_rent_epoch {
502    miraland_sdk::declare_id!("4BrSEo9yocvW66UXrG6wqzTjiGwRsyq1fKbqk2yrBGaq");
503}
504
505pub mod on_load_preserve_rent_epoch_for_rent_exempt_accounts {
506    miraland_sdk::declare_id!("5PxkpSkieoAFGaN8NuVXGQnHmVxe27DS5Q42wewroM1w");
507}
508
509pub mod account_hash_ignore_slot {
510    miraland_sdk::declare_id!("Aify2XEM5uFNprngYP8D8jyL1aHJ61FWs5erCxB2aN1r");
511}
512
513pub mod set_exempt_rent_epoch_max {
514    miraland_sdk::declare_id!("7Tr7PC29heiSC7KdhAHCiYHcZdoR2c8cQ3hS7HG4WYC9");
515}
516
517pub mod relax_authority_signer_check_for_lookup_table_creation {
518    miraland_sdk::declare_id!("C3ntUw4zmc86bNdFnExymqUPG4nUbJgV3Ng5GCPuGgan");
519}
520
521pub mod stop_sibling_instruction_search_at_parent {
522    miraland_sdk::declare_id!("BAAkVzojXVbP8M6UCvSFphu5w4TNkdMK7a8fvXfSg63K");
523}
524
525pub mod vote_state_update_root_fix {
526    miraland_sdk::declare_id!("2NmVW5eyqpz2rk9sJbtpEV9NhQgXPYVWJ5yVo4jp74ai");
527}
528
529pub mod cap_accounts_data_allocations_per_transaction {
530    miraland_sdk::declare_id!("A4nSusDCkARGEdmhxHfBVKxgqKV79P3hSpBikAio1Ri4");
531}
532
533pub mod epoch_accounts_hash {
534    miraland_sdk::declare_id!("FYiGZ24WhAwRirirZyeKfu1CG7QX455ZN26DhhEz2gxH");
535}
536
537pub mod remove_deprecated_request_unit_ix {
538    miraland_sdk::declare_id!("8Ww4n3KDG4VHfs18EQV1Wh1JJ4XsgZWnmARxYsPNbvV4");
539}
540
541pub mod disable_rehash_for_rent_epoch {
542    miraland_sdk::declare_id!("4ZRYdjX3o3EvWQAftrqCRM3AG3hMvo5Z6TjzMMXJNmLX");
543}
544
545pub mod increase_tx_account_lock_limit {
546    miraland_sdk::declare_id!("5THgob3FTSEkyt2N3qBX2Q8wGMGAmzfpbBhLZoSZKVkK");
547}
548
549pub mod limit_max_instruction_trace_length {
550    miraland_sdk::declare_id!("38srZF58JcmdxFfgnzNPLfmDoodN9pHZsbDLVxWAeCjx");
551}
552
553pub mod check_syscall_outputs_do_not_overlap {
554    miraland_sdk::declare_id!("2Jdyr1T8MLHJo11g1R6x31hQubbiTLTB2PkdWhYpXzVY");
555}
556
557pub mod enable_bpf_loader_set_authority_checked_ix {
558    miraland_sdk::declare_id!("Ei1isDj2dmZ2nYrpQjyziauFtogYVSKQKAQvuA6D7zor");
559}
560
561pub mod enable_alt_bn128_syscall {
562    miraland_sdk::declare_id!("A2qmibCwjNqp9ki93c5u2QduQLtorh97QkD3EyHibmgz");
563}
564pub mod enable_alt_bn128_compression_syscall {
565    miraland_sdk::declare_id!("3uVo7rt3wpiLCJJ5t6hBVZJRgwLgKjrPcJjRATs6yEFM");
566}
567
568pub mod enable_program_redeployment_cooldown {
569    miraland_sdk::declare_id!("J4pnb9G1wopFrK1PSezsF5MobFVm4wqp1znPrZ8zk1Vg");
570}
571
572pub mod commission_updates_only_allowed_in_first_half_of_epoch {
573    miraland_sdk::declare_id!("7PU1XcsEtKJ3mDEyuEKXhSUapLGM3HMveM97Ghjr6V4u");
574}
575
576pub mod enable_turbine_fanout_experiments {
577    miraland_sdk::declare_id!("9Fi5xXv7RiiKQhrbvwrrM5Q3hEB7VtytegM4U1hWd2ac");
578}
579
580pub mod disable_turbine_fanout_experiments {
581    miraland_sdk::declare_id!("2NowhDaiW3CbPfjzuAdZgyK5fgBpxZyBaQJXHgEmwMbp");
582}
583
584pub mod move_serialized_len_ptr_in_cpi {
585    miraland_sdk::declare_id!("D8Uyu9cPJUs4hq3A671SZVb1a245YbdX73H6dmSiyDXe");
586}
587
588pub mod update_hashes_per_tick {
589    miraland_sdk::declare_id!("7FMX8ib6MKWbF1rU22TMQGRLRCS5d8KQRgrq1nsiUeqE");
590}
591
592pub mod enable_big_mod_exp_syscall {
593    miraland_sdk::declare_id!("BABQkLp7BqGxdDZMxKGotaSBJM6vz9mKCCS1yWzfJDn9");
594}
595
596pub mod disable_builtin_loader_ownership_chains {
597    miraland_sdk::declare_id!("Ae1bZsuXGR4WQNgURnitkJ97yzKUnaN9rSZHoC18ep3i");
598}
599
600pub mod cap_transaction_accounts_data_size {
601    miraland_sdk::declare_id!("8bWvzEWb7qvRGeYwkwpEakMAimSv3mNgGjr1Gp84dHXf");
602}
603
604pub mod remove_congestion_multiplier_from_fee_calculation {
605    miraland_sdk::declare_id!("5FpytkUYJPtiiEs348wyKeVswSZkzQrLpcWjobfvvCjp");
606}
607
608pub mod enable_request_heap_frame_ix {
609    miraland_sdk::declare_id!("jGgt7owpUVRmtbbxh4MG6oJTeTVdn8sru7gWrgJWh2W");
610}
611
612pub mod prevent_rent_paying_rent_recipients {
613    miraland_sdk::declare_id!("Dh9AUCEjhCjBSMd2ZWezX1RdzxbrD51RwBFkZ91ptKX6");
614}
615
616pub mod delay_visibility_of_program_deployment {
617    miraland_sdk::declare_id!("9Yenrk5CURWbENBYM4M6YgsP1f5gLFna2J8fgcgUaTbJ");
618}
619
620pub mod apply_cost_tracker_during_replay {
621    miraland_sdk::declare_id!("3kL7bT87XdJJGVwymujE3rDTTLm89zxfjxBYJrERHkja");
622}
623pub mod bpf_account_data_direct_mapping {
624    miraland_sdk::declare_id!("FeeggaQwvK34GY3Eep8CGsrkWnJDPf5ixAReZaasZ1hr");
625}
626
627pub mod add_set_tx_loaded_accounts_data_size_instruction {
628    miraland_sdk::declare_id!("G7n7ioWpwAKeRyLA88amhF5AXiV8LKGLK9zpJcpgJPP3");
629}
630
631pub mod switch_to_new_elf_parser {
632    miraland_sdk::declare_id!("AEgCQUhVKm9dHg8Ko8CWnXxbpLxDi8ocxF9YdQUQFRuy");
633}
634
635pub mod round_up_heap_size {
636    miraland_sdk::declare_id!("9gP8EkkdoJs84YirDrr7HDph2eJ2sULfUDEBAyuk6h6f");
637}
638
639pub mod remove_bpf_loader_incorrect_program_id {
640    miraland_sdk::declare_id!("HoGpsuQRozYmcECoQeS2Vko5BUKsspbgustUFAxZKtN8");
641}
642
643pub mod include_loaded_accounts_data_size_in_fee_calculation {
644    miraland_sdk::declare_id!("Em14upxZBEn8phtTU413mciEtTpdjmFgM1r4ZHvgUmoM");
645}
646
647pub mod native_programs_consume_cu {
648    miraland_sdk::declare_id!("AY6myQp4ZBUnm4m6igbjJVyuaoiRbi7vAbmJ8EqtjutR");
649}
650
651pub mod simplify_writable_program_account_check {
652    miraland_sdk::declare_id!("2NeJrnUM8acFXAcdGtrbXQPpRCoUx6yN9fGyzrUbTXyW");
653}
654
655pub mod stop_truncating_strings_in_syscalls {
656    miraland_sdk::declare_id!("Fhuefj6TLhuzpkuuNSN5evJUgeU8ncDqVBrhUaRYzFYJ");
657}
658
659pub mod clean_up_delegation_errors {
660    miraland_sdk::declare_id!("GTwUxeNF4bFhuQZudK7GhhdM6XocZ8tV2oEuRn2tLTL3");
661}
662
663pub mod vote_state_add_vote_latency {
664    miraland_sdk::declare_id!("G5PzC75sXn9xfBs8fYGcPZXkdsEghTxZPtSyoJajg1N");
665}
666
667pub mod checked_arithmetic_in_fee_validation {
668    miraland_sdk::declare_id!("9smpZNhHhNSKk9ofPUF1WDudaRqh1xnWJrZE4A3wgsLm");
669}
670
671pub mod last_restart_slot_sysvar {
672    miraland_sdk::declare_id!("BmRw1Cg72dEdYe6JASpGznodr1ryyLfbFoEPZn8Cha84");
673}
674
675pub mod reduce_stake_warmup_cooldown {
676    miraland_sdk::declare_id!("BkynwF8uZGLaeEFo1ciirN6ozoXtWHdi8AyJvT522zGG");
677}
678
679mod revise_turbine_epoch_stakes {
680    miraland_sdk::declare_id!("APLRhyXeMsypAJeBiGyE2uivUi7z8JAnx9gHsY211Pcj");
681}
682
683pub mod enable_poseidon_syscall {
684    miraland_sdk::declare_id!("A2Tg6BQD2btsATMEHwVzT2jXRsueyRyk1jDGME4bsmu8");
685}
686
687pub mod timely_vote_credits {
688    miraland_sdk::declare_id!("76rnHGcyD2bCi5CrgdKjuXknHBjcVhBa3AXD4sBGjj5a");
689}
690
691pub mod remaining_compute_units_syscall_enabled {
692    miraland_sdk::declare_id!("98jLtzmDsy5fRBom4STziC5v4QM7TJtPZuQMxyQC3Anj");
693}
694
695pub mod enable_program_runtime_v2_and_loader_v4 {
696    miraland_sdk::declare_id!("37iUXmu2wwtVGFTkjsKdJozCEDc5NV8SuqKSbRgHRdjN");
697}
698
699pub mod require_rent_exempt_split_destination {
700    miraland_sdk::declare_id!("E88TG7ovEzzjrTcjUs21pGvBJtSJa92vFzHRvqQMAXdd");
701}
702
703pub mod better_error_codes_for_tx_lamport_check {
704    miraland_sdk::declare_id!("FusXtSgpukBFueFMLd6nBcZdnCDAffwUMosw1u9XqLRS");
705}
706
707pub mod update_hashes_per_tick2 {
708    miraland_sdk::declare_id!("8sFZTxpMza4kUoVpvrZz4sk6mcG46BM1d6ghAfd6cz8k");
709}
710
711pub mod update_hashes_per_tick3 {
712    miraland_sdk::declare_id!("8Sh4fvhQnEbULcR4fbnmAf7yjfHzNqrupKM7xXLnt2Qs");
713}
714
715pub mod update_hashes_per_tick4 {
716    miraland_sdk::declare_id!("3JRHWTUhsZdHCyuGvKgMWpLfpQUWkgsXLAz4vqx3u1xu");
717}
718
719pub mod update_hashes_per_tick5 {
720    miraland_sdk::declare_id!("CLXxPbFWLGCVzW1jPo1H38UGwGoz4UncmkrLQsfASZFc");
721}
722
723pub mod update_hashes_per_tick6 {
724    miraland_sdk::declare_id!("FFkv7qUdjindy4vHxDf2SGmmgeNoK4ZVdVWtJKGj4oM4");
725}
726
727pub mod validate_fee_collector_account {
728    miraland_sdk::declare_id!("6rx1ZUWENuBB4og2KqhSCR1cpaFpfjqrLHvQiJfN4VFT");
729}
730
731pub mod disable_rent_fees_collection {
732    miraland_sdk::declare_id!("2m4tqba9mJ2W55Z4tU1QWqsmxxDR1Z4f945TKWooEGuW");
733}
734
735pub mod enable_zk_transfer_with_fee {
736    miraland_sdk::declare_id!("4SfSmAdtkSt5uBGVsx4RBY3Z3jyuo2m2mQss3gA9AvUW");
737}
738
739pub mod drop_legacy_shreds {
740    miraland_sdk::declare_id!("CzP5s8kWixq2U4h7pKeNkzq6x2cVeJhwxgM8bB6m6mCg");
741}
742
743pub mod allow_commission_decrease_at_any_time {
744    miraland_sdk::declare_id!("C7vnTthLpM7Tz5bH5b7My9op4jwoJk4R5PBUCMWRd5dD");
745}
746
747pub mod consume_blockstore_duplicate_proofs {
748    miraland_sdk::declare_id!("sD5CYgZ9acawPhYkpszjQNAphBohP7qYiaEEsewFQaH");
749}
750
751pub mod index_erasure_conflict_duplicate_proofs {
752    miraland_sdk::declare_id!("5xFJJztY9D5EQhLiBthKRHU5kg5h7x1b52vGpnwzYVep");
753}
754
755pub mod merkle_conflict_duplicate_proofs {
756    miraland_sdk::declare_id!("HSwuZ1VfMMUG6mXWo2SPiGsbRrYnjXiC2a98RC6ZShKg");
757}
758
759pub mod disable_bpf_loader_instructions {
760    miraland_sdk::declare_id!("2tx9keGzrsFHba9j3LfLm4QyMHg3uaKoXAGJmSkn6Mgv");
761}
762
763pub mod deprecate_executable_meta_update_in_bpf_loader {
764    miraland_sdk::declare_id!("4cvufB5AdaaPum7ZjQfRHJDqmD81wiiZVsAP2ReJGAEV");
765}
766
767pub mod enable_zk_proof_from_account {
768    miraland_sdk::declare_id!("9gRxP7Pi7sWAVuhLg22QHcrhEs1UhWEwcWZgkUZDTXTk");
769}
770
771pub mod cost_model_requested_write_lock_cost {
772    miraland_sdk::declare_id!("DnADtnAoAoPzRpeK83g2W6eUYRrtk8sFaTxj7RSKF65k");
773}
774
775pub mod enable_gossip_duplicate_proof_ingestion {
776    miraland_sdk::declare_id!("Ec5KxA5iUVDb4A95QJu6b1EABdPHWe1uP4xcezSxW5zZ");
777}
778
779pub mod enable_chained_merkle_shreds {
780    miraland_sdk::declare_id!("2MjwbrGZBTkRkkibnWjMKwrSFcBJ1NrKmndhUeFLnChm");
781}
782
783pub mod remove_rounding_in_fee_calculation {
784    miraland_sdk::declare_id!("EvR8BDv7qX256Pq6sn5CN7S549wbx86Bvg3iNr4qJfmh");
785}
786
787lazy_static! {
788    /// Map of feature identifiers to user-visible description
789    pub static ref FEATURE_NAMES: HashMap<Pubkey, &'static str> = [
790        (secp256k1_program_enabled::id(), "secp256k1 program"),
791        (deprecate_rewards_sysvar::id(), "deprecate unused rewards sysvar"),
792        (pico_inflation::id(), "pico inflation"),
793        (full_inflation::devnet_and_testnet::id(), "full inflation on devnet and testnet"),
794        (spl_token_v2_multisig_fix::id(), "solarti-token multisig fix"),
795        (no_overflow_rent_distribution::id(), "no overflow rent distribution"),
796        (filter_stake_delegation_accounts::id(), "filter stake_delegation_accounts #14062"),
797        (require_custodian_for_locked_stake_authorize::id(), "require custodian to authorize withdrawer change for locked stake"),
798        (spl_token_v2_self_transfer_fix::id(), "solarti-token self-transfer fix"),
799        (full_inflation::mainnet::certusone::enable::id(), "full inflation enabled by Certus One"),
800        (full_inflation::mainnet::certusone::vote::id(), "community vote allowing Certus One to enable full inflation"),
801        (warp_timestamp_again::id(), "warp timestamp again, adjust bounding to 25% fast 80% slow #15204"),
802        (check_init_vote_data::id(), "check initialized Vote data"),
803        (secp256k1_recover_syscall_enabled::id(), "secp256k1_recover syscall"),
804        (system_transfer_zero_check::id(), "perform all checks for transfers of 0 lamports"),
805        (blake3_syscall_enabled::id(), "blake3 syscall"),
806        (dedupe_config_program_signers::id(), "dedupe config program signers"),
807        (verify_tx_signatures_len::id(), "prohibit extra transaction signatures"),
808        (vote_stake_checked_instructions::id(), "vote/state program checked instructions #18345"),
809        (rent_for_sysvars::id(), "collect rent from accounts owned by sysvars"),
810        (libsecp256k1_0_5_upgrade_enabled::id(), "upgrade libsecp256k1 to v0.5.0"),
811        (tx_wide_compute_cap::id(), "transaction wide compute cap"),
812        (spl_token_v2_set_authority_fix::id(), "solarti-token set_authority fix"),
813        (merge_nonce_error_into_system_error::id(), "merge NonceError into SystemError"),
814        (disable_fees_sysvar::id(), "disable fees sysvar"),
815        (stake_merge_with_unmatched_credits_observed::id(), "allow merging active stakes with unmatched credits_observed #18985"),
816        (zk_token_sdk_enabled::id(), "enable Zk Token proof program and syscalls"),
817        (curve25519_syscall_enabled::id(), "enable curve25519 syscalls"),
818        (versioned_tx_message_enabled::id(), "enable versioned transaction message processing"),
819        (libsecp256k1_fail_on_bad_count::id(), "fail libsecp256k1_verify if count appears wrong"),
820        (libsecp256k1_fail_on_bad_count2::id(), "fail libsecp256k1_verify if count appears wrong"),
821        (instructions_sysvar_owned_by_sysvar::id(), "fix owner for instructions sysvar"),
822        (stake_program_advance_activating_credits_observed::id(), "Enable advancing credits observed for activation epoch #19309"),
823        (credits_auto_rewind::id(), "Auto rewind stake's credits_observed if (accidental) vote recreation is detected #22546"),
824        (demote_program_write_locks::id(), "demote program write locks to readonly, except when upgradeable loader present #19593 #20265"),
825        (ed25519_program_enabled::id(), "enable builtin ed25519 signature verify program"),
826        (return_data_syscall_enabled::id(), "enable sol_{set,get}_return_data syscall"),
827        (reduce_required_deploy_balance::id(), "reduce required payer balance for program deploys"),
828        (sol_log_data_syscall_enabled::id(), "enable sol_log_data syscall"),
829        (stakes_remove_delegation_if_inactive::id(), "remove delegations from stakes cache when inactive"),
830        (do_support_realloc::id(), "support account data reallocation"),
831        (prevent_calling_precompiles_as_programs::id(), "prevent calling precompiles as programs"),
832        (optimize_epoch_boundary_updates::id(), "optimize epoch boundary updates"),
833        (remove_native_loader::id(), "remove support for the native loader"),
834        (send_to_tpu_vote_port::id(), "send votes to the tpu vote port"),
835        (requestable_heap_size::id(), "Requestable heap frame size"),
836        (disable_fee_calculator::id(), "deprecate fee calculator"),
837        (add_compute_budget_program::id(), "Add compute_budget_program"),
838        (nonce_must_be_writable::id(), "nonce must be writable"),
839        (spl_token_v3_3_0_release::id(), "solarti-token v3.3.0 release"),
840        (leave_nonce_on_success::id(), "leave nonce as is on success"),
841        (reject_empty_instruction_without_program::id(), "fail instructions which have native_loader as program_id directly"),
842        (fixed_memcpy_nonoverlapping_check::id(), "use correct check for nonoverlapping regions in memcpy syscall"),
843        (reject_non_rent_exempt_vote_withdraws::id(), "fail vote withdraw instructions which leave the account non-rent-exempt"),
844        (evict_invalid_stakes_cache_entries::id(), "evict invalid stakes cache entries on epoch boundaries"),
845        (allow_votes_to_directly_update_vote_state::id(), "enable direct vote state update"),
846        (cap_accounts_data_len::id(), "cap the accounts data len"),
847        (max_tx_account_locks::id(), "enforce max number of locked accounts per transaction"),
848        (require_rent_exempt_accounts::id(), "require all new transaction accounts with data to be rent-exempt"),
849        (filter_votes_outside_slot_hashes::id(), "filter vote slots older than the slot hashes history"),
850        (update_syscall_base_costs::id(), "update syscall base costs"),
851        (stake_deactivate_delinquent_instruction::id(), "enable the deactivate delinquent stake instruction #23932"),
852        (vote_withdraw_authority_may_change_authorized_voter::id(), "vote account withdraw authority may change the authorized voter #22521"),
853        (spl_associated_token_account_v1_0_4::id(), "SPL Associated Token Account Program release version 1.0.4, tied to token 3.3.0 #22648"),
854        (reject_vote_account_close_unless_zero_credit_epoch::id(), "fail vote account withdraw to 0 unless account earned 0 credits in last completed epoch"),
855        (add_get_processed_sibling_instruction_syscall::id(), "add add_get_processed_sibling_instruction_syscall"),
856        (bank_transaction_count_fix::id(), "fixes Bank::transaction_count to include all committed transactions, not just successful ones"),
857        (disable_bpf_deprecated_load_instructions::id(), "disable ldabs* and ldind* SBF instructions"),
858        (disable_bpf_unresolved_symbols_at_runtime::id(), "disable reporting of unresolved SBF symbols at runtime"),
859        (record_instruction_in_transaction_context_push::id(), "move the CPI stack overflow check to the end of push"),
860        (syscall_saturated_math::id(), "syscalls use saturated math"),
861        (check_physical_overlapping::id(), "check physical overlapping regions"),
862        (limit_secp256k1_recovery_id::id(), "limit secp256k1 recovery id"),
863        (disable_deprecated_loader::id(), "disable the deprecated BPF loader"),
864        (check_slice_translation_size::id(), "check size when translating slices"),
865        (stake_split_uses_rent_sysvar::id(), "stake split instruction uses rent sysvar"),
866        (add_get_minimum_delegation_instruction_to_stake_program::id(), "add GetMinimumDelegation instruction to stake program"),
867        (error_on_syscall_bpf_function_hash_collisions::id(), "error on bpf function hash collisions"),
868        (reject_callx_r10::id(), "Reject bpf callx r10 instructions"),
869        (drop_redundant_turbine_path::id(), "drop redundant turbine path"),
870        (executables_incur_cpi_data_cost::id(), "Executables incur CPI data costs"),
871        (fix_recent_blockhashes::id(), "stop adding hashes for skipped slots to recent blockhashes"),
872        (update_rewards_from_cached_accounts::id(), "update rewards from cached accounts"),
873        (enable_partitioned_epoch_reward::id(), "enable partitioned rewards at epoch boundary #32166"),
874        (spl_token_v3_4_0::id(), "Solarti Token Program version 3.4.0 release #24740"),
875        (spl_associated_token_account_v1_1_0::id(), "SPL Associated Token Account Program version 1.1.0 release #24741"),
876        (default_units_per_instruction::id(), "Default max tx-wide compute units calculated per instruction"),
877        (stake_allow_zero_undelegated_amount::id(), "Allow zero-lamport undelegated amount for initialized stakes #24670"),
878        (require_static_program_ids_in_transaction::id(), "require static program ids in versioned transactions"),
879        (stake_raise_minimum_delegation_to_1_mln::id(), "Raise minimum stake delegation to 1.0 MLN #24357"),
880        (stake_minimum_delegation_for_rewards::id(), "stakes must be at least the minimum delegation to earn rewards"),
881        (add_set_compute_unit_price_ix::id(), "add compute budget ix for setting a compute unit price"),
882        (disable_deploy_of_alloc_free_syscall::id(), "disable new deployments of deprecated sol_alloc_free_ syscall"),
883        (include_account_index_in_rent_error::id(), "include account index in rent tx error #25190"),
884        (add_shred_type_to_shred_seed::id(), "add shred-type to shred seed #25556"),
885        (warp_timestamp_with_a_vengeance::id(), "warp timestamp again, adjust bounding to 150% slow #25666"),
886        (separate_nonce_from_blockhash::id(), "separate durable nonce and blockhash domains #25744"),
887        (enable_durable_nonce::id(), "enable durable nonce #25744"),
888        (vote_state_update_credit_per_dequeue::id(), "Calculate vote credits for VoteStateUpdate per vote dequeue to match credit awards for Vote instruction"),
889        (quick_bail_on_panic::id(), "quick bail on panic"),
890        (nonce_must_be_authorized::id(), "nonce must be authorized"),
891        (nonce_must_be_advanceable::id(), "durable nonces must be advanceable"),
892        (vote_authorize_with_seed::id(), "An instruction you can use to change a vote accounts authority when the current authority is a derived key #25860"),
893        (cap_accounts_data_size_per_block::id(), "cap the accounts data size per block #25517"),
894        (stake_redelegate_instruction::id(), "enable the redelegate stake instruction #26294"),
895        (preserve_rent_epoch_for_rent_exempt_accounts::id(), "preserve rent epoch for rent exempt accounts #26479"),
896        (enable_bpf_loader_extend_program_ix::id(), "enable bpf upgradeable loader ExtendProgram instruction #25234"),
897        (skip_rent_rewrites::id(), "skip rewriting rent exempt accounts during rent collection #26491"),
898        (enable_early_verification_of_account_modifications::id(), "enable early verification of account modifications #25899"),
899        (disable_rehash_for_rent_epoch::id(), "on accounts hash calculation, do not try to rehash accounts #28934"),
900        (account_hash_ignore_slot::id(), "ignore slot when calculating an account hash #28420"),
901        (set_exempt_rent_epoch_max::id(), "set rent epoch to Epoch::MAX for rent-exempt accounts #28683"),
902        (on_load_preserve_rent_epoch_for_rent_exempt_accounts::id(), "on bank load account, do not try to fix up rent_epoch #28541"),
903        (prevent_crediting_accounts_that_end_rent_paying::id(), "prevent crediting rent paying accounts #26606"),
904        (cap_bpf_program_instruction_accounts::id(), "enforce max number of accounts per bpf program instruction #26628"),
905        (loosen_cpi_size_restriction::id(), "loosen cpi size restrictions #26641"),
906        (use_default_units_in_fee_calculation::id(), "use default units per instruction in fee calculation #26785"),
907        (compact_vote_state_updates::id(), "Compact vote state updates to lower block size"),
908        (incremental_snapshot_only_incremental_hash_calculation::id(), "only hash accounts in incremental snapshot during incremental snapshot creation #26799"),
909        (disable_cpi_setting_executable_and_rent_epoch::id(), "disable setting is_executable and_rent_epoch in CPI #26987"),
910        (relax_authority_signer_check_for_lookup_table_creation::id(), "relax authority signer check for lookup table creation #27205"),
911        (stop_sibling_instruction_search_at_parent::id(), "stop the search in get_processed_sibling_instruction when the parent instruction is reached #27289"),
912        (vote_state_update_root_fix::id(), "fix root in vote state updates #27361"),
913        (cap_accounts_data_allocations_per_transaction::id(), "cap accounts data allocations per transaction #27375"),
914        (epoch_accounts_hash::id(), "enable epoch accounts hash calculation #27539"),
915        (remove_deprecated_request_unit_ix::id(), "remove support for RequestUnitsDeprecated instruction #27500"),
916        (increase_tx_account_lock_limit::id(), "increase tx account lock limit to 128 #27241"),
917        (limit_max_instruction_trace_length::id(), "limit max instruction trace length #27939"),
918        (check_syscall_outputs_do_not_overlap::id(), "check syscall outputs do_not overlap #28600"),
919        (enable_bpf_loader_set_authority_checked_ix::id(), "enable bpf upgradeable loader SetAuthorityChecked instruction #28424"),
920        (enable_alt_bn128_syscall::id(), "add alt_bn128 syscalls #27961"),
921        (enable_program_redeployment_cooldown::id(), "enable program redeployment cooldown #29135"),
922        (commission_updates_only_allowed_in_first_half_of_epoch::id(), "validator commission updates are only allowed in the first half of an epoch #29362"),
923        (enable_turbine_fanout_experiments::id(), "enable turbine fanout experiments #29393"),
924        (disable_turbine_fanout_experiments::id(), "disable turbine fanout experiments #29393"),
925        (move_serialized_len_ptr_in_cpi::id(), "cpi ignore serialized_len_ptr #29592"),
926        (update_hashes_per_tick::id(), "Update desired hashes per tick on epoch boundary"),
927        (enable_big_mod_exp_syscall::id(), "add big_mod_exp syscall #28503"),
928        (disable_builtin_loader_ownership_chains::id(), "disable builtin loader ownership chains #29956"),
929        (cap_transaction_accounts_data_size::id(), "cap transaction accounts data size up to a limit #27839"),
930        (remove_congestion_multiplier_from_fee_calculation::id(), "Remove congestion multiplier from transaction fee calculation #29881"),
931        (enable_request_heap_frame_ix::id(), "Enable transaction to request heap frame using compute budget instruction #30076"),
932        (prevent_rent_paying_rent_recipients::id(), "prevent recipients of rent rewards from ending in rent-paying state #30151"),
933        (delay_visibility_of_program_deployment::id(), "delay visibility of program upgrades #30085"),
934        (apply_cost_tracker_during_replay::id(), "apply cost tracker to blocks during replay #29595"),
935        (add_set_tx_loaded_accounts_data_size_instruction::id(), "add compute budget instruction for setting account data size per transaction #30366"),
936        (switch_to_new_elf_parser::id(), "switch to new ELF parser #30497"),
937        (round_up_heap_size::id(), "round up heap size when calculating heap cost #30679"),
938        (remove_bpf_loader_incorrect_program_id::id(), "stop incorrectly throwing IncorrectProgramId in bpf_loader #30747"),
939        (include_loaded_accounts_data_size_in_fee_calculation::id(), "include transaction loaded accounts data size in base fee calculation #30657"),
940        (native_programs_consume_cu::id(), "Native program should consume compute units #30620"),
941        (simplify_writable_program_account_check::id(), "Simplify checks performed for writable upgradeable program accounts #30559"),
942        (stop_truncating_strings_in_syscalls::id(), "Stop truncating strings in syscalls #31029"),
943        (clean_up_delegation_errors::id(), "Return InsufficientDelegation instead of InsufficientFunds or InsufficientStake where applicable #31206"),
944        (vote_state_add_vote_latency::id(), "replace Lockout with LandedVote (including vote latency) in vote state #31264"),
945        (checked_arithmetic_in_fee_validation::id(), "checked arithmetic in fee validation #31273"),
946        (bpf_account_data_direct_mapping::id(), "use memory regions to map account data into the rbpf vm instead of copying the data"),
947        (last_restart_slot_sysvar::id(), "enable new sysvar last_restart_slot"),
948        (reduce_stake_warmup_cooldown::id(), "reduce stake warmup cooldown from 25% to 9%"),
949        (revise_turbine_epoch_stakes::id(), "revise turbine epoch stakes"),
950        (enable_poseidon_syscall::id(), "Enable Poseidon syscall"),
951        (timely_vote_credits::id(), "use timeliness of votes in determining credits to award"),
952        (remaining_compute_units_syscall_enabled::id(), "enable the remaining_compute_units syscall"),
953        (enable_program_runtime_v2_and_loader_v4::id(), "Enable Program-Runtime-v2 and Loader-v4 #33293"),
954        (require_rent_exempt_split_destination::id(), "Require stake split destination account to be rent exempt"),
955        (better_error_codes_for_tx_lamport_check::id(), "better error codes for tx lamport check #33353"),
956        (enable_alt_bn128_compression_syscall::id(), "add alt_bn128 compression syscalls"),
957        (update_hashes_per_tick2::id(), "Update desired hashes per tick to 2.8M"),
958        (update_hashes_per_tick3::id(), "Update desired hashes per tick to 4.4M"),
959        (update_hashes_per_tick4::id(), "Update desired hashes per tick to 7.6M"),
960        (update_hashes_per_tick5::id(), "Update desired hashes per tick to 9.2M"),
961        (update_hashes_per_tick6::id(), "Update desired hashes per tick to 10M"),
962        (validate_fee_collector_account::id(), "validate fee collector account #33888"),
963        (disable_rent_fees_collection::id(), "Disable rent fees collection #33945"),
964        (enable_zk_transfer_with_fee::id(), "enable Zk Token proof program transfer with fee"),
965        (drop_legacy_shreds::id(), "drops legacy shreds #34328"),
966        (allow_commission_decrease_at_any_time::id(), "Allow commission decrease at any time in epoch #33843"),
967        (consume_blockstore_duplicate_proofs::id(), "consume duplicate proofs from blockstore in consensus #34372"),
968        (index_erasure_conflict_duplicate_proofs::id(), "generate duplicate proofs for index and erasure conflicts #34360"),
969        (merkle_conflict_duplicate_proofs::id(), "generate duplicate proofs for merkle root conflicts #34270"),
970        (disable_bpf_loader_instructions::id(), "disable bpf loader management instructions #34194"),
971        (deprecate_executable_meta_update_in_bpf_loader::id(), "deprecate executable meta flag update in bpf loader #34194"),
972        (enable_zk_proof_from_account::id(), "Enable zk token proof program to read proof from accounts instead of instruction data #34750"),
973        (curve25519_restrict_msm_length::id(), "restrict curve25519 multiscalar multiplication vector lengths #34763"),
974        (cost_model_requested_write_lock_cost::id(), "cost model uses number of requested write locks #34819"),
975        (enable_gossip_duplicate_proof_ingestion::id(), "enable gossip duplicate proof ingestion #32963"),
976        (enable_chained_merkle_shreds::id(), "Enable chained Merkle shreds #34916"),
977        (remove_rounding_in_fee_calculation::id(), "Removing unwanted rounding in fee calculation #34982"),
978        /*************** ADD NEW FEATURES HERE ***************/
979    ]
980    .iter()
981    .cloned()
982    .collect();
983
984    /// Unique identifier of the current software's feature set
985    pub static ref ID: Hash = {
986        let mut hasher = Hasher::default();
987        let mut feature_ids = FEATURE_NAMES.keys().collect::<Vec<_>>();
988        feature_ids.sort();
989        for feature in feature_ids {
990            hasher.hash(feature.as_ref());
991        }
992        hasher.result()
993    };
994}
995
996#[derive(Clone, PartialEq, Eq, Hash)]
997pub struct FullInflationFeaturePair {
998    pub vote_id: Pubkey, // Feature that grants the candidate the ability to enable full inflation
999    pub enable_id: Pubkey, // Feature to enable full inflation by the candidate
1000}
1001
1002lazy_static! {
1003    /// Set of feature pairs that once enabled will trigger full inflation
1004    pub static ref FULL_INFLATION_FEATURE_PAIRS: HashSet<FullInflationFeaturePair> = [
1005        FullInflationFeaturePair {
1006            vote_id: full_inflation::mainnet::certusone::vote::id(),
1007            enable_id: full_inflation::mainnet::certusone::enable::id(),
1008        },
1009    ]
1010    .iter()
1011    .cloned()
1012    .collect();
1013}
1014
1015/// `FeatureSet` holds the set of currently active/inactive runtime features
1016#[derive(AbiExample, Debug, Clone, Eq, PartialEq)]
1017pub struct FeatureSet {
1018    pub active: HashMap<Pubkey, Slot>,
1019    pub inactive: HashSet<Pubkey>,
1020}
1021impl Default for FeatureSet {
1022    fn default() -> Self {
1023        // All features disabled
1024        Self {
1025            active: HashMap::new(),
1026            inactive: FEATURE_NAMES.keys().cloned().collect(),
1027        }
1028    }
1029}
1030impl FeatureSet {
1031    pub fn is_active(&self, feature_id: &Pubkey) -> bool {
1032        self.active.contains_key(feature_id)
1033    }
1034
1035    pub fn activated_slot(&self, feature_id: &Pubkey) -> Option<Slot> {
1036        self.active.get(feature_id).copied()
1037    }
1038
1039    /// List of enabled features that trigger full inflation
1040    pub fn full_inflation_features_enabled(&self) -> HashSet<Pubkey> {
1041        let mut hash_set = FULL_INFLATION_FEATURE_PAIRS
1042            .iter()
1043            .filter_map(|pair| {
1044                if self.is_active(&pair.vote_id) && self.is_active(&pair.enable_id) {
1045                    Some(pair.enable_id)
1046                } else {
1047                    None
1048                }
1049            })
1050            .collect::<HashSet<_>>();
1051
1052        if self.is_active(&full_inflation::devnet_and_testnet::id()) {
1053            hash_set.insert(full_inflation::devnet_and_testnet::id());
1054        }
1055        hash_set
1056    }
1057
1058    /// All features enabled, useful for testing
1059    pub fn all_enabled() -> Self {
1060        Self {
1061            active: FEATURE_NAMES.keys().cloned().map(|key| (key, 0)).collect(),
1062            inactive: HashSet::new(),
1063        }
1064    }
1065
1066    /// Activate a feature
1067    pub fn activate(&mut self, feature_id: &Pubkey, slot: u64) {
1068        self.inactive.remove(feature_id);
1069        self.active.insert(*feature_id, slot);
1070    }
1071
1072    /// Deactivate a feature
1073    pub fn deactivate(&mut self, feature_id: &Pubkey) {
1074        self.active.remove(feature_id);
1075        self.inactive.insert(*feature_id);
1076    }
1077
1078    pub fn new_warmup_cooldown_rate_epoch(&self, epoch_schedule: &EpochSchedule) -> Option<Epoch> {
1079        self.activated_slot(&reduce_stake_warmup_cooldown::id())
1080            .map(|slot| epoch_schedule.get_epoch(slot))
1081    }
1082}
1083
1084#[cfg(test)]
1085mod test {
1086    use super::*;
1087
1088    #[test]
1089    fn test_full_inflation_features_enabled_devnet_and_testnet() {
1090        let mut feature_set = FeatureSet::default();
1091        assert!(feature_set.full_inflation_features_enabled().is_empty());
1092        feature_set
1093            .active
1094            .insert(full_inflation::devnet_and_testnet::id(), 42);
1095        assert_eq!(
1096            feature_set.full_inflation_features_enabled(),
1097            [full_inflation::devnet_and_testnet::id()]
1098                .iter()
1099                .cloned()
1100                .collect()
1101        );
1102    }
1103
1104    #[test]
1105    fn test_full_inflation_features_enabled() {
1106        // Normal sequence: vote_id then enable_id
1107        let mut feature_set = FeatureSet::default();
1108        assert!(feature_set.full_inflation_features_enabled().is_empty());
1109        feature_set
1110            .active
1111            .insert(full_inflation::mainnet::certusone::vote::id(), 42);
1112        assert!(feature_set.full_inflation_features_enabled().is_empty());
1113        feature_set
1114            .active
1115            .insert(full_inflation::mainnet::certusone::enable::id(), 42);
1116        assert_eq!(
1117            feature_set.full_inflation_features_enabled(),
1118            [full_inflation::mainnet::certusone::enable::id()]
1119                .iter()
1120                .cloned()
1121                .collect()
1122        );
1123
1124        // Backwards sequence: enable_id and then vote_id
1125        let mut feature_set = FeatureSet::default();
1126        assert!(feature_set.full_inflation_features_enabled().is_empty());
1127        feature_set
1128            .active
1129            .insert(full_inflation::mainnet::certusone::enable::id(), 42);
1130        assert!(feature_set.full_inflation_features_enabled().is_empty());
1131        feature_set
1132            .active
1133            .insert(full_inflation::mainnet::certusone::vote::id(), 42);
1134        assert_eq!(
1135            feature_set.full_inflation_features_enabled(),
1136            [full_inflation::mainnet::certusone::enable::id()]
1137                .iter()
1138                .cloned()
1139                .collect()
1140        );
1141    }
1142
1143    #[test]
1144    fn test_feature_set_activate_deactivate() {
1145        let mut feature_set = FeatureSet::default();
1146
1147        let feature = Pubkey::new_unique();
1148        assert!(!feature_set.is_active(&feature));
1149        feature_set.activate(&feature, 0);
1150        assert!(feature_set.is_active(&feature));
1151        feature_set.deactivate(&feature);
1152        assert!(!feature_set.is_active(&feature));
1153    }
1154}