diff --git a/runtime/src/bank.rs b/runtime/src/bank.rs index e2ab858660361f..a4555ed60dbd79 100644 --- a/runtime/src/bank.rs +++ b/runtime/src/bank.rs @@ -42,9 +42,11 @@ use solana_sdk::recent_blockhashes_account; pub use solana_sdk::reward_type::RewardType; use { crate::{ - bank::metrics::*, + bank::{ + builtins::{BuiltinPrototype, BUILTINS}, + metrics::*, + }, bank_forks::BankForks, - builtins::{BuiltinPrototype, BUILTINS}, epoch_rewards_hasher::hash_rewards_into_partitions, epoch_stakes::{EpochStakes, NodeVoteAccounts}, installed_scheduler_pool::{BankWithScheduler, InstalledSchedulerRwLock}, @@ -210,6 +212,7 @@ struct VerifyAccountsHashConfig { mod address_lookup_table; pub mod bank_hash_details; mod builtin_programs; +pub mod builtins; pub mod epoch_accounts_hash_utils; mod fee_distribution; mod metrics; @@ -5994,7 +5997,7 @@ impl Bank { .iter() .chain(additional_builtins.unwrap_or(&[]).iter()) { - if builtin.feature_id.is_none() { + if builtin.enable_feature_id.is_none() { self.add_builtin( builtin.program_id, builtin.name.to_string(), @@ -7340,7 +7343,7 @@ impl Bank { new_feature_activations: &HashSet, ) { for builtin in BUILTINS.iter() { - if let Some(feature_id) = builtin.feature_id { + if let Some(feature_id) = builtin.enable_feature_id { let should_apply_action_for_feature_transition = if only_apply_transitions_for_new_features { new_feature_activations.contains(&feature_id) diff --git a/runtime/src/builtins.rs b/runtime/src/bank/builtins/mod.rs similarity index 55% rename from runtime/src/builtins.rs rename to runtime/src/bank/builtins/mod.rs index 2c7c36fa0ec415..4e8574b7f9144c 100644 --- a/runtime/src/builtins.rs +++ b/runtime/src/bank/builtins/mod.rs @@ -1,110 +1,78 @@ -use { - solana_program_runtime::invoke_context::BuiltinFunctionWithContext, - solana_sdk::{ - bpf_loader, bpf_loader_deprecated, bpf_loader_upgradeable, feature_set, pubkey::Pubkey, - }, -}; - -/// Transitions of built-in programs at epoch bondaries when features are activated. -pub struct BuiltinPrototype { - pub feature_id: Option, - pub program_id: Pubkey, - pub name: &'static str, - pub entrypoint: BuiltinFunctionWithContext, -} +pub mod prototypes; -impl std::fmt::Debug for BuiltinPrototype { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { - let mut builder = f.debug_struct("BuiltinPrototype"); - builder.field("program_id", &self.program_id); - builder.field("name", &self.name); - builder.field("feature_id", &self.feature_id); - builder.finish() - } -} - -#[cfg(RUSTC_WITH_SPECIALIZATION)] -impl solana_frozen_abi::abi_example::AbiExample for BuiltinPrototype { - fn example() -> Self { - // BuiltinPrototype isn't serializable by definition. - solana_program_runtime::declare_process_instruction!(MockBuiltin, 0, |_invoke_context| { - // Do nothing - Ok(()) - }); - Self { - feature_id: None, - program_id: Pubkey::default(), - name: "", - entrypoint: MockBuiltin::vm, - } - } -} +pub use prototypes::{BuiltinPrototype, StatelessBuiltinPrototype}; +use solana_sdk::{bpf_loader, bpf_loader_deprecated, bpf_loader_upgradeable, feature_set}; pub static BUILTINS: &[BuiltinPrototype] = &[ BuiltinPrototype { - feature_id: None, + enable_feature_id: None, program_id: solana_system_program::id(), name: "system_program", entrypoint: solana_system_program::system_processor::Entrypoint::vm, }, BuiltinPrototype { - feature_id: None, + enable_feature_id: None, program_id: solana_vote_program::id(), name: "vote_program", entrypoint: solana_vote_program::vote_processor::Entrypoint::vm, }, BuiltinPrototype { - feature_id: None, + enable_feature_id: None, program_id: solana_stake_program::id(), name: "stake_program", entrypoint: solana_stake_program::stake_instruction::Entrypoint::vm, }, BuiltinPrototype { - feature_id: None, + enable_feature_id: None, program_id: solana_config_program::id(), name: "config_program", entrypoint: solana_config_program::config_processor::Entrypoint::vm, }, BuiltinPrototype { - feature_id: None, + enable_feature_id: None, program_id: bpf_loader_deprecated::id(), name: "solana_bpf_loader_deprecated_program", entrypoint: solana_bpf_loader_program::Entrypoint::vm, }, BuiltinPrototype { - feature_id: None, + enable_feature_id: None, program_id: bpf_loader::id(), name: "solana_bpf_loader_program", entrypoint: solana_bpf_loader_program::Entrypoint::vm, }, BuiltinPrototype { - feature_id: None, + enable_feature_id: None, program_id: bpf_loader_upgradeable::id(), name: "solana_bpf_loader_upgradeable_program", entrypoint: solana_bpf_loader_program::Entrypoint::vm, }, BuiltinPrototype { - feature_id: None, + enable_feature_id: None, program_id: solana_sdk::compute_budget::id(), name: "compute_budget_program", entrypoint: solana_compute_budget_program::Entrypoint::vm, }, BuiltinPrototype { - feature_id: None, + enable_feature_id: None, program_id: solana_sdk::address_lookup_table::program::id(), name: "address_lookup_table_program", entrypoint: solana_address_lookup_table_program::processor::Entrypoint::vm, }, BuiltinPrototype { - feature_id: Some(feature_set::zk_token_sdk_enabled::id()), + enable_feature_id: Some(feature_set::zk_token_sdk_enabled::id()), program_id: solana_zk_token_sdk::zk_token_proof_program::id(), name: "zk_token_proof_program", entrypoint: solana_zk_token_proof_program::Entrypoint::vm, }, BuiltinPrototype { - feature_id: Some(feature_set::enable_program_runtime_v2_and_loader_v4::id()), + enable_feature_id: Some(feature_set::enable_program_runtime_v2_and_loader_v4::id()), program_id: solana_sdk::loader_v4::id(), name: "loader_v4", entrypoint: solana_loader_v4_program::Entrypoint::vm, }, ]; + +pub static STATELESS_BUILTINS: &[StatelessBuiltinPrototype] = &[StatelessBuiltinPrototype { + program_id: solana_sdk::feature::id(), + name: "feature_gate_program", +}]; diff --git a/runtime/src/bank/builtins/prototypes.rs b/runtime/src/bank/builtins/prototypes.rs new file mode 100644 index 00000000000000..5d9ea505152dda --- /dev/null +++ b/runtime/src/bank/builtins/prototypes.rs @@ -0,0 +1,48 @@ +use { + solana_program_runtime::invoke_context::BuiltinFunctionWithContext, solana_sdk::pubkey::Pubkey, +}; + +/// Transitions of built-in programs at epoch boundaries when features are activated. +pub struct BuiltinPrototype { + pub enable_feature_id: Option, + pub program_id: Pubkey, + pub name: &'static str, + pub entrypoint: BuiltinFunctionWithContext, +} + +impl std::fmt::Debug for BuiltinPrototype { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + let mut builder = f.debug_struct("BuiltinPrototype"); + builder.field("program_id", &self.program_id); + builder.field("name", &self.name); + builder.field("enable_feature_id", &self.enable_feature_id); + builder.finish() + } +} + +#[cfg(RUSTC_WITH_SPECIALIZATION)] +impl solana_frozen_abi::abi_example::AbiExample for BuiltinPrototype { + fn example() -> Self { + // BuiltinPrototype isn't serializable by definition. + solana_program_runtime::declare_process_instruction!(MockBuiltin, 0, |_invoke_context| { + // Do nothing + Ok(()) + }); + Self { + enable_feature_id: None, + program_id: Pubkey::default(), + name: "", + entrypoint: MockBuiltin::vm, + } + } +} + +/// Transitions of stateless built-in programs at epoch boundaries when +/// features are activated. +/// These are built-in programs that don't actually exist, but their address +/// is reserved. +#[derive(Debug)] +pub struct StatelessBuiltinPrototype { + pub program_id: Pubkey, + pub name: &'static str, +} diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index fac4169301004d..57936c2c7e6bac 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -9,7 +9,6 @@ pub mod bank; pub mod bank_client; pub mod bank_forks; pub mod bank_utils; -pub mod builtins; pub mod commitment; pub mod compute_budget_details; mod epoch_rewards_hasher; diff --git a/runtime/src/serde_snapshot.rs b/runtime/src/serde_snapshot.rs index 8e678044e23670..f866f32577f38e 100644 --- a/runtime/src/serde_snapshot.rs +++ b/runtime/src/serde_snapshot.rs @@ -1,7 +1,6 @@ use { crate::{ - bank::{Bank, BankFieldsToDeserialize, BankRc}, - builtins::BuiltinPrototype, + bank::{builtins::BuiltinPrototype, Bank, BankFieldsToDeserialize, BankRc}, epoch_stakes::EpochStakes, serde_snapshot::storage::SerializableAccountStorageEntry, snapshot_utils::{ diff --git a/runtime/src/snapshot_bank_utils.rs b/runtime/src/snapshot_bank_utils.rs index cfb767d11fd7ab..a9f613e431feaa 100644 --- a/runtime/src/snapshot_bank_utils.rs +++ b/runtime/src/snapshot_bank_utils.rs @@ -1,7 +1,6 @@ use { crate::{ - bank::{Bank, BankFieldsToDeserialize, BankSlotDelta}, - builtins::BuiltinPrototype, + bank::{builtins::BuiltinPrototype, Bank, BankFieldsToDeserialize, BankSlotDelta}, serde_snapshot::{ bank_from_streams, bank_to_stream, fields_from_streams, BankIncrementalSnapshotPersistence, SerdeStyle, diff --git a/runtime/src/snapshot_minimizer.rs b/runtime/src/snapshot_minimizer.rs index 15fe706dc0e504..ddd47c887ab7bb 100644 --- a/runtime/src/snapshot_minimizer.rs +++ b/runtime/src/snapshot_minimizer.rs @@ -1,7 +1,10 @@ //! Used to create minimal snapshots - separated here to keep accounts_db simpler use { - crate::{bank::Bank, builtins::BUILTINS, static_ids}, + crate::{ + bank::{builtins::BUILTINS, Bank}, + static_ids, + }, dashmap::DashSet, log::info, rayon::{