diff --git a/programs/sbf/c/src/invoked/invoked.c b/programs/sbf/c/src/invoked/invoked.c index f57896c47bf44c..37671cfb9fe51b 100644 --- a/programs/sbf/c/src/invoked/invoked.c +++ b/programs/sbf/c/src/invoked/invoked.c @@ -31,10 +31,11 @@ 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_id = - (SolPubkey){.x = {2, 168, 246, 145, 78, 136, 161, 110, 57, 90, 225, - 40, 148, 143, 250, 105, 86, 147, 55, 104, 24, 221, - 71, 67, 82, 33, 243, 198, 0, 0, 0, 0}}; + 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}}; for (int i = 0; i < params.data_len; i++) { sol_assert(params.data[i] == i); @@ -63,7 +64,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_id)); + &sbf_loader_upgradeable_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 47e5a22d4c1c76..28d242efa7f8be 100644 --- a/programs/sbf/c/src/read_program/read_program.c +++ b/programs/sbf/c/src/read_program/read_program.c @@ -10,7 +10,7 @@ extern uint64_t entrypoint(const uint8_t *input) { return ERROR_INVALID_ARGUMENT; } - char ka_data[] = {0x7F, 0x45, 0x4C, 0x46}; + char ka_data[] = {0x02, 0x00, 0x00, 0x00}; sol_assert(params.ka_num == 1); sol_assert(!sol_memcmp(params.ka[0].data, ka_data, 4)); diff --git a/programs/sbf/rust/invoked/src/processor.rs b/programs/sbf/rust/invoked/src/processor.rs index 52d02dc99a6c21..8f60a90c15cf4e 100644 --- a/programs/sbf/rust/invoked/src/processor.rs +++ b/programs/sbf/rust/invoked/src/processor.rs @@ -7,7 +7,7 @@ use { crate::instructions::*, solana_program::{ account_info::AccountInfo, - bpf_loader, + bpf_loader_upgradeable, entrypoint::{ProgramResult, MAX_PERMITTED_DATA_INCREASE}, log::sol_log_64, msg, @@ -70,7 +70,10 @@ 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::id()); + assert_eq!( + accounts[INVOKED_PROGRAM_INDEX].owner, + &bpf_loader_upgradeable::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 c4006f2055e1ef..e2bd8439972f09 100644 --- a/programs/sbf/tests/programs.rs +++ b/programs/sbf/tests/programs.rs @@ -264,6 +264,48 @@ fn load_program_and_advance_slot( ) } +fn load_upgradeable_program_wrapper( + bank_client: &BankClient, + mint_keypair: &Keypair, + authority_keypair: &Keypair, + name: &str, +) -> Pubkey { + let buffer_keypair = Keypair::new(); + let program_keypair = Keypair::new(); + load_upgradeable_program( + bank_client, + mint_keypair, + &buffer_keypair, + &program_keypair, + authority_keypair, + name, + ); + program_keypair.pubkey() +} + +fn load_upgradeable_program_and_advance_slot( + bank_client: &mut BankClient, + bank_forks: &RwLock, + mint_keypair: &Keypair, + authority_keypair: &Keypair, + name: &str, +) -> (Arc, Pubkey) { + let program_id = + load_upgradeable_program_wrapper(bank_client, mint_keypair, authority_keypair, name); + + // 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, &Pubkey::default()) + .expect("Failed to advance the slot"); + + let bank = bank_client + .advance_slot(1, bank_forks, &Pubkey::default()) + .expect("Failed to advance the slot"); + + (bank, program_id) +} + #[test] #[cfg(any(feature = "sbf_c", feature = "sbf_rust"))] fn test_program_sbf_sanity() { @@ -323,32 +365,24 @@ fn test_program_sbf_sanity() { println!("Test program: {:?}", program.0); let GenesisConfigInfo { - mut genesis_config, + genesis_config, mint_keypair, .. } = create_genesis_config(50); - // deactivate `disable_bpf_loader_instructions` feature so that the program - // can be loaded, finalized and tested. - genesis_config - .accounts - .remove(&feature_set::disable_bpf_loader_instructions::id()); - - genesis_config - .accounts - .remove(&feature_set::deprecate_executable_meta_update_in_bpf_loader::id()); - 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(); // Call user program - let (_, program_id) = load_program_and_advance_slot( + let (_, program_id) = load_upgradeable_program_and_advance_slot( &mut bank_client, bank_forks.as_ref(), - &bpf_loader::id(), &mint_keypair, + &authority_keypair, program.0, ); + let account_metas = vec![ AccountMeta::new(mint_keypair.pubkey(), true), AccountMeta::new(Keypair::new().pubkey(), false), @@ -404,6 +438,12 @@ fn test_program_sbf_loader_deprecated() { } } +/// This test is written with bpf_loader v2 specific instructions, which will be +/// deprecated when `disable_bpf_loader_instructions` feature is activated. +/// +/// The same test has been migrated to +/// `test_sol_alloc_free_no_longer_deployable_with_upgradeable_loader` with a new version +/// of bpf_upgradeable_loader! #[test] #[cfg(feature = "sbf_rust")] fn test_sol_alloc_free_no_longer_deployable() { @@ -428,9 +468,8 @@ fn test_sol_alloc_free_no_longer_deployable() { .accounts .remove(&feature_set::deprecate_executable_meta_update_in_bpf_loader::id()); - let (bank, bank_forks) = Bank::new_with_bank_forks_for_tests(&genesis_config); + let (bank, _bank_forks) = Bank::new_with_bank_forks_for_tests(&genesis_config); - // Populate loader account with elf that depends on _sol_alloc_free syscall let elf = load_program_from_file("solana_sbf_rust_deprecated_loader"); let mut program_account = AccountSharedData::new(1, elf.len(), &bpf_loader::id()); program_account @@ -452,70 +491,51 @@ fn test_sol_alloc_free_no_longer_deployable() { bank.last_blockhash(), ); - let invoke_tx = Transaction::new( - &[&mint_keypair], - Message::new( - &[Instruction::new_with_bytes( - program_address, - &[255], - vec![AccountMeta::new(mint_keypair.pubkey(), true)], - )], - Some(&mint_keypair.pubkey()), - ), - bank.last_blockhash(), - ); - // Try and deploy a program that depends on _sol_alloc_free assert_eq!( bank.process_transaction(&finalize_tx).unwrap_err(), TransactionError::InstructionError(0, InstructionError::InvalidAccountData) ); +} - // Enable _sol_alloc_free syscall - let slot = bank.slot(); - drop(bank); - let mut bank = Arc::into_inner(bank_forks.write().unwrap().remove(slot).unwrap()).unwrap(); - bank.deactivate_feature(&solana_sdk::feature_set::disable_deploy_of_alloc_free_syscall::id()); - bank.clear_signatures(); - bank.clear_program_cache(); - let bank = bank_forks - .write() - .unwrap() - .insert(bank) - .clone_without_scheduler(); - - // Try and finalize the program now that sol_alloc_free is re-enabled - assert!(bank.process_transaction(&finalize_tx).is_ok()); - let new_slot = bank.slot() + 1; - let bank = bank_forks - .write() - .unwrap() - .insert(Bank::new_from_parent(bank, &Pubkey::default(), new_slot)) - .clone_without_scheduler(); - - // invoke the program - assert!(bank.process_transaction(&invoke_tx).is_ok()); - - // disable _sol_alloc_free - let slot = bank.slot(); - drop(bank); - let mut bank = Arc::try_unwrap(bank_forks.write().unwrap().remove(slot).unwrap()).unwrap(); - bank.activate_feature(&solana_sdk::feature_set::disable_deploy_of_alloc_free_syscall::id()); - bank.clear_signatures(); - let bank = bank_forks - .write() - .unwrap() - .insert(bank) - .clone_without_scheduler(); +#[test] +#[cfg(feature = "sbf_rust")] +#[should_panic( + expected = "called `Result::unwrap()` on an `Err` value: TransactionError(InstructionError(1, InvalidAccountData))" +)] +fn test_sol_alloc_free_no_longer_deployable_with_upgradeable_loader() { + solana_logger::setup(); - // invoke should still succeed because cached - assert!(bank.process_transaction(&invoke_tx).is_ok()); + let GenesisConfigInfo { + genesis_config, + mint_keypair, + .. + } = create_genesis_config(50); - bank.clear_signatures(); - bank.clear_program_cache(); + 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(); - // invoke should still succeed on execute because the program is already deployed - assert!(bank.process_transaction(&invoke_tx).is_ok()); + // Populate loader account with `solana_sbf_rust_deprecated_loader` elf, which + // depends on `sol_alloc_free_` syscall. This can be verified with + // $ elfdump solana_sbf_rust_deprecated_loader.so + // : 0000000000001ab8 000000070000000a R_BPF_64_32 0000000000000000 sol_alloc_free_ + // In the symbol table, there is `sol_alloc_free_`. + // In fact, `sol_alloc_free_` is called from sbf allocator, which is originated from + // AccountInfo::realloc() in the program code. + + // Expect that deployment to fail. B/C during deployment, there is an elf + // verification step, which uses the runtime to look up relocatable symbols + // 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( + &mut bank_client, + bank_forks.as_ref(), + &mint_keypair, + &authority_keypair, + "solana_sbf_rust_deprecated_loader", + ); } #[test] @@ -537,28 +557,20 @@ fn test_program_sbf_duplicate_accounts() { println!("Test program: {:?}", program); let GenesisConfigInfo { - mut genesis_config, + genesis_config, mint_keypair, .. } = create_genesis_config(50); - // deactivate `disable_bpf_loader_instructions` feature so that the program - // can be loaded, finalized and tested. - genesis_config - .accounts - .remove(&feature_set::disable_bpf_loader_instructions::id()); - - genesis_config - .accounts - .remove(&feature_set::deprecate_executable_meta_update_in_bpf_loader::id()); - let (bank, bank_forks) = Bank::new_with_bank_forks_for_tests(&genesis_config); let mut bank_client = BankClient::new_shared(bank.clone()); - let (bank, program_id) = load_program_and_advance_slot( + let authority_keypair = Keypair::new(); + + let (bank, program_id) = load_upgradeable_program_and_advance_slot( &mut bank_client, bank_forks.as_ref(), - &bpf_loader::id(), &mint_keypair, + &authority_keypair, program, ); let payee_account = AccountSharedData::new(10, 1, &program_id); @@ -652,30 +664,23 @@ fn test_program_sbf_error_handling() { println!("Test program: {:?}", program); let GenesisConfigInfo { - mut genesis_config, + genesis_config, mint_keypair, .. } = create_genesis_config(50); - // deactivate `disable_bpf_loader_instructions` feature so that the program - // can be loaded, finalized and tested. - genesis_config - .accounts - .remove(&feature_set::disable_bpf_loader_instructions::id()); - - genesis_config - .accounts - .remove(&feature_set::deprecate_executable_meta_update_in_bpf_loader::id()); - let (bank, bank_forks) = Bank::new_with_bank_forks_for_tests(&genesis_config); let mut bank_client = BankClient::new_shared(bank); - let (_, program_id) = load_program_and_advance_slot( + let authority_keypair = Keypair::new(); + + let (_bank, program_id) = load_upgradeable_program_and_advance_slot( &mut bank_client, bank_forks.as_ref(), - &bpf_loader::id(), &mint_keypair, + &authority_keypair, program, ); + let account_metas = vec![AccountMeta::new(mint_keypair.pubkey(), true)]; let instruction = Instruction::new_with_bytes(program_id, &[1], account_metas.clone()); @@ -769,29 +774,20 @@ fn test_return_data_and_log_data_syscall() { for program in programs.iter() { let GenesisConfigInfo { - mut genesis_config, + genesis_config, mint_keypair, .. } = create_genesis_config(50); - // deactivate `disable_bpf_loader_instructions` feature so that the program - // can be loaded, finalized and tested. - genesis_config - .accounts - .remove(&feature_set::disable_bpf_loader_instructions::id()); - - genesis_config - .accounts - .remove(&feature_set::deprecate_executable_meta_update_in_bpf_loader::id()); - 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_program_and_advance_slot( + let (bank, program_id) = load_upgradeable_program_and_advance_slot( &mut bank_client, bank_forks.as_ref(), - &bpf_loader::id(), &mint_keypair, + &authority_keypair, program, ); @@ -848,33 +844,34 @@ fn test_program_sbf_invoke_sanity() { println!("Test program: {:?}", program); let GenesisConfigInfo { - mut genesis_config, + genesis_config, mint_keypair, .. } = create_genesis_config(50); - // deactivate `disable_bpf_loader_instructions` feature so that the program - // can be loaded, finalized and tested. - genesis_config - .accounts - .remove(&feature_set::disable_bpf_loader_instructions::id()); - - genesis_config - .accounts - .remove(&feature_set::deprecate_executable_meta_update_in_bpf_loader::id()); - 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 invoke_program_id = load_upgradeable_program_wrapper( + &bank_client, + &mint_keypair, + &authority_keypair, + program.1, + ); + + let invoked_program_id = load_upgradeable_program_wrapper( + &bank_client, + &mint_keypair, + &authority_keypair, + program.2, + ); - let invoke_program_id = - load_program(&bank_client, &bpf_loader::id(), &mint_keypair, program.1); - let invoked_program_id = - load_program(&bank_client, &bpf_loader::id(), &mint_keypair, program.2); - let (bank, noop_program_id) = load_program_and_advance_slot( + let (bank, noop_program_id) = load_upgradeable_program_and_advance_slot( &mut bank_client, bank_forks.as_ref(), - &bpf_loader::id(), &mint_keypair, + &authority_keypair, program.3, ); @@ -1256,34 +1253,27 @@ fn test_program_sbf_invoke_sanity() { #[cfg(feature = "sbf_rust")] fn test_program_sbf_program_id_spoofing() { let GenesisConfigInfo { - mut genesis_config, + genesis_config, mint_keypair, .. } = create_genesis_config(50); - // deactivate `disable_bpf_loader_instructions` feature so that the program - // can be loaded, finalized and tested. - genesis_config - .accounts - .remove(&feature_set::disable_bpf_loader_instructions::id()); - genesis_config - .accounts - .remove(&feature_set::deprecate_executable_meta_update_in_bpf_loader::id()); - 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 malicious_swap_pubkey = load_program( + let malicious_swap_pubkey = load_upgradeable_program_wrapper( &bank_client, - &bpf_loader::id(), &mint_keypair, + &authority_keypair, "solana_sbf_rust_spoof1", ); - let (bank, malicious_system_pubkey) = load_program_and_advance_slot( + + let (bank, malicious_system_pubkey) = load_upgradeable_program_and_advance_slot( &mut bank_client, bank_forks.as_ref(), - &bpf_loader::id(), &mint_keypair, + &authority_keypair, "solana_sbf_rust_spoof1_system", ); @@ -1317,36 +1307,30 @@ fn test_program_sbf_program_id_spoofing() { #[cfg(feature = "sbf_rust")] fn test_program_sbf_caller_has_access_to_cpi_program() { let GenesisConfigInfo { - mut genesis_config, + genesis_config, mint_keypair, .. } = create_genesis_config(50); - // deactivate `disable_bpf_loader_instructions` feature so that the program - // can be loaded, finalized and tested. - genesis_config - .accounts - .remove(&feature_set::disable_bpf_loader_instructions::id()); - genesis_config - .accounts - .remove(&feature_set::deprecate_executable_meta_update_in_bpf_loader::id()); - 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 caller_pubkey = load_program( + let caller_pubkey = load_upgradeable_program_wrapper( &bank_client, - &bpf_loader::id(), &mint_keypair, + &authority_keypair, "solana_sbf_rust_caller_access", ); - let (_, caller2_pubkey) = load_program_and_advance_slot( + + let (_bank, caller2_pubkey) = load_upgradeable_program_and_advance_slot( &mut bank_client, bank_forks.as_ref(), - &bpf_loader::id(), &mint_keypair, + &authority_keypair, "solana_sbf_rust_caller_access", ); + let account_metas = vec![ AccountMeta::new_readonly(caller_pubkey, false), AccountMeta::new_readonly(caller2_pubkey, false), @@ -1365,28 +1349,20 @@ fn test_program_sbf_ro_modify() { solana_logger::setup(); let GenesisConfigInfo { - mut genesis_config, + genesis_config, mint_keypair, .. } = create_genesis_config(50); - // deactivate `disable_bpf_loader_instructions` feature so that the program - // can be loaded, finalized and tested. - genesis_config - .accounts - .remove(&feature_set::disable_bpf_loader_instructions::id()); - genesis_config - .accounts - .remove(&feature_set::deprecate_executable_meta_update_in_bpf_loader::id()); - 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_pubkey) = load_program_and_advance_slot( + let (bank, program_pubkey) = load_upgradeable_program_and_advance_slot( &mut bank_client, bank_forks.as_ref(), - &bpf_loader::id(), &mint_keypair, + &authority_keypair, "solana_sbf_rust_ro_modify", ); @@ -1430,27 +1406,20 @@ fn test_program_sbf_call_depth() { solana_logger::setup(); let GenesisConfigInfo { - mut genesis_config, + genesis_config, mint_keypair, .. } = create_genesis_config(50); - // deactivate `disable_bpf_loader_instructions` feature so that the program - // can be loaded, finalized and tested. - genesis_config - .accounts - .remove(&feature_set::disable_bpf_loader_instructions::id()); - genesis_config - .accounts - .remove(&feature_set::deprecate_executable_meta_update_in_bpf_loader::id()); - let (bank, bank_forks) = Bank::new_with_bank_forks_for_tests(&genesis_config); let mut bank_client = BankClient::new_shared(bank); - let (_, program_id) = load_program_and_advance_slot( + let authority_keypair = Keypair::new(); + + let (_, program_id) = load_upgradeable_program_and_advance_slot( &mut bank_client, bank_forks.as_ref(), - &bpf_loader::id(), &mint_keypair, + &authority_keypair, "solana_sbf_rust_call_depth", ); @@ -1474,27 +1443,20 @@ fn test_program_sbf_compute_budget() { solana_logger::setup(); let GenesisConfigInfo { - mut genesis_config, + genesis_config, mint_keypair, .. } = create_genesis_config(50); - // deactivate `disable_bpf_loader_instructions` feature so that the program - // can be loaded, finalized and tested. - genesis_config - .accounts - .remove(&feature_set::disable_bpf_loader_instructions::id()); - genesis_config - .accounts - .remove(&feature_set::deprecate_executable_meta_update_in_bpf_loader::id()); - let (bank, bank_forks) = Bank::new_with_bank_forks_for_tests(&genesis_config); let mut bank_client = BankClient::new_shared(bank); - let (_, program_id) = load_program_and_advance_slot( + let authority_keypair = Keypair::new(); + + let (_, program_id) = load_upgradeable_program_and_advance_slot( &mut bank_client, bank_forks.as_ref(), - &bpf_loader::id(), &mint_keypair, + &authority_keypair, "solana_sbf_rust_noop", ); let message = Message::new( @@ -1612,28 +1574,20 @@ fn test_program_sbf_instruction_introspection() { solana_logger::setup(); let GenesisConfigInfo { - mut genesis_config, + genesis_config, mint_keypair, .. } = create_genesis_config(50_000); - // deactivate `disable_bpf_loader_instructions` feature so that the program - // can be loaded, finalized and tested. - genesis_config - .accounts - .remove(&feature_set::disable_bpf_loader_instructions::id()); - genesis_config - .accounts - .remove(&feature_set::deprecate_executable_meta_update_in_bpf_loader::id()); - 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_program_and_advance_slot( + let (bank, program_id) = load_upgradeable_program_and_advance_slot( &mut bank_client, bank_forks.as_ref(), - &bpf_loader::id(), &mint_keypair, + &authority_keypair, "solana_sbf_rust_instruction_introspection", ); @@ -1674,6 +1628,9 @@ fn test_program_sbf_instruction_introspection() { assert!(bank.get_account(&sysvar::instructions::id()).is_none()); } +/// This test is to test bpf_loader v2 `Finalize` instruction with different +/// programs. It is going to be deprecated once we activate +/// `disable_bpf_loader_instructions`. #[test] #[cfg(feature = "sbf_rust")] fn test_program_sbf_test_use_latest_executor() { @@ -1724,6 +1681,7 @@ fn test_program_sbf_test_use_latest_executor() { bank_client .advance_slot(1, bank_forks.as_ref(), &Pubkey::default()) .expect("Failed to advance the slot"); + assert!(bank_client .send_and_confirm_message(&[&mint_keypair, &program_keypair], message) .is_err()); @@ -2382,43 +2340,34 @@ fn test_program_sbf_invoke_upgradeable_via_cpi() { solana_logger::setup(); let GenesisConfigInfo { - mut genesis_config, + genesis_config, mint_keypair, .. } = create_genesis_config(50); - // deactivate `disable_bpf_loader_instructions` feature so that the program - // can be loaded, finalized and tested. - genesis_config - .accounts - .remove(&feature_set::disable_bpf_loader_instructions::id()); - - genesis_config - .accounts - .remove(&feature_set::deprecate_executable_meta_update_in_bpf_loader::id()); - let (bank, bank_forks) = Bank::new_with_bank_forks_for_tests(&genesis_config); let mut bank_client = BankClient::new_shared(bank); - let invoke_and_return = load_program( - &bank_client, - &bpf_loader::id(), + 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(); - let authority_keypair = Keypair::new(); - load_upgradeable_program( + let program_id = load_upgradeable_program_wrapper( &bank_client, &mint_keypair, - &buffer_keypair, - &program_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()) @@ -2452,7 +2401,7 @@ fn test_program_sbf_invoke_upgradeable_via_cpi() { "solana_sbf_rust_upgraded", ); bank_client.set_sysvar_for_tests(&clock::Clock { - slot: 2, + slot: 3, ..clock::Clock::default() }); bank_client @@ -2531,12 +2480,18 @@ fn test_program_sbf_disguised_as_sbf_loader() { bank.deactivate_feature( &solana_sdk::feature_set::remove_bpf_loader_incorrect_program_id::id(), ); - bank.deactivate_feature(&feature_set::disable_bpf_loader_instructions::id()); - bank.deactivate_feature(&feature_set::deprecate_executable_meta_update_in_bpf_loader::id()); - let bank = bank.wrap_with_bank_forks_for_tests().0; - let bank_client = BankClient::new_shared(bank); + 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( + &mut bank_client, + bank_forks.as_ref(), + &mint_keypair, + &authority_keypair, + program, + ); - let program_id = load_program(&bank_client, &bpf_loader::id(), &mint_keypair, program); let account_metas = vec![AccountMeta::new_readonly(program_id, false)]; let instruction = Instruction::new_with_bytes(bpf_loader::id(), &[1], account_metas); let result = bank_client.send_and_confirm_instruction(&mint_keypair, instruction); @@ -2553,29 +2508,20 @@ fn test_program_reads_from_program_account() { solana_logger::setup(); let GenesisConfigInfo { - mut genesis_config, + genesis_config, mint_keypair, .. } = create_genesis_config(50); - // deactivate `disable_bpf_loader_instructions` feature so that the program - // can be loaded, finalized and tested. - genesis_config - .accounts - .remove(&feature_set::disable_bpf_loader_instructions::id()); - - genesis_config - .accounts - .remove(&feature_set::deprecate_executable_meta_update_in_bpf_loader::id()); - 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 (_, program_id) = load_program_and_advance_slot( + let (_bank, program_id) = load_upgradeable_program_and_advance_slot( &mut bank_client, bank_forks.as_ref(), - &bpf_loader::id(), &mint_keypair, + &authority_keypair, "read_program", ); let account_metas = vec![AccountMeta::new_readonly(program_id, false)]; @@ -2591,21 +2537,11 @@ fn test_program_sbf_c_dup() { solana_logger::setup(); let GenesisConfigInfo { - mut genesis_config, + genesis_config, mint_keypair, .. } = create_genesis_config(50); - // deactivate `disable_bpf_loader_instructions` feature so that the program - // can be loaded, finalized and tested. - genesis_config - .accounts - .remove(&feature_set::disable_bpf_loader_instructions::id()); - - genesis_config - .accounts - .remove(&feature_set::deprecate_executable_meta_update_in_bpf_loader::id()); - let (bank, bank_forks) = Bank::new_with_bank_forks_for_tests(&genesis_config); let account_address = Pubkey::new_unique(); @@ -2613,12 +2549,12 @@ fn test_program_sbf_c_dup() { bank.store_account(&account_address, &account); let mut bank_client = BankClient::new_shared(bank); - - let (_, program_id) = load_program_and_advance_slot( + let authority_keypair = Keypair::new(); + let (_, program_id) = load_upgradeable_program_and_advance_slot( &mut bank_client, bank_forks.as_ref(), - &bpf_loader::id(), &mint_keypair, + &authority_keypair, "ser", ); let account_metas = vec![ @@ -2637,27 +2573,20 @@ fn test_program_sbf_upgrade_via_cpi() { solana_logger::setup(); let GenesisConfigInfo { - mut genesis_config, + genesis_config, mint_keypair, .. } = create_genesis_config(50); - // deactivate `disable_bpf_loader_instructions` feature so that the program - // can be loaded, finalized and tested. - genesis_config - .accounts - .remove(&feature_set::disable_bpf_loader_instructions::id()); - - genesis_config - .accounts - .remove(&feature_set::deprecate_executable_meta_update_in_bpf_loader::id()); - let (bank, bank_forks) = Bank::new_with_bank_forks_for_tests(&genesis_config); let mut bank_client = BankClient::new_shared(bank); - let invoke_and_return = load_program( - &bank_client, - &bpf_loader::id(), + 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", ); @@ -2758,42 +2687,27 @@ fn test_program_sbf_set_upgrade_authority_via_cpi() { solana_logger::setup(); let GenesisConfigInfo { - mut genesis_config, + genesis_config, mint_keypair, .. } = create_genesis_config(50); - // deactivate `disable_bpf_loader_instructions` feature so that the program - // can be loaded, finalized and tested. - genesis_config - .accounts - .remove(&feature_set::disable_bpf_loader_instructions::id()); - - genesis_config - .accounts - .remove(&feature_set::deprecate_executable_meta_update_in_bpf_loader::id()); - 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(); // Deploy CPI invoker program - let invoke_and_return = load_program( + let invoke_and_return = load_upgradeable_program_wrapper( &bank_client, - &bpf_loader::id(), &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(); - let authority_keypair = Keypair::new(); - load_upgradeable_program( + let program_id = load_upgradeable_program_wrapper( &bank_client, &mint_keypair, - &buffer_keypair, - &program_keypair, &authority_keypair, "solana_sbf_rust_upgradeable", ); @@ -2978,6 +2892,8 @@ fn test_program_upgradeable_locks() { assert_eq!(results2[1], Err(TransactionError::AccountInUse)); } +/// This test is to test bpf_loader v2 `Finalize` instruction. It is going to be +/// deprecated once we activate `disable_bpf_loader_instructions`. #[test] #[cfg(feature = "sbf_rust")] fn test_program_sbf_finalize() { @@ -3043,29 +2959,20 @@ fn test_program_sbf_ro_account_modify() { solana_logger::setup(); let GenesisConfigInfo { - mut genesis_config, + genesis_config, mint_keypair, .. } = create_genesis_config(50); - // deactivate `disable_bpf_loader_instructions` feature so that the program - // can be loaded, finalized and tested. - genesis_config - .accounts - .remove(&feature_set::disable_bpf_loader_instructions::id()); - - genesis_config - .accounts - .remove(&feature_set::deprecate_executable_meta_update_in_bpf_loader::id()); - 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_program_and_advance_slot( + let (bank, program_id) = load_upgradeable_program_and_advance_slot( &mut bank_client, bank_forks.as_ref(), - &bpf_loader::id(), &mint_keypair, + &authority_keypair, "solana_sbf_rust_ro_account_modify", ); @@ -3116,21 +3023,11 @@ fn test_program_sbf_realloc() { const START_BALANCE: u64 = 100_000_000_000; let GenesisConfigInfo { - mut genesis_config, + genesis_config, mint_keypair, .. } = create_genesis_config(1_000_000_000_000); - // deactivate `disable_bpf_loader_instructions` feature so that the program - // can be loaded, finalized and tested. - genesis_config - .accounts - .remove(&feature_set::disable_bpf_loader_instructions::id()); - - genesis_config - .accounts - .remove(&feature_set::deprecate_executable_meta_update_in_bpf_loader::id()); - let mint_pubkey = mint_keypair.pubkey(); let signer = &[&mint_keypair]; for direct_mapping in [false, true] { @@ -3143,12 +3040,13 @@ fn test_program_sbf_realloc() { } let (bank, bank_forks) = bank.wrap_with_bank_forks_for_tests(); let mut bank_client = BankClient::new_shared(bank.clone()); + let authority_keypair = Keypair::new(); - let (bank, program_id) = load_program_and_advance_slot( + let (bank, program_id) = load_upgradeable_program_and_advance_slot( &mut bank_client, bank_forks.as_ref(), - &bpf_loader::id(), &mint_keypair, + &authority_keypair, "solana_sbf_rust_realloc", ); @@ -3467,34 +3365,25 @@ fn test_program_sbf_realloc_invoke() { } = create_genesis_config(1_000_000_000_000); genesis_config.rent = Rent::default(); - // deactivate `disable_bpf_loader_instructions` feature so that the program - // can be loaded, finalized and tested. - genesis_config - .accounts - .remove(&feature_set::disable_bpf_loader_instructions::id()); - - genesis_config - .accounts - .remove(&feature_set::deprecate_executable_meta_update_in_bpf_loader::id()); - let mint_pubkey = mint_keypair.pubkey(); let signer = &[&mint_keypair]; 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 realloc_program_id = load_program( + let realloc_program_id = load_upgradeable_program_wrapper( &bank_client, - &bpf_loader::id(), &mint_keypair, + &authority_keypair, "solana_sbf_rust_realloc", ); - let (bank, realloc_invoke_program_id) = load_program_and_advance_slot( + let (bank, realloc_invoke_program_id) = load_upgradeable_program_and_advance_slot( &mut bank_client, bank_forks.as_ref(), - &bpf_loader::id(), &mint_keypair, + &authority_keypair, "solana_sbf_rust_realloc_invoke", ); @@ -3949,7 +3838,7 @@ fn test_program_sbf_realloc_invoke() { TransactionError::InstructionError(0, InstructionError::InvalidRealloc) ); - // Realloc rescursively and fill data + // Realloc recursively and fill data let invoke_keypair = Keypair::new(); let invoke_pubkey = invoke_keypair.pubkey().clone(); let invoke_account = AccountSharedData::new(START_BALANCE, 0, &realloc_invoke_program_id); @@ -3992,47 +3881,38 @@ fn test_program_sbf_processed_inner_instruction() { solana_logger::setup(); let GenesisConfigInfo { - mut genesis_config, + genesis_config, mint_keypair, .. } = create_genesis_config(50); - // deactivate `disable_bpf_loader_instructions` feature so that the program - // can be loaded, finalized and tested. - genesis_config - .accounts - .remove(&feature_set::disable_bpf_loader_instructions::id()); - - genesis_config - .accounts - .remove(&feature_set::deprecate_executable_meta_update_in_bpf_loader::id()); - 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 sibling_program_id = load_program( + let sibling_program_id = load_upgradeable_program_wrapper( &bank_client, - &bpf_loader::id(), &mint_keypair, + &authority_keypair, "solana_sbf_rust_sibling_instructions", ); - let sibling_inner_program_id = load_program( + let sibling_inner_program_id = load_upgradeable_program_wrapper( &bank_client, - &bpf_loader::id(), &mint_keypair, + &authority_keypair, "solana_sbf_rust_sibling_inner_instructions", ); - let noop_program_id = load_program( + let noop_program_id = load_upgradeable_program_wrapper( &bank_client, - &bpf_loader::id(), &mint_keypair, + &authority_keypair, "solana_sbf_rust_noop", ); - let (_, invoke_and_return_program_id) = load_program_and_advance_slot( + let (_, invoke_and_return_program_id) = load_upgradeable_program_and_advance_slot( &mut bank_client, bank_forks.as_ref(), - &bpf_loader::id(), &mint_keypair, + &authority_keypair, "solana_sbf_rust_invoke_and_return", ); @@ -4084,16 +3964,6 @@ fn test_program_fees() { .. } = create_genesis_config(500_000_000); - // deactivate `disable_bpf_loader_instructions` feature so that the program - // can be loaded, finalized and tested. - genesis_config - .accounts - .remove(&feature_set::disable_bpf_loader_instructions::id()); - - genesis_config - .accounts - .remove(&feature_set::deprecate_executable_meta_update_in_bpf_loader::id()); - genesis_config.fee_rate_governor = FeeRateGovernor::new(congestion_multiplier, 0); let mut bank = Bank::new_for_tests(&genesis_config); let fee_structure = @@ -4101,12 +3971,13 @@ fn test_program_fees() { bank.fee_structure = fee_structure.clone(); 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 (_, program_id) = load_program_and_advance_slot( + let (_bank, program_id) = load_upgradeable_program_and_advance_slot( &mut bank_client, bank_forks.as_ref(), - &bpf_loader::id(), &mint_keypair, + &authority_keypair, "solana_sbf_rust_noop", ); @@ -4161,30 +4032,21 @@ fn test_program_fees() { #[cfg(feature = "sbf_rust")] fn test_get_minimum_delegation() { let GenesisConfigInfo { - mut genesis_config, + genesis_config, mint_keypair, .. } = create_genesis_config(100_123_456_789); - // deactivate `disable_bpf_loader_instructions` feature so that the program - // can be loaded, finalized and tested. - genesis_config - .accounts - .remove(&feature_set::disable_bpf_loader_instructions::id()); - - genesis_config - .accounts - .remove(&feature_set::deprecate_executable_meta_update_in_bpf_loader::id()); - let bank = Bank::new_for_tests(&genesis_config); let (bank, bank_forks) = bank.wrap_with_bank_forks_for_tests(); let mut bank_client = BankClient::new_shared(bank.clone()); + let authority_keypair = Keypair::new(); - let (_, program_id) = load_program_and_advance_slot( + let (_bank, program_id) = load_upgradeable_program_and_advance_slot( &mut bank_client, bank_forks.as_ref(), - &bpf_loader::id(), &mint_keypair, + &authority_keypair, "solana_sbf_rust_get_minimum_delegation", ); @@ -4249,33 +4111,31 @@ fn test_cpi_account_ownership_writability() { if !direct_mapping { feature_set.deactivate(&feature_set::bpf_account_data_direct_mapping::id()); } - // deactivate `disable_bpf_loader_instructions` feature so that the program - // can be loaded, finalized and tested. - feature_set.deactivate(&feature_set::disable_bpf_loader_instructions::id()); - feature_set.deactivate(&feature_set::deprecate_executable_meta_update_in_bpf_loader::id()); + bank.feature_set = Arc::new(feature_set); 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 invoke_program_id = load_program( + let invoke_program_id = load_upgradeable_program_wrapper( &bank_client, - &bpf_loader::id(), &mint_keypair, + &authority_keypair, "solana_sbf_rust_invoke", ); - let invoked_program_id = load_program( + let invoked_program_id = load_upgradeable_program_wrapper( &bank_client, - &bpf_loader::id(), &mint_keypair, + &authority_keypair, "solana_sbf_rust_invoked", ); - let (bank, realloc_program_id) = load_program_and_advance_slot( + let (bank, realloc_program_id) = load_upgradeable_program_and_advance_slot( &mut bank_client, bank_forks.as_ref(), - &bpf_loader::id(), &mint_keypair, + &authority_keypair, "solana_sbf_rust_realloc", ); @@ -4435,27 +4295,24 @@ fn test_cpi_account_data_updates() { if !direct_mapping { feature_set.deactivate(&feature_set::bpf_account_data_direct_mapping::id()); } - // deactivate `disable_bpf_loader_instructions` feature so that the program - // can be loaded, finalized and tested. - feature_set.deactivate(&feature_set::disable_bpf_loader_instructions::id()); - feature_set.deactivate(&feature_set::deprecate_executable_meta_update_in_bpf_loader::id()); bank.feature_set = Arc::new(feature_set); 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 invoke_program_id = load_program( + let invoke_program_id = load_upgradeable_program_wrapper( &bank_client, - &bpf_loader::id(), &mint_keypair, + &authority_keypair, "solana_sbf_rust_invoke", ); - let (bank, realloc_program_id) = load_program_and_advance_slot( + let (bank, realloc_program_id) = load_upgradeable_program_and_advance_slot( &mut bank_client, bank_forks.as_ref(), - &bpf_loader::id(), &mint_keypair, + &authority_keypair, "solana_sbf_rust_realloc", ); @@ -4590,11 +4447,6 @@ fn test_cpi_deprecated_loader_realloc() { feature_set.deactivate(&feature_set::bpf_account_data_direct_mapping::id()); } - // deactivate `disable_bpf_loader_instructions` feature so that the program - // can be loaded, finalized and tested. - feature_set.deactivate(&feature_set::disable_bpf_loader_instructions::id()); - feature_set.deactivate(&feature_set::deprecate_executable_meta_update_in_bpf_loader::id()); - bank.feature_set = Arc::new(feature_set); let (bank, bank_forks) = bank.wrap_with_bank_forks_for_tests(); @@ -4605,12 +4457,13 @@ 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_program_and_advance_slot( + let (bank, invoke_program_id) = load_upgradeable_program_and_advance_slot( &mut bank_client, bank_forks.as_ref(), - &bpf_loader::id(), &mint_keypair, + &authority_keypair, "solana_sbf_rust_invoke", ); @@ -4699,21 +4552,11 @@ fn test_cpi_change_account_data_memory_allocation() { solana_logger::setup(); let GenesisConfigInfo { - mut genesis_config, + genesis_config, mint_keypair, .. } = create_genesis_config(100_123_456_789); - // deactivate `disable_bpf_loader_instructions` feature so that the program - // can be loaded, finalized and tested. - genesis_config - .accounts - .remove(&feature_set::disable_bpf_loader_instructions::id()); - - genesis_config - .accounts - .remove(&feature_set::deprecate_executable_meta_update_in_bpf_loader::id()); - let mut bank = Bank::new_for_tests(&genesis_config); declare_process_instruction!(MockBuiltin, 42, |invoke_context| { @@ -4758,12 +4601,13 @@ fn test_cpi_change_account_data_memory_allocation() { 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, invoke_program_id) = load_program_and_advance_slot( + let (bank, invoke_program_id) = load_upgradeable_program_and_advance_slot( &mut bank_client, bank_forks.as_ref(), - &bpf_loader::id(), &mint_keypair, + &authority_keypair, "solana_sbf_rust_invoke", ); @@ -4794,33 +4638,24 @@ fn test_cpi_invalid_account_info_pointers() { solana_logger::setup(); let GenesisConfigInfo { - mut genesis_config, + genesis_config, mint_keypair, .. } = create_genesis_config(100_123_456_789); - // deactivate `disable_bpf_loader_instructions` feature so that the program - // can be loaded, finalized and tested. - genesis_config - .accounts - .remove(&feature_set::disable_bpf_loader_instructions::id()); - - genesis_config - .accounts - .remove(&feature_set::deprecate_executable_meta_update_in_bpf_loader::id()); - let bank = Bank::new_for_tests(&genesis_config); 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 c_invoke_program_id = - load_program(&bank_client, &bpf_loader::id(), &mint_keypair, "invoke"); + load_upgradeable_program_wrapper(&bank_client, &mint_keypair, &authority_keypair, "invoke"); - let (bank, invoke_program_id) = load_program_and_advance_slot( + let (bank, invoke_program_id) = load_upgradeable_program_and_advance_slot( &mut bank_client, bank_forks.as_ref(), - &bpf_loader::id(), &mint_keypair, + &authority_keypair, "solana_sbf_rust_invoke", ); @@ -4866,21 +4701,11 @@ fn test_deny_executable_write() { solana_logger::setup(); let GenesisConfigInfo { - mut genesis_config, + genesis_config, mint_keypair, .. } = create_genesis_config(100_123_456_789); - // deactivate `disable_bpf_loader_instructions` feature so that the program - // can be loaded, finalized and tested. - genesis_config - .accounts - .remove(&feature_set::disable_bpf_loader_instructions::id()); - - genesis_config - .accounts - .remove(&feature_set::deprecate_executable_meta_update_in_bpf_loader::id()); - for direct_mapping in [false, true] { let mut bank = Bank::new_for_tests(&genesis_config); let feature_set = Arc::make_mut(&mut bank.feature_set); @@ -4891,12 +4716,13 @@ fn test_deny_executable_write() { } 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, invoke_program_id) = load_program_and_advance_slot( + let (_bank, invoke_program_id) = load_upgradeable_program_and_advance_slot( &mut bank_client, bank_forks.as_ref(), - &bpf_loader::id(), &mint_keypair, + &authority_keypair, "solana_sbf_rust_invoke", ); diff --git a/runtime/src/loader_utils.rs b/runtime/src/loader_utils.rs index cddb37595cef91..a89dd0e228b9f1 100644 --- a/runtime/src/loader_utils.rs +++ b/runtime/src/loader_utils.rs @@ -116,6 +116,7 @@ pub fn load_upgradeable_buffer( let program = load_program_from_file(name); let buffer_pubkey = buffer_keypair.pubkey(); let buffer_authority_pubkey = buffer_authority_keypair.pubkey(); + let program_buffer_bytes = UpgradeableLoaderState::size_of_programdata(program.len()); bank_client .send_and_confirm_message( @@ -127,7 +128,7 @@ pub fn load_upgradeable_buffer( &buffer_authority_pubkey, 1.max( bank_client - .get_minimum_balance_for_rent_exemption(program.len()) + .get_minimum_balance_for_rent_exemption(program_buffer_bytes) .unwrap(), ), program.len(),