diff --git a/Cargo.lock b/Cargo.lock index 007de69dba..6b72c40607 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3411,6 +3411,7 @@ dependencies = [ "serde_json", "serial_test", "serial_test_derive", + "solana-bpf-loader-program", "solana-budget-program", "solana-chacha-cuda", "solana-clap-utils", @@ -3566,14 +3567,11 @@ dependencies = [ "log 0.4.8", "solana-bpf-loader-program", "solana-budget-program", - "solana-config-program", "solana-exchange-program", "solana-runtime", "solana-sdk", - "solana-stake-program", "solana-storage-program", "solana-vest-program", - "solana-vote-program", ] [[package]] @@ -3922,6 +3920,7 @@ dependencies = [ "serde", "serde_derive", "solana-bpf-loader-program", + "solana-config-program", "solana-logger", "solana-measure", "solana-metrics", diff --git a/bench-exchange/tests/bench_exchange.rs b/bench-exchange/tests/bench_exchange.rs index f5dd1c80be..c99abd8418 100644 --- a/bench-exchange/tests/bench_exchange.rs +++ b/bench-exchange/tests/bench_exchange.rs @@ -86,7 +86,7 @@ fn test_exchange_bank_client() { solana_logger::setup(); let (genesis_config, identity) = create_genesis_config(100_000_000_000_000); let mut bank = Bank::new(&genesis_config); - bank.add_instruction_processor(id(), process_instruction); + bank.add_static_program("exchange_program", id(), process_instruction); let clients = vec![BankClient::new(bank)]; let mut config = Config::default(); diff --git a/core/Cargo.toml b/core/Cargo.toml index f8c834e3c5..97b8ef28e8 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -41,6 +41,7 @@ regex = "1.3.6" serde = "1.0.105" serde_derive = "1.0.103" serde_json = "1.0.48" +solana-bpf-loader-program = { path = "../programs/bpf_loader", version = "1.1.8" } solana-budget-program = { path = "../programs/budget", version = "1.1.8" } solana-clap-utils = { path = "../clap-utils", version = "1.1.8" } solana-client = { path = "../client", version = "1.1.8" } diff --git a/core/src/lib.rs b/core/src/lib.rs index 52c5f9af54..a0b7a6c6d3 100644 --- a/core/src/lib.rs +++ b/core/src/lib.rs @@ -58,6 +58,9 @@ pub mod verified_vote_packets; pub mod weighted_shuffle; pub mod window_service; +#[macro_use] +extern crate solana_bpf_loader_program; + #[macro_use] extern crate solana_budget_program; diff --git a/core/src/validator.rs b/core/src/validator.rs index 136dd67347..5c6a8b529d 100644 --- a/core/src/validator.rs +++ b/core/src/validator.rs @@ -709,6 +709,9 @@ impl TestValidator { genesis_config .native_instruction_processors .push(solana_budget_program!()); + genesis_config + .native_instruction_processors + .push(solana_bpf_loader_program!()); genesis_config.rent.lamports_per_byte_year = 1; genesis_config.rent.exemption_threshold = 1.0; diff --git a/genesis-programs/Cargo.toml b/genesis-programs/Cargo.toml index 6653dc6abc..297e291f31 100644 --- a/genesis-programs/Cargo.toml +++ b/genesis-programs/Cargo.toml @@ -12,14 +12,11 @@ edition = "2018" log = { version = "0.4.8" } solana-bpf-loader-program = { path = "../programs/bpf_loader", version = "1.1.8" } solana-budget-program = { path = "../programs/budget", version = "1.1.8" } -solana-config-program = { path = "../programs/config", version = "1.1.8" } solana-exchange-program = { path = "../programs/exchange", version = "1.1.8" } solana-runtime = { path = "../runtime", version = "1.1.8" } solana-sdk = { path = "../sdk", version = "1.1.8" } -solana-stake-program = { path = "../programs/stake", version = "1.1.8" } solana-storage-program = { path = "../programs/storage", version = "1.1.8" } solana-vest-program = { path = "../programs/vest", version = "1.1.8" } -solana-vote-program = { path = "../programs/vote", version = "1.1.8" } [lib] crate-type = ["lib"] diff --git a/genesis-programs/src/lib.rs b/genesis-programs/src/lib.rs index 543e870bd7..2d2c18169f 100644 --- a/genesis-programs/src/lib.rs +++ b/genesis-programs/src/lib.rs @@ -1,6 +1,6 @@ use solana_sdk::{ clock::Epoch, genesis_config::OperatingMode, inflation::Inflation, - move_loader::solana_move_loader_program, pubkey::Pubkey, system_program::solana_system_program, + move_loader::solana_move_loader_program, pubkey::Pubkey, }; #[macro_use] @@ -8,17 +8,11 @@ extern crate solana_bpf_loader_program; #[macro_use] extern crate solana_budget_program; #[macro_use] -extern crate solana_config_program; -#[macro_use] extern crate solana_exchange_program; #[macro_use] -extern crate solana_stake_program; -#[macro_use] extern crate solana_storage_program; #[macro_use] extern crate solana_vest_program; -#[macro_use] -extern crate solana_vote_program; use log::*; use solana_runtime::bank::{Bank, EnteredEpochCallback}; @@ -56,12 +50,8 @@ pub fn get_programs(operating_mode: OperatingMode, epoch: Epoch) -> Option Option { - if epoch == 0 { - Some(vec![ - solana_config_program!(), - solana_stake_program!(), - solana_system_program(), - solana_vote_program!(), - ]) - } else if epoch == std::u64::MAX - 1 { + if epoch == std::u64::MAX - 1 { // The epoch of std::u64::MAX - 1 is a placeholder and is expected to be reduced in // a future hard fork. Some(vec![solana_bpf_loader_program!()]) @@ -93,13 +76,7 @@ pub fn get_programs(operating_mode: OperatingMode, epoch: Epoch) -> Option { if epoch == 0 { - Some(vec![ - solana_config_program!(), - solana_stake_program!(), - solana_system_program(), - solana_vote_program!(), - solana_bpf_loader_program!(), - ]) + Some(vec![solana_bpf_loader_program!()]) } else if epoch == std::u64::MAX { // The epoch of std::u64::MAX is a placeholder and is expected to be reduced in a // future hard fork. @@ -124,7 +101,7 @@ pub fn get_entered_epoch_callback(operating_mode: OperatingMode) -> EnteredEpoch if let Some(new_programs) = get_programs(operating_mode, bank.epoch()) { for (name, program_id) in new_programs.iter() { info!("Registering {} at {}", name, program_id); - bank.register_native_instruction_processor(name, program_id); + bank.add_native_program(name, program_id); } } }) @@ -155,7 +132,7 @@ mod tests { fn test_development_programs() { assert_eq!( get_programs(OperatingMode::Development, 0).unwrap().len(), - 10 + 6 ); assert_eq!(get_programs(OperatingMode::Development, 1), None); } @@ -175,15 +152,6 @@ mod tests { #[test] fn test_softlaunch_programs() { - assert_eq!( - get_programs(OperatingMode::Stable, 0), - Some(vec![ - solana_config_program!(), - solana_stake_program!(), - solana_system_program(), - solana_vote_program!(), - ]) - ); assert_eq!(get_programs(OperatingMode::Stable, 1), None); assert!(get_programs(OperatingMode::Stable, std::u64::MAX - 1).is_some()); assert!(get_programs(OperatingMode::Stable, std::u64::MAX).is_some()); diff --git a/genesis/src/main.rs b/genesis/src/main.rs index 7dec922e79..e948c37877 100644 --- a/genesis/src/main.rs +++ b/genesis/src/main.rs @@ -438,7 +438,7 @@ fn main() -> Result<(), Box> { ); let native_instruction_processors = - solana_genesis_programs::get_programs(operating_mode, 0).unwrap(); + solana_genesis_programs::get_programs(operating_mode, 0).unwrap_or_else(|| vec![]); let inflation = solana_genesis_programs::get_inflation(operating_mode, 0).unwrap(); let mut genesis_config = GenesisConfig { diff --git a/ledger/src/snapshot_utils.rs b/ledger/src/snapshot_utils.rs index 80dc187aa2..4010f03a4a 100644 --- a/ledger/src/snapshot_utils.rs +++ b/ledger/src/snapshot_utils.rs @@ -621,8 +621,8 @@ where stream.by_ref(), &append_vecs_path, )?; - bank.set_bank_rc(rc, bank::StatusCacheRc::default()); + bank.finish_init(); Ok(bank) }, )?; diff --git a/local-cluster/src/local_cluster.rs b/local-cluster/src/local_cluster.rs index 5935142495..1dd2854297 100644 --- a/local-cluster/src/local_cluster.rs +++ b/local-cluster/src/local_cluster.rs @@ -169,9 +169,7 @@ impl LocalCluster { OperatingMode::Stable | OperatingMode::Preview => { genesis_config.native_instruction_processors = solana_genesis_programs::get_programs(genesis_config.operating_mode, 0) - .unwrap() - .into_iter() - .collect() + .unwrap_or_else(|| vec![]) } OperatingMode::Development => { genesis_config diff --git a/programs/bpf/Cargo.lock b/programs/bpf/Cargo.lock index 6297a0b32d..efa654422a 100644 --- a/programs/bpf/Cargo.lock +++ b/programs/bpf/Cargo.lock @@ -1970,6 +1970,7 @@ dependencies = [ "serde", "serde_derive", "solana-bpf-loader-program", + "solana-config-program", "solana-logger", "solana-measure", "solana-metrics", diff --git a/programs/bpf/tests/programs.rs b/programs/bpf/tests/programs.rs index 72c4103314..0282a6e382 100644 --- a/programs/bpf/tests/programs.rs +++ b/programs/bpf/tests/programs.rs @@ -1,5 +1,6 @@ #[cfg(any(feature = "bpf_c", feature = "bpf_rust"))] mod bpf { + use solana_bpf_loader_program::solana_bpf_loader_program; use solana_runtime::{ bank::Bank, bank_client::BankClient, @@ -83,10 +84,13 @@ mod bpf { println!("Test program: {:?}", program.0); let GenesisConfigInfo { - genesis_config, + mut genesis_config, mint_keypair, .. } = create_genesis_config(50); + genesis_config + .native_instruction_processors + .push(solana_bpf_loader_program!()); let bank = Arc::new(Bank::new(&genesis_config)); // Create bank with specific slot, used by solana_bpf_rust_sysvar test let bank = @@ -133,10 +137,13 @@ mod bpf { println!("Test program: {:?}", program); let GenesisConfigInfo { - genesis_config, + mut genesis_config, mint_keypair, .. } = create_genesis_config(50); + genesis_config + .native_instruction_processors + .push(solana_bpf_loader_program!()); let bank = Arc::new(Bank::new(&genesis_config)); let bank_client = BankClient::new_shared(&bank); let program_id = load_bpf_program(&bank_client, &mint_keypair, program); @@ -215,10 +222,13 @@ mod bpf { println!("Test program: {:?}", program); let GenesisConfigInfo { - genesis_config, + mut genesis_config, mint_keypair, .. } = create_genesis_config(50); + genesis_config + .native_instruction_processors + .push(solana_bpf_loader_program!()); let bank = Bank::new(&genesis_config); let bank_client = BankClient::new(bank); let program_id = load_bpf_program(&bank_client, &mint_keypair, program); diff --git a/programs/budget/src/budget_processor.rs b/programs/budget/src/budget_processor.rs index bcc29c058c..042ae586ca 100644 --- a/programs/budget/src/budget_processor.rs +++ b/programs/budget/src/budget_processor.rs @@ -238,7 +238,7 @@ mod tests { fn create_bank(lamports: u64) -> (Bank, Keypair) { let (genesis_config, mint_keypair) = create_genesis_config(lamports); let mut bank = Bank::new(&genesis_config); - bank.add_instruction_processor(id(), process_instruction); + bank.add_static_program("budget_program", id(), process_instruction); (bank, mint_keypair) } diff --git a/programs/config/Cargo.toml b/programs/config/Cargo.toml index 6c1aa67212..5a1568c092 100644 --- a/programs/config/Cargo.toml +++ b/programs/config/Cargo.toml @@ -20,7 +20,7 @@ solana-sdk = { path = "../../sdk", version = "1.1.8" } solana-logger = { path = "../../logger", version = "1.1.8" } [lib] -crate-type = ["lib", "cdylib"] +crate-type = ["lib"] name = "solana_config_program" [package.metadata.docs.rs] diff --git a/programs/config/src/lib.rs b/programs/config/src/lib.rs index 0d26c3548a..dced35d309 100644 --- a/programs/config/src/lib.rs +++ b/programs/config/src/lib.rs @@ -2,16 +2,11 @@ pub mod config_instruction; pub mod config_processor; pub mod date_instruction; -use crate::config_processor::process_instruction; use bincode::{deserialize, serialize, serialized_size}; use serde_derive::{Deserialize, Serialize}; use solana_sdk::{account::Account, pubkey::Pubkey, short_vec}; -solana_sdk::declare_program!( - "Config1111111111111111111111111111111111111", - solana_config_program, - process_instruction -); +solana_sdk::declare_id!("Config1111111111111111111111111111111111111"); pub trait ConfigState: serde::Serialize + Default { /// Maximum space that the serialized representation will require diff --git a/programs/exchange/src/exchange_processor.rs b/programs/exchange/src/exchange_processor.rs index e28f531daf..d382b30281 100644 --- a/programs/exchange/src/exchange_processor.rs +++ b/programs/exchange/src/exchange_processor.rs @@ -577,7 +577,7 @@ mod test { fn create_bank(lamports: u64) -> (Bank, Keypair) { let (genesis_config, mint_keypair) = create_genesis_config(lamports); let mut bank = Bank::new(&genesis_config); - bank.add_instruction_processor(id(), process_instruction); + bank.add_static_program("excahnge_program", id(), process_instruction); (bank, mint_keypair) } diff --git a/programs/failure/tests/failure.rs b/programs/failure/tests/failure.rs index 5cb93cfb2b..52f9fbc752 100644 --- a/programs/failure/tests/failure.rs +++ b/programs/failure/tests/failure.rs @@ -13,7 +13,7 @@ fn test_program_native_failure() { let (genesis_config, alice_keypair) = create_genesis_config(50); let program_id = Pubkey::new_rand(); let bank = Bank::new(&genesis_config); - bank.register_native_instruction_processor("solana_failure_program", &program_id); + bank.add_native_program("solana_failure_program", &program_id); // Call user program let instruction = create_invoke_instruction(alice_keypair.pubkey(), program_id, &1u8); diff --git a/programs/librapay/Cargo.lock b/programs/librapay/Cargo.lock index e4367d0c12..d82e596078 100644 --- a/programs/librapay/Cargo.lock +++ b/programs/librapay/Cargo.lock @@ -2672,6 +2672,7 @@ dependencies = [ "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "rayon 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", +<<<<<<< HEAD "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "solana-bpf-loader-program 1.1.0", @@ -2683,6 +2684,19 @@ dependencies = [ "solana-stake-program 1.1.0", "solana-storage-program 1.1.0", "solana-vote-program 1.1.0", +======= + "serde 1.0.106 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.106 (registry+https://github.com/rust-lang/crates.io-index)", + "solana-config-program 1.2.0", + "solana-logger 1.2.0", + "solana-measure 1.2.0", + "solana-metrics 1.2.0", + "solana-rayon-threadlimit 1.2.0", + "solana-sdk 1.2.0", + "solana-stake-program 1.2.0", + "solana-storage-program 1.2.0", + "solana-vote-program 1.2.0", +>>>>>>> efad19318... Make default programs static (#9717) "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "thiserror 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", ] diff --git a/programs/librapay/src/librapay_transaction.rs b/programs/librapay/src/librapay_transaction.rs index dd7910ec5c..79d8a77b5a 100644 --- a/programs/librapay/src/librapay_transaction.rs +++ b/programs/librapay/src/librapay_transaction.rs @@ -161,11 +161,16 @@ mod tests { fn create_bank(lamports: u64) -> (Arc, Keypair, Keypair, Pubkey, Pubkey) { let (mut genesis_config, mint) = create_genesis_config(lamports); genesis_config.rent.lamports_per_byte_year = 0; +<<<<<<< HEAD let mut bank = Bank::new(&genesis_config); bank.add_instruction_processor( solana_sdk::move_loader::id(), MoveProcessor::process_instruction, ); +======= + let bank = Bank::new(&genesis_config); + bank.add_native_program("solana_move_loader_program", &solana_sdk::move_loader::id()); +>>>>>>> efad19318... Make default programs static (#9717) let shared_bank = Arc::new(bank); let bank_client = BankClient::new_shared(&shared_bank); let genesis_pubkey = create_genesis(&mint, &bank_client, 1_000_000); diff --git a/programs/ownable/src/ownable_processor.rs b/programs/ownable/src/ownable_processor.rs index e43f800dc2..5abbf9e36f 100644 --- a/programs/ownable/src/ownable_processor.rs +++ b/programs/ownable/src/ownable_processor.rs @@ -71,7 +71,7 @@ mod tests { fn create_bank(lamports: u64) -> (Bank, Keypair) { let (genesis_config, mint_keypair) = create_genesis_config(lamports); let mut bank = Bank::new(&genesis_config); - bank.add_instruction_processor(crate::id(), process_instruction); + bank.add_static_program("ownable_program", crate::id(), process_instruction); (bank, mint_keypair) } diff --git a/programs/stake/Cargo.toml b/programs/stake/Cargo.toml index 85f9ddb237..c24489d7b5 100644 --- a/programs/stake/Cargo.toml +++ b/programs/stake/Cargo.toml @@ -25,7 +25,7 @@ thiserror = "1.0" solana-logger = { path = "../../logger", version = "1.1.8" } [lib] -crate-type = ["lib", "cdylib"] +crate-type = ["lib"] name = "solana_stake_program" [package.metadata.docs.rs] diff --git a/programs/stake/src/lib.rs b/programs/stake/src/lib.rs index 7112680d99..78d1a5f706 100644 --- a/programs/stake/src/lib.rs +++ b/programs/stake/src/lib.rs @@ -4,11 +4,7 @@ pub mod config; pub mod stake_instruction; pub mod stake_state; -solana_sdk::declare_program!( - "Stake11111111111111111111111111111111111111", - solana_stake_program, - stake_instruction::process_instruction -); +solana_sdk::declare_id!("Stake11111111111111111111111111111111111111"); pub fn add_genesis_accounts(genesis_config: &mut GenesisConfig) -> u64 { config::add_genesis_account(genesis_config) diff --git a/programs/vest/src/vest_processor.rs b/programs/vest/src/vest_processor.rs index a2df199dc5..6dba509785 100644 --- a/programs/vest/src/vest_processor.rs +++ b/programs/vest/src/vest_processor.rs @@ -161,11 +161,7 @@ mod tests { fn create_bank(lamports: u64) -> (Bank, Keypair) { let (genesis_config, mint_keypair) = create_genesis_config(lamports); let mut bank = Bank::new(&genesis_config); - bank.add_instruction_processor( - solana_config_program::id(), - solana_config_program::config_processor::process_instruction, - ); - bank.add_instruction_processor(id(), process_instruction); + bank.add_static_program("vest_program", id(), process_instruction); (bank, mint_keypair) } @@ -472,7 +468,7 @@ mod tests { ) .unwrap_err(); - // Ensure bob can update which account he wants vested funds transfered to. + // Ensure bob can update which account he wants vested funds transferred to. bank_client .transfer(1, &alice_keypair, &bob_pubkey) .unwrap(); diff --git a/programs/vote/Cargo.toml b/programs/vote/Cargo.toml index 3748b3be50..d7b90c2e84 100644 --- a/programs/vote/Cargo.toml +++ b/programs/vote/Cargo.toml @@ -20,7 +20,7 @@ solana-sdk = { path = "../../sdk", version = "1.1.8" } thiserror = "1.0" [lib] -crate-type = ["lib", "cdylib"] +crate-type = ["lib"] name = "solana_vote_program" [package.metadata.docs.rs] diff --git a/programs/vote/src/lib.rs b/programs/vote/src/lib.rs index e6d0b272e3..fbb37f7863 100644 --- a/programs/vote/src/lib.rs +++ b/programs/vote/src/lib.rs @@ -6,10 +6,4 @@ pub mod vote_transaction; #[macro_use] extern crate solana_metrics; -use crate::vote_instruction::process_instruction; - -solana_sdk::declare_program!( - "Vote111111111111111111111111111111111111111", - solana_vote_program, - process_instruction -); +solana_sdk::declare_id!("Vote111111111111111111111111111111111111111"); diff --git a/runtime/Cargo.toml b/runtime/Cargo.toml index 308ffa6f9d..190810f7fd 100644 --- a/runtime/Cargo.toml +++ b/runtime/Cargo.toml @@ -28,6 +28,7 @@ rayon = "1.3.0" serde = { version = "1.0.105", features = ["rc"] } serde_derive = "1.0.103" solana-bpf-loader-program = { path = "../programs/bpf_loader", version = "1.1.8" } +solana-config-program = { path = "../programs/config", version = "1.1.0" } solana-logger = { path = "../logger", version = "1.1.8" } solana-measure = { path = "../measure", version = "1.1.8" } solana-metrics = { path = "../metrics", version = "1.1.8" } @@ -39,7 +40,6 @@ solana-vote-program = { path = "../programs/vote", version = "1.1.8" } tempfile = "3.1.0" thiserror = "1.0" - [lib] crate-type = ["lib"] name = "solana_runtime" diff --git a/runtime/benches/bank.rs b/runtime/benches/bank.rs index 1c5f82879b..a9c466bbb7 100644 --- a/runtime/benches/bank.rs +++ b/runtime/benches/bank.rs @@ -122,11 +122,12 @@ fn do_bench_transactions( let (mut genesis_config, mint_keypair) = create_genesis_config(100_000_000); genesis_config.ticks_per_slot = 100; let mut bank = Bank::new(&genesis_config); - bank.add_instruction_processor(Pubkey::new(&BUILTIN_PROGRAM_ID), process_instruction); - bank.register_native_instruction_processor( - "solana_noop_program", - &Pubkey::new(&NOOP_PROGRAM_ID), + bank.add_static_program( + "builtin_program", + Pubkey::new(&BUILTIN_PROGRAM_ID), + process_instruction, ); + bank.add_native_program("solana_noop_program", &Pubkey::new(&NOOP_PROGRAM_ID)); let bank = Arc::new(bank); let bank_client = BankClient::new_shared(&bank); let transactions = create_transactions(&bank_client, &mint_keypair); diff --git a/runtime/src/bank.rs b/runtime/src/bank.rs index 2a0d30f201..ed7e5ac97c 100644 --- a/runtime/src/bank.rs +++ b/runtime/src/bank.rs @@ -17,7 +17,7 @@ use crate::{ status_cache::{SlotDelta, StatusCache}, storage_utils, storage_utils::StorageAccounts, - system_instruction_processor::{get_system_account_kind, SystemAccountKind}, + system_instruction_processor::{self, get_system_account_kind, SystemAccountKind}, transaction_batch::TransactionBatch, transaction_utils::OrderedIterator, }; @@ -374,6 +374,7 @@ impl Bank { bank.rc.accounts = Arc::new(Accounts::new(paths)); bank.process_genesis_config(genesis_config); + bank.finish_init(); // Freeze accounts after process_genesis_config creates the initial append vecs Arc::get_mut(&mut bank.rc.accounts) @@ -456,7 +457,7 @@ impl Bank { is_delta: AtomicBool::new(false), tick_height: AtomicU64::new(parent.tick_height.load(Ordering::Relaxed)), signature_count: AtomicU64::new(0), - message_processor: MessageProcessor::default(), + message_processor: parent.message_processor.clone(), entered_epoch_callback: parent.entered_epoch_callback.clone(), hard_forks: parent.hard_forks.clone(), last_vote_sync: AtomicU64::new(parent.last_vote_sync.load(Ordering::Relaxed)), @@ -903,14 +904,14 @@ impl Bank { // Add additional native programs specified in the genesis config for (name, program_id) in &genesis_config.native_instruction_processors { - self.register_native_instruction_processor(name, program_id); + self.add_native_program(name, program_id); } } - pub fn register_native_instruction_processor(&self, name: &str, program_id: &Pubkey) { - debug!("Adding native program {} under {:?}", name, program_id); + pub fn add_native_program(&self, name: &str, program_id: &Pubkey) { let account = native_loader::create_loadable_account(name); self.store_account(program_id, &account); + debug!("Added native program {} under {:?}", name, program_id); } /// Return the last block hash registered. @@ -1764,6 +1765,29 @@ impl Bank { self.src = status_cache_rc; } + pub fn finish_init(&mut self) { + self.add_static_program( + "system_program", + solana_sdk::system_program::id(), + system_instruction_processor::process_instruction, + ); + self.add_static_program( + "config_program", + solana_config_program::id(), + solana_config_program::config_processor::process_instruction, + ); + self.add_static_program( + "stake_program", + solana_stake_program::id(), + solana_stake_program::stake_instruction::process_instruction, + ); + self.add_static_program( + "vote_program", + solana_vote_program::id(), + solana_vote_program::vote_instruction::process_instruction, + ); + } + pub fn set_parent(&mut self, parent: &Arc) { self.rc.parent = RwLock::new(Some(parent.clone())); } @@ -2147,21 +2171,29 @@ impl Bank { } /// Add an instruction processor to intercept instructions before the dynamic loader. - pub fn add_instruction_processor( + pub fn add_static_program( &mut self, + name: &str, program_id: Pubkey, process_instruction: ProcessInstruction, ) { + match self.get_account(&program_id) { + Some(account) => { + assert_eq!( + account.owner, + native_loader::id(), + "Cannot overwrite non-native loader account" + ); + } + None => { + // Add a bogus executable native account, which will be loaded and ignored. + let account = native_loader::create_loadable_account(name); + self.store_account(&program_id, &account); + } + } self.message_processor .add_instruction_processor(program_id, process_instruction); - - if let Some(program_account) = self.get_account(&program_id) { - // It is not valid to intercept instructions for a non-native loader account - assert_eq!(program_account.owner, solana_sdk::native_loader::id()); - } else { - // Register a bogus executable account, which will be loaded and ignored. - self.register_native_instruction_processor("", &program_id); - } + debug!("Added static program {} under {:?}", name, program_id); } pub fn compare_bank(&self, dbank: &Bank) { @@ -2273,8 +2305,7 @@ mod tests { poh_config::PohConfig, rent::Rent, signature::{Keypair, Signer}, - system_instruction, - system_program::{self, solana_system_program}, + system_instruction, system_program, sysvar::{fees::Fees, rewards::Rewards}, timing::duration_as_s, }; @@ -2531,7 +2562,7 @@ mod tests { bank_with_success_txs.store_account(&keypair6.pubkey(), &account6); // Make native instruction loader rent exempt - let system_program_id = solana_system_program().1; + let system_program_id = system_program::id(); let mut system_program_account = bank.get_account(&system_program_id).unwrap(); system_program_account.lamports = bank.get_minimum_balance_for_rent_exemption(system_program_account.data.len()); @@ -2729,7 +2760,7 @@ mod tests { ) as u64, ); bank.rent_collector.slots_per_year = 421_812.0; - bank.add_instruction_processor(mock_program_id, mock_process_instruction); + bank.add_static_program("mock_program", mock_program_id, mock_process_instruction); bank } @@ -5019,28 +5050,35 @@ mod tests { } #[test] - fn test_add_instruction_processor() { + fn test_add_static_program() { let (genesis_config, mint_keypair) = create_genesis_config(500); let mut bank = Bank::new(&genesis_config); + fn mock_vote_program_id() -> Pubkey { + Pubkey::new(&[42u8; 32]) + } fn mock_vote_processor( program_id: &Pubkey, _keyed_accounts: &[KeyedAccount], _instruction_data: &[u8], ) -> std::result::Result<(), InstructionError> { - if !solana_vote_program::check_id(program_id) { + if mock_vote_program_id() != *program_id { return Err(InstructionError::IncorrectProgramId); } Err(InstructionError::CustomError(42)) } - assert!(bank.get_account(&solana_vote_program::id()).is_none()); - bank.add_instruction_processor(solana_vote_program::id(), mock_vote_processor); - assert!(bank.get_account(&solana_vote_program::id()).is_some()); + assert!(bank.get_account(&mock_vote_program_id()).is_none()); + bank.add_static_program( + "mock_vote_program", + mock_vote_program_id(), + mock_vote_processor, + ); + assert!(bank.get_account(&mock_vote_program_id()).is_some()); let mock_account = Keypair::new(); let mock_validator_identity = Keypair::new(); - let instructions = vote_instruction::create_account( + let mut instructions = vote_instruction::create_account( &mint_keypair.pubkey(), &mock_account.pubkey(), &VoteInit { @@ -5049,6 +5087,7 @@ mod tests { }, 1, ); + instructions[1].program_id = mock_vote_program_id(); let transaction = Transaction::new_signed_instructions( &[&mint_keypair, &mock_account, &mock_validator_identity], @@ -5066,13 +5105,12 @@ mod tests { } #[test] - fn test_add_instruction_processor_for_existing_program() { + fn test_add_duplicate_static_program() { let GenesisConfigInfo { genesis_config, mint_keypair, .. } = create_genesis_config_with_leader(500, &Pubkey::new_rand(), 0); - let mut bank = Bank::new(&genesis_config); fn mock_vote_processor( @@ -5102,7 +5140,11 @@ mod tests { ); let vote_loader_account = bank.get_account(&solana_vote_program::id()).unwrap(); - bank.add_instruction_processor(solana_vote_program::id(), mock_vote_processor); + bank.add_static_program( + "solana_vote_program", + solana_vote_program::id(), + mock_vote_processor, + ); let new_vote_loader_account = bank.get_account(&solana_vote_program::id()).unwrap(); // Vote loader account should not be updated since it was included in the genesis config. assert_eq!(vote_loader_account.data, new_vote_loader_account.data); @@ -5130,7 +5172,7 @@ mod tests { } // Non-native loader accounts can not be used for instruction processing - bank.add_instruction_processor(mint_keypair.pubkey(), mock_ix_processor); + bank.add_static_program("mock_program", mint_keypair.pubkey(), mock_ix_processor); } #[test] fn test_recent_blockhashes_sysvar() { @@ -5149,6 +5191,7 @@ mod tests { bank = Arc::new(new_from_parent(&bank)); } } + #[test] fn test_bank_inherit_last_vote_sync() { let (genesis_config, _) = create_genesis_config(500); @@ -5689,7 +5732,7 @@ mod tests { } let mock_program_id = Pubkey::new(&[2u8; 32]); - bank.add_instruction_processor(mock_program_id, mock_process_instruction); + bank.add_static_program("mock_program", mock_program_id, mock_process_instruction); let from_pubkey = Pubkey::new_rand(); let to_pubkey = Pubkey::new_rand(); @@ -5732,7 +5775,7 @@ mod tests { } let mock_program_id = Pubkey::new(&[2u8; 32]); - bank.add_instruction_processor(mock_program_id, mock_process_instruction); + bank.add_static_program("mock_program", mock_program_id, mock_process_instruction); let from_pubkey = Pubkey::new_rand(); let to_pubkey = Pubkey::new_rand(); @@ -5792,7 +5835,11 @@ mod tests { Ok(()) } - bank.add_instruction_processor(solana_vote_program::id(), mock_vote_processor); + bank.add_static_program( + "solana_vote_program", + solana_vote_program::id(), + mock_vote_processor, + ); let result = bank.process_transaction(&tx); assert_eq!(result, Ok(())); let account = bank.get_account(&solana_vote_program::id()).unwrap(); diff --git a/runtime/src/genesis_utils.rs b/runtime/src/genesis_utils.rs index 2accac24b6..2094be6fae 100644 --- a/runtime/src/genesis_utils.rs +++ b/runtime/src/genesis_utils.rs @@ -5,7 +5,7 @@ use solana_sdk::{ pubkey::Pubkey, rent::Rent, signature::{Keypair, Signer}, - system_program::{self, solana_system_program}, + system_program, }; use solana_stake_program::stake_state; use solana_vote_program::vote_state; @@ -133,18 +133,9 @@ pub fn create_genesis_config_with_leader_ex( .cloned() .collect(); - // Bare minimum program set - let native_instruction_processors = vec![ - solana_system_program(), - solana_bpf_loader_program!(), - solana_vote_program!(), - solana_stake_program!(), - ]; - let fee_rate_governor = FeeRateGovernor::new(0, 0); // most tests can't handle transaction fees let mut genesis_config = GenesisConfig { accounts, - native_instruction_processors, fee_rate_governor, rent, ..GenesisConfig::default() diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index bec77dc00f..5a9e665d9f 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -21,18 +21,13 @@ mod system_instruction_processor; pub mod transaction_batch; pub mod transaction_utils; -#[macro_use] -extern crate solana_metrics; - -#[macro_use] +extern crate solana_bpf_loader_program; +extern crate solana_config_program; +extern crate solana_stake_program; extern crate solana_vote_program; #[macro_use] -extern crate solana_stake_program; - -#[macro_use] -extern crate solana_bpf_loader_program; - +extern crate solana_metrics; #[macro_use] extern crate serde_derive; diff --git a/runtime/src/message_processor.rs b/runtime/src/message_processor.rs index 8b739f1046..bb57064892 100644 --- a/runtime/src/message_processor.rs +++ b/runtime/src/message_processor.rs @@ -1,4 +1,4 @@ -use crate::{native_loader, rent_collector::RentCollector, system_instruction_processor}; +use crate::{native_loader, rent_collector::RentCollector}; use serde::{Deserialize, Serialize}; use solana_sdk::{ account::{create_keyed_readonly_accounts, Account, KeyedAccount}, @@ -161,22 +161,17 @@ impl PreAccount { pub type ProcessInstruction = fn(&Pubkey, &[KeyedAccount], &[u8]) -> Result<(), InstructionError>; pub type SymbolCache = RwLock, Symbol>>; -#[derive(Serialize, Deserialize)] +#[derive(Default, Deserialize, Serialize)] pub struct MessageProcessor { #[serde(skip)] instruction_processors: Vec<(Pubkey, ProcessInstruction)>, #[serde(skip)] symbol_cache: SymbolCache, } -impl Default for MessageProcessor { - fn default() -> Self { - let instruction_processors: Vec<(Pubkey, ProcessInstruction)> = vec![( - system_program::id(), - system_instruction_processor::process_instruction, - )]; - - Self { - instruction_processors, +impl Clone for MessageProcessor { + fn clone(&self) -> Self { + MessageProcessor { + instruction_processors: self.instruction_processors.clone(), symbol_cache: RwLock::new(HashMap::new()), } } @@ -188,8 +183,16 @@ impl MessageProcessor { program_id: Pubkey, process_instruction: ProcessInstruction, ) { - self.instruction_processors - .push((program_id, process_instruction)); + match self + .instruction_processors + .iter_mut() + .find(|(key, _)| program_id == *key) + { + Some((_, processor)) => *processor = process_instruction, + None => self + .instruction_processors + .push((program_id, process_instruction)), + } } /// Process an instruction diff --git a/runtime/src/storage_utils.rs b/runtime/src/storage_utils.rs index e848c4e9dc..3fd5bf0d9d 100644 --- a/runtime/src/storage_utils.rs +++ b/runtime/src/storage_utils.rs @@ -103,7 +103,8 @@ pub(crate) mod tests { let validator_keypair = Keypair::new(); let validator_pubkey = validator_keypair.pubkey(); let mut bank = Bank::new(&genesis_config); - bank.add_instruction_processor( + bank.add_static_program( + "storage_program", solana_storage_program::id(), storage_processor::process_instruction, ); diff --git a/runtime/tests/noop.rs b/runtime/tests/noop.rs index eae9c0704d..35db435b39 100644 --- a/runtime/tests/noop.rs +++ b/runtime/tests/noop.rs @@ -12,7 +12,7 @@ fn test_program_native_noop() { let (genesis_config, alice_keypair) = create_genesis_config(50); let program_id = Pubkey::new_rand(); let bank = Bank::new(&genesis_config); - bank.register_native_instruction_processor("solana_noop_program", &program_id); + bank.add_native_program("solana_noop_program", &program_id); // Call user program let instruction = create_invoke_instruction(alice_keypair.pubkey(), program_id, &1u8); diff --git a/runtime/tests/stake.rs b/runtime/tests/stake.rs index bb71fd198a..66cbcba2bf 100644 --- a/runtime/tests/stake.rs +++ b/runtime/tests/stake.rs @@ -100,13 +100,10 @@ fn test_stake_create_and_split_single_signature() { solana_logger::setup(); let GenesisConfigInfo { - mut genesis_config, + genesis_config, mint_keypair: staker_keypair, .. } = create_genesis_config_with_leader(100_000_000_000, &Pubkey::new_rand(), 1_000_000); - genesis_config - .native_instruction_processors - .push(solana_stake_program::solana_stake_program!()); let staker_pubkey = staker_keypair.pubkey(); @@ -166,13 +163,10 @@ fn test_stake_account_lifetime() { let identity_pubkey = identity_keypair.pubkey(); let GenesisConfigInfo { - mut genesis_config, + genesis_config, mint_keypair, .. } = create_genesis_config_with_leader(100_000_000_000, &Pubkey::new_rand(), 1_000_000); - genesis_config - .native_instruction_processors - .push(solana_stake_program::solana_stake_program!()); let bank = Bank::new(&genesis_config); let mint_pubkey = mint_keypair.pubkey(); let mut bank = Arc::new(bank); @@ -403,13 +397,10 @@ fn test_create_stake_account_from_seed() { let identity_pubkey = identity_keypair.pubkey(); let GenesisConfigInfo { - mut genesis_config, + genesis_config, mint_keypair, .. } = create_genesis_config_with_leader(100_000_000_000, &Pubkey::new_rand(), 1_000_000); - genesis_config - .native_instruction_processors - .push(solana_stake_program::solana_stake_program!()); let bank = Bank::new(&genesis_config); let mint_pubkey = mint_keypair.pubkey(); let bank = Arc::new(bank); diff --git a/runtime/tests/storage.rs b/runtime/tests/storage.rs index f46d7538e9..3ed26b4409 100644 --- a/runtime/tests/storage.rs +++ b/runtime/tests/storage.rs @@ -45,7 +45,7 @@ fn test_account_owner() { } = create_genesis_config(1000); let mut bank = Bank::new(&genesis_config); let mint_pubkey = mint_keypair.pubkey(); - bank.add_instruction_processor(id(), process_instruction); + bank.add_static_program("storage_program", id(), process_instruction); let bank = Arc::new(bank); let bank_client = BankClient::new_shared(&bank); diff --git a/sdk/src/genesis_config.rs b/sdk/src/genesis_config.rs index 09e3737679..8627493f68 100644 --- a/sdk/src/genesis_config.rs +++ b/sdk/src/genesis_config.rs @@ -13,7 +13,7 @@ use crate::{ rent::Rent, shred_version::compute_shred_version, signature::{Keypair, Signer}, - system_program::{self, solana_system_program}, + system_program, }; use bincode::{deserialize, serialize}; use chrono::{TimeZone, Utc}; @@ -72,7 +72,7 @@ pub fn create_genesis_config(lamports: u64) -> (GenesisConfig, Keypair) { faucet_keypair.pubkey(), Account::new(lamports, 0, &system_program::id()), )], - &[solana_system_program()], + &[], ), faucet_keypair, ) diff --git a/sdk/src/system_program.rs b/sdk/src/system_program.rs index 8b1ce46811..867211b3a3 100644 --- a/sdk/src/system_program.rs +++ b/sdk/src/system_program.rs @@ -1,5 +1 @@ crate::declare_id!("11111111111111111111111111111111"); - -pub fn solana_system_program() -> (String, crate::pubkey::Pubkey) { - ("solana_system_program".to_string(), id()) -} diff --git a/stake-accounts/src/stake_accounts.rs b/stake-accounts/src/stake_accounts.rs index 5b01fd9b92..bebdf545e9 100644 --- a/stake-accounts/src/stake_accounts.rs +++ b/stake-accounts/src/stake_accounts.rs @@ -216,11 +216,7 @@ mod tests { fn create_bank(lamports: u64) -> (Bank, Keypair, u64) { let (genesis_config, mint_keypair) = create_genesis_config(lamports); - let mut bank = Bank::new(&genesis_config); - bank.add_instruction_processor( - solana_stake_program::id(), - solana_stake_program::stake_instruction::process_instruction, - ); + let bank = Bank::new(&genesis_config); let rent = bank.get_minimum_balance_for_rent_exemption(std::mem::size_of::()); (bank, mint_keypair, rent) }