Skip to content

Commit bb102f7

Browse files
committed
Isolate runtime specific features via RuntimeFeatures struct
1 parent 7bb8e2d commit bb102f7

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+555
-298
lines changed

Cargo.lock

+1-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cli/src/program.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -3023,7 +3023,7 @@ fn verify_elf(
30233023
) -> Result<(), Box<dyn std::error::Error>> {
30243024
// Verify the program
30253025
let program_runtime_environment = create_program_runtime_environment_v1(
3026-
&feature_set,
3026+
&feature_set.runtime_features(),
30273027
&SVMTransactionExecutionBudget::default(),
30283028
true,
30293029
false,

cli/src/program_v4.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -717,7 +717,7 @@ pub fn process_deploy_program(
717717
}
718718
let program_runtime_environment =
719719
solana_bpf_loader_program::syscalls::create_program_runtime_environment_v1(
720-
&feature_set,
720+
&feature_set.runtime_features(),
721721
&SVMTransactionExecutionBudget::default(),
722722
true,
723723
false,

feature-set/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ solana-frozen-abi-macro = { workspace = true, optional = true, features = [
1919
"frozen-abi",
2020
] }
2121
solana-hash = { workspace = true }
22+
solana-program-runtime = { workspace = true }
2223
solana-pubkey = { workspace = true, default-features = false }
2324
solana-sha256-hasher = { workspace = true }
2425

feature-set/src/lib.rs

+60
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use {
44
ahash::{AHashMap, AHashSet},
55
solana_epoch_schedule::EpochSchedule,
66
solana_hash::Hash,
7+
solana_program_runtime::invoke_context::RuntimeFeatures,
78
solana_pubkey::Pubkey,
89
solana_sha256_hasher::Hasher,
910
std::sync::LazyLock,
@@ -98,6 +99,65 @@ impl FeatureSet {
9899
self.activated_slot(&reduce_stake_warmup_cooldown::id())
99100
.map(|slot| epoch_schedule.get_epoch(slot))
100101
}
102+
103+
pub fn runtime_features(&self) -> RuntimeFeatures {
104+
RuntimeFeatures {
105+
lift_cpi_caller_restriction: self.activated_slot(&lift_cpi_caller_restriction::id()),
106+
move_precompile_verification_to_svm: self
107+
.activated_slot(&move_precompile_verification_to_svm::id()),
108+
remove_accounts_executable_flag_checks: self
109+
.activated_slot(&remove_accounts_executable_flag_checks::id()),
110+
bpf_account_data_direct_mapping: self
111+
.activated_slot(&bpf_account_data_direct_mapping::id()),
112+
enable_bpf_loader_set_authority_checked_ix: self
113+
.activated_slot(&enable_bpf_loader_set_authority_checked_ix::id()),
114+
enable_loader_v4: self.activated_slot(&enable_loader_v4::id()),
115+
deplete_cu_meter_on_vm_failure: self
116+
.activated_slot(&deplete_cu_meter_on_vm_failure::id()),
117+
abort_on_invalid_curve: self.activated_slot(&abort_on_invalid_curve::id()),
118+
blake3_syscall_enabled: self.activated_slot(&blake3_syscall_enabled::id()),
119+
curve25519_syscall_enabled: self.activated_slot(&curve25519_syscall_enabled::id()),
120+
disable_deploy_of_alloc_free_syscall: self
121+
.activated_slot(&disable_deploy_of_alloc_free_syscall::id()),
122+
disable_fees_sysvar: self.activated_slot(&disable_fees_sysvar::id()),
123+
disable_sbpf_v0_execution: self.activated_slot(&disable_sbpf_v0_execution::id()),
124+
enable_alt_bn128_compression_syscall: self
125+
.activated_slot(&enable_alt_bn128_compression_syscall::id()),
126+
enable_alt_bn128_syscall: self.activated_slot(&enable_alt_bn128_syscall::id()),
127+
enable_big_mod_exp_syscall: self.activated_slot(&enable_big_mod_exp_syscall::id()),
128+
enable_get_epoch_stake_syscall: self
129+
.activated_slot(&enable_get_epoch_stake_syscall::id()),
130+
enable_poseidon_syscall: self.activated_slot(&enable_poseidon_syscall::id()),
131+
enable_sbpf_v1_deployment_and_execution: self
132+
.activated_slot(&enable_sbpf_v1_deployment_and_execution::id()),
133+
enable_sbpf_v2_deployment_and_execution: self
134+
.activated_slot(&enable_sbpf_v2_deployment_and_execution::id()),
135+
enable_sbpf_v3_deployment_and_execution: self
136+
.activated_slot(&enable_sbpf_v3_deployment_and_execution::id()),
137+
get_sysvar_syscall_enabled: self.activated_slot(&get_sysvar_syscall_enabled::id()),
138+
last_restart_slot_sysvar: self.activated_slot(&last_restart_slot_sysvar::id()),
139+
reenable_sbpf_v0_execution: self.activated_slot(&reenable_sbpf_v0_execution::id()),
140+
remaining_compute_units_syscall_enabled: self
141+
.activated_slot(&remaining_compute_units_syscall_enabled::id()),
142+
remove_bpf_loader_incorrect_program_id: self
143+
.activated_slot(&remove_bpf_loader_incorrect_program_id::id()),
144+
move_stake_and_move_lamports_ixs: self
145+
.activated_slot(&move_stake_and_move_lamports_ixs::id()),
146+
stake_raise_minimum_delegation_to_1_sol: self
147+
.activated_slot(&stake_raise_minimum_delegation_to_1_sol::id()),
148+
deprecate_legacy_vote_ixs: self.activated_slot(&deprecate_legacy_vote_ixs::id()),
149+
mask_out_rent_epoch_in_vm_serialization: self
150+
.activated_slot(&mask_out_rent_epoch_in_vm_serialization::id()),
151+
simplify_alt_bn128_syscall_error_codes: self
152+
.activated_slot(&simplify_alt_bn128_syscall_error_codes::id()),
153+
fix_alt_bn128_multiplication_input_length: self
154+
.activated_slot(&fix_alt_bn128_multiplication_input_length::id()),
155+
loosen_cpi_size_restriction: self.activated_slot(&loosen_cpi_size_restriction::id()),
156+
increase_tx_account_lock_limit: self
157+
.activated_slot(&increase_tx_account_lock_limit::id()),
158+
disable_rent_fees_collection: self.activated_slot(&disable_rent_fees_collection::id()),
159+
}
160+
}
101161
}
102162

103163
pub mod deprecate_rewards_sysvar {

ledger/src/leader_schedule_cache.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -521,7 +521,11 @@ mod tests {
521521
&vote_account,
522522
&validator_identity,
523523
bootstrap_validator_stake_lamports()
524-
+ solana_stake_program::get_minimum_delegation(&bank.feature_set),
524+
+ solana_stake_program::get_minimum_delegation(
525+
bank.feature_set.is_active(
526+
&agave_feature_set::stake_raise_minimum_delegation_to_1_sol::id(),
527+
),
528+
),
525529
);
526530
let node_pubkey = validator_identity.pubkey();
527531

program-runtime/Cargo.toml

-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ license = { workspace = true }
1010
edition = { workspace = true }
1111

1212
[dependencies]
13-
agave-feature-set = { workspace = true }
1413
base64 = { workspace = true }
1514
bincode = { workspace = true }
1615
enum-iterator = { workspace = true }

program-runtime/src/invoke_context.rs

+108-16
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,6 @@ use {
88
stable_log,
99
sysvar_cache::SysvarCache,
1010
},
11-
agave_feature_set::{
12-
lift_cpi_caller_restriction, remove_accounts_executable_flag_checks, FeatureSet,
13-
},
1411
solana_account::{create_account_shared_data_for_test, AccountSharedData},
1512
solana_clock::Slot,
1613
solana_epoch_schedule::EpochSchedule,
@@ -44,6 +41,87 @@ use {
4441
},
4542
};
4643

44+
#[derive(Clone, Copy, Default)]
45+
pub struct RuntimeFeatures {
46+
pub lift_cpi_caller_restriction: Option<Slot>,
47+
pub move_precompile_verification_to_svm: Option<Slot>,
48+
pub remove_accounts_executable_flag_checks: Option<Slot>,
49+
pub bpf_account_data_direct_mapping: Option<Slot>,
50+
pub enable_bpf_loader_set_authority_checked_ix: Option<Slot>,
51+
pub enable_loader_v4: Option<Slot>,
52+
pub deplete_cu_meter_on_vm_failure: Option<Slot>,
53+
pub abort_on_invalid_curve: Option<Slot>,
54+
pub blake3_syscall_enabled: Option<Slot>,
55+
pub curve25519_syscall_enabled: Option<Slot>,
56+
pub disable_deploy_of_alloc_free_syscall: Option<Slot>,
57+
pub disable_fees_sysvar: Option<Slot>,
58+
pub disable_sbpf_v0_execution: Option<Slot>,
59+
pub enable_alt_bn128_compression_syscall: Option<Slot>,
60+
pub enable_alt_bn128_syscall: Option<Slot>,
61+
pub enable_big_mod_exp_syscall: Option<Slot>,
62+
pub enable_get_epoch_stake_syscall: Option<Slot>,
63+
pub enable_poseidon_syscall: Option<Slot>,
64+
pub enable_sbpf_v1_deployment_and_execution: Option<Slot>,
65+
pub enable_sbpf_v2_deployment_and_execution: Option<Slot>,
66+
pub enable_sbpf_v3_deployment_and_execution: Option<Slot>,
67+
pub get_sysvar_syscall_enabled: Option<Slot>,
68+
pub last_restart_slot_sysvar: Option<Slot>,
69+
pub reenable_sbpf_v0_execution: Option<Slot>,
70+
pub remaining_compute_units_syscall_enabled: Option<Slot>,
71+
pub remove_bpf_loader_incorrect_program_id: Option<Slot>,
72+
pub move_stake_and_move_lamports_ixs: Option<Slot>,
73+
pub stake_raise_minimum_delegation_to_1_sol: Option<Slot>,
74+
pub deprecate_legacy_vote_ixs: Option<Slot>,
75+
pub mask_out_rent_epoch_in_vm_serialization: Option<Slot>,
76+
pub simplify_alt_bn128_syscall_error_codes: Option<Slot>,
77+
pub fix_alt_bn128_multiplication_input_length: Option<Slot>,
78+
pub loosen_cpi_size_restriction: Option<Slot>,
79+
pub increase_tx_account_lock_limit: Option<Slot>,
80+
pub disable_rent_fees_collection: Option<Slot>,
81+
}
82+
83+
impl RuntimeFeatures {
84+
pub fn all_enabled() -> Self {
85+
Self {
86+
lift_cpi_caller_restriction: Some(0),
87+
move_precompile_verification_to_svm: Some(0),
88+
remove_accounts_executable_flag_checks: Some(0),
89+
bpf_account_data_direct_mapping: Some(0),
90+
enable_bpf_loader_set_authority_checked_ix: Some(0),
91+
enable_loader_v4: Some(0),
92+
deplete_cu_meter_on_vm_failure: Some(0),
93+
abort_on_invalid_curve: Some(0),
94+
blake3_syscall_enabled: Some(0),
95+
curve25519_syscall_enabled: Some(0),
96+
disable_deploy_of_alloc_free_syscall: Some(0),
97+
disable_fees_sysvar: Some(0),
98+
disable_sbpf_v0_execution: Some(0),
99+
enable_alt_bn128_compression_syscall: Some(0),
100+
enable_alt_bn128_syscall: Some(0),
101+
enable_big_mod_exp_syscall: Some(0),
102+
enable_get_epoch_stake_syscall: Some(0),
103+
enable_poseidon_syscall: Some(0),
104+
enable_sbpf_v1_deployment_and_execution: Some(0),
105+
enable_sbpf_v2_deployment_and_execution: Some(0),
106+
enable_sbpf_v3_deployment_and_execution: Some(0),
107+
get_sysvar_syscall_enabled: Some(0),
108+
last_restart_slot_sysvar: Some(0),
109+
reenable_sbpf_v0_execution: Some(0),
110+
remaining_compute_units_syscall_enabled: Some(0),
111+
remove_bpf_loader_incorrect_program_id: Some(0),
112+
move_stake_and_move_lamports_ixs: Some(0),
113+
stake_raise_minimum_delegation_to_1_sol: Some(0),
114+
deprecate_legacy_vote_ixs: Some(0),
115+
mask_out_rent_epoch_in_vm_serialization: Some(0),
116+
simplify_alt_bn128_syscall_error_codes: Some(0),
117+
fix_alt_bn128_multiplication_input_length: Some(0),
118+
loosen_cpi_size_restriction: Some(0),
119+
increase_tx_account_lock_limit: Some(0),
120+
disable_rent_fees_collection: Some(0),
121+
}
122+
}
123+
}
124+
47125
pub type BuiltinFunctionWithContext = BuiltinFunction<InvokeContext<'static>>;
48126

49127
/// Adapter so we can unify the interfaces of built-in programs and syscalls
@@ -147,15 +225,15 @@ pub struct EnvironmentConfig<'a> {
147225
pub blockhash: Hash,
148226
pub blockhash_lamports_per_signature: u64,
149227
epoch_stake_callback: &'a dyn InvokeContextCallback,
150-
pub feature_set: Arc<FeatureSet>,
228+
pub feature_set: Arc<RuntimeFeatures>,
151229
sysvar_cache: &'a SysvarCache,
152230
}
153231
impl<'a> EnvironmentConfig<'a> {
154232
pub fn new(
155233
blockhash: Hash,
156234
blockhash_lamports_per_signature: u64,
157235
epoch_stake_callback: &'a dyn InvokeContextCallback,
158-
feature_set: Arc<FeatureSet>,
236+
feature_set: Arc<RuntimeFeatures>,
159237
sysvar_cache: &'a SysvarCache,
160238
) -> Self {
161239
Self {
@@ -426,9 +504,7 @@ impl<'a> InvokeContext<'a> {
426504

427505
// Find and validate executables / program accounts
428506
let callee_program_id = instruction.program_id;
429-
let program_account_index = if self
430-
.get_feature_set()
431-
.is_active(&lift_cpi_caller_restriction::id())
507+
let program_account_index = if self.get_feature_set().lift_cpi_caller_restriction.is_some()
432508
{
433509
self.transaction_context
434510
.find_index_of_program_account(&callee_program_id)
@@ -446,9 +522,10 @@ impl<'a> InvokeContext<'a> {
446522
let borrowed_program_account = instruction_context
447523
.try_borrow_instruction_account(self.transaction_context, program_account_index)?;
448524
#[allow(deprecated)]
449-
if !self
525+
if self
450526
.get_feature_set()
451-
.is_active(&remove_accounts_executable_flag_checks::id())
527+
.remove_accounts_executable_flag_checks
528+
.is_none()
452529
&& !borrowed_program_account.is_executable()
453530
{
454531
ic_msg!(self, "Account {} is not executable", callee_program_id);
@@ -521,7 +598,8 @@ impl<'a> InvokeContext<'a> {
521598
*borrowed_root_account.get_key()
522599
} else if self
523600
.get_feature_set()
524-
.is_active(&remove_accounts_executable_flag_checks::id())
601+
.remove_accounts_executable_flag_checks
602+
.is_some()
525603
{
526604
if bpf_loader_deprecated::check_id(owner_id)
527605
|| bpf_loader::check_id(owner_id)
@@ -646,17 +724,32 @@ impl<'a> InvokeContext<'a> {
646724
}
647725

648726
/// Get the current feature set.
649-
pub fn get_feature_set(&self) -> &FeatureSet {
727+
pub fn get_feature_set(&self) -> &RuntimeFeatures {
650728
&self.environment_config.feature_set
651729
}
652730

653731
/// Set feature set.
654732
///
655733
/// Only use for tests and benchmarks.
656-
pub fn mock_set_feature_set(&mut self, feature_set: Arc<FeatureSet>) {
734+
#[cfg(feature = "dev-context-only-utils")]
735+
pub fn mock_set_feature_set(&mut self, feature_set: Arc<RuntimeFeatures>) {
657736
self.environment_config.feature_set = feature_set;
658737
}
659738

739+
pub fn is_stake_raise_minimum_delegation_to_1_sol_active(&self) -> bool {
740+
self.environment_config
741+
.feature_set
742+
.stake_raise_minimum_delegation_to_1_sol
743+
.is_some()
744+
}
745+
746+
pub fn is_deprecate_legacy_vote_ixs_active(&self) -> bool {
747+
self.environment_config
748+
.feature_set
749+
.deprecate_legacy_vote_ixs
750+
.is_some()
751+
}
752+
660753
/// Get cached sysvars
661754
pub fn get_sysvar_cache(&self) -> &SysvarCache {
662755
self.environment_config.sysvar_cache
@@ -738,14 +831,13 @@ macro_rules! with_mock_invoke_context {
738831
$transaction_accounts:expr $(,)?
739832
) => {
740833
use {
741-
agave_feature_set::FeatureSet,
742834
solana_log_collector::LogCollector,
743835
solana_svm_callback::InvokeContextCallback,
744836
solana_type_overrides::sync::Arc,
745837
$crate::{
746838
__private::{Hash, ReadableAccount, Rent, TransactionContext},
747839
execution_budget::{SVMTransactionExecutionBudget, SVMTransactionExecutionCost},
748-
invoke_context::{EnvironmentConfig, InvokeContext},
840+
invoke_context::{EnvironmentConfig, InvokeContext, RuntimeFeatures},
749841
loaded_programs::ProgramCacheForTxBatch,
750842
sysvar_cache::SysvarCache,
751843
},
@@ -783,7 +875,7 @@ macro_rules! with_mock_invoke_context {
783875
Hash::default(),
784876
0,
785877
&MockInvokeContextCallback {},
786-
Arc::new(FeatureSet::all_enabled()),
878+
Arc::new(RuntimeFeatures::all_enabled()),
787879
&sysvar_cache,
788880
);
789881
let mut program_cache_for_tx_batch = ProgramCacheForTxBatch::default();

program-test/src/lib.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,8 @@ pub fn invoke_builtin_function(
131131
// Serialize entrypoint parameters with SBF ABI
132132
let mask_out_rent_epoch_in_vm_serialization = invoke_context
133133
.get_feature_set()
134-
.is_active(&agave_feature_set::mask_out_rent_epoch_in_vm_serialization::id());
134+
.mask_out_rent_epoch_in_vm_serialization
135+
.is_some();
135136
let (mut parameter_bytes, _regions, _account_lengths) = serialize_parameters(
136137
transaction_context,
137138
instruction_context,

programs/bpf_loader/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ license = { workspace = true }
1010
edition = { workspace = true }
1111

1212
[dependencies]
13-
agave-feature-set = { workspace = true }
1413
bincode = { workspace = true }
1514
libsecp256k1 = { workspace = true }
1615
num-traits = { workspace = true }
@@ -60,6 +59,7 @@ solana-epoch-schedule = { workspace = true }
6059
solana-fee-calculator = { workspace = true }
6160
solana-last-restart-slot = { workspace = true }
6261
solana-program = { workspace = true }
62+
solana-program-runtime = { workspace = true, features = ["dev-context-only-utils"] }
6363
solana-pubkey = { workspace = true, features = ["rand"] }
6464
solana-rent = { workspace = true }
6565
solana-slot-hashes = { workspace = true }

0 commit comments

Comments
 (0)