diff --git a/Cargo.lock b/Cargo.lock index ad1180c6247e86..38141b6e43410f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -180,7 +180,7 @@ dependencies = [ "serde_yaml 0.8.26", "serde_yaml 0.9.34+deprecated", "solana-clap-utils", - "solana-config-program", + "solana-config-program-client", "solana-hash", "solana-keypair", "solana-logger", @@ -3874,6 +3874,16 @@ dependencies = [ "unicase", ] +[[package]] +name = "kaigan" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ba15de5aeb137f0f65aa3bf82187647f1285abfe5b20c80c2c37f7007ad519a" +dependencies = [ + "borsh 0.10.3", + "serde", +] + [[package]] name = "keccak" version = "0.1.5" @@ -6396,7 +6406,7 @@ dependencies = [ "solana-account", "solana-account-decoder-client-types", "solana-clock", - "solana-config-program", + "solana-config-program-client", "solana-epoch-schedule", "solana-fee-calculator", "solana-hash", @@ -6975,7 +6985,6 @@ dependencies = [ "solana-address-lookup-table-program", "solana-bpf-loader-program", "solana-compute-budget-program", - "solana-config-program", "solana-loader-v4-program", "solana-program-runtime", "solana-pubkey", @@ -6999,7 +7008,6 @@ dependencies = [ "solana-address-lookup-table-program", "solana-bpf-loader-program", "solana-compute-budget-program", - "solana-config-program", "solana-frozen-abi", "solana-loader-v4-program", "solana-pubkey", @@ -7142,7 +7150,7 @@ dependencies = [ "solana-commitment-config", "solana-compute-budget", "solana-compute-budget-interface", - "solana-config-program", + "solana-config-program-client", "solana-connection-cache", "solana-decode-error", "solana-epoch-schedule", @@ -7467,28 +7475,16 @@ dependencies = [ ] [[package]] -name = "solana-config-program" -version = "2.3.0" +name = "solana-config-program-client" +version = "0.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53aceac36f105fd4922e29b4f0c1f785b69d7b3e7e387e384b8985c8e0c3595e" dependencies = [ "bincode", - "chrono", + "borsh 0.10.3", + "kaigan", "serde", - "serde_derive", - "solana-account", - "solana-bincode", - "solana-instruction", - "solana-keypair", - "solana-log-collector", - "solana-logger", - "solana-packet", - "solana-program-runtime", - "solana-pubkey", - "solana-sdk-ids", - "solana-short-vec", - "solana-signer", - "solana-stake-interface", - "solana-system-interface", - "solana-transaction-context 2.3.0", + "solana-program", ] [[package]] @@ -8596,7 +8592,6 @@ dependencies = [ "serial_test", "solana-accounts-db", "solana-client", - "solana-config-program", "solana-core", "solana-download-utils", "solana-entry", @@ -9699,7 +9694,6 @@ dependencies = [ "solana-builtins", "solana-compute-budget", "solana-compute-budget-instruction", - "solana-config-program", "solana-cost-model", "solana-fee", "solana-frozen-abi", @@ -10163,7 +10157,7 @@ dependencies = [ "solana-bincode", "solana-clock", "solana-compute-budget", - "solana-config-program", + "solana-config-program-client", "solana-epoch-rewards", "solana-epoch-schedule", "solana-genesis-config", diff --git a/Cargo.toml b/Cargo.toml index ad4c6d9abceba5..267e09e6cdd2be 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -94,7 +94,6 @@ members = [ "programs/bpf_loader/gen-syscall-list", "programs/compute-budget", "programs/compute-budget-bench", - "programs/config", "programs/ed25519-tests", "programs/loader-v4", "programs/stake", @@ -406,7 +405,7 @@ solana-compute-budget = { path = "compute-budget", version = "=2.3.0" } solana-compute-budget-instruction = { path = "compute-budget-instruction", version = "=2.3.0" } solana-compute-budget-interface = "2.2.1" solana-compute-budget-program = { path = "programs/compute-budget", version = "=2.3.0" } -solana-config-program = { path = "programs/config", version = "=2.3.0" } +solana-config-program-client = "0.0.2" solana-connection-cache = { path = "connection-cache", version = "=2.3.0", default-features = false } solana-core = { path = "core", version = "=2.3.0" } solana-cost-model = { path = "cost-model", version = "=2.3.0" } diff --git a/account-decoder/Cargo.toml b/account-decoder/Cargo.toml index 27ed2e8f4621fc..6de3a8ff015505 100644 --- a/account-decoder/Cargo.toml +++ b/account-decoder/Cargo.toml @@ -22,7 +22,7 @@ serde_json = { workspace = true } solana-account = { workspace = true } solana-account-decoder-client-types = { workspace = true, features = ["zstd"] } solana-clock = { workspace = true } -solana-config-program = { workspace = true } +solana-config-program-client = { workspace = true, features = ["serde"] } solana-epoch-schedule = { workspace = true } solana-fee-calculator = { workspace = true } solana-instruction = { workspace = true } @@ -44,6 +44,7 @@ zstd = { workspace = true } [dev-dependencies] assert_matches = { workspace = true } +solana-account = { workspace = true, features = ["bincode"] } solana-hash = { workspace = true } solana-program = { workspace = true, default-features = false } solana-pubkey = { workspace = true, features = ["rand"] } diff --git a/account-decoder/src/parse_config.rs b/account-decoder/src/parse_config.rs index 89a2cc2176eaed..58252751e68bfd 100644 --- a/account-decoder/src/parse_config.rs +++ b/account-decoder/src/parse_config.rs @@ -5,7 +5,7 @@ use { }, bincode::deserialize, serde_json::Value, - solana_config_program::{get_config_data, ConfigKeys}, + solana_config_program_client::{get_config_data, ConfigKeys}, solana_program::stake::config::{ Config as StakeConfig, {self as stake_config}, }, @@ -96,10 +96,29 @@ pub struct UiConfig { #[cfg(test)] mod test { use { - super::*, crate::validator_info::ValidatorInfo, serde_json::json, - solana_account::ReadableAccount, solana_config_program::create_config_account, + super::*, + crate::validator_info::ValidatorInfo, + bincode::serialize, + serde_json::json, + solana_account::{Account, AccountSharedData, ReadableAccount}, + solana_config_program_client::ConfigKeys, }; + fn create_config_account( + keys: Vec<(Pubkey, bool)>, + config_data: &T, + lamports: u64, + ) -> AccountSharedData { + let mut data = serialize(&ConfigKeys { keys }).unwrap(); + data.extend_from_slice(&serialize(config_data).unwrap()); + AccountSharedData::from(Account { + lamports, + data, + owner: solana_sdk_ids::config::id(), + ..Account::default() + }) + } + #[test] fn test_parse_config() { let stake_config = StakeConfig { diff --git a/account-decoder/src/validator_info.rs b/account-decoder/src/validator_info.rs index 3b616a060dcdc5..9d35b6d75cfa89 100644 --- a/account-decoder/src/validator_info.rs +++ b/account-decoder/src/validator_info.rs @@ -1,4 +1,4 @@ -use solana_config_program::ConfigState; +use solana_config_program_client::instructions_bincode::ConfigState; pub const MAX_SHORT_FIELD_LENGTH: usize = 80; pub const MAX_LONG_FIELD_LENGTH: usize = 300; diff --git a/builtins-default-costs/Cargo.toml b/builtins-default-costs/Cargo.toml index 5df1c863d8b5dc..a407803791c9f8 100644 --- a/builtins-default-costs/Cargo.toml +++ b/builtins-default-costs/Cargo.toml @@ -17,7 +17,6 @@ log = { workspace = true } solana-address-lookup-table-program = { workspace = true } solana-bpf-loader-program = { workspace = true } solana-compute-budget-program = { workspace = true } -solana-config-program = { workspace = true } solana-frozen-abi = { workspace = true, optional = true, features = [ "frozen-abi", ] } diff --git a/builtins-default-costs/src/lib.rs b/builtins-default-costs/src/lib.rs index 278ae51fce233e..1f77b5443a1575 100644 --- a/builtins-default-costs/src/lib.rs +++ b/builtins-default-costs/src/lib.rs @@ -7,8 +7,7 @@ use { solana_pubkey::Pubkey, solana_sdk_ids::{ address_lookup_table, bpf_loader, bpf_loader_deprecated, bpf_loader_upgradeable, - compute_budget, config, ed25519_program, loader_v4, secp256k1_program, stake, - system_program, vote, + compute_budget, ed25519_program, loader_v4, secp256k1_program, stake, system_program, vote, }, }; @@ -102,7 +101,7 @@ lazy_static! { /// correctly furnishing `core_bpf_migration_feature`. /// #[allow(dead_code)] -const TOTAL_COUNT_BUILTINS: usize = 12; +const TOTAL_COUNT_BUILTINS: usize = 11; #[cfg(test)] static_assertions::const_assert_eq!( MIGRATING_BUILTINS_COSTS.len() + NON_MIGRATING_BUILTINS_COSTS.len(), @@ -118,21 +117,13 @@ pub const MIGRATING_BUILTINS_COSTS: &[(Pubkey, BuiltinCost)] = &[ position: 0, }), ), - ( - config::id(), - BuiltinCost::Migrating(MigratingBuiltinCost { - native_cost: solana_config_program::config_processor::DEFAULT_COMPUTE_UNITS, - core_bpf_migration_feature: feature_set::migrate_config_program_to_core_bpf::id(), - position: 1, - }), - ), ( address_lookup_table::id(), BuiltinCost::Migrating(MigratingBuiltinCost { native_cost: solana_address_lookup_table_program::processor::DEFAULT_COMPUTE_UNITS, core_bpf_migration_feature: feature_set::migrate_address_lookup_table_program_to_core_bpf::id(), - position: 2, + position: 1, }), ), ]; @@ -340,20 +331,6 @@ mod test { get_migration_feature_id(feature_index), &feature_set::migrate_stake_program_to_core_bpf::id() ); - let feature_index = get_builtin_migration_feature_index(&config::id()); - assert!(matches!( - feature_index, - BuiltinMigrationFeatureIndex::BuiltinWithMigrationFeature(_) - )); - let BuiltinMigrationFeatureIndex::BuiltinWithMigrationFeature(feature_index) = - feature_index - else { - panic!("expect migrating builtin") - }; - assert_eq!( - get_migration_feature_id(feature_index), - &feature_set::migrate_config_program_to_core_bpf::id() - ); let feature_index = get_builtin_migration_feature_index(&address_lookup_table::id()); assert!(matches!( feature_index, diff --git a/builtins/Cargo.toml b/builtins/Cargo.toml index d068d9088ae83e..ff081555d91f7a 100644 --- a/builtins/Cargo.toml +++ b/builtins/Cargo.toml @@ -17,7 +17,6 @@ agave-feature-set = { workspace = true } solana-address-lookup-table-program = { workspace = true } solana-bpf-loader-program = { workspace = true } solana-compute-budget-program = { workspace = true } -solana-config-program = { workspace = true } solana-loader-v4-program = { workspace = true } solana-program-runtime = { workspace = true } solana-pubkey = { workspace = true } diff --git a/builtins/src/lib.rs b/builtins/src/lib.rs index 86867e2b9c05fa..5a2be4e79d1f67 100644 --- a/builtins/src/lib.rs +++ b/builtins/src/lib.rs @@ -77,19 +77,6 @@ pub static BUILTINS: &[BuiltinPrototype] = &[ program_id: solana_stake_program::id(), entrypoint: solana_stake_program::stake_instruction::Entrypoint::vm, }, - BuiltinPrototype { - core_bpf_migration_config: Some(CoreBpfMigrationConfig { - source_buffer_address: buffer_accounts::config_program::id(), - upgrade_authority_address: None, - feature_id: agave_feature_set::migrate_config_program_to_core_bpf::id(), - migration_target: CoreBpfMigrationTargetType::Builtin, - datapoint_name: "migrate_builtin_to_core_bpf_config_program", - }), - name: "config_program", - enable_feature_id: None, - program_id: solana_config_program::id(), - entrypoint: solana_config_program::config_processor::Entrypoint::vm, - }, testable_prototype!(BuiltinPrototype { core_bpf_migration_config: None, name: solana_bpf_loader_deprecated_program, @@ -161,9 +148,6 @@ mod buffer_accounts { pub mod address_lookup_table_program { solana_pubkey::declare_id!("AhXWrD9BBUYcKjtpA3zuiiZG4ysbo6C6wjHo1QhERk6A"); } - pub mod config_program { - solana_pubkey::declare_id!("BuafH9fBv62u6XjzrzS4ZjAE8963ejqF5rt1f8Uga4Q3"); - } pub mod stake_program { solana_pubkey::declare_id!("8t3vv6v99tQA6Gp7fVdsBH66hQMaswH5qsJVqJqo8xvG"); } @@ -368,36 +352,34 @@ mod tests { ); // Stake has a live migration config, so it has no test-only configs // to test here. - // Config has a live migration config, so it has no test-only configs - // to test here. assert_eq!( - &super::BUILTINS[4].core_bpf_migration_config, + &super::BUILTINS[3].core_bpf_migration_config, &Some(super::test_only::solana_bpf_loader_deprecated_program::CONFIG) ); assert_eq!( - &super::BUILTINS[5].core_bpf_migration_config, + &super::BUILTINS[4].core_bpf_migration_config, &Some(super::test_only::solana_bpf_loader_program::CONFIG) ); assert_eq!( - &super::BUILTINS[6].core_bpf_migration_config, + &super::BUILTINS[5].core_bpf_migration_config, &Some(super::test_only::solana_bpf_loader_upgradeable_program::CONFIG) ); assert_eq!( - &super::BUILTINS[7].core_bpf_migration_config, + &super::BUILTINS[6].core_bpf_migration_config, &Some(super::test_only::compute_budget_program::CONFIG) ); // Address Lookup Table has a live migration config, so it has no // test-only configs to test here. assert_eq!( - &super::BUILTINS[9].core_bpf_migration_config, + &super::BUILTINS[8].core_bpf_migration_config, &Some(super::test_only::zk_token_proof_program::CONFIG) ); assert_eq!( - &super::BUILTINS[10].core_bpf_migration_config, + &super::BUILTINS[9].core_bpf_migration_config, &Some(super::test_only::loader_v4::CONFIG) ); assert_eq!( - &super::BUILTINS[11].core_bpf_migration_config, + &super::BUILTINS[10].core_bpf_migration_config, &Some(super::test_only::zk_elgamal_proof_program::CONFIG) ); } diff --git a/cli/Cargo.toml b/cli/Cargo.toml index 9cb28d57034977..d7b98761a12139 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -42,7 +42,7 @@ solana-cluster-type = "=2.2.1" solana-commitment-config = "=2.2.1" solana-compute-budget = { workspace = true } solana-compute-budget-interface = { version = "=2.2.1", features = ["borsh"] } -solana-config-program = { workspace = true } +solana-config-program-client = { workspace = true, features = ["serde"] } solana-connection-cache = { workspace = true } solana-decode-error = "=2.2.1" solana-epoch-schedule = "=2.2.1" diff --git a/cli/src/validator_info.rs b/cli/src/validator_info.rs index 70dea42e48cc6a..950710450d6f35 100644 --- a/cli/src/validator_info.rs +++ b/cli/src/validator_info.rs @@ -20,7 +20,11 @@ use { keypair::DefaultSigner, }, solana_cli_output::{CliValidatorInfo, CliValidatorInfoVec}, - solana_config_program::{config_instruction, get_config_data, ConfigKeys, ConfigState}, + solana_config_program_client::{ + get_config_data, + instructions_bincode::{self as config_instruction, ConfigState}, + ConfigKeys, + }, solana_keypair::Keypair, solana_message::Message, solana_pubkey::Pubkey, @@ -129,7 +133,7 @@ fn parse_validator_info( pubkey: &Pubkey, account: &Account, ) -> Result<(Pubkey, Map), Box> { - if account.owner != solana_config_program::id() { + if account.owner != solana_config_program_client::ID { return Err(format!("{pubkey} is not a validator info account").into()); } let key_list: ConfigKeys = deserialize(&account.data)?; @@ -302,7 +306,7 @@ pub fn process_set_validator_info( } // Check for existing validator-info account - let all_config = rpc_client.get_program_accounts(&solana_config_program::id())?; + let all_config = rpc_client.get_program_accounts(&solana_config_program_client::ID)?; let existing_account = all_config .iter() .filter( @@ -334,7 +338,7 @@ pub fn process_set_validator_info( (config.signers[0].pubkey(), true), ]; let data_len = ValidatorInfo::max_space() - .checked_add(ConfigKeys::serialized_size(keys.clone())) + .checked_add(serialized_size(&ConfigKeys { keys: keys.clone() }).unwrap()) .expect("ValidatorInfo and two keys fit into a u64"); let lamports = rpc_client.get_minimum_balance_for_rent_exemption(data_len as usize)?; @@ -429,7 +433,7 @@ pub fn process_get_validator_info( rpc_client.get_account(&validator_info_pubkey)?, )] } else { - let all_config = rpc_client.get_program_accounts(&solana_config_program::id())?; + let all_config = rpc_client.get_program_accounts(&solana_config_program_client::ID)?; all_config .into_iter() .filter(|(_, validator_info_account)| { @@ -583,7 +587,7 @@ mod tests { parse_validator_info( &Pubkey::default(), &Account { - owner: solana_config_program::id(), + owner: solana_config_program_client::ID, data, ..Account::default() } @@ -618,7 +622,7 @@ mod tests { assert!(parse_validator_info( &Pubkey::default(), &Account { - owner: solana_config_program::id(), + owner: solana_config_program_client::ID, data, ..Account::default() }, diff --git a/compute-budget-instruction/src/builtin_programs_filter.rs b/compute-budget-instruction/src/builtin_programs_filter.rs index c8dcc212779119..4813918a20cb64 100644 --- a/compute-budget-instruction/src/builtin_programs_filter.rs +++ b/compute-budget-instruction/src/builtin_programs_filter.rs @@ -115,10 +115,6 @@ mod test { solana_sdk_ids::stake::id(), feature_set::migrate_stake_program_to_core_bpf::id(), ), - ( - solana_sdk_ids::config::id(), - feature_set::migrate_config_program_to_core_bpf::id(), - ), ( solana_sdk_ids::address_lookup_table::id(), feature_set::migrate_address_lookup_table_program_to_core_bpf::id(), diff --git a/install/Cargo.toml b/install/Cargo.toml index 76cee4063e1bb7..57e93650ace397 100644 --- a/install/Cargo.toml +++ b/install/Cargo.toml @@ -30,7 +30,7 @@ serde_derive = { workspace = true } serde_yaml = { workspace = true } serde_yaml_08 = { package = "serde_yaml", version = "0.8.26" } solana-clap-utils = { workspace = true } -solana-config-program = { workspace = true } +solana-config-program-client = { workspace = true, features = ["serde"] } solana-hash = "=2.2.1" solana-keypair = "=2.2.1" solana-logger = "=2.3.1" diff --git a/install/src/command.rs b/install/src/command.rs index 617d4d1c2724c1..8e2ec34892fe35 100644 --- a/install/src/command.rs +++ b/install/src/command.rs @@ -9,7 +9,10 @@ use { crossbeam_channel::unbounded, indicatif::{ProgressBar, ProgressStyle}, serde_derive::{Deserialize, Serialize}, - solana_config_program::{config_instruction, get_config_data, ConfigState}, + solana_config_program_client::{ + get_config_data, + instructions_bincode::{self as config_instruction, ConfigState}, + }, solana_hash::Hash, solana_keypair::{read_keypair_file, signable::Signable, Keypair}, solana_message::Message, diff --git a/install/src/update_manifest.rs b/install/src/update_manifest.rs index 32d1cab6eb64e6..f86a2979ebebbe 100644 --- a/install/src/update_manifest.rs +++ b/install/src/update_manifest.rs @@ -1,6 +1,6 @@ use { serde_derive::{Deserialize, Serialize}, - solana_config_program::ConfigState, + solana_config_program_client::instructions_bincode::ConfigState, solana_hash::Hash, solana_keypair::signable::Signable, solana_pubkey::Pubkey, diff --git a/local-cluster/Cargo.toml b/local-cluster/Cargo.toml index 82104121a2f80a..2ff058d4032c08 100644 --- a/local-cluster/Cargo.toml +++ b/local-cluster/Cargo.toml @@ -17,7 +17,6 @@ rand = { workspace = true } rayon = { workspace = true } solana-accounts-db = { workspace = true } solana-client = { workspace = true } -solana-config-program = { workspace = true } solana-core = { workspace = true } solana-entry = { workspace = true } solana-gossip = { workspace = true } diff --git a/local-cluster/tests/local_cluster.rs b/local-cluster/tests/local_cluster.rs index fafc5f383afef2..f25c659a44ac4e 100644 --- a/local-cluster/tests/local_cluster.rs +++ b/local-cluster/tests/local_cluster.rs @@ -435,7 +435,6 @@ fn test_mainnet_beta_cluster_type() { // Programs that are available at epoch 0 for program_id in [ - &solana_config_program::id(), &solana_sdk::system_program::id(), &solana_sdk::stake::program::id(), &solana_vote_program::id(), diff --git a/program-test/src/programs.rs b/program-test/src/programs.rs index dbee33c63ebec1..ba0159560909b0 100644 --- a/program-test/src/programs.rs +++ b/program-test/src/programs.rs @@ -56,7 +56,7 @@ static CORE_BPF_PROGRAMS: &[(Pubkey, Option, &[u8])] = &[ ), ( solana_sdk_ids::config::ID, - Some(feature_set::migrate_config_program_to_core_bpf::ID), + None, include_bytes!("programs/core_bpf_config-3.0.0.so"), ), ( diff --git a/programs/config/Cargo.toml b/programs/config/Cargo.toml deleted file mode 100644 index bb3fc16c26476b..00000000000000 --- a/programs/config/Cargo.toml +++ /dev/null @@ -1,40 +0,0 @@ -[package] -name = "solana-config-program" -description = "Solana Config program" -documentation = "https://docs.rs/solana-config-program" -version = { workspace = true } -authors = { workspace = true } -repository = { workspace = true } -homepage = { workspace = true } -license = { workspace = true } -edition = { workspace = true } - -[dependencies] -bincode = { workspace = true } -chrono = { workspace = true, features = ["default", "serde"] } -serde = { workspace = true } -serde_derive = { workspace = true } -solana-account = { workspace = true } -solana-bincode = { workspace = true } -solana-instruction = { workspace = true } -solana-log-collector = { workspace = true } -solana-packet = { workspace = true } -solana-program-runtime = { workspace = true } -solana-pubkey = { workspace = true } -solana-sdk-ids = { workspace = true } -solana-short-vec = { workspace = true } -solana-stake-interface = { workspace = true } -solana-system-interface = { workspace = true } -solana-transaction-context = { workspace = true } - -[dev-dependencies] -solana-keypair = { workspace = true } -solana-logger = { workspace = true } -solana-signer = { workspace = true } - -[lib] -crate-type = ["lib"] -name = "solana_config_program" - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] diff --git a/programs/config/src/config_instruction.rs b/programs/config/src/config_instruction.rs deleted file mode 100644 index ae411d5669c109..00000000000000 --- a/programs/config/src/config_instruction.rs +++ /dev/null @@ -1,49 +0,0 @@ -use { - crate::{id, ConfigKeys, ConfigState}, - solana_instruction::{AccountMeta, Instruction}, - solana_pubkey::Pubkey, - solana_system_interface::instruction as system_instruction, -}; - -fn initialize_account(config_pubkey: &Pubkey) -> Instruction { - let account_metas = vec![AccountMeta::new(*config_pubkey, true)]; - let account_data = (ConfigKeys { keys: vec![] }, T::default()); - Instruction::new_with_bincode(id(), &account_data, account_metas) -} - -/// Create a new, empty configuration account -pub fn create_account( - from_account_pubkey: &Pubkey, - config_account_pubkey: &Pubkey, - lamports: u64, - keys: Vec<(Pubkey, bool)>, -) -> Vec { - let space = T::max_space() + ConfigKeys::serialized_size(keys); - vec![ - system_instruction::create_account( - from_account_pubkey, - config_account_pubkey, - lamports, - space, - &id(), - ), - initialize_account::(config_account_pubkey), - ] -} - -/// Store new data in a configuration account -pub fn store( - config_account_pubkey: &Pubkey, - is_config_signer: bool, - keys: Vec<(Pubkey, bool)>, - data: &T, -) -> Instruction { - let mut account_metas = vec![AccountMeta::new(*config_account_pubkey, is_config_signer)]; - for (signer_pubkey, _) in keys.iter().filter(|(_, is_signer)| *is_signer) { - if signer_pubkey != config_account_pubkey { - account_metas.push(AccountMeta::new(*signer_pubkey, true)); - } - } - let account_data = (ConfigKeys { keys }, data); - Instruction::new_with_bincode(id(), &account_data, account_metas) -} diff --git a/programs/config/src/config_processor.rs b/programs/config/src/config_processor.rs deleted file mode 100644 index c7d7d45ebaf030..00000000000000 --- a/programs/config/src/config_processor.rs +++ /dev/null @@ -1,848 +0,0 @@ -//! Config program - -use { - crate::ConfigKeys, bincode::deserialize, solana_bincode::limited_deserialize, - solana_instruction::error::InstructionError, solana_log_collector::ic_msg, - solana_program_runtime::declare_process_instruction, solana_pubkey::Pubkey, - solana_transaction_context::IndexOfAccount, std::collections::BTreeSet, -}; - -pub const DEFAULT_COMPUTE_UNITS: u64 = 450; - -declare_process_instruction!(Entrypoint, DEFAULT_COMPUTE_UNITS, |invoke_context| { - let transaction_context = &invoke_context.transaction_context; - let instruction_context = transaction_context.get_current_instruction_context()?; - let data = instruction_context.get_instruction_data(); - - let key_list: ConfigKeys = limited_deserialize(data, solana_packet::PACKET_DATA_SIZE as u64)?; - let config_account_key = transaction_context.get_key_of_account_at_index( - instruction_context.get_index_of_instruction_account_in_transaction(0)?, - )?; - let config_account = - instruction_context.try_borrow_instruction_account(transaction_context, 0)?; - let is_config_account_signer = config_account.is_signer(); - let current_data: ConfigKeys = { - if config_account.get_owner() != &crate::id() { - return Err(InstructionError::InvalidAccountOwner); - } - - deserialize(config_account.get_data()).map_err(|err| { - ic_msg!( - invoke_context, - "Unable to deserialize config account: {}", - err - ); - InstructionError::InvalidAccountData - })? - }; - drop(config_account); - - let current_signer_keys: Vec = current_data - .keys - .iter() - .filter(|(_, is_signer)| *is_signer) - .map(|(pubkey, _)| *pubkey) - .collect(); - if current_signer_keys.is_empty() { - // Config account keypair must be a signer on account initialization, - // or when no signers specified in Config data - if !is_config_account_signer { - return Err(InstructionError::MissingRequiredSignature); - } - } - - let mut counter = 0; - for (signer, _) in key_list.keys.iter().filter(|(_, is_signer)| *is_signer) { - counter += 1; - if signer != config_account_key { - let signer_account = instruction_context - .try_borrow_instruction_account(transaction_context, counter as IndexOfAccount) - .map_err(|_| { - ic_msg!( - invoke_context, - "account {:?} is not in account list", - signer, - ); - InstructionError::MissingRequiredSignature - })?; - if !signer_account.is_signer() { - ic_msg!( - invoke_context, - "account {:?} signer_key().is_none()", - signer - ); - return Err(InstructionError::MissingRequiredSignature); - } - if signer_account.get_key() != signer { - ic_msg!( - invoke_context, - "account[{:?}].signer_key() does not match Config data)", - counter + 1 - ); - return Err(InstructionError::MissingRequiredSignature); - } - // If Config account is already initialized, update signatures must match Config data - if !current_data.keys.is_empty() - && !current_signer_keys.iter().any(|pubkey| pubkey == signer) - { - ic_msg!( - invoke_context, - "account {:?} is not in stored signer list", - signer - ); - return Err(InstructionError::MissingRequiredSignature); - } - } else if !is_config_account_signer { - ic_msg!(invoke_context, "account[0].signer_key().is_none()"); - return Err(InstructionError::MissingRequiredSignature); - } - } - - // dedupe signers - let total_new_keys = key_list.keys.len(); - let unique_new_keys = key_list.keys.into_iter().collect::>(); - if unique_new_keys.len() != total_new_keys { - ic_msg!(invoke_context, "new config contains duplicate keys"); - return Err(InstructionError::InvalidArgument); - } - - // Check for Config data signers not present in incoming account update - if current_signer_keys.len() > counter { - ic_msg!( - invoke_context, - "too few signers: {:?}; expected: {:?}", - counter, - current_signer_keys.len() - ); - return Err(InstructionError::MissingRequiredSignature); - } - - let mut config_account = - instruction_context.try_borrow_instruction_account(transaction_context, 0)?; - if config_account.get_data().len() < data.len() { - ic_msg!(invoke_context, "instruction data too large"); - return Err(InstructionError::InvalidInstructionData); - } - config_account.get_data_mut()?[..data.len()].copy_from_slice(data); - Ok(()) -}); - -#[cfg(test)] -mod tests { - use { - super::*, - crate::{config_instruction, get_config_data, id, ConfigKeys, ConfigState}, - bincode::serialized_size, - serde_derive::{Deserialize, Serialize}, - solana_account::{AccountSharedData, ReadableAccount}, - solana_instruction::AccountMeta, - solana_keypair::Keypair, - solana_program_runtime::invoke_context::mock_process_instruction, - solana_pubkey::Pubkey, - solana_signer::Signer, - solana_system_interface::instruction::SystemInstruction, - }; - - fn process_instruction( - instruction_data: &[u8], - transaction_accounts: Vec<(Pubkey, AccountSharedData)>, - instruction_accounts: Vec, - expected_result: Result<(), InstructionError>, - ) -> Vec { - mock_process_instruction( - &id(), - Vec::new(), - instruction_data, - transaction_accounts, - instruction_accounts, - expected_result, - Entrypoint::vm, - |_invoke_context| {}, - |_invoke_context| {}, - ) - } - - #[derive(Serialize, Deserialize, Debug, PartialEq, Eq)] - struct MyConfig { - pub item: u64, - } - impl Default for MyConfig { - fn default() -> Self { - Self { item: 123_456_789 } - } - } - impl MyConfig { - pub fn new(item: u64) -> Self { - Self { item } - } - pub fn deserialize(input: &[u8]) -> Option { - deserialize(input).ok() - } - } - - impl ConfigState for MyConfig { - fn max_space() -> u64 { - serialized_size(&Self::default()).unwrap() - } - } - - fn create_config_account(keys: Vec<(Pubkey, bool)>) -> (Keypair, AccountSharedData) { - let from_pubkey = Pubkey::new_unique(); - let config_keypair = Keypair::new(); - let config_pubkey = config_keypair.pubkey(); - let instructions = - config_instruction::create_account::(&from_pubkey, &config_pubkey, 1, keys); - let system_instruction = limited_deserialize( - &instructions[0].data, - solana_packet::PACKET_DATA_SIZE as u64, - ) - .unwrap(); - let SystemInstruction::CreateAccount { - lamports: _, - space, - owner: _, - } = system_instruction - else { - panic!("Not a CreateAccount system instruction") - }; - let config_account = AccountSharedData::new(0, space as usize, &id()); - let accounts = process_instruction( - &instructions[1].data, - vec![(config_pubkey, config_account)], - vec![AccountMeta { - pubkey: config_pubkey, - is_signer: true, - is_writable: true, - }], - Ok(()), - ); - (config_keypair, accounts[0].clone()) - } - - #[test] - fn test_process_create_ok() { - solana_logger::setup(); - let (_, config_account) = create_config_account(vec![]); - assert_eq!( - Some(MyConfig::default()), - deserialize(get_config_data(config_account.data()).unwrap()).ok() - ); - } - - #[test] - fn test_process_store_ok() { - solana_logger::setup(); - let keys = vec![]; - let (config_keypair, config_account) = create_config_account(keys.clone()); - let config_pubkey = config_keypair.pubkey(); - let my_config = MyConfig::new(42); - - let instruction = config_instruction::store(&config_pubkey, true, keys, &my_config); - let accounts = process_instruction( - &instruction.data, - vec![(config_pubkey, config_account)], - vec![AccountMeta { - pubkey: config_pubkey, - is_signer: true, - is_writable: true, - }], - Ok(()), - ); - assert_eq!( - Some(my_config), - deserialize(get_config_data(accounts[0].data()).unwrap()).ok() - ); - } - - #[test] - fn test_process_store_fail_instruction_data_too_large() { - solana_logger::setup(); - let keys = vec![]; - let (config_keypair, config_account) = create_config_account(keys.clone()); - let config_pubkey = config_keypair.pubkey(); - let my_config = MyConfig::new(42); - - let mut instruction = config_instruction::store(&config_pubkey, true, keys, &my_config); - instruction.data = vec![0; 123]; // <-- Replace data with a vector that's too large - process_instruction( - &instruction.data, - vec![(config_pubkey, config_account)], - vec![AccountMeta { - pubkey: config_pubkey, - is_signer: true, - is_writable: true, - }], - Err(InstructionError::InvalidInstructionData), - ); - } - - #[test] - fn test_process_store_fail_account0_not_signer() { - solana_logger::setup(); - let keys = vec![]; - let (config_keypair, config_account) = create_config_account(keys); - let config_pubkey = config_keypair.pubkey(); - let my_config = MyConfig::new(42); - - let mut instruction = config_instruction::store(&config_pubkey, true, vec![], &my_config); - instruction.accounts[0].is_signer = false; // <----- not a signer - process_instruction( - &instruction.data, - vec![(config_pubkey, config_account)], - vec![AccountMeta { - pubkey: config_pubkey, - is_signer: false, - is_writable: true, - }], - Err(InstructionError::MissingRequiredSignature), - ); - } - - #[test] - fn test_process_store_with_additional_signers() { - solana_logger::setup(); - let pubkey = Pubkey::new_unique(); - let signer0_pubkey = Pubkey::new_unique(); - let signer1_pubkey = Pubkey::new_unique(); - let keys = vec![ - (pubkey, false), - (signer0_pubkey, true), - (signer1_pubkey, true), - ]; - let (config_keypair, config_account) = create_config_account(keys.clone()); - let config_pubkey = config_keypair.pubkey(); - let my_config = MyConfig::new(42); - let signer0_account = AccountSharedData::new(0, 0, &Pubkey::new_unique()); - let signer1_account = AccountSharedData::new(0, 0, &Pubkey::new_unique()); - - let instruction = config_instruction::store(&config_pubkey, true, keys.clone(), &my_config); - let accounts = process_instruction( - &instruction.data, - vec![ - (config_pubkey, config_account), - (signer0_pubkey, signer0_account), - (signer1_pubkey, signer1_account), - ], - vec![ - AccountMeta { - pubkey: config_pubkey, - is_signer: true, - is_writable: true, - }, - AccountMeta { - pubkey: signer0_pubkey, - is_signer: true, - is_writable: false, - }, - AccountMeta { - pubkey: signer1_pubkey, - is_signer: true, - is_writable: false, - }, - ], - Ok(()), - ); - let meta_data: ConfigKeys = deserialize(accounts[0].data()).unwrap(); - assert_eq!(meta_data.keys, keys); - assert_eq!( - Some(my_config), - deserialize(get_config_data(accounts[0].data()).unwrap()).ok() - ); - } - - #[test] - fn test_process_store_without_config_signer() { - solana_logger::setup(); - let pubkey = Pubkey::new_unique(); - let signer0_pubkey = Pubkey::new_unique(); - let keys = vec![(pubkey, false), (signer0_pubkey, true)]; - let (config_keypair, _) = create_config_account(keys.clone()); - let config_pubkey = config_keypair.pubkey(); - let my_config = MyConfig::new(42); - let signer0_account = AccountSharedData::new(0, 0, &id()); - - let instruction = config_instruction::store(&config_pubkey, false, keys, &my_config); - process_instruction( - &instruction.data, - vec![(signer0_pubkey, signer0_account)], - vec![AccountMeta { - pubkey: signer0_pubkey, - is_signer: true, - is_writable: false, - }], - Err(InstructionError::InvalidAccountData), - ); - } - - #[test] - fn test_process_store_with_bad_additional_signer() { - solana_logger::setup(); - let signer0_pubkey = Pubkey::new_unique(); - let signer1_pubkey = Pubkey::new_unique(); - let signer0_account = AccountSharedData::new(0, 0, &Pubkey::new_unique()); - let signer1_account = AccountSharedData::new(0, 0, &Pubkey::new_unique()); - let keys = vec![(signer0_pubkey, true)]; - let (config_keypair, config_account) = create_config_account(keys.clone()); - let config_pubkey = config_keypair.pubkey(); - let my_config = MyConfig::new(42); - - // Config-data pubkey doesn't match signer - let instruction = config_instruction::store(&config_pubkey, true, keys, &my_config); - process_instruction( - &instruction.data, - vec![ - (config_pubkey, config_account.clone()), - (signer1_pubkey, signer1_account), - ], - vec![ - AccountMeta { - pubkey: config_pubkey, - is_signer: true, - is_writable: true, - }, - AccountMeta { - pubkey: signer1_pubkey, - is_signer: true, - is_writable: false, - }, - ], - Err(InstructionError::MissingRequiredSignature), - ); - - // Config-data pubkey not a signer - process_instruction( - &instruction.data, - vec![ - (config_pubkey, config_account), - (signer0_pubkey, signer0_account), - ], - vec![ - AccountMeta { - pubkey: config_pubkey, - is_signer: true, - is_writable: true, - }, - AccountMeta { - pubkey: signer0_pubkey, - is_signer: false, - is_writable: false, - }, - ], - Err(InstructionError::MissingRequiredSignature), - ); - } - - #[test] - fn test_config_updates() { - solana_logger::setup(); - let pubkey = Pubkey::new_unique(); - let signer0_pubkey = Pubkey::new_unique(); - let signer1_pubkey = Pubkey::new_unique(); - let signer2_pubkey = Pubkey::new_unique(); - let signer0_account = AccountSharedData::new(0, 0, &Pubkey::new_unique()); - let signer1_account = AccountSharedData::new(0, 0, &Pubkey::new_unique()); - let signer2_account = AccountSharedData::new(0, 0, &Pubkey::new_unique()); - let keys = vec![ - (pubkey, false), - (signer0_pubkey, true), - (signer1_pubkey, true), - ]; - let (config_keypair, config_account) = create_config_account(keys.clone()); - let config_pubkey = config_keypair.pubkey(); - let my_config = MyConfig::new(42); - - let instruction = config_instruction::store(&config_pubkey, true, keys.clone(), &my_config); - let accounts = process_instruction( - &instruction.data, - vec![ - (config_pubkey, config_account), - (signer0_pubkey, signer0_account.clone()), - (signer1_pubkey, signer1_account.clone()), - ], - vec![ - AccountMeta { - pubkey: config_pubkey, - is_signer: true, - is_writable: true, - }, - AccountMeta { - pubkey: signer0_pubkey, - is_signer: true, - is_writable: false, - }, - AccountMeta { - pubkey: signer1_pubkey, - is_signer: true, - is_writable: false, - }, - ], - Ok(()), - ); - - // Update with expected signatures - let new_config = MyConfig::new(84); - let instruction = - config_instruction::store(&config_pubkey, false, keys.clone(), &new_config); - let accounts = process_instruction( - &instruction.data, - vec![ - (config_pubkey, accounts[0].clone()), - (signer0_pubkey, signer0_account.clone()), - (signer1_pubkey, signer1_account.clone()), - ], - vec![ - AccountMeta { - pubkey: config_pubkey, - is_signer: false, - is_writable: true, - }, - AccountMeta { - pubkey: signer0_pubkey, - is_signer: true, - is_writable: false, - }, - AccountMeta { - pubkey: signer1_pubkey, - is_signer: true, - is_writable: false, - }, - ], - Ok(()), - ); - let meta_data: ConfigKeys = deserialize(accounts[0].data()).unwrap(); - assert_eq!(meta_data.keys, keys); - assert_eq!( - new_config, - MyConfig::deserialize(get_config_data(accounts[0].data()).unwrap()).unwrap() - ); - - // Attempt update with incomplete signatures - let keys = vec![(pubkey, false), (signer0_pubkey, true)]; - let instruction = config_instruction::store(&config_pubkey, false, keys, &my_config); - process_instruction( - &instruction.data, - vec![ - (config_pubkey, accounts[0].clone()), - (signer0_pubkey, signer0_account.clone()), - (signer1_pubkey, signer1_account), - ], - vec![ - AccountMeta { - pubkey: config_pubkey, - is_signer: false, - is_writable: true, - }, - AccountMeta { - pubkey: signer0_pubkey, - is_signer: true, - is_writable: false, - }, - AccountMeta { - pubkey: signer1_pubkey, - is_signer: false, - is_writable: false, - }, - ], - Err(InstructionError::MissingRequiredSignature), - ); - - // Attempt update with incorrect signatures - let keys = vec![ - (pubkey, false), - (signer0_pubkey, true), - (signer2_pubkey, true), - ]; - let instruction = config_instruction::store(&config_pubkey, false, keys, &my_config); - process_instruction( - &instruction.data, - vec![ - (config_pubkey, accounts[0].clone()), - (signer0_pubkey, signer0_account), - (signer2_pubkey, signer2_account), - ], - vec![ - AccountMeta { - pubkey: config_pubkey, - is_signer: false, - is_writable: true, - }, - AccountMeta { - pubkey: signer0_pubkey, - is_signer: true, - is_writable: false, - }, - AccountMeta { - pubkey: signer2_pubkey, - is_signer: true, - is_writable: false, - }, - ], - Err(InstructionError::MissingRequiredSignature), - ); - } - - #[test] - fn test_config_initialize_contains_duplicates_fails() { - solana_logger::setup(); - let config_address = Pubkey::new_unique(); - let signer0_pubkey = Pubkey::new_unique(); - let signer0_account = AccountSharedData::new(0, 0, &Pubkey::new_unique()); - let keys = vec![ - (config_address, false), - (signer0_pubkey, true), - (signer0_pubkey, true), - ]; - let (config_keypair, config_account) = create_config_account(keys.clone()); - let config_pubkey = config_keypair.pubkey(); - let my_config = MyConfig::new(42); - - // Attempt initialization with duplicate signer inputs - let instruction = config_instruction::store(&config_pubkey, true, keys, &my_config); - process_instruction( - &instruction.data, - vec![ - (config_pubkey, config_account), - (signer0_pubkey, signer0_account), - ], - vec![ - AccountMeta { - pubkey: config_pubkey, - is_signer: true, - is_writable: true, - }, - AccountMeta { - pubkey: signer0_pubkey, - is_signer: true, - is_writable: false, - }, - AccountMeta { - pubkey: signer0_pubkey, - is_signer: true, - is_writable: false, - }, - ], - Err(InstructionError::InvalidArgument), - ); - } - - #[test] - fn test_config_update_contains_duplicates_fails() { - solana_logger::setup(); - let config_address = Pubkey::new_unique(); - let signer0_pubkey = Pubkey::new_unique(); - let signer1_pubkey = Pubkey::new_unique(); - let signer0_account = AccountSharedData::new(0, 0, &Pubkey::new_unique()); - let signer1_account = AccountSharedData::new(0, 0, &Pubkey::new_unique()); - let keys = vec![ - (config_address, false), - (signer0_pubkey, true), - (signer1_pubkey, true), - ]; - let (config_keypair, config_account) = create_config_account(keys.clone()); - let config_pubkey = config_keypair.pubkey(); - let my_config = MyConfig::new(42); - - let instruction = config_instruction::store(&config_pubkey, true, keys, &my_config); - let accounts = process_instruction( - &instruction.data, - vec![ - (config_pubkey, config_account), - (signer0_pubkey, signer0_account.clone()), - (signer1_pubkey, signer1_account), - ], - vec![ - AccountMeta { - pubkey: config_pubkey, - is_signer: true, - is_writable: true, - }, - AccountMeta { - pubkey: signer0_pubkey, - is_signer: true, - is_writable: false, - }, - AccountMeta { - pubkey: signer1_pubkey, - is_signer: true, - is_writable: false, - }, - ], - Ok(()), - ); - - // Attempt update with duplicate signer inputs - let new_config = MyConfig::new(84); - let dupe_keys = vec![ - (config_address, false), - (signer0_pubkey, true), - (signer0_pubkey, true), - ]; - let instruction = config_instruction::store(&config_pubkey, false, dupe_keys, &new_config); - process_instruction( - &instruction.data, - vec![ - (config_pubkey, accounts[0].clone()), - (signer0_pubkey, signer0_account), - ], - vec![ - AccountMeta { - pubkey: config_pubkey, - is_signer: true, - is_writable: true, - }, - AccountMeta { - pubkey: signer0_pubkey, - is_signer: true, - is_writable: false, - }, - AccountMeta { - pubkey: signer0_pubkey, - is_signer: true, - is_writable: false, - }, - ], - Err(InstructionError::InvalidArgument), - ); - } - - #[test] - fn test_config_updates_requiring_config() { - solana_logger::setup(); - let pubkey = Pubkey::new_unique(); - let signer0_pubkey = Pubkey::new_unique(); - let signer0_account = AccountSharedData::new(0, 0, &Pubkey::new_unique()); - let keys = vec![ - (pubkey, false), - (signer0_pubkey, true), - (signer0_pubkey, true), - ]; // Dummy keys for account sizing - let (config_keypair, config_account) = create_config_account(keys); - let config_pubkey = config_keypair.pubkey(); - let my_config = MyConfig::new(42); - let keys = vec![ - (pubkey, false), - (signer0_pubkey, true), - (config_keypair.pubkey(), true), - ]; - - let instruction = config_instruction::store(&config_pubkey, true, keys.clone(), &my_config); - let accounts = process_instruction( - &instruction.data, - vec![ - (config_pubkey, config_account), - (signer0_pubkey, signer0_account.clone()), - ], - vec![ - AccountMeta { - pubkey: config_pubkey, - is_signer: true, - is_writable: true, - }, - AccountMeta { - pubkey: signer0_pubkey, - is_signer: true, - is_writable: false, - }, - ], - Ok(()), - ); - - // Update with expected signatures - let new_config = MyConfig::new(84); - let instruction = - config_instruction::store(&config_pubkey, true, keys.clone(), &new_config); - let accounts = process_instruction( - &instruction.data, - vec![ - (config_pubkey, accounts[0].clone()), - (signer0_pubkey, signer0_account), - ], - vec![ - AccountMeta { - pubkey: config_pubkey, - is_signer: true, - is_writable: true, - }, - AccountMeta { - pubkey: signer0_pubkey, - is_signer: true, - is_writable: false, - }, - ], - Ok(()), - ); - let meta_data: ConfigKeys = deserialize(accounts[0].data()).unwrap(); - assert_eq!(meta_data.keys, keys); - assert_eq!( - new_config, - MyConfig::deserialize(get_config_data(accounts[0].data()).unwrap()).unwrap() - ); - - // Attempt update with incomplete signatures - let keys = vec![(pubkey, false), (config_keypair.pubkey(), true)]; - let instruction = config_instruction::store(&config_pubkey, true, keys, &my_config); - process_instruction( - &instruction.data, - vec![(config_pubkey, accounts[0].clone())], - vec![AccountMeta { - pubkey: config_pubkey, - is_signer: true, - is_writable: true, - }], - Err(InstructionError::MissingRequiredSignature), - ); - } - - #[test] - fn test_config_initialize_no_panic() { - let from_pubkey = Pubkey::new_unique(); - let config_pubkey = Pubkey::new_unique(); - let (_, _config_account) = create_config_account(vec![]); - let instructions = - config_instruction::create_account::(&from_pubkey, &config_pubkey, 1, vec![]); - process_instruction( - &instructions[1].data, - Vec::new(), - Vec::new(), - Err(InstructionError::NotEnoughAccountKeys), - ); - } - - #[test] - fn test_config_bad_owner() { - let from_pubkey = Pubkey::new_unique(); - let config_pubkey = Pubkey::new_unique(); - let new_config = MyConfig::new(84); - let signer0_pubkey = Pubkey::new_unique(); - let signer0_account = AccountSharedData::new(0, 0, &Pubkey::new_unique()); - let config_account = AccountSharedData::new(0, 0, &Pubkey::new_unique()); - let (_, _config_account) = create_config_account(vec![]); - let keys = vec![ - (from_pubkey, false), - (signer0_pubkey, true), - (config_pubkey, true), - ]; - - let instruction = config_instruction::store(&config_pubkey, true, keys, &new_config); - process_instruction( - &instruction.data, - vec![ - (config_pubkey, config_account), - (signer0_pubkey, signer0_account), - ], - vec![ - AccountMeta { - pubkey: config_pubkey, - is_signer: true, - is_writable: true, - }, - AccountMeta { - pubkey: signer0_pubkey, - is_signer: true, - is_writable: false, - }, - ], - Err(InstructionError::InvalidAccountOwner), - ); - } -} diff --git a/programs/config/src/date_instruction.rs b/programs/config/src/date_instruction.rs deleted file mode 100644 index b07a386f51cd05..00000000000000 --- a/programs/config/src/date_instruction.rs +++ /dev/null @@ -1,59 +0,0 @@ -/// -/// A library for creating a trusted date oracle. -/// -use bincode::{deserialize, serialized_size}; -use { - crate::{config_instruction, ConfigState}, - chrono::{ - prelude::{DateTime, TimeZone, Utc}, - serde::ts_seconds, - }, - serde_derive::{Deserialize, Serialize}, - solana_instruction::Instruction, - solana_pubkey::Pubkey, -}; - -#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)] -pub struct DateConfig { - #[serde(with = "ts_seconds")] - pub date_time: DateTime, -} - -impl Default for DateConfig { - fn default() -> Self { - Self { - date_time: Utc.timestamp_opt(0, 0).unwrap(), - } - } -} -impl DateConfig { - pub fn new(date_time: DateTime) -> Self { - Self { date_time } - } - - pub fn deserialize(input: &[u8]) -> Option { - deserialize(input).ok() - } -} - -impl ConfigState for DateConfig { - fn max_space() -> u64 { - serialized_size(&Self::default()).unwrap() - } -} - -/// Create a date account. The date is set to the Unix epoch. -pub fn create_account( - payer_pubkey: &Pubkey, - date_pubkey: &Pubkey, - lamports: u64, -) -> Vec { - config_instruction::create_account::(payer_pubkey, date_pubkey, lamports, vec![]) -} - -/// Set the date in the date account. The account pubkey must be signed in the -/// transaction containing this instruction. -pub fn store(date_pubkey: &Pubkey, date_time: DateTime) -> Instruction { - let date_config = DateConfig::new(date_time); - config_instruction::store(date_pubkey, true, vec![], &date_config) -} diff --git a/programs/config/src/lib.rs b/programs/config/src/lib.rs deleted file mode 100644 index c76411eacaec69..00000000000000 --- a/programs/config/src/lib.rs +++ /dev/null @@ -1,69 +0,0 @@ -#![allow(clippy::arithmetic_side_effects)] -pub mod config_instruction; -pub mod config_processor; -#[deprecated( - since = "2.0.0", - note = "The config program API no longer supports date instructions." -)] -pub mod date_instruction; - -pub use solana_sdk_ids::config::id; -#[allow(deprecated)] -use solana_stake_interface::config::Config as StakeConfig; -use { - bincode::{deserialize, serialize, serialized_size}, - serde_derive::{Deserialize, Serialize}, - solana_account::{Account, AccountSharedData}, - solana_pubkey::Pubkey, - solana_short_vec as short_vec, -}; - -pub trait ConfigState: serde::Serialize + Default { - /// Maximum space that the serialized representation will require - fn max_space() -> u64; -} - -// TODO move ConfigState into `solana_program` to implement trait locally -#[allow(deprecated)] -impl ConfigState for StakeConfig { - fn max_space() -> u64 { - serialized_size(&StakeConfig::default()).unwrap() - } -} - -/// A collection of keys to be stored in Config account data. -#[derive(Debug, Default, Deserialize, Serialize)] -pub struct ConfigKeys { - // Each key tuple comprises a unique `Pubkey` identifier, - // and `bool` whether that key is a signer of the data - #[serde(with = "short_vec")] - pub keys: Vec<(Pubkey, bool)>, -} - -impl ConfigKeys { - pub fn serialized_size(keys: Vec<(Pubkey, bool)>) -> u64 { - serialized_size(&ConfigKeys { keys }).unwrap() - } -} - -pub fn get_config_data(bytes: &[u8]) -> Result<&[u8], bincode::Error> { - deserialize::(bytes) - .and_then(|keys| serialized_size(&keys)) - .map(|offset| &bytes[offset as usize..]) -} - -// utility for pre-made Accounts -pub fn create_config_account( - keys: Vec<(Pubkey, bool)>, - config_data: &T, - lamports: u64, -) -> AccountSharedData { - let mut data = serialize(&ConfigKeys { keys }).unwrap(); - data.extend_from_slice(&serialize(config_data).unwrap()); - AccountSharedData::from(Account { - lamports, - data, - owner: id(), - ..Account::default() - }) -} diff --git a/programs/sbf/Cargo.lock b/programs/sbf/Cargo.lock index 11bd4b29b1ffc0..36a62d97a02976 100644 --- a/programs/sbf/Cargo.lock +++ b/programs/sbf/Cargo.lock @@ -3005,6 +3005,16 @@ dependencies = [ "unicase", ] +[[package]] +name = "kaigan" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ba15de5aeb137f0f65aa3bf82187647f1285abfe5b20c80c2c37f7007ad519a" +dependencies = [ + "borsh 0.10.3", + "serde", +] + [[package]] name = "keccak" version = "0.1.5" @@ -5263,7 +5273,7 @@ dependencies = [ "solana-account", "solana-account-decoder-client-types", "solana-clock", - "solana-config-program", + "solana-config-program-client", "solana-epoch-schedule", "solana-fee-calculator", "solana-instruction", @@ -5612,7 +5622,6 @@ dependencies = [ "solana-address-lookup-table-program", "solana-bpf-loader-program", "solana-compute-budget-program", - "solana-config-program", "solana-loader-v4-program", "solana-program-runtime", "solana-pubkey", @@ -5635,7 +5644,6 @@ dependencies = [ "solana-address-lookup-table-program", "solana-bpf-loader-program", "solana-compute-budget-program", - "solana-config-program", "solana-loader-v4-program", "solana-pubkey", "solana-sdk-ids", @@ -5873,25 +5881,16 @@ dependencies = [ ] [[package]] -name = "solana-config-program" -version = "2.3.0" +name = "solana-config-program-client" +version = "0.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53aceac36f105fd4922e29b4f0c1f785b69d7b3e7e387e384b8985c8e0c3595e" dependencies = [ "bincode", - "chrono", + "borsh 0.10.3", + "kaigan", "serde", - "serde_derive", - "solana-account", - "solana-bincode", - "solana-instruction", - "solana-log-collector", - "solana-packet", - "solana-program-runtime", - "solana-pubkey", - "solana-sdk-ids", - "solana-short-vec", - "solana-stake-interface", - "solana-system-interface", - "solana-transaction-context 2.3.0", + "solana-program", ] [[package]] @@ -7607,7 +7606,6 @@ dependencies = [ "solana-builtins", "solana-compute-budget", "solana-compute-budget-instruction", - "solana-config-program", "solana-cost-model", "solana-fee", "solana-inline-spl", @@ -8524,7 +8522,7 @@ dependencies = [ "solana-account", "solana-bincode", "solana-clock", - "solana-config-program", + "solana-config-program-client", "solana-genesis-config", "solana-instruction", "solana-log-collector", diff --git a/programs/stake/Cargo.toml b/programs/stake/Cargo.toml index 8a12ad6f755c20..e0c45695ab70c6 100644 --- a/programs/stake/Cargo.toml +++ b/programs/stake/Cargo.toml @@ -16,7 +16,7 @@ log = { workspace = true } solana-account = { workspace = true } solana-bincode = { workspace = true } solana-clock = { workspace = true } -solana-config-program = { workspace = true } +solana-config-program-client = { workspace = true, features = ["serde"] } solana-genesis-config = { workspace = true } solana-instruction = { workspace = true } solana-log-collector = { workspace = true } diff --git a/programs/stake/src/config.rs b/programs/stake/src/config.rs index 284b30705f955a..5042aa82eebcbd 100644 --- a/programs/stake/src/config.rs +++ b/programs/stake/src/config.rs @@ -6,13 +6,30 @@ )] pub use solana_stake_interface::config::*; use { - bincode::deserialize, - solana_account::{AccountSharedData, ReadableAccount, WritableAccount}, - solana_config_program::{create_config_account, get_config_data}, + bincode::{deserialize, serialize}, + solana_account::{Account, AccountSharedData, ReadableAccount, WritableAccount}, + solana_config_program_client::{get_config_data, ConfigKeys}, solana_genesis_config::GenesisConfig, + solana_pubkey::Pubkey, solana_transaction_context::BorrowedAccount, }; +#[allow(deprecated)] +fn create_config_account( + keys: Vec<(Pubkey, bool)>, + config_data: &Config, + lamports: u64, +) -> AccountSharedData { + let mut data = serialize(&ConfigKeys { keys }).unwrap(); + data.extend_from_slice(&serialize(config_data).unwrap()); + AccountSharedData::from(Account { + lamports, + data, + owner: solana_sdk_ids::config::id(), + ..Account::default() + }) +} + #[allow(deprecated)] pub fn from(account: &BorrowedAccount) -> Option { get_config_data(account.get_data()) diff --git a/runtime/Cargo.toml b/runtime/Cargo.toml index 4e8b18f2615c1e..0ced971fb323f3 100644 --- a/runtime/Cargo.toml +++ b/runtime/Cargo.toml @@ -55,7 +55,6 @@ solana-bucket-map = { workspace = true } solana-builtins = { workspace = true } solana-compute-budget = { workspace = true } solana-compute-budget-instruction = { workspace = true } -solana-config-program = { workspace = true } solana-cost-model = { workspace = true } solana-fee = { workspace = true } solana-frozen-abi = { workspace = true, optional = true, features = [ diff --git a/runtime/src/bank/builtin_programs.rs b/runtime/src/bank/builtin_programs.rs index 17e43bad1e764d..c5fb4dcf7ac4c7 100644 --- a/runtime/src/bank/builtin_programs.rs +++ b/runtime/src/bank/builtin_programs.rs @@ -155,10 +155,9 @@ mod tests_core_bpf_migration { #[test_case(TestPrototype::Builtin(&BUILTINS[0]); "system")] #[test_case(TestPrototype::Builtin(&BUILTINS[1]); "vote")] #[test_case(TestPrototype::Builtin(&BUILTINS[2]); "stake")] - #[test_case(TestPrototype::Builtin(&BUILTINS[3]); "config")] - #[test_case(TestPrototype::Builtin(&BUILTINS[4]); "bpf_loader_deprecated")] - #[test_case(TestPrototype::Builtin(&BUILTINS[5]); "bpf_loader")] - #[test_case(TestPrototype::Builtin(&BUILTINS[8]); "address_lookup_table")] + #[test_case(TestPrototype::Builtin(&BUILTINS[3]); "bpf_loader_deprecated")] + #[test_case(TestPrototype::Builtin(&BUILTINS[4]); "bpf_loader")] + #[test_case(TestPrototype::Builtin(&BUILTINS[7]); "address_lookup_table")] fn test_core_bpf_migration(prototype: TestPrototype) { let (mut genesis_config, mint_keypair) = create_genesis_config(1_000_000 * LAMPORTS_PER_SOL); diff --git a/runtime/src/bank/builtins/core_bpf_migration/target_builtin.rs b/runtime/src/bank/builtins/core_bpf_migration/target_builtin.rs index 124859abf59614..58c263f7d0ac48 100644 --- a/runtime/src/bank/builtins/core_bpf_migration/target_builtin.rs +++ b/runtime/src/bank/builtins/core_bpf_migration/target_builtin.rs @@ -110,7 +110,6 @@ mod tests { #[test_case(solana_sdk::bpf_loader_deprecated::id(), None)] #[test_case(solana_sdk::bpf_loader_upgradeable::id(), None)] #[test_case(solana_sdk::compute_budget::id(), None)] - #[test_case(solana_config_program::id(), None)] #[test_case(solana_stake_program::id(), None)] #[test_case(solana_system_program::id(), None)] #[test_case(solana_vote_program::id(), None)] diff --git a/runtime/src/bank/tests.rs b/runtime/src/bank/tests.rs index a72b08bbdb25ca..060e538a91c034 100644 --- a/runtime/src/bank/tests.rs +++ b/runtime/src/bank/tests.rs @@ -6516,26 +6516,26 @@ fn test_bank_hash_consistency() { if bank.slot == 0 { assert_eq!( bank.hash().to_string(), - "Hn2FoJuoFWXVFVnwcQ6peuT24mUPmhDtXHXVjKD7M4yP", + "5nHFM2YArJdULMoAEtn2cXSaqk4v1UXs9upTvoc2FMn7", ); } if bank.slot == 32 { assert_eq!( bank.hash().to_string(), - "Hdrk5wqzRZbofSgZMC3ztfNimrFu6DeYp751JWvtabo" + "FPr64zXMcEE45qWRYy7hpvNRpzZD2ckqHes13uyiU1to" ); } if bank.slot == 64 { assert_eq!( bank.hash().to_string(), - "4EcAFkTxymwwPGeCgadhkrkg2hqfAPzuQZoN2NFqPzyg" + "HENrhATjg2gghYyV34CLPnMUq2VuTKwUjGXWwAz96Vzs" ); } if bank.slot == 128 { assert_eq!( bank.hash().to_string(), - "4BK3VANr5mhyRyrwbUHYb2kmM5m76PBGkhmKMrQ2aq7L" + "GjpfTe9dmB1HbrnC4BMaETPAqPUtXvXNG5ccnHSeMPnH" ); break; } @@ -6754,7 +6754,7 @@ fn test_shrink_candidate_slots_cached() { // No more slots should be shrunk assert_eq!(bank2.shrink_candidate_slots(), 0); // alive_counts represents the count of alive accounts in the three slots 0,1,2 - assert_eq!(alive_counts, vec![15, 1, 6]); + assert_eq!(alive_counts, vec![14, 1, 6]); } #[test] diff --git a/runtime/src/genesis_utils.rs b/runtime/src/genesis_utils.rs index 4757ac744ec307..46a029dfb6c68d 100644 --- a/runtime/src/genesis_utils.rs +++ b/runtime/src/genesis_utils.rs @@ -29,7 +29,7 @@ pub fn bootstrap_validator_stake_lamports() -> u64 { // Number of lamports automatically used for genesis accounts pub const fn genesis_sysvar_and_builtin_program_lamports() -> u64 { - const NUM_BUILTIN_PROGRAMS: u64 = 9; + const NUM_BUILTIN_PROGRAMS: u64 = 8; const NUM_PRECOMPILES: u64 = 2; const STAKE_HISTORY_MIN_BALANCE: u64 = 114_979_200; const CLOCK_SYSVAR_MIN_BALANCE: u64 = 1_169_280; diff --git a/scripts/patch-crates.sh b/scripts/patch-crates.sh index 2613b8b5777ead..eeed925ad87233 100644 --- a/scripts/patch-crates.sh +++ b/scripts/patch-crates.sh @@ -43,7 +43,6 @@ update_solana_dependencies() { solana-address-lookup-table-program solana-bpf-loader-program solana-compute-budget-program - solana-config-program solana-stake-program solana-system-program solana-vote-program @@ -134,7 +133,6 @@ patch_crates_io_solana_no_header() { crates_map+=("solana-address-lookup-table-program programs/address-lookup-table") crates_map+=("solana-bpf-loader-program programs/bpf_loader") crates_map+=("solana-compute-budget-program programs/compute-budget") - crates_map+=("solana-config-program programs/config") crates_map+=("solana-stake-program programs/stake") crates_map+=("solana-system-program programs/system") crates_map+=("solana-vote-program programs/vote") diff --git a/svm/examples/Cargo.lock b/svm/examples/Cargo.lock index b113cdc63cf94b..6f68660e4d32ef 100644 --- a/svm/examples/Cargo.lock +++ b/svm/examples/Cargo.lock @@ -2935,6 +2935,16 @@ dependencies = [ "unicase", ] +[[package]] +name = "kaigan" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ba15de5aeb137f0f65aa3bf82187647f1285abfe5b20c80c2c37f7007ad519a" +dependencies = [ + "borsh 0.10.4", + "serde", +] + [[package]] name = "keccak" version = "0.1.5" @@ -5121,7 +5131,7 @@ dependencies = [ "solana-account", "solana-account-decoder-client-types", "solana-clock", - "solana-config-program", + "solana-config-program-client", "solana-epoch-schedule", "solana-fee-calculator", "solana-instruction", @@ -5470,7 +5480,6 @@ dependencies = [ "solana-address-lookup-table-program", "solana-bpf-loader-program", "solana-compute-budget-program", - "solana-config-program", "solana-loader-v4-program", "solana-program-runtime", "solana-pubkey", @@ -5493,7 +5502,6 @@ dependencies = [ "solana-address-lookup-table-program", "solana-bpf-loader-program", "solana-compute-budget-program", - "solana-config-program", "solana-loader-v4-program", "solana-pubkey", "solana-sdk-ids", @@ -5731,25 +5739,16 @@ dependencies = [ ] [[package]] -name = "solana-config-program" -version = "2.3.0" +name = "solana-config-program-client" +version = "0.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53aceac36f105fd4922e29b4f0c1f785b69d7b3e7e387e384b8985c8e0c3595e" dependencies = [ "bincode", - "chrono", + "borsh 0.10.4", + "kaigan", "serde", - "serde_derive", - "solana-account", - "solana-bincode", - "solana-instruction", - "solana-log-collector", - "solana-packet", - "solana-program-runtime", - "solana-pubkey", - "solana-sdk-ids", - "solana-short-vec", - "solana-stake-interface", - "solana-system-interface", - "solana-transaction-context 2.3.0", + "solana-program", ] [[package]] @@ -7431,7 +7430,6 @@ dependencies = [ "solana-builtins", "solana-compute-budget", "solana-compute-budget-instruction", - "solana-config-program", "solana-cost-model", "solana-fee", "solana-inline-spl", @@ -7846,7 +7844,7 @@ dependencies = [ "solana-account", "solana-bincode", "solana-clock", - "solana-config-program", + "solana-config-program-client", "solana-genesis-config", "solana-instruction", "solana-log-collector", diff --git a/test-validator/src/lib.rs b/test-validator/src/lib.rs index d5fcd89f0b2681..a4d2fa5b16fbcc 100644 --- a/test-validator/src/lib.rs +++ b/test-validator/src/lib.rs @@ -1303,8 +1303,8 @@ mod test { async fn test_core_bpf_programs() { let (test_validator, _payer) = TestValidatorGenesis::default() .deactivate_features(&[ - // Don't migrate the config program. - solana_sdk::feature_set::migrate_config_program_to_core_bpf::id(), + // Don't migrate the lookup table program. + solana_sdk::feature_set::migrate_address_lookup_table_program_to_core_bpf::id(), ]) .start_async() .await; @@ -1320,14 +1320,14 @@ mod test { .await .unwrap(); - // Address lookup table is a BPF program. + // Address lookup table is builtin. let account = fetched_programs[0].as_ref().unwrap(); - assert_eq!(account.owner, solana_sdk_ids::bpf_loader_upgradeable::id()); + assert_eq!(account.owner, solana_sdk_ids::native_loader::id()); assert!(account.executable); - // Config is a builtin. + // Config is a a BPF program. let account = fetched_programs[1].as_ref().unwrap(); - assert_eq!(account.owner, solana_sdk_ids::native_loader::id()); + assert_eq!(account.owner, solana_sdk_ids::bpf_loader_upgradeable::id()); assert!(account.executable); // Feature Gate is a BPF program.