diff --git a/cli/tests/program.rs b/cli/tests/program.rs index fc13f626d0c3ae..baf84a4ac2b08a 100644 --- a/cli/tests/program.rs +++ b/cli/tests/program.rs @@ -13,7 +13,7 @@ use { solana_cli_output::{parse_sign_only_reply_string, OutputFormat}, solana_client::rpc_config::RpcSendTransactionConfig, solana_faucet::faucet::run_local_faucet, - solana_feature_set::enable_alt_bn128_syscall, + solana_feature_set::{enable_alt_bn128_syscall, enable_loader_v4}, solana_rpc::rpc::JsonRpcConfig, solana_rpc_client::rpc_client::{GetConfirmedSignaturesForAddress2Config, RpcClient}, solana_rpc_client_api::config::RpcTransactionConfig, @@ -33,7 +33,7 @@ use { transaction::Transaction, }, solana_streamer::socket::SocketAddrSpace, - solana_test_validator::{TestValidator, TestValidatorGenesis}, + solana_test_validator::TestValidatorGenesis, solana_transaction_status::UiTransactionEncoding, std::{ env, @@ -82,8 +82,17 @@ fn test_cli_program_deploy_non_upgradeable() { let mint_keypair = Keypair::new(); let mint_pubkey = mint_keypair.pubkey(); let faucet_addr = run_local_faucet(mint_keypair, None); - let test_validator = - TestValidator::with_no_fees(mint_pubkey, Some(faucet_addr), SocketAddrSpace::Unspecified); + let test_validator = TestValidatorGenesis::default() + .fee_rate_governor(FeeRateGovernor::new(0, 0)) + .rent(Rent { + lamports_per_byte_year: 1, + exemption_threshold: 1.0, + ..Rent::default() + }) + .faucet_addr(Some(faucet_addr)) + .deactivate_features(&[enable_loader_v4::id()]) + .start_with_mint_address(mint_pubkey, SocketAddrSpace::Unspecified) + .expect("validator start failed"); let rpc_client = RpcClient::new_with_commitment(test_validator.rpc_url(), CommitmentConfig::processed()); @@ -287,8 +296,17 @@ fn test_cli_program_deploy_no_authority() { let mint_keypair = Keypair::new(); let mint_pubkey = mint_keypair.pubkey(); let faucet_addr = run_local_faucet(mint_keypair, None); - let test_validator = - TestValidator::with_no_fees(mint_pubkey, Some(faucet_addr), SocketAddrSpace::Unspecified); + let test_validator = TestValidatorGenesis::default() + .fee_rate_governor(FeeRateGovernor::new(0, 0)) + .rent(Rent { + lamports_per_byte_year: 1, + exemption_threshold: 1.0, + ..Rent::default() + }) + .faucet_addr(Some(faucet_addr)) + .deactivate_features(&[enable_loader_v4::id()]) + .start_with_mint_address(mint_pubkey, SocketAddrSpace::Unspecified) + .expect("validator start failed"); let rpc_client = RpcClient::new_with_commitment(test_validator.rpc_url(), CommitmentConfig::processed()); @@ -406,6 +424,7 @@ fn test_cli_program_deploy_feature(enable_feature: bool, skip_preflight: bool) { test_validator_builder.deactivate_features(&[enable_alt_bn128_syscall::id()]); } + test_validator_builder = test_validator_builder.deactivate_features(&[enable_loader_v4::id()]); let test_validator = test_validator_builder .start_with_mint_address(mint_pubkey, SocketAddrSpace::Unspecified) .expect("validator start failed"); @@ -542,6 +561,7 @@ fn test_cli_program_upgrade_with_feature(enable_feature: bool) { test_validator_builder.deactivate_features(&[enable_alt_bn128_syscall::id()]); } + test_validator_builder = test_validator_builder.deactivate_features(&[enable_loader_v4::id()]); let test_validator = test_validator_builder .start_with_mint_address(mint_pubkey, SocketAddrSpace::Unspecified) .expect("validator start failed"); @@ -691,8 +711,17 @@ fn test_cli_program_deploy_with_authority() { let mint_keypair = Keypair::new(); let mint_pubkey = mint_keypair.pubkey(); let faucet_addr = run_local_faucet(mint_keypair, None); - let test_validator = - TestValidator::with_no_fees(mint_pubkey, Some(faucet_addr), SocketAddrSpace::Unspecified); + let test_validator = TestValidatorGenesis::default() + .fee_rate_governor(FeeRateGovernor::new(0, 0)) + .rent(Rent { + lamports_per_byte_year: 1, + exemption_threshold: 1.0, + ..Rent::default() + }) + .faucet_addr(Some(faucet_addr)) + .deactivate_features(&[enable_loader_v4::id()]) + .start_with_mint_address(mint_pubkey, SocketAddrSpace::Unspecified) + .expect("validator start failed"); let rpc_client = RpcClient::new_with_commitment(test_validator.rpc_url(), CommitmentConfig::processed()); @@ -1093,8 +1122,17 @@ fn test_cli_program_upgrade_auto_extend(skip_preflight: bool) { let mint_keypair = Keypair::new(); let mint_pubkey = mint_keypair.pubkey(); let faucet_addr = run_local_faucet(mint_keypair, None); - let test_validator = - TestValidator::with_no_fees(mint_pubkey, Some(faucet_addr), SocketAddrSpace::Unspecified); + let test_validator = TestValidatorGenesis::default() + .fee_rate_governor(FeeRateGovernor::new(0, 0)) + .rent(Rent { + lamports_per_byte_year: 1, + exemption_threshold: 1.0, + ..Rent::default() + }) + .faucet_addr(Some(faucet_addr)) + .deactivate_features(&[enable_loader_v4::id()]) + .start_with_mint_address(mint_pubkey, SocketAddrSpace::Unspecified) + .expect("validator start failed"); let rpc_client = RpcClient::new_with_commitment(test_validator.rpc_url(), CommitmentConfig::processed()); @@ -1255,8 +1293,17 @@ fn test_cli_program_close_program() { let mint_keypair = Keypair::new(); let mint_pubkey = mint_keypair.pubkey(); let faucet_addr = run_local_faucet(mint_keypair, None); - let test_validator = - TestValidator::with_no_fees(mint_pubkey, Some(faucet_addr), SocketAddrSpace::Unspecified); + let test_validator = TestValidatorGenesis::default() + .fee_rate_governor(FeeRateGovernor::new(0, 0)) + .rent(Rent { + lamports_per_byte_year: 1, + exemption_threshold: 1.0, + ..Rent::default() + }) + .faucet_addr(Some(faucet_addr)) + .deactivate_features(&[enable_loader_v4::id()]) + .start_with_mint_address(mint_pubkey, SocketAddrSpace::Unspecified) + .expect("validator start failed"); let rpc_client = RpcClient::new_with_commitment(test_validator.rpc_url(), CommitmentConfig::processed()); @@ -1374,8 +1421,17 @@ fn test_cli_program_extend_program() { let mint_keypair = Keypair::new(); let mint_pubkey = mint_keypair.pubkey(); let faucet_addr = run_local_faucet(mint_keypair, None); - let test_validator = - TestValidator::with_no_fees(mint_pubkey, Some(faucet_addr), SocketAddrSpace::Unspecified); + let test_validator = TestValidatorGenesis::default() + .fee_rate_governor(FeeRateGovernor::new(0, 0)) + .rent(Rent { + lamports_per_byte_year: 1, + exemption_threshold: 1.0, + ..Rent::default() + }) + .faucet_addr(Some(faucet_addr)) + .deactivate_features(&[enable_loader_v4::id()]) + .start_with_mint_address(mint_pubkey, SocketAddrSpace::Unspecified) + .expect("validator start failed"); let rpc_client = RpcClient::new_with_commitment(test_validator.rpc_url(), CommitmentConfig::processed()); @@ -1550,8 +1606,17 @@ fn test_cli_program_write_buffer() { let mint_keypair = Keypair::new(); let mint_pubkey = mint_keypair.pubkey(); let faucet_addr = run_local_faucet(mint_keypair, None); - let test_validator = - TestValidator::with_no_fees(mint_pubkey, Some(faucet_addr), SocketAddrSpace::Unspecified); + let test_validator = TestValidatorGenesis::default() + .fee_rate_governor(FeeRateGovernor::new(0, 0)) + .rent(Rent { + lamports_per_byte_year: 1, + exemption_threshold: 1.0, + ..Rent::default() + }) + .faucet_addr(Some(faucet_addr)) + .deactivate_features(&[enable_loader_v4::id()]) + .start_with_mint_address(mint_pubkey, SocketAddrSpace::Unspecified) + .expect("validator start failed"); let rpc_client = RpcClient::new_with_commitment(test_validator.rpc_url(), CommitmentConfig::processed()); @@ -2037,8 +2102,17 @@ fn test_cli_program_set_buffer_authority() { let mint_keypair = Keypair::new(); let mint_pubkey = mint_keypair.pubkey(); let faucet_addr = run_local_faucet(mint_keypair, None); - let test_validator = - TestValidator::with_no_fees(mint_pubkey, Some(faucet_addr), SocketAddrSpace::Unspecified); + let test_validator = TestValidatorGenesis::default() + .fee_rate_governor(FeeRateGovernor::new(0, 0)) + .rent(Rent { + lamports_per_byte_year: 1, + exemption_threshold: 1.0, + ..Rent::default() + }) + .faucet_addr(Some(faucet_addr)) + .deactivate_features(&[enable_loader_v4::id()]) + .start_with_mint_address(mint_pubkey, SocketAddrSpace::Unspecified) + .expect("validator start failed"); let rpc_client = RpcClient::new_with_commitment(test_validator.rpc_url(), CommitmentConfig::processed()); @@ -2209,8 +2283,17 @@ fn test_cli_program_mismatch_buffer_authority() { let mint_keypair = Keypair::new(); let mint_pubkey = mint_keypair.pubkey(); let faucet_addr = run_local_faucet(mint_keypair, None); - let test_validator = - TestValidator::with_no_fees(mint_pubkey, Some(faucet_addr), SocketAddrSpace::Unspecified); + let test_validator = TestValidatorGenesis::default() + .fee_rate_governor(FeeRateGovernor::new(0, 0)) + .rent(Rent { + lamports_per_byte_year: 1, + exemption_threshold: 1.0, + ..Rent::default() + }) + .faucet_addr(Some(faucet_addr)) + .deactivate_features(&[enable_loader_v4::id()]) + .start_with_mint_address(mint_pubkey, SocketAddrSpace::Unspecified) + .expect("validator start failed"); let rpc_client = RpcClient::new_with_commitment(test_validator.rpc_url(), CommitmentConfig::processed()); @@ -2335,8 +2418,17 @@ fn test_cli_program_deploy_with_offline_signing(use_offline_signer_as_fee_payer: let mint_keypair = Keypair::new(); let mint_pubkey = mint_keypair.pubkey(); let faucet_addr = run_local_faucet(mint_keypair, None); - let test_validator = - TestValidator::with_no_fees(mint_pubkey, Some(faucet_addr), SocketAddrSpace::Unspecified); + let test_validator = TestValidatorGenesis::default() + .fee_rate_governor(FeeRateGovernor::new(0, 0)) + .rent(Rent { + lamports_per_byte_year: 1, + exemption_threshold: 1.0, + ..Rent::default() + }) + .faucet_addr(Some(faucet_addr)) + .deactivate_features(&[enable_loader_v4::id()]) + .start_with_mint_address(mint_pubkey, SocketAddrSpace::Unspecified) + .expect("validator start failed"); let rpc_client = RpcClient::new_with_commitment(test_validator.rpc_url(), CommitmentConfig::processed()); @@ -2528,8 +2620,17 @@ fn test_cli_program_show() { let mint_keypair = Keypair::new(); let mint_pubkey = mint_keypair.pubkey(); let faucet_addr = run_local_faucet(mint_keypair, None); - let test_validator = - TestValidator::with_no_fees(mint_pubkey, Some(faucet_addr), SocketAddrSpace::Unspecified); + let test_validator = TestValidatorGenesis::default() + .fee_rate_governor(FeeRateGovernor::new(0, 0)) + .rent(Rent { + lamports_per_byte_year: 1, + exemption_threshold: 1.0, + ..Rent::default() + }) + .faucet_addr(Some(faucet_addr)) + .deactivate_features(&[enable_loader_v4::id()]) + .start_with_mint_address(mint_pubkey, SocketAddrSpace::Unspecified) + .expect("validator start failed"); let rpc_client = RpcClient::new_with_commitment(test_validator.rpc_url(), CommitmentConfig::processed()); @@ -2725,8 +2826,17 @@ fn test_cli_program_dump() { let mint_keypair = Keypair::new(); let mint_pubkey = mint_keypair.pubkey(); let faucet_addr = run_local_faucet(mint_keypair, None); - let test_validator = - TestValidator::with_no_fees(mint_pubkey, Some(faucet_addr), SocketAddrSpace::Unspecified); + let test_validator = TestValidatorGenesis::default() + .fee_rate_governor(FeeRateGovernor::new(0, 0)) + .rent(Rent { + lamports_per_byte_year: 1, + exemption_threshold: 1.0, + ..Rent::default() + }) + .faucet_addr(Some(faucet_addr)) + .deactivate_features(&[enable_loader_v4::id()]) + .start_with_mint_address(mint_pubkey, SocketAddrSpace::Unspecified) + .expect("validator start failed"); let rpc_client = RpcClient::new_with_commitment(test_validator.rpc_url(), CommitmentConfig::processed()); @@ -2864,6 +2974,7 @@ fn test_cli_program_deploy_with_args(compute_unit_price: Option, use_rpc: b exemption_threshold: 1.0, ..Rent::default() }) + .deactivate_features(&[enable_loader_v4::id()]) .rpc_config(JsonRpcConfig { enable_rpc_transaction_history: true, faucet_addr: Some(faucet_addr), diff --git a/programs/bpf_loader/src/lib.rs b/programs/bpf_loader/src/lib.rs index e37b2dcb53ef87..8441ff7038524e 100644 --- a/programs/bpf_loader/src/lib.rs +++ b/programs/bpf_loader/src/lib.rs @@ -1670,6 +1670,9 @@ mod tests { expected_result, Entrypoint::vm, |invoke_context| { + let mut feature_set = invoke_context.get_feature_set().clone(); + feature_set.deactivate(&enable_loader_v4::id()); + invoke_context.mock_set_feature_set(Arc::new(feature_set)); test_utils::load_all_invoked_programs(invoke_context); }, |_invoke_context| {}, diff --git a/programs/sbf/benches/bpf_loader.rs b/programs/sbf/benches/bpf_loader.rs index 7475e9ea2d0f53..d2c98719c0f6b6 100644 --- a/programs/sbf/benches/bpf_loader.rs +++ b/programs/sbf/benches/bpf_loader.rs @@ -32,7 +32,7 @@ use { bank::Bank, bank_client::BankClient, genesis_utils::{create_genesis_config, GenesisConfigInfo}, - loader_utils::{load_program_from_file, load_upgradeable_program_and_advance_slot}, + loader_utils::{load_program_from_file, load_program_of_loader_v4}, }, solana_sdk::{ account::AccountSharedData, @@ -201,9 +201,9 @@ fn bench_program_execute_noop(bencher: &mut Bencher) { let authority_keypair = Keypair::new(); let mint_pubkey = mint_keypair.pubkey(); - let (_, invoke_program_id) = load_upgradeable_program_and_advance_slot( + let (_bank, invoke_program_id) = load_program_of_loader_v4( &mut bank_client, - bank_forks.as_ref(), + &bank_forks, &mint_keypair, &authority_keypair, "noop", diff --git a/programs/sbf/c/src/invoked/invoked.c b/programs/sbf/c/src/invoked/invoked.c index 37671cfb9fe51b..03c6e284a4a88d 100644 --- a/programs/sbf/c/src/invoked/invoked.c +++ b/programs/sbf/c/src/invoked/invoked.c @@ -31,11 +31,10 @@ extern uint64_t entrypoint(const uint8_t *input) { static const int INVOKED_PROGRAM_DUP_INDEX = 3; sol_assert(sol_deserialize(input, ¶ms, 4)); - SolPubkey sbf_loader_upgradeable_id = - (SolPubkey){.x = { - 2, 168, 246, 145, 78, 136, 161, 176, 226, 16, 21, 62, - 247, 99, 174, 43, 0, 194, 185, 61, 22, 193, 36, 210, 192, - 83, 122, 16, 4, 128, 0, 0}}; + SolPubkey loader_v4_id = + (SolPubkey){.x = { + 5, 18, 180, 17, 81, 81, 227, 122, 173, 10, 139, 197, 211, 136, 46, 123, 127, 218, 76, 243, 210, 192, 40, 200, 207, 131, 54, 24, 0, 0, 0, 0 + }}; for (int i = 0; i < params.data_len; i++) { sol_assert(params.data[i] == i); @@ -64,7 +63,7 @@ extern uint64_t entrypoint(const uint8_t *input) { sol_assert( SolPubkey_same(accounts[INVOKED_PROGRAM_INDEX].key, params.program_id)) sol_assert(SolPubkey_same(accounts[INVOKED_PROGRAM_INDEX].owner, - &sbf_loader_upgradeable_id)); + &loader_v4_id)); sol_assert(!accounts[INVOKED_PROGRAM_INDEX].is_signer); sol_assert(!accounts[INVOKED_PROGRAM_INDEX].is_writable); sol_assert(accounts[INVOKED_PROGRAM_INDEX].rent_epoch == UINT64_MAX); diff --git a/programs/sbf/c/src/read_program/read_program.c b/programs/sbf/c/src/read_program/read_program.c index 28d242efa7f8be..89eca3de9e22cc 100644 --- a/programs/sbf/c/src/read_program/read_program.c +++ b/programs/sbf/c/src/read_program/read_program.c @@ -10,10 +10,8 @@ extern uint64_t entrypoint(const uint8_t *input) { return ERROR_INVALID_ARGUMENT; } - char ka_data[] = {0x02, 0x00, 0x00, 0x00}; - sol_assert(params.ka_num == 1); - sol_assert(!sol_memcmp(params.ka[0].data, ka_data, 4)); + sol_assert(!sol_memcmp(params.ka[0].data, params.data, params.data_len)); sol_assert(params.ka[0].is_signer == false); sol_assert(params.ka[0].is_writable == false); sol_assert(params.ka[0].executable == true); diff --git a/programs/sbf/rust/invoked/src/lib.rs b/programs/sbf/rust/invoked/src/lib.rs index 1429cd71a7e51b..ab92368a87a875 100644 --- a/programs/sbf/rust/invoked/src/lib.rs +++ b/programs/sbf/rust/invoked/src/lib.rs @@ -5,8 +5,8 @@ use { solana_program::{ account_info::AccountInfo, - bpf_loader_upgradeable, entrypoint::{ProgramResult, MAX_PERMITTED_DATA_INCREASE}, + loader_v4, log::sol_log_64, msg, program::{get_return_data, invoke, invoke_signed, set_return_data}, @@ -69,10 +69,7 @@ fn process_instruction( assert!(!accounts[INVOKED_ARGUMENT_INDEX].executable); assert_eq!(accounts[INVOKED_PROGRAM_INDEX].key, program_id); - assert_eq!( - accounts[INVOKED_PROGRAM_INDEX].owner, - &bpf_loader_upgradeable::id() - ); + assert_eq!(accounts[INVOKED_PROGRAM_INDEX].owner, &loader_v4::id()); assert!(!accounts[INVOKED_PROGRAM_INDEX].is_signer); assert!(!accounts[INVOKED_PROGRAM_INDEX].is_writable); assert_eq!(accounts[INVOKED_PROGRAM_INDEX].rent_epoch, u64::MAX); diff --git a/programs/sbf/tests/programs.rs b/programs/sbf/tests/programs.rs index c5e4ad0de8b3ef..fabdf9314581fd 100644 --- a/programs/sbf/tests/programs.rs +++ b/programs/sbf/tests/programs.rs @@ -10,27 +10,20 @@ #[cfg(feature = "sbf_rust")] use { borsh::{from_slice, to_vec, BorshDeserialize, BorshSerialize}, - itertools::izip, - solana_account_decoder::parse_bpf_loader::{ - parse_bpf_upgradeable_loader, BpfUpgradeableLoaderAccountType, - }, solana_compute_budget::compute_budget::ComputeBudget, solana_feature_set::{self as feature_set, FeatureSet}, - solana_ledger::token_balances::collect_token_balances, solana_program_runtime::invoke_context::mock_process_instruction, solana_rbpf::vm::ContextObject, solana_runtime::{ - bank::{Bank, TransactionBalancesSet}, + bank::Bank, bank_client::BankClient, - bank_forks::BankForks, genesis_utils::{ bootstrap_validator_stake_lamports, create_genesis_config, create_genesis_config_with_leader_ex, GenesisConfigInfo, }, loader_utils::{ - create_program, load_program_from_file, load_upgradeable_buffer, - load_upgradeable_program, load_upgradeable_program_and_advance_slot, - load_upgradeable_program_wrapper, set_upgrade_authority, upgrade_program, + create_program, instructions_to_load_program_of_loader_v4, load_program_from_file, + load_program_of_loader_v4, load_upgradeable_buffer, load_upgradeable_program, }, }, solana_runtime_transaction::{ @@ -42,7 +35,6 @@ use { solana_sbf_rust_realloc_invoke_dep::*, solana_sdk::{ account::{AccountSharedData, ReadableAccount, WritableAccount}, - account_utils::StateMut, bpf_loader, bpf_loader_deprecated, bpf_loader_upgradeable, client::SyncClient, clock::{UnixTimestamp, MAX_PROCESSING_AGE}, @@ -53,16 +45,17 @@ use { genesis_config::ClusterType, hash::Hash, instruction::{AccountMeta, Instruction, InstructionError}, - message::{v0::LoadedAddresses, Message, SanitizedMessage}, + loader_v4, + message::{Message, SanitizedMessage}, pubkey::Pubkey, rent::Rent, reserved_account_keys::ReservedAccountKeys, - signature::{keypair_from_seed, Keypair, Signer}, + signature::{Keypair, Signer}, stake, - system_instruction::{self, MAX_PERMITTED_DATA_LENGTH}, + system_instruction::MAX_PERMITTED_DATA_LENGTH, system_program, sysvar::{self, clock}, - transaction::{Transaction, TransactionError, VersionedTransaction}, + transaction::{Transaction, TransactionError}, }, solana_svm::{ transaction_commit_result::{CommittedTransaction, TransactionCommitResult}, @@ -71,19 +64,8 @@ use { }, solana_svm_transaction::svm_message::SVMMessage, solana_timings::ExecuteTimings, - solana_transaction_status::{ - map_inner_instructions, ConfirmedTransactionWithStatusMeta, TransactionStatusMeta, - TransactionWithStatusMeta, VersionedTransactionWithStatusMeta, - }, solana_type_overrides::rand, - std::{ - assert_eq, - cell::RefCell, - collections::HashMap, - str::FromStr, - sync::{Arc, RwLock}, - time::Duration, - }, + std::{assert_eq, cell::RefCell, str::FromStr, sync::Arc, time::Duration}, }; #[cfg(feature = "sbf_rust")] @@ -128,94 +110,6 @@ fn load_execute_and_commit_transaction(bank: &Bank, tx: Transaction) -> Transact commit_results.pop().unwrap() } -#[cfg(feature = "sbf_rust")] -fn execute_transactions( - bank: &Bank, - txs: Vec, -) -> Vec> { - let batch = bank.prepare_batch_for_tests(txs.clone()); - let mut timings = ExecuteTimings::default(); - let mut mint_decimals = HashMap::new(); - let tx_pre_token_balances = collect_token_balances(&bank, &batch, &mut mint_decimals); - let ( - commit_results, - TransactionBalancesSet { - pre_balances, - post_balances, - .. - }, - ) = bank.load_execute_and_commit_transactions( - &batch, - usize::MAX, - true, - ExecutionRecordingConfig::new_single_setting(true), - &mut timings, - None, - ); - let tx_post_token_balances = collect_token_balances(&bank, &batch, &mut mint_decimals); - - izip!( - txs.iter(), - commit_results.into_iter(), - pre_balances.into_iter(), - post_balances.into_iter(), - tx_pre_token_balances.into_iter(), - tx_post_token_balances.into_iter(), - ) - .map( - |( - tx, - commit_result, - pre_balances, - post_balances, - pre_token_balances, - post_token_balances, - )| { - commit_result.map(|committed_tx| { - let CommittedTransaction { - status, - log_messages, - inner_instructions, - return_data, - executed_units, - fee_details, - .. - } = committed_tx; - - let inner_instructions = inner_instructions - .map(|inner_instructions| map_inner_instructions(inner_instructions).collect()); - - let tx_status_meta = TransactionStatusMeta { - status, - fee: fee_details.total_fee(), - pre_balances, - post_balances, - pre_token_balances: Some(pre_token_balances), - post_token_balances: Some(post_token_balances), - inner_instructions, - log_messages, - rewards: None, - loaded_addresses: LoadedAddresses::default(), - return_data, - compute_units_consumed: Some(executed_units), - }; - - ConfirmedTransactionWithStatusMeta { - slot: bank.slot(), - tx_with_meta: TransactionWithStatusMeta::Complete( - VersionedTransactionWithStatusMeta { - transaction: VersionedTransaction::from(tx.clone()), - meta: tx_status_meta, - }, - ), - block_time: None, - } - }) - }, - ) - .collect() -} - #[cfg(feature = "sbf_rust")] const LOADED_ACCOUNTS_DATA_SIZE_LIMIT_FOR_TEST: u32 = 64 * 1024 * 1024; @@ -290,9 +184,9 @@ fn test_program_sbf_sanity() { let authority_keypair = Keypair::new(); // Call user program - let (_, program_id) = load_upgradeable_program_and_advance_slot( + let (_bank, program_id) = load_program_of_loader_v4( &mut bank_client, - bank_forks.as_ref(), + &bank_forks, &mint_keypair, &authority_keypair, program.0, @@ -356,7 +250,7 @@ fn test_program_sbf_loader_deprecated() { #[test] #[cfg(feature = "sbf_rust")] #[should_panic( - expected = "called `Result::unwrap()` on an `Err` value: TransactionError(InstructionError(1, InvalidAccountData))" + expected = "called `Result::unwrap()` on an `Err` value: TransactionError(InstructionError(0, InvalidAccountData))" )] fn test_sol_alloc_free_no_longer_deployable_with_upgradeable_loader() { solana_logger::setup(); @@ -384,9 +278,9 @@ fn test_sol_alloc_free_no_longer_deployable_with_upgradeable_loader() { // in elf inside syscall table. In this case, `sol_alloc_free_` can't be // found in syscall table. Hence, the verification fails and the deployment // fails. - let (_bank, _program_id) = load_upgradeable_program_and_advance_slot( + let (_bank, _program_id) = load_program_of_loader_v4( &mut bank_client, - bank_forks.as_ref(), + &bank_forks, &mint_keypair, &authority_keypair, "solana_sbf_rust_deprecated_loader", @@ -421,9 +315,9 @@ fn test_program_sbf_duplicate_accounts() { let mut bank_client = BankClient::new_shared(bank.clone()); let authority_keypair = Keypair::new(); - let (bank, program_id) = load_upgradeable_program_and_advance_slot( + let (bank, program_id) = load_program_of_loader_v4( &mut bank_client, - bank_forks.as_ref(), + &bank_forks, &mint_keypair, &authority_keypair, program, @@ -528,9 +422,9 @@ fn test_program_sbf_error_handling() { let mut bank_client = BankClient::new_shared(bank); let authority_keypair = Keypair::new(); - let (_bank, program_id) = load_upgradeable_program_and_advance_slot( + let (_bank, program_id) = load_program_of_loader_v4( &mut bank_client, - bank_forks.as_ref(), + &bank_forks, &mint_keypair, &authority_keypair, program, @@ -638,9 +532,9 @@ fn test_return_data_and_log_data_syscall() { let mut bank_client = BankClient::new_shared(bank.clone()); let authority_keypair = Keypair::new(); - let (bank, program_id) = load_upgradeable_program_and_advance_slot( + let (bank, program_id) = load_program_of_loader_v4( &mut bank_client, - bank_forks.as_ref(), + &bank_forks, &mint_keypair, &authority_keypair, program, @@ -707,23 +601,23 @@ fn test_program_sbf_invoke_sanity() { let mut bank_client = BankClient::new_shared(bank.clone()); let authority_keypair = Keypair::new(); - let invoke_program_id = load_upgradeable_program_wrapper( - &bank_client, + let (_bank, invoke_program_id) = load_program_of_loader_v4( + &mut bank_client, + &bank_forks, &mint_keypair, &authority_keypair, program.1, ); - - let invoked_program_id = load_upgradeable_program_wrapper( - &bank_client, + let (_bank, invoked_program_id) = load_program_of_loader_v4( + &mut bank_client, + &bank_forks, &mint_keypair, &authority_keypair, program.2, ); - - let (bank, noop_program_id) = load_upgradeable_program_and_advance_slot( + let (bank, noop_program_id) = load_program_of_loader_v4( &mut bank_client, - bank_forks.as_ref(), + &bank_forks, &mint_keypair, &authority_keypair, program.3, @@ -1128,16 +1022,16 @@ fn test_program_sbf_program_id_spoofing() { let mut bank_client = BankClient::new_shared(bank.clone()); let authority_keypair = Keypair::new(); - let malicious_swap_pubkey = load_upgradeable_program_wrapper( - &bank_client, + let (_bank, malicious_swap_pubkey) = load_program_of_loader_v4( + &mut bank_client, + &bank_forks, &mint_keypair, &authority_keypair, "solana_sbf_rust_spoof1", ); - - let (bank, malicious_system_pubkey) = load_upgradeable_program_and_advance_slot( + let (bank, malicious_system_pubkey) = load_program_of_loader_v4( &mut bank_client, - bank_forks.as_ref(), + &bank_forks, &mint_keypair, &authority_keypair, "solana_sbf_rust_spoof1_system", @@ -1182,16 +1076,16 @@ fn test_program_sbf_caller_has_access_to_cpi_program() { let mut bank_client = BankClient::new_shared(bank.clone()); let authority_keypair = Keypair::new(); - let caller_pubkey = load_upgradeable_program_wrapper( - &bank_client, + let (_bank, caller_pubkey) = load_program_of_loader_v4( + &mut bank_client, + &bank_forks, &mint_keypair, &authority_keypair, "solana_sbf_rust_caller_access", ); - - let (_bank, caller2_pubkey) = load_upgradeable_program_and_advance_slot( + let (_bank, caller2_pubkey) = load_program_of_loader_v4( &mut bank_client, - bank_forks.as_ref(), + &bank_forks, &mint_keypair, &authority_keypair, "solana_sbf_rust_caller_access", @@ -1221,9 +1115,9 @@ fn test_program_sbf_ro_modify() { let mut bank_client = BankClient::new_shared(bank.clone()); let authority_keypair = Keypair::new(); - let (bank, program_pubkey) = load_upgradeable_program_and_advance_slot( + let (bank, program_pubkey) = load_program_of_loader_v4( &mut bank_client, - bank_forks.as_ref(), + &bank_forks, &mint_keypair, &authority_keypair, "solana_sbf_rust_ro_modify", @@ -1278,9 +1172,9 @@ fn test_program_sbf_call_depth() { let mut bank_client = BankClient::new_shared(bank); let authority_keypair = Keypair::new(); - let (_, program_id) = load_upgradeable_program_and_advance_slot( + let (_bank, program_id) = load_program_of_loader_v4( &mut bank_client, - bank_forks.as_ref(), + &bank_forks, &mint_keypair, &authority_keypair, "solana_sbf_rust_call_depth", @@ -1315,9 +1209,9 @@ fn test_program_sbf_compute_budget() { let mut bank_client = BankClient::new_shared(bank); let authority_keypair = Keypair::new(); - let (_, program_id) = load_upgradeable_program_and_advance_slot( + let (_bank, program_id) = load_program_of_loader_v4( &mut bank_client, - bank_forks.as_ref(), + &bank_forks, &mint_keypair, &authority_keypair, "solana_sbf_rust_noop", @@ -1446,9 +1340,9 @@ fn test_program_sbf_instruction_introspection() { let mut bank_client = BankClient::new_shared(bank.clone()); let authority_keypair = Keypair::new(); - let (bank, program_id) = load_upgradeable_program_and_advance_slot( + let (_bank, program_id) = load_program_of_loader_v4( &mut bank_client, - bank_forks.as_ref(), + &bank_forks, &mint_keypair, &authority_keypair, "solana_sbf_rust_instruction_introspection", @@ -1491,106 +1385,6 @@ fn test_program_sbf_instruction_introspection() { assert!(bank.get_account(&sysvar::instructions::id()).is_none()); } -#[test] -#[cfg(feature = "sbf_rust")] -fn test_program_sbf_upgrade() { - solana_logger::setup(); - - let GenesisConfigInfo { - genesis_config, - mint_keypair, - .. - } = create_genesis_config(50); - let (bank, bank_forks) = Bank::new_with_bank_forks_for_tests(&genesis_config); - let mut bank_client = BankClient::new_shared(bank); - - // Deploy upgrade program - let buffer_keypair = Keypair::new(); - let program_keypair = Keypair::new(); - let program_id = program_keypair.pubkey(); - let authority_keypair = Keypair::new(); - load_upgradeable_program( - &bank_client, - &mint_keypair, - &buffer_keypair, - &program_keypair, - &authority_keypair, - "solana_sbf_rust_upgradeable", - ); - bank_client - .advance_slot(1, bank_forks.as_ref(), &Pubkey::default()) - .expect("Failed to advance the slot"); - - let mut instruction = - Instruction::new_with_bytes(program_id, &[0], vec![AccountMeta::new(clock::id(), false)]); - - // Call upgrade program - let result = bank_client.send_and_confirm_instruction(&mint_keypair, instruction.clone()); - assert_eq!( - result.unwrap_err().unwrap(), - TransactionError::InstructionError(0, InstructionError::Custom(42)) - ); - - // Upgrade program - let buffer_keypair = Keypair::new(); - upgrade_program( - &bank_client, - &mint_keypair, - &buffer_keypair, - &program_id, - &authority_keypair, - "solana_sbf_rust_upgraded", - ); - bank_client.set_sysvar_for_tests(&clock::Clock { - slot: 2, - ..clock::Clock::default() - }); - bank_client - .advance_slot(1, bank_forks.as_ref(), &Pubkey::default()) - .expect("Failed to advance the slot"); - - // Call upgraded program - instruction.data[0] += 1; - let result = bank_client.send_and_confirm_instruction(&mint_keypair, instruction.clone()); - assert_eq!( - result.unwrap_err().unwrap(), - TransactionError::InstructionError(0, InstructionError::Custom(43)) - ); - - // Set a new authority - let new_authority_keypair = Keypair::new(); - set_upgrade_authority( - &bank_client, - &mint_keypair, - &program_id, - &authority_keypair, - Some(&new_authority_keypair.pubkey()), - ); - - // Upgrade back to the original program - let buffer_keypair = Keypair::new(); - upgrade_program( - &bank_client, - &mint_keypair, - &buffer_keypair, - &program_id, - &new_authority_keypair, - "solana_sbf_rust_upgradeable", - ); - - bank_client - .advance_slot(1, bank_forks.as_ref(), &Pubkey::default()) - .expect("Failed to advance the slot"); - - // Call original program - instruction.data[0] += 1; - let result = bank_client.send_and_confirm_instruction(&mint_keypair, instruction); - assert_eq!( - result.unwrap_err().unwrap(), - TransactionError::InstructionError(0, InstructionError::Custom(42)) - ); -} - fn get_stable_genesis_config() -> GenesisConfigInfo { let validator_pubkey = Pubkey::from_str("GLh546CXmtZdvpEzL8sxzqhhUf7KPvmGaRpFHB5W1sjV").unwrap(); @@ -1636,10 +1430,13 @@ fn test_program_sbf_invoke_stable_genesis_and_bank() { solana_logger::setup(); let GenesisConfigInfo { - genesis_config, + mut genesis_config, mint_keypair, .. } = get_stable_genesis_config(); + genesis_config + .accounts + .remove(&feature_set::enable_loader_v4::id()); let bank = Bank::new_for_tests(&genesis_config); let bank = Arc::new(bank); let bank_client = BankClient::new_shared(bank.clone()); @@ -1818,26 +1615,31 @@ fn test_program_sbf_invoke_in_same_tx_as_deployment() { let mut bank_client = BankClient::new_shared(bank.clone()); // Deploy upgradeable program - let buffer_keypair = Keypair::new(); - let program_keypair = Keypair::new(); - let program_id = program_keypair.pubkey(); let authority_keypair = Keypair::new(); + let (program_keypair, deployment_instructions) = instructions_to_load_program_of_loader_v4( + &bank_client, + &mint_keypair, + &authority_keypair, + "solana_sbf_rust_noop", + None, + None, + ); + let program_id = program_keypair.pubkey(); // Deploy indirect invocation program - let indirect_program_keypair = Keypair::new(); - load_upgradeable_program( - &bank_client, + let (_bank, indirect_program_id) = load_program_of_loader_v4( + &mut bank_client, + &bank_forks, &mint_keypair, - &buffer_keypair, - &indirect_program_keypair, &authority_keypair, "solana_sbf_rust_invoke_and_return", ); + // Prepare invocations let invoke_instruction = Instruction::new_with_bytes(program_id, &[0], vec![AccountMeta::new(clock::id(), false)]); let indirect_invoke_instruction = Instruction::new_with_bytes( - indirect_program_keypair.pubkey(), + indirect_program_id, &[0], vec![ AccountMeta::new_readonly(program_id, false), @@ -1845,34 +1647,6 @@ fn test_program_sbf_invoke_in_same_tx_as_deployment() { ], ); - // Prepare deployment - let program = load_upgradeable_buffer( - &bank_client, - &mint_keypair, - &buffer_keypair, - &authority_keypair, - "solana_sbf_rust_noop", - ); - let deployment_instructions = bpf_loader_upgradeable::deploy_with_max_program_len( - &mint_keypair.pubkey(), - &program_keypair.pubkey(), - &buffer_keypair.pubkey(), - &authority_keypair.pubkey(), - 1.max( - bank_client - .get_minimum_balance_for_rent_exemption( - bpf_loader_upgradeable::UpgradeableLoaderState::size_of_program(), - ) - .unwrap(), - ), - program.len() * 2, - ) - .unwrap(); - - let bank = bank_client - .advance_slot(1, bank_forks.as_ref(), &Pubkey::default()) - .expect("Failed to advance slot"); - // Deployment is invisible to both top-level-instructions and CPI instructions for (index, invoke_instruction) in [invoke_instruction, indirect_invoke_instruction] .into_iter() @@ -1880,22 +1654,19 @@ fn test_program_sbf_invoke_in_same_tx_as_deployment() { { let mut instructions = deployment_instructions.clone(); instructions.push(invoke_instruction); - let tx = Transaction::new( - &[&mint_keypair, &program_keypair, &authority_keypair], - Message::new(&instructions, Some(&mint_keypair.pubkey())), - bank.last_blockhash(), - ); + let result = bank_client + .send_and_confirm_message( + &[&mint_keypair, &program_keypair, &authority_keypair], + Message::new(&instructions, Some(&mint_keypair.pubkey())), + ) + .unwrap_err() + .unwrap(); if index == 0 { - let result = load_execute_and_commit_transaction(&bank, tx); - assert_eq!( - result.unwrap().status, - Err(TransactionError::ProgramAccountNotFound), - ); + assert_eq!(result, TransactionError::ProgramAccountNotFound); } else { - let (result, _, _) = process_transaction_and_record_inner(&bank, tx); assert_eq!( - result.unwrap_err(), - TransactionError::InstructionError(2, InstructionError::UnsupportedProgramId), + result, + TransactionError::InstructionError(38, InstructionError::UnsupportedProgramId), ); } } @@ -1915,45 +1686,54 @@ fn test_program_sbf_invoke_in_same_tx_as_redeployment() { let mut bank_client = BankClient::new_shared(bank.clone()); // Deploy upgradeable program - let buffer_keypair = Keypair::new(); - let program_keypair = Keypair::new(); - let program_id = program_keypair.pubkey(); let authority_keypair = Keypair::new(); - load_upgradeable_program( - &bank_client, + let (_bank, program_id) = load_program_of_loader_v4( + &mut bank_client, + &bank_forks, &mint_keypair, - &buffer_keypair, - &program_keypair, &authority_keypair, "solana_sbf_rust_noop", ); + let (source_program_keypair, mut deployment_instructions) = + instructions_to_load_program_of_loader_v4( + &bank_client, + &mint_keypair, + &authority_keypair, + "solana_sbf_rust_panic", + None, + Some(&program_id), + ); + let undeployment_instruction = loader_v4::retract(&program_id, &authority_keypair.pubkey()); + let deployment_instruction = deployment_instructions.pop().unwrap(); + let signers: &[&[&Keypair]] = &[ + &[&mint_keypair, &source_program_keypair], + &[&mint_keypair, &source_program_keypair, &authority_keypair], + &[&mint_keypair, &authority_keypair], + ]; + let signers = std::iter::once(signers[0]) + .chain(std::iter::once(signers[1])) + .chain(std::iter::repeat(signers[2])); + for (instruction, signers) in deployment_instructions.into_iter().zip(signers) { + let message = Message::new(&[instruction], Some(&mint_keypair.pubkey())); + bank_client + .send_and_confirm_message(signers, message) + .unwrap(); + } // Deploy indirect invocation program - let indirect_program_keypair = Keypair::new(); - load_upgradeable_program( - &bank_client, + let (bank, indirect_program_id) = load_program_of_loader_v4( + &mut bank_client, + &bank_forks, &mint_keypair, - &buffer_keypair, - &indirect_program_keypair, &authority_keypair, "solana_sbf_rust_invoke_and_return", ); - // Deploy panic program - let panic_program_keypair = Keypair::new(); - load_upgradeable_program( - &bank_client, - &mint_keypair, - &buffer_keypair, - &panic_program_keypair, - &authority_keypair, - "solana_sbf_rust_panic", - ); - + // Prepare invocations let invoke_instruction = Instruction::new_with_bytes(program_id, &[0], vec![AccountMeta::new(clock::id(), false)]); let indirect_invoke_instruction = Instruction::new_with_bytes( - indirect_program_keypair.pubkey(), + indirect_program_id, &[0], vec![ AccountMeta::new_readonly(program_id, false), @@ -1961,31 +1741,6 @@ fn test_program_sbf_invoke_in_same_tx_as_redeployment() { ], ); - // load_upgradeable_program sets clock sysvar to 1, which causes the program to be effective - // after 2 slots. They need to be called individually to create the correct fork graph in between. - bank_client - .advance_slot(1, bank_forks.as_ref(), &Pubkey::default()) - .unwrap(); - let bank = bank_client - .advance_slot(1, bank_forks.as_ref(), &Pubkey::default()) - .unwrap(); - - // Prepare redeployment - let buffer_keypair = Keypair::new(); - load_upgradeable_buffer( - &bank_client, - &mint_keypair, - &buffer_keypair, - &authority_keypair, - "solana_sbf_rust_panic", - ); - let redeployment_instruction = bpf_loader_upgradeable::upgrade( - &program_id, - &buffer_keypair.pubkey(), - &authority_keypair.pubkey(), - &mint_keypair.pubkey(), - ); - // Redeployment causes programs to be unavailable to both top-level-instructions and CPI instructions for invoke_instruction in [invoke_instruction, indirect_invoke_instruction] { // Call upgradeable program @@ -1995,7 +1750,11 @@ fn test_program_sbf_invoke_in_same_tx_as_redeployment() { // Upgrade the program and invoke in same tx let message = Message::new( - &[redeployment_instruction.clone(), invoke_instruction], + &[ + undeployment_instruction.clone(), + deployment_instruction.clone(), + invoke_instruction, + ], Some(&mint_keypair.pubkey()), ); let tx = Transaction::new( @@ -2006,7 +1765,7 @@ fn test_program_sbf_invoke_in_same_tx_as_redeployment() { let (result, _, _) = process_transaction_and_record_inner(&bank, tx); assert_eq!( result.unwrap_err(), - TransactionError::InstructionError(1, InstructionError::UnsupportedProgramId), + TransactionError::InstructionError(2, InstructionError::UnsupportedProgramId), ); } } @@ -2025,201 +1784,62 @@ fn test_program_sbf_invoke_in_same_tx_as_undeployment() { let mut bank_client = BankClient::new_shared(bank.clone()); // Deploy upgradeable program - let buffer_keypair = Keypair::new(); - let program_keypair = Keypair::new(); - let program_id = program_keypair.pubkey(); let authority_keypair = Keypair::new(); - load_upgradeable_program( - &bank_client, - &mint_keypair, - &buffer_keypair, - &program_keypair, - &authority_keypair, - "solana_sbf_rust_noop", - ); - - // Deploy indirect invocation program - let indirect_program_keypair = Keypair::new(); - load_upgradeable_program( - &bank_client, - &mint_keypair, - &buffer_keypair, - &indirect_program_keypair, - &authority_keypair, - "solana_sbf_rust_invoke_and_return", - ); - - let invoke_instruction = - Instruction::new_with_bytes(program_id, &[0], vec![AccountMeta::new(clock::id(), false)]); - let indirect_invoke_instruction = Instruction::new_with_bytes( - indirect_program_keypair.pubkey(), - &[0], - vec![ - AccountMeta::new_readonly(program_id, false), - AccountMeta::new_readonly(clock::id(), false), - ], - ); - - // load_upgradeable_program sets clock sysvar to 1, which causes the program to be effective - // after 2 slots. They need to be called individually to create the correct fork graph in between. - bank_client - .advance_slot(1, bank_forks.as_ref(), &Pubkey::default()) - .unwrap(); - let bank = bank_client - .advance_slot(1, bank_forks.as_ref(), &Pubkey::default()) - .unwrap(); - - // Prepare undeployment - let (programdata_address, _) = Pubkey::find_program_address( - &[program_keypair.pubkey().as_ref()], - &bpf_loader_upgradeable::id(), - ); - let undeployment_instruction = bpf_loader_upgradeable::close_any( - &programdata_address, - &mint_keypair.pubkey(), - Some(&authority_keypair.pubkey()), - Some(&program_id), - ); - - // Undeployment is visible to both top-level-instructions and CPI instructions - for invoke_instruction in [invoke_instruction, indirect_invoke_instruction] { - // Call upgradeable program - let result = - bank_client.send_and_confirm_instruction(&mint_keypair, invoke_instruction.clone()); - assert!(result.is_ok()); - - // Upgrade the program and invoke in same tx - let message = Message::new( - &[undeployment_instruction.clone(), invoke_instruction], - Some(&mint_keypair.pubkey()), - ); - let tx = Transaction::new( - &[&mint_keypair, &authority_keypair], - message.clone(), - bank.last_blockhash(), - ); - let (result, _, _) = process_transaction_and_record_inner(&bank, tx); - assert_eq!( - result.unwrap_err(), - TransactionError::InstructionError(1, InstructionError::UnsupportedProgramId), - ); - } -} - -#[test] -#[cfg(feature = "sbf_rust")] -fn test_program_sbf_invoke_upgradeable_via_cpi() { - solana_logger::setup(); - - let GenesisConfigInfo { - genesis_config, - mint_keypair, - .. - } = create_genesis_config(50); - - let (bank, bank_forks) = Bank::new_with_bank_forks_for_tests(&genesis_config); - let mut bank_client = BankClient::new_shared(bank); - let authority_keypair = Keypair::new(); - - let (_bank, invoke_and_return) = load_upgradeable_program_and_advance_slot( + let (_bank, program_id) = load_program_of_loader_v4( &mut bank_client, - bank_forks.as_ref(), + &bank_forks, &mint_keypair, &authority_keypair, - "solana_sbf_rust_invoke_and_return", - ); - - // Deploy upgradeable program - let program_id = load_upgradeable_program_wrapper( - &bank_client, - &mint_keypair, - &authority_keypair, - "solana_sbf_rust_upgradeable", - ); - bank_client.set_sysvar_for_tests(&clock::Clock { - slot: 2, - ..clock::Clock::default() - }); - - bank_client - .advance_slot(1, bank_forks.as_ref(), &Pubkey::default()) - .expect("Failed to advance slot"); - - let mut instruction = Instruction::new_with_bytes( - invoke_and_return, - &[0], - vec![ - AccountMeta::new_readonly(program_id, false), - AccountMeta::new_readonly(clock::id(), false), - ], - ); - - // Call invoker program to invoke the upgradeable program - instruction.data[0] += 1; - let result = bank_client.send_and_confirm_instruction(&mint_keypair, instruction.clone()); - assert_eq!( - result.unwrap_err().unwrap(), - TransactionError::InstructionError(0, InstructionError::Custom(42)) - ); - - // Upgrade program - let buffer_keypair = Keypair::new(); - upgrade_program( - &bank_client, - &mint_keypair, - &buffer_keypair, - &program_id, - &authority_keypair, - "solana_sbf_rust_upgraded", - ); - bank_client.set_sysvar_for_tests(&clock::Clock { - slot: 3, - ..clock::Clock::default() - }); - bank_client - .advance_slot(1, bank_forks.as_ref(), &Pubkey::default()) - .expect("Failed to advance slot"); - - // Call the upgraded program - instruction.data[0] += 1; - let result = bank_client.send_and_confirm_instruction(&mint_keypair, instruction.clone()); - assert_eq!( - result.unwrap_err().unwrap(), - TransactionError::InstructionError(0, InstructionError::Custom(43)) + "solana_sbf_rust_noop", ); - // Set a new authority - let new_authority_keypair = Keypair::new(); - set_upgrade_authority( - &bank_client, + // Deploy indirect invocation program + let (bank, indirect_program_id) = load_program_of_loader_v4( + &mut bank_client, + &bank_forks, &mint_keypair, - &program_id, &authority_keypair, - Some(&new_authority_keypair.pubkey()), + "solana_sbf_rust_invoke_and_return", ); - // Upgrade back to the original program - let buffer_keypair = Keypair::new(); - upgrade_program( - &bank_client, - &mint_keypair, - &buffer_keypair, - &program_id, - &new_authority_keypair, - "solana_sbf_rust_upgradeable", + // Prepare invocations + let invoke_instruction = + Instruction::new_with_bytes(program_id, &[0], vec![AccountMeta::new(clock::id(), false)]); + let indirect_invoke_instruction = Instruction::new_with_bytes( + indirect_program_id, + &[0], + vec![ + AccountMeta::new_readonly(program_id, false), + AccountMeta::new_readonly(clock::id(), false), + ], ); - bank_client - .advance_slot(1, bank_forks.as_ref(), &Pubkey::default()) - .expect("Failed to advance slot"); + // Prepare undeployment + let undeployment_instruction = loader_v4::retract(&program_id, &authority_keypair.pubkey()); - // Call original program - instruction.data[0] += 1; - let result = bank_client.send_and_confirm_instruction(&mint_keypair, instruction.clone()); - assert_eq!( - result.unwrap_err().unwrap(), - TransactionError::InstructionError(0, InstructionError::Custom(42)) - ); + // Undeployment is visible to both top-level-instructions and CPI instructions + for invoke_instruction in [invoke_instruction, indirect_invoke_instruction] { + // Call upgradeable program + let result = + bank_client.send_and_confirm_instruction(&mint_keypair, invoke_instruction.clone()); + assert!(result.is_ok()); + + // Upgrade the program and invoke in same tx + let message = Message::new( + &[undeployment_instruction.clone(), invoke_instruction], + Some(&mint_keypair.pubkey()), + ); + let tx = Transaction::new( + &[&mint_keypair, &authority_keypair], + message.clone(), + bank.last_blockhash(), + ); + let (result, _, _) = process_transaction_and_record_inner(&bank, tx); + assert_eq!( + result.unwrap_err(), + TransactionError::InstructionError(1, InstructionError::UnsupportedProgramId), + ); + } } #[test] @@ -2249,9 +1869,9 @@ fn test_program_sbf_disguised_as_sbf_loader() { let mut bank_client = BankClient::new_shared(bank); let authority_keypair = Keypair::new(); - let (_bank, program_id) = load_upgradeable_program_and_advance_slot( + let (_bank, program_id) = load_program_of_loader_v4( &mut bank_client, - bank_forks.as_ref(), + &bank_forks, &mint_keypair, &authority_keypair, program, @@ -2282,15 +1902,20 @@ fn test_program_reads_from_program_account() { let mut bank_client = BankClient::new_shared(bank); let authority_keypair = Keypair::new(); - let (_bank, program_id) = load_upgradeable_program_and_advance_slot( + let (_bank, program_id) = load_program_of_loader_v4( &mut bank_client, - bank_forks.as_ref(), + &bank_forks, &mint_keypair, &authority_keypair, "read_program", ); + let data = bank_client.get_account_data(&program_id).unwrap().unwrap(); let account_metas = vec![AccountMeta::new_readonly(program_id, false)]; - let instruction = Instruction::new_with_bytes(program_id, &[], account_metas); + let instruction = Instruction::new_with_bytes( + program_id, + &data[0..loader_v4::LoaderV4State::program_data_offset()], + account_metas, + ); bank_client .send_and_confirm_instruction(&mint_keypair, instruction) .unwrap(); @@ -2315,9 +1940,9 @@ fn test_program_sbf_c_dup() { let mut bank_client = BankClient::new_shared(bank); let authority_keypair = Keypair::new(); - let (_, program_id) = load_upgradeable_program_and_advance_slot( + let (_bank, program_id) = load_program_of_loader_v4( &mut bank_client, - bank_forks.as_ref(), + &bank_forks, &mint_keypair, &authority_keypair, "ser", @@ -2334,7 +1959,7 @@ fn test_program_sbf_c_dup() { #[test] #[cfg(feature = "sbf_rust")] -fn test_program_sbf_upgrade_via_cpi() { +fn test_program_sbf_upgrade() { solana_logger::setup(); let GenesisConfigInfo { @@ -2342,113 +1967,91 @@ fn test_program_sbf_upgrade_via_cpi() { mint_keypair, .. } = create_genesis_config(50); - let (bank, bank_forks) = Bank::new_with_bank_forks_for_tests(&genesis_config); let mut bank_client = BankClient::new_shared(bank); - let authority_keypair = Keypair::new(); - - let (_bank, invoke_and_return) = load_upgradeable_program_and_advance_slot( - &mut bank_client, - bank_forks.as_ref(), - &mint_keypair, - &authority_keypair, - "solana_sbf_rust_invoke_and_return", - ); - // Deploy upgradeable program - let buffer_keypair = Keypair::new(); - let program_keypair = Keypair::new(); - let program_id = program_keypair.pubkey(); + // Deploy upgrade program let authority_keypair = Keypair::new(); - load_upgradeable_program( - &bank_client, + let (_bank, program_id) = load_program_of_loader_v4( + &mut bank_client, + &bank_forks, &mint_keypair, - &buffer_keypair, - &program_keypair, &authority_keypair, "solana_sbf_rust_upgradeable", ); - bank_client - .advance_slot(1, bank_forks.as_ref(), &Pubkey::default()) - .expect("Failed to advance the slot"); - let program_account = bank_client.get_account(&program_id).unwrap().unwrap(); - let Ok(bpf_loader_upgradeable::UpgradeableLoaderState::Program { - programdata_address, - }) = program_account.state() - else { - unreachable!() - }; - let original_programdata = bank_client - .get_account_data(&programdata_address) - .unwrap() - .unwrap(); - - let mut instruction = Instruction::new_with_bytes( - invoke_and_return, - &[0], - vec![ - AccountMeta::new_readonly(program_id, false), - AccountMeta::new_readonly(clock::id(), false), - ], - ); - // Call the upgradable program - instruction.data[0] += 1; + // Call upgradeable program + let mut instruction = + Instruction::new_with_bytes(program_id, &[0], vec![AccountMeta::new(clock::id(), false)]); let result = bank_client.send_and_confirm_instruction(&mint_keypair, instruction.clone()); assert_eq!( result.unwrap_err().unwrap(), TransactionError::InstructionError(0, InstructionError::Custom(42)) ); - // Load the buffer account - let buffer_keypair = Keypair::new(); - load_upgradeable_buffer( - &bank_client, - &mint_keypair, - &buffer_keypair, - &authority_keypair, - "solana_sbf_rust_upgraded", - ); - - // Upgrade program via CPI - let mut upgrade_instruction = bpf_loader_upgradeable::upgrade( + // Set authority + let new_authority_keypair = Keypair::new(); + let authority_instruction = loader_v4::transfer_authority( &program_id, - &buffer_keypair.pubkey(), &authority_keypair.pubkey(), - &mint_keypair.pubkey(), + &new_authority_keypair.pubkey(), ); - upgrade_instruction.program_id = invoke_and_return; - upgrade_instruction - .accounts - .insert(0, AccountMeta::new(bpf_loader_upgradeable::id(), false)); - let message = Message::new(&[upgrade_instruction], Some(&mint_keypair.pubkey())); + let message = Message::new(&[authority_instruction], Some(&mint_keypair.pubkey())); bank_client - .send_and_confirm_message(&[&mint_keypair, &authority_keypair], message) + .send_and_confirm_message( + &[&mint_keypair, &authority_keypair, &new_authority_keypair], + message, + ) .unwrap(); + // Upgrade program + let (source_program_keypair, mut deployment_instructions) = + instructions_to_load_program_of_loader_v4( + &bank_client, + &mint_keypair, + &new_authority_keypair, + "solana_sbf_rust_upgraded", + None, + Some(&program_id), + ); + deployment_instructions.insert( + deployment_instructions.len() - 1, + loader_v4::retract(&program_id, &new_authority_keypair.pubkey()), + ); + let signers: &[&[&Keypair]] = &[ + &[&mint_keypair, &source_program_keypair], + &[ + &mint_keypair, + &source_program_keypair, + &new_authority_keypair, + ], + &[&mint_keypair, &new_authority_keypair], + ]; + let signers = std::iter::once(signers[0]) + .chain(std::iter::once(signers[1])) + .chain(std::iter::repeat(signers[2])); + for (instruction, signers) in deployment_instructions.into_iter().zip(signers) { + let message = Message::new(&[instruction], Some(&mint_keypair.pubkey())); + bank_client + .send_and_confirm_message(signers, message) + .unwrap(); + } bank_client - .advance_slot(1, bank_forks.as_ref(), &Pubkey::default()) + .advance_slot(1, &bank_forks, &Pubkey::default()) .expect("Failed to advance the slot"); - // Call the upgraded program + // Call upgraded program instruction.data[0] += 1; let result = bank_client.send_and_confirm_instruction(&mint_keypair, instruction.clone()); assert_eq!( result.unwrap_err().unwrap(), TransactionError::InstructionError(0, InstructionError::Custom(43)) ); - - // Validate that the programdata was actually overwritten - let programdata = bank_client - .get_account_data(&programdata_address) - .unwrap() - .unwrap(); - assert_ne!(programdata, original_programdata); } #[test] #[cfg(feature = "sbf_rust")] -fn test_program_sbf_set_upgrade_authority_via_cpi() { +fn test_program_sbf_upgrade_via_cpi() { solana_logger::setup(); let GenesisConfigInfo { @@ -2461,200 +2064,115 @@ fn test_program_sbf_set_upgrade_authority_via_cpi() { let mut bank_client = BankClient::new_shared(bank); let authority_keypair = Keypair::new(); - // Deploy CPI invoker program - let invoke_and_return = load_upgradeable_program_wrapper( - &bank_client, + let (_bank, invoke_and_return) = load_program_of_loader_v4( + &mut bank_client, + &bank_forks, &mint_keypair, &authority_keypair, "solana_sbf_rust_invoke_and_return", ); // Deploy upgradeable program - let program_id = load_upgradeable_program_wrapper( - &bank_client, + let authority_keypair = Keypair::new(); + let (_bank, program_id) = load_program_of_loader_v4( + &mut bank_client, + &bank_forks, &mint_keypair, &authority_keypair, "solana_sbf_rust_upgradeable", ); - bank_client - .advance_slot(1, bank_forks.as_ref(), &Pubkey::default()) - .expect("Failed to advance the slot"); + // Call the upgradable program via CPI + let mut instruction = Instruction::new_with_bytes( + invoke_and_return, + &[0], + vec![ + AccountMeta::new_readonly(program_id, false), + AccountMeta::new_readonly(clock::id(), false), + ], + ); + instruction.data[0] += 1; + let result = bank_client.send_and_confirm_instruction(&mint_keypair, instruction.clone()); + assert_eq!( + result.unwrap_err().unwrap(), + TransactionError::InstructionError(0, InstructionError::Custom(42)) + ); - // Set program upgrade authority instruction to invoke via CPI - let new_upgrade_authority_key = Keypair::new().pubkey(); - let mut set_upgrade_authority_instruction = bpf_loader_upgradeable::set_upgrade_authority( + // Set authority via CPI + let new_authority_keypair = Keypair::new(); + let mut authority_instruction = loader_v4::transfer_authority( &program_id, &authority_keypair.pubkey(), - Some(&new_upgrade_authority_key), + &new_authority_keypair.pubkey(), ); - - // Invoke set_upgrade_authority via CPI invoker program - set_upgrade_authority_instruction.program_id = invoke_and_return; - set_upgrade_authority_instruction + authority_instruction.program_id = invoke_and_return; + authority_instruction .accounts - .insert(0, AccountMeta::new(bpf_loader_upgradeable::id(), false)); - - let message = Message::new( - &[set_upgrade_authority_instruction], - Some(&mint_keypair.pubkey()), - ); + .insert(0, AccountMeta::new(loader_v4::id(), false)); + let message = Message::new(&[authority_instruction], Some(&mint_keypair.pubkey())); bank_client - .send_and_confirm_message(&[&mint_keypair, &authority_keypair], message) + .send_and_confirm_message( + &[&mint_keypair, &authority_keypair, &new_authority_keypair], + message, + ) .unwrap(); - // Assert upgrade authority was changed - let program_account_data = bank_client.get_account_data(&program_id).unwrap().unwrap(); - let program_account = parse_bpf_upgradeable_loader(&program_account_data).unwrap(); - - let upgrade_authority_key = match program_account { - BpfUpgradeableLoaderAccountType::Program(ui_program) => { - let program_data_account_key = Pubkey::from_str(&ui_program.program_data).unwrap(); - let program_data_account_data = bank_client - .get_account_data(&program_data_account_key) - .unwrap() - .unwrap(); - let program_data_account = - parse_bpf_upgradeable_loader(&program_data_account_data).unwrap(); - - match program_data_account { - BpfUpgradeableLoaderAccountType::ProgramData(ui_program_data) => ui_program_data - .authority - .map(|a| Pubkey::from_str(&a).unwrap()), - _ => None, - } - } - _ => None, - }; - - assert_eq!(Some(new_upgrade_authority_key), upgrade_authority_key); -} - -#[test] -#[cfg(feature = "sbf_rust")] -fn test_program_upgradeable_locks() { - fn setup_program_upgradeable_locks( - payer_keypair: &Keypair, - buffer_keypair: &Keypair, - program_keypair: &Keypair, - ) -> (Arc, Arc>, Transaction, Transaction) { - solana_logger::setup(); - - let GenesisConfigInfo { - genesis_config, - mint_keypair, - .. - } = create_genesis_config(2_000_000_000); - let (bank, bank_forks) = Bank::new_with_bank_forks_for_tests(&genesis_config); - let mut bank_client = BankClient::new_shared(bank.clone()); - - load_upgradeable_program( + // Upgrade program via CPI + let (source_program_keypair, mut deployment_instructions) = + instructions_to_load_program_of_loader_v4( &bank_client, &mint_keypair, - buffer_keypair, - program_keypair, - payer_keypair, - "solana_sbf_rust_panic", + &new_authority_keypair, + "solana_sbf_rust_upgraded", + None, + Some(&program_id), ); - - // Load the buffer account - load_upgradeable_buffer( - &bank_client, + deployment_instructions.insert( + deployment_instructions.len() - 1, + loader_v4::retract(&program_id, &new_authority_keypair.pubkey()), + ); + let mut upgrade_instruction = deployment_instructions.pop().unwrap(); + let signers: &[&[&Keypair]] = &[ + &[&mint_keypair, &source_program_keypair], + &[ &mint_keypair, - buffer_keypair, - &payer_keypair, - "solana_sbf_rust_noop", - ); - - let bank = bank_client - .advance_slot(1, bank_forks.as_ref(), &Pubkey::default()) - .expect("Failed to advance the slot"); - + &source_program_keypair, + &new_authority_keypair, + ], + &[&mint_keypair, &new_authority_keypair], + ]; + let signers = std::iter::once(signers[0]) + .chain(std::iter::once(signers[1])) + .chain(std::iter::repeat(signers[2])); + for (instruction, signers) in deployment_instructions.into_iter().zip(signers) { + let message = Message::new(&[instruction], Some(&mint_keypair.pubkey())); bank_client - .send_and_confirm_instruction( - &mint_keypair, - system_instruction::transfer( - &mint_keypair.pubkey(), - &payer_keypair.pubkey(), - 1_000_000_000, - ), - ) + .send_and_confirm_message(signers, message) .unwrap(); - - let invoke_tx = Transaction::new( - &[payer_keypair], - Message::new( - &[Instruction::new_with_bytes( - program_keypair.pubkey(), - &[0; 0], - vec![], - )], - Some(&payer_keypair.pubkey()), - ), - bank.last_blockhash(), - ); - let upgrade_tx = Transaction::new( - &[payer_keypair], - Message::new( - &[bpf_loader_upgradeable::upgrade( - &program_keypair.pubkey(), - &buffer_keypair.pubkey(), - &payer_keypair.pubkey(), - &payer_keypair.pubkey(), - )], - Some(&payer_keypair.pubkey()), - ), - bank.last_blockhash(), - ); - - (bank, bank_forks, invoke_tx, upgrade_tx) } + upgrade_instruction.program_id = invoke_and_return; + upgrade_instruction + .accounts + .insert(0, AccountMeta::new(loader_v4::id(), false)); + let message = Message::new(&[upgrade_instruction], Some(&mint_keypair.pubkey())); + let result = + bank_client.send_and_confirm_message(&[&mint_keypair, &new_authority_keypair], message); + // This fails for now because of the `callee_account.is_executable()` check in CPI `translate_and_update_accounts()` + assert_eq!( + result.unwrap_err().unwrap(), + TransactionError::InstructionError(0, InstructionError::AccountDataSizeChanged) + ); + bank_client + .advance_slot(1, &bank_forks, &Pubkey::default()) + .expect("Failed to advance the slot"); - let payer_keypair = keypair_from_seed(&[56u8; 32]).unwrap(); - let buffer_keypair = keypair_from_seed(&[11; 32]).unwrap(); - let program_keypair = keypair_from_seed(&[77u8; 32]).unwrap(); - - let results1 = { - let (bank, _bank_forks, invoke_tx, upgrade_tx) = - setup_program_upgradeable_locks(&payer_keypair, &buffer_keypair, &program_keypair); - execute_transactions(&bank, vec![upgrade_tx, invoke_tx]) - }; - - let results2 = { - let (bank, _bank_forks, invoke_tx, upgrade_tx) = - setup_program_upgradeable_locks(&payer_keypair, &buffer_keypair, &program_keypair); - execute_transactions(&bank, vec![invoke_tx, upgrade_tx]) - }; - - assert!(matches!( - results1[0], - Ok(ConfirmedTransactionWithStatusMeta { - tx_with_meta: TransactionWithStatusMeta::Complete(VersionedTransactionWithStatusMeta { - meta: TransactionStatusMeta { status: Ok(()), .. }, - .. - }), - .. - }) - )); - assert_eq!(results1[1], Err(TransactionError::AccountInUse)); - - assert!(matches!( - results2[0], - Ok(ConfirmedTransactionWithStatusMeta { - tx_with_meta: TransactionWithStatusMeta::Complete(VersionedTransactionWithStatusMeta { - meta: TransactionStatusMeta { - status: Err(TransactionError::InstructionError( - 0, - InstructionError::ProgramFailedToComplete - )), - .. - }, - .. - }), - .. - }) - )); - assert_eq!(results2[1], Err(TransactionError::AccountInUse)); + // Call the upgraded program via CPI + instruction.data[0] += 1; + let result = bank_client.send_and_confirm_instruction(&mint_keypair, instruction.clone()); + assert_eq!( + result.unwrap_err().unwrap(), + TransactionError::InstructionError(0, InstructionError::UnsupportedProgramId) + ); } #[test] @@ -2672,9 +2190,9 @@ fn test_program_sbf_ro_account_modify() { let mut bank_client = BankClient::new_shared(bank.clone()); let authority_keypair = Keypair::new(); - let (bank, program_id) = load_upgradeable_program_and_advance_slot( + let (bank, program_id) = load_program_of_loader_v4( &mut bank_client, - bank_forks.as_ref(), + &bank_forks, &mint_keypair, &authority_keypair, "solana_sbf_rust_ro_account_modify", @@ -2746,9 +2264,9 @@ fn test_program_sbf_realloc() { let mut bank_client = BankClient::new_shared(bank.clone()); let authority_keypair = Keypair::new(); - let (bank, program_id) = load_upgradeable_program_and_advance_slot( + let (bank, program_id) = load_program_of_loader_v4( &mut bank_client, - bank_forks.as_ref(), + &bank_forks, &mint_keypair, &authority_keypair, "solana_sbf_rust_realloc", @@ -3163,16 +2681,16 @@ fn test_program_sbf_realloc_invoke() { let mut bank_client = BankClient::new_shared(bank.clone()); let authority_keypair = Keypair::new(); - let realloc_program_id = load_upgradeable_program_wrapper( - &bank_client, + let (_bank, realloc_program_id) = load_program_of_loader_v4( + &mut bank_client, + &bank_forks, &mint_keypair, &authority_keypair, "solana_sbf_rust_realloc", ); - - let (bank, realloc_invoke_program_id) = load_upgradeable_program_and_advance_slot( + let (bank, realloc_invoke_program_id) = load_program_of_loader_v4( &mut bank_client, - bank_forks.as_ref(), + &bank_forks, &mint_keypair, &authority_keypair, "solana_sbf_rust_realloc_invoke", @@ -3776,27 +3294,30 @@ fn test_program_sbf_processed_inner_instruction() { let mut bank_client = BankClient::new_shared(bank.clone()); let authority_keypair = Keypair::new(); - let sibling_program_id = load_upgradeable_program_wrapper( - &bank_client, + let (_bank, sibling_program_id) = load_program_of_loader_v4( + &mut bank_client, + &bank_forks, &mint_keypair, &authority_keypair, "solana_sbf_rust_sibling_instructions", ); - let sibling_inner_program_id = load_upgradeable_program_wrapper( - &bank_client, + let (_bank, sibling_inner_program_id) = load_program_of_loader_v4( + &mut bank_client, + &bank_forks, &mint_keypair, &authority_keypair, "solana_sbf_rust_sibling_inner_instructions", ); - let noop_program_id = load_upgradeable_program_wrapper( - &bank_client, + let (_bank, noop_program_id) = load_program_of_loader_v4( + &mut bank_client, + &bank_forks, &mint_keypair, &authority_keypair, - "solana_sbf_rust_noop", + "noop", ); - let (_, invoke_and_return_program_id) = load_upgradeable_program_and_advance_slot( + let (_bank, invoke_and_return_program_id) = load_program_of_loader_v4( &mut bank_client, - bank_forks.as_ref(), + &bank_forks, &mint_keypair, &authority_keypair, "solana_sbf_rust_invoke_and_return", @@ -3859,9 +3380,9 @@ fn test_program_fees() { let mut bank_client = BankClient::new_shared(bank); let authority_keypair = Keypair::new(); - let (_bank, program_id) = load_upgradeable_program_and_advance_slot( + let (_bank, program_id) = load_program_of_loader_v4( &mut bank_client, - bank_forks.as_ref(), + &bank_forks, &mint_keypair, &authority_keypair, "solana_sbf_rust_noop", @@ -3946,9 +3467,9 @@ fn test_get_minimum_delegation() { let mut bank_client = BankClient::new_shared(bank.clone()); let authority_keypair = Keypair::new(); - let (_bank, program_id) = load_upgradeable_program_and_advance_slot( + let (_bank, program_id) = load_program_of_loader_v4( &mut bank_client, - bank_forks.as_ref(), + &bank_forks, &mint_keypair, &authority_keypair, "solana_sbf_rust_get_minimum_delegation", @@ -4021,23 +3542,23 @@ fn test_cpi_account_ownership_writability() { let mut bank_client = BankClient::new_shared(bank); let authority_keypair = Keypair::new(); - let invoke_program_id = load_upgradeable_program_wrapper( - &bank_client, + let (_bank, invoke_program_id) = load_program_of_loader_v4( + &mut bank_client, + &bank_forks, &mint_keypair, &authority_keypair, "solana_sbf_rust_invoke", ); - - let invoked_program_id = load_upgradeable_program_wrapper( - &bank_client, + let (_bank, invoked_program_id) = load_program_of_loader_v4( + &mut bank_client, + &bank_forks, &mint_keypair, &authority_keypair, "solana_sbf_rust_invoked", ); - - let (bank, realloc_program_id) = load_upgradeable_program_and_advance_slot( + let (bank, realloc_program_id) = load_program_of_loader_v4( &mut bank_client, - bank_forks.as_ref(), + &bank_forks, &mint_keypair, &authority_keypair, "solana_sbf_rust_realloc", @@ -4205,16 +3726,16 @@ fn test_cpi_account_data_updates() { let mut bank_client = BankClient::new_shared(bank); let authority_keypair = Keypair::new(); - let invoke_program_id = load_upgradeable_program_wrapper( - &bank_client, + let (_bank, invoke_program_id) = load_program_of_loader_v4( + &mut bank_client, + &bank_forks, &mint_keypair, &authority_keypair, "solana_sbf_rust_invoke", ); - - let (bank, realloc_program_id) = load_upgradeable_program_and_advance_slot( + let (bank, realloc_program_id) = load_program_of_loader_v4( &mut bank_client, - bank_forks.as_ref(), + &bank_forks, &mint_keypair, &authority_keypair, "solana_sbf_rust_realloc", @@ -4363,9 +3884,9 @@ fn test_cpi_deprecated_loader_realloc() { let mut bank_client = BankClient::new_shared(bank); let authority_keypair = Keypair::new(); - let (bank, invoke_program_id) = load_upgradeable_program_and_advance_slot( + let (bank, invoke_program_id) = load_program_of_loader_v4( &mut bank_client, - bank_forks.as_ref(), + &bank_forks, &mint_keypair, &authority_keypair, "solana_sbf_rust_invoke", @@ -4508,9 +4029,9 @@ fn test_cpi_change_account_data_memory_allocation() { let mut bank_client = BankClient::new_shared(bank); let authority_keypair = Keypair::new(); - let (bank, invoke_program_id) = load_upgradeable_program_and_advance_slot( + let (bank, invoke_program_id) = load_program_of_loader_v4( &mut bank_client, - bank_forks.as_ref(), + &bank_forks, &mint_keypair, &authority_keypair, "solana_sbf_rust_invoke", @@ -4553,12 +4074,16 @@ fn test_cpi_invalid_account_info_pointers() { let mut bank_client = BankClient::new_shared(bank); let authority_keypair = Keypair::new(); - let c_invoke_program_id = - load_upgradeable_program_wrapper(&bank_client, &mint_keypair, &authority_keypair, "invoke"); - - let (bank, invoke_program_id) = load_upgradeable_program_and_advance_slot( + let (_bank, c_invoke_program_id) = load_program_of_loader_v4( + &mut bank_client, + &bank_forks, + &mint_keypair, + &authority_keypair, + "invoke", + ); + let (bank, invoke_program_id) = load_program_of_loader_v4( &mut bank_client, - bank_forks.as_ref(), + &bank_forks, &mint_keypair, &authority_keypair, "solana_sbf_rust_invoke", @@ -4623,9 +4148,9 @@ fn test_deny_executable_write() { let mut bank_client = BankClient::new_shared(bank); let authority_keypair = Keypair::new(); - let (_bank, invoke_program_id) = load_upgradeable_program_and_advance_slot( + let (_bank, invoke_program_id) = load_program_of_loader_v4( &mut bank_client, - bank_forks.as_ref(), + &bank_forks, &mint_keypair, &authority_keypair, "solana_sbf_rust_invoke", @@ -4678,9 +4203,9 @@ fn test_update_callee_account() { let mut bank_client = BankClient::new_shared(bank.clone()); let authority_keypair = Keypair::new(); - let (bank, invoke_program_id) = load_upgradeable_program_and_advance_slot( + let (bank, invoke_program_id) = load_program_of_loader_v4( &mut bank_client, - bank_forks.as_ref(), + &bank_forks, &mint_keypair, &authority_keypair, "solana_sbf_rust_invoke", @@ -4963,9 +4488,9 @@ fn test_account_info_in_account() { let mut bank_client = BankClient::new_shared(bank.clone()); let authority_keypair = Keypair::new(); - let (bank, invoke_program_id) = load_upgradeable_program_and_advance_slot( + let (bank, invoke_program_id) = load_program_of_loader_v4( &mut bank_client, - bank_forks.as_ref(), + &bank_forks, &mint_keypair, &authority_keypair, program, @@ -5021,27 +4546,21 @@ fn test_clone_account_data() { let mut bank_client = BankClient::new_shared(bank.clone()); let authority_keypair = Keypair::new(); - let (_, invoke_program_id) = load_upgradeable_program_and_advance_slot( + let (_bank, invoke_program_id) = load_program_of_loader_v4( &mut bank_client, - bank_forks.as_ref(), + &bank_forks, &mint_keypair, &authority_keypair, "solana_sbf_rust_invoke", ); - - let (bank, invoke_program_id2) = load_upgradeable_program_and_advance_slot( + let (bank, invoke_program_id2) = load_program_of_loader_v4( &mut bank_client, - bank_forks.as_ref(), + &bank_forks, &mint_keypair, &authority_keypair, "solana_sbf_rust_invoke", ); - assert_ne!(invoke_program_id, invoke_program_id2); - - println!("invoke_program_id:{invoke_program_id}"); - println!("invoke_program_id2:{invoke_program_id2}"); - let account_keypair = Keypair::new(); let mint_pubkey = mint_keypair.pubkey(); @@ -5156,9 +4675,9 @@ fn test_stack_heap_zeroed() { let mut bank_client = BankClient::new_shared(bank); let authority_keypair = Keypair::new(); - let (bank, invoke_program_id) = load_upgradeable_program_and_advance_slot( + let (bank, invoke_program_id) = load_program_of_loader_v4( &mut bank_client, - bank_forks.as_ref(), + &bank_forks, &mint_keypair, &authority_keypair, "solana_sbf_rust_invoke", @@ -5222,9 +4741,9 @@ fn test_function_call_args() { let mut bank_client = BankClient::new_shared(bank); let authority_keypair = Keypair::new(); - let (bank, program_id) = load_upgradeable_program_and_advance_slot( + let (bank, program_id) = load_program_of_loader_v4( &mut bank_client, - bank_forks.as_ref(), + &bank_forks, &mint_keypair, &authority_keypair, "solana_sbf_rust_call_args", diff --git a/programs/sbf/tests/simulation.rs b/programs/sbf/tests/simulation.rs index 62732531065915..e16d25eee2910f 100644 --- a/programs/sbf/tests/simulation.rs +++ b/programs/sbf/tests/simulation.rs @@ -6,7 +6,7 @@ use { bank::Bank, bank_client::BankClient, genesis_utils::{create_genesis_config, GenesisConfigInfo}, - loader_utils::load_upgradeable_program_and_advance_slot, + loader_utils::load_program_of_loader_v4, }, solana_runtime_transaction::runtime_transaction::RuntimeTransaction, solana_sdk::{ @@ -31,7 +31,7 @@ fn test_no_panic_banks_client() { let (bank, bank_forks) = Bank::new_with_bank_forks_for_tests(&genesis_config); let mut bank_client = BankClient::new_shared(bank.clone()); let authority_keypair = Keypair::new(); - let (bank, program_id) = load_upgradeable_program_and_advance_slot( + let (bank, program_id) = load_program_of_loader_v4( &mut bank_client, bank_forks.as_ref(), &mint_keypair, diff --git a/programs/sbf/tests/syscall_get_epoch_stake.rs b/programs/sbf/tests/syscall_get_epoch_stake.rs index 2cd7e20a1f3590..d87a30eec7d24d 100644 --- a/programs/sbf/tests/syscall_get_epoch_stake.rs +++ b/programs/sbf/tests/syscall_get_epoch_stake.rs @@ -8,7 +8,7 @@ use { genesis_utils::{ create_genesis_config_with_vote_accounts, GenesisConfigInfo, ValidatorVoteKeypairs, }, - loader_utils::load_upgradeable_program_and_advance_slot, + loader_utils::load_program_of_loader_v4, }, solana_runtime_transaction::runtime_transaction::RuntimeTransaction, solana_sdk::{ @@ -70,9 +70,9 @@ fn test_syscall_get_epoch_stake() { let mut bank_client = BankClient::new_shared(bank); let authority_keypair = Keypair::new(); - let (bank, program_id) = load_upgradeable_program_and_advance_slot( + let (bank, program_id) = load_program_of_loader_v4( &mut bank_client, - bank_forks.as_ref(), + &bank_forks, &mint_keypair, &authority_keypair, "solana_sbf_syscall_get_epoch_stake", diff --git a/programs/sbf/tests/sysvar.rs b/programs/sbf/tests/sysvar.rs index 41a3d7016daffa..a54c89158bffc6 100644 --- a/programs/sbf/tests/sysvar.rs +++ b/programs/sbf/tests/sysvar.rs @@ -6,7 +6,7 @@ use { bank::Bank, bank_client::BankClient, genesis_utils::{create_genesis_config, GenesisConfigInfo}, - loader_utils::load_upgradeable_program_and_advance_slot, + loader_utils::load_program_of_loader_v4, }, solana_runtime_transaction::runtime_transaction::RuntimeTransaction, solana_sdk::{ @@ -62,7 +62,7 @@ fn test_sysvar_syscalls() { let (bank, bank_forks) = bank.wrap_with_bank_forks_for_tests(); let mut bank_client = BankClient::new_shared(bank); let authority_keypair = Keypair::new(); - let (bank, program_id) = load_upgradeable_program_and_advance_slot( + let (bank, program_id) = load_program_of_loader_v4( &mut bank_client, bank_forks.as_ref(), &mint_keypair, diff --git a/runtime/src/bank/tests.rs b/runtime/src/bank/tests.rs index 4becb2b4b2dc98..d650c2d79bf7d1 100644 --- a/runtime/src/bank/tests.rs +++ b/runtime/src/bank/tests.rs @@ -7130,6 +7130,7 @@ fn test_bpf_loader_upgradeable_deploy_with_max_len() { let (genesis_config, mint_keypair) = create_genesis_config_no_tx_fee(1_000_000_000); let mut bank = Bank::new_for_tests(&genesis_config); bank.feature_set = Arc::new(FeatureSet::all_enabled()); + bank.deactivate_feature(&solana_feature_set::enable_loader_v4::id()); let (bank, bank_forks) = bank.wrap_with_bank_forks_for_tests(); let mut bank_client = BankClient::new_shared(bank.clone()); @@ -13093,12 +13094,10 @@ fn test_deploy_last_epoch_slot() { solana_logger::setup(); // Bank Setup - let (mut genesis_config, mint_keypair) = create_genesis_config(1_000_000 * LAMPORTS_PER_SOL); - genesis_config - .accounts - .remove(&feature_set::disable_fees_sysvar::id()); + let (genesis_config, mint_keypair) = create_genesis_config(1_000_000 * LAMPORTS_PER_SOL); let mut bank = Bank::new_for_tests(&genesis_config); - bank.activate_feature(&feature_set::disable_fees_sysvar::id()); + bank.feature_set = Arc::new(FeatureSet::all_enabled()); + bank.deactivate_feature(&solana_feature_set::enable_loader_v4::id()); // go to the last slot in the epoch let (bank, bank_forks) = bank.wrap_with_bank_forks_for_tests(); diff --git a/runtime/src/loader_utils.rs b/runtime/src/loader_utils.rs index 61404464bce264..7c849560b294ed 100644 --- a/runtime/src/loader_utils.rs +++ b/runtime/src/loader_utils.rs @@ -273,7 +273,9 @@ pub fn instructions_to_load_program_of_loader_v4( &payer_keypair.pubkey(), &program_keypair.pubkey(), bank_client - .get_minimum_balance_for_rent_exemption(program.len()) + .get_minimum_balance_for_rent_exemption( + loader_v4::LoaderV4State::program_data_offset().saturating_add(program.len()), + ) .unwrap(), 0, loader_id,