From 0f8f8cd9706f869f05153c22f3d26507b27f2c6f Mon Sep 17 00:00:00 2001 From: HaoranYi Date: Wed, 20 Mar 2024 10:54:15 -0500 Subject: [PATCH] Revert deprecate executable feature (#309) * revert deprecate executable feature * add native loader account transfer test --------- Co-authored-by: HaoranYi --- cli/src/program.rs | 15 +- cli/tests/program.rs | 44 ++-- ledger-tool/src/program.rs | 1 - program-runtime/src/invoke_context.rs | 14 +- program-runtime/src/message_processor.rs | 16 +- program-test/src/lib.rs | 24 +-- .../address-lookup-table/src/processor.rs | 22 +- programs/bpf_loader/benches/serialization.rs | 49 +---- programs/bpf_loader/src/lib.rs | 188 ++++++------------ programs/bpf_loader/src/serialization.rs | 65 ++---- programs/bpf_loader/src/syscalls/cpi.rs | 84 +++----- programs/config/src/config_processor.rs | 2 +- programs/loader-v4/src/lib.rs | 25 ++- programs/sbf/benches/bpf_loader.rs | 10 +- programs/stake/src/stake_instruction.rs | 37 +--- programs/stake/src/stake_state.rs | 105 ++++------ programs/system/src/system_instruction.rs | 22 +- programs/system/src/system_processor.rs | 62 +++++- programs/vote/src/vote_state/mod.rs | 24 +-- programs/zk-token-proof/src/lib.rs | 14 +- runtime/src/bank.rs | 9 +- runtime/src/bank/tests.rs | 40 ++-- sdk/src/account.rs | 94 +-------- sdk/src/feature_set.rs | 5 - sdk/src/transaction_context.rs | 96 +++------ svm/src/account_loader.rs | 15 +- 26 files changed, 353 insertions(+), 729 deletions(-) diff --git a/cli/src/program.rs b/cli/src/program.rs index 099da9dbaf2438..c35871868f0f04 100644 --- a/cli/src/program.rs +++ b/cli/src/program.rs @@ -44,7 +44,7 @@ use { }, solana_rpc_client_nonce_utils::blockhash_query::BlockhashQuery, solana_sdk::{ - account::{is_executable, Account}, + account::Account, account_utils::StateMut, bpf_loader, bpf_loader_deprecated, bpf_loader_upgradeable::{self, UpgradeableLoaderState}, @@ -1066,15 +1066,6 @@ fn get_default_program_keypair(program_location: &Option) -> Keypair { program_keypair } -fn is_account_executable(account: &Account) -> bool { - if account.owner == bpf_loader_deprecated::id() || account.owner == bpf_loader::id() { - account.executable - } else { - let feature_set = FeatureSet::all_enabled(); - is_executable(account, &feature_set) - } -} - /// Deploy program using upgradeable loader. It also can process program upgrades #[allow(clippy::too_many_arguments)] fn process_program_deploy( @@ -1131,7 +1122,7 @@ fn process_program_deploy( .into()); } - if !is_account_executable(&account) { + if !account.executable { // Continue an initial deploy true } else if let Ok(UpgradeableLoaderState::Program { @@ -2534,7 +2525,7 @@ fn complete_partial_program_init( ) -> Result<(Vec, u64), Box> { let mut instructions: Vec = vec![]; let mut balance_needed = 0; - if is_account_executable(account) { + if account.executable { return Err("Buffer account is already executable".into()); } if account.owner != *loader_id && !system_program::check_id(&account.owner) { diff --git a/cli/tests/program.rs b/cli/tests/program.rs index 039df1d64b8ae8..6eb281d65b9e35 100644 --- a/cli/tests/program.rs +++ b/cli/tests/program.rs @@ -14,11 +14,9 @@ use { solana_rpc_client::rpc_client::RpcClient, solana_rpc_client_nonce_utils::blockhash_query::BlockhashQuery, solana_sdk::{ - account::is_executable, account_utils::StateMut, bpf_loader_upgradeable::{self, UpgradeableLoaderState}, commitment_config::CommitmentConfig, - feature_set::FeatureSet, pubkey::Pubkey, signature::{Keypair, NullSigner, Signer}, }, @@ -102,7 +100,7 @@ fn test_cli_program_deploy_non_upgradeable() { let account0 = rpc_client.get_account(&program_id).unwrap(); assert_eq!(account0.lamports, minimum_balance_for_program); assert_eq!(account0.owner, bpf_loader_upgradeable::id()); - assert!(is_executable(&account0, &FeatureSet::all_enabled())); + assert!(account0.executable); let (programdata_pubkey, _) = Pubkey::find_program_address(&[program_id.as_ref()], &bpf_loader_upgradeable::id()); @@ -112,10 +110,7 @@ fn test_cli_program_deploy_non_upgradeable() { minimum_balance_for_programdata ); assert_eq!(programdata_account.owner, bpf_loader_upgradeable::id()); - assert!(!is_executable( - &programdata_account, - &FeatureSet::all_enabled() - )); + assert!(!programdata_account.executable); assert_eq!( programdata_account.data[UpgradeableLoaderState::size_of_programdata_metadata()..], program_data[..] @@ -143,7 +138,7 @@ fn test_cli_program_deploy_non_upgradeable() { .unwrap(); assert_eq!(account1.lamports, minimum_balance_for_program); assert_eq!(account1.owner, bpf_loader_upgradeable::id()); - assert!(is_executable(&account1, &FeatureSet::all_enabled())); + assert!(account1.executable); let (programdata_pubkey, _) = Pubkey::find_program_address( &[custom_address_keypair.pubkey().as_ref()], &bpf_loader_upgradeable::id(), @@ -154,10 +149,7 @@ fn test_cli_program_deploy_non_upgradeable() { minimum_balance_for_programdata ); assert_eq!(programdata_account.owner, bpf_loader_upgradeable::id()); - assert!(!is_executable( - &programdata_account, - &FeatureSet::all_enabled() - )); + assert!(!programdata_account.executable); assert_eq!( programdata_account.data[UpgradeableLoaderState::size_of_programdata_metadata()..], program_data[..] @@ -385,7 +377,7 @@ fn test_cli_program_deploy_with_authority() { let program_account = rpc_client.get_account(&program_keypair.pubkey()).unwrap(); assert_eq!(program_account.lamports, minimum_balance_for_program); assert_eq!(program_account.owner, bpf_loader_upgradeable::id()); - assert!(is_executable(&program_account, &FeatureSet::all_enabled())); + assert!(program_account.executable); let (programdata_pubkey, _) = Pubkey::find_program_address( &[program_keypair.pubkey().as_ref()], &bpf_loader_upgradeable::id(), @@ -396,10 +388,7 @@ fn test_cli_program_deploy_with_authority() { minimum_balance_for_programdata ); assert_eq!(programdata_account.owner, bpf_loader_upgradeable::id()); - assert!(!is_executable( - &programdata_account, - &FeatureSet::all_enabled() - )); + assert!(!programdata_account.executable); assert_eq!( programdata_account.data[UpgradeableLoaderState::size_of_programdata_metadata()..], program_data[..] @@ -433,7 +422,7 @@ fn test_cli_program_deploy_with_authority() { let program_account = rpc_client.get_account(&program_pubkey).unwrap(); assert_eq!(program_account.lamports, minimum_balance_for_program); assert_eq!(program_account.owner, bpf_loader_upgradeable::id()); - assert!(is_executable(&program_account, &FeatureSet::all_enabled())); + assert!(program_account.executable); let (programdata_pubkey, _) = Pubkey::find_program_address(&[program_pubkey.as_ref()], &bpf_loader_upgradeable::id()); let programdata_account = rpc_client.get_account(&programdata_pubkey).unwrap(); @@ -442,10 +431,7 @@ fn test_cli_program_deploy_with_authority() { minimum_balance_for_programdata ); assert_eq!(programdata_account.owner, bpf_loader_upgradeable::id()); - assert!(!is_executable( - &programdata_account, - &FeatureSet::all_enabled() - )); + assert!(program_account.executable); assert_eq!( programdata_account.data[UpgradeableLoaderState::size_of_programdata_metadata()..], program_data[..] @@ -470,7 +456,7 @@ fn test_cli_program_deploy_with_authority() { let program_account = rpc_client.get_account(&program_pubkey).unwrap(); assert_eq!(program_account.lamports, minimum_balance_for_program); assert_eq!(program_account.owner, bpf_loader_upgradeable::id()); - assert!(is_executable(&program_account, &FeatureSet::all_enabled())); + assert!(program_account.executable); let (programdata_pubkey, _) = Pubkey::find_program_address(&[program_pubkey.as_ref()], &bpf_loader_upgradeable::id()); let programdata_account = rpc_client.get_account(&programdata_pubkey).unwrap(); @@ -479,10 +465,7 @@ fn test_cli_program_deploy_with_authority() { minimum_balance_for_programdata ); assert_eq!(programdata_account.owner, bpf_loader_upgradeable::id()); - assert!(!is_executable( - &programdata_account, - &FeatureSet::all_enabled() - )); + assert!(program_account.executable); assert_eq!( programdata_account.data[UpgradeableLoaderState::size_of_programdata_metadata()..], program_data[..] @@ -548,7 +531,7 @@ fn test_cli_program_deploy_with_authority() { let program_account = rpc_client.get_account(&program_pubkey).unwrap(); assert_eq!(program_account.lamports, minimum_balance_for_program); assert_eq!(program_account.owner, bpf_loader_upgradeable::id()); - assert!(is_executable(&program_account, &FeatureSet::all_enabled())); + assert!(program_account.executable); let (programdata_pubkey, _) = Pubkey::find_program_address(&[program_pubkey.as_ref()], &bpf_loader_upgradeable::id()); let programdata_account = rpc_client.get_account(&programdata_pubkey).unwrap(); @@ -557,10 +540,7 @@ fn test_cli_program_deploy_with_authority() { minimum_balance_for_programdata ); assert_eq!(programdata_account.owner, bpf_loader_upgradeable::id()); - assert!(!is_executable( - &programdata_account, - &FeatureSet::all_enabled() - )); + assert!(program_account.executable); assert_eq!( programdata_account.data[UpgradeableLoaderState::size_of_programdata_metadata()..], program_data[..] diff --git a/ledger-tool/src/program.rs b/ledger-tool/src/program.rs index 24df2168a338bf..0b4855ccb7f756 100644 --- a/ledger-tool/src/program.rs +++ b/ledger-tool/src/program.rs @@ -540,7 +540,6 @@ pub fn program(ledger_path: &Path, matches: &ArgMatches<'_>) { .get_current_instruction_context() .unwrap(), true, // copy_account_data - &invoke_context.feature_set, ) .unwrap(); diff --git a/program-runtime/src/invoke_context.rs b/program-runtime/src/invoke_context.rs index 7e930fad169627..5b2d417912256f 100644 --- a/program-runtime/src/invoke_context.rs +++ b/program-runtime/src/invoke_context.rs @@ -403,7 +403,7 @@ impl<'a> InvokeContext<'a> { })?; let borrowed_program_account = instruction_context .try_borrow_instruction_account(self.transaction_context, program_account_index)?; - if !borrowed_program_account.is_executable(&self.feature_set) { + if !borrowed_program_account.is_executable() { ic_msg!(self, "Account {} is not executable", callee_program_id); return Err(InstructionError::AccountNotExecutable); } @@ -802,17 +802,17 @@ mod tests { MockInstruction::NoopFail => return Err(InstructionError::GenericError), MockInstruction::ModifyOwned => instruction_context .try_borrow_instruction_account(transaction_context, 0)? - .set_data_from_slice(&[1], &invoke_context.feature_set)?, + .set_data_from_slice(&[1])?, MockInstruction::ModifyNotOwned => instruction_context .try_borrow_instruction_account(transaction_context, 1)? - .set_data_from_slice(&[1], &invoke_context.feature_set)?, + .set_data_from_slice(&[1])?, MockInstruction::ModifyReadonly => instruction_context .try_borrow_instruction_account(transaction_context, 2)? - .set_data_from_slice(&[1], &invoke_context.feature_set)?, + .set_data_from_slice(&[1])?, MockInstruction::UnbalancedPush => { instruction_context .try_borrow_instruction_account(transaction_context, 0)? - .checked_add_lamports(1, &invoke_context.feature_set)?; + .checked_add_lamports(1)?; let program_id = *transaction_context.get_key_of_account_at_index(3)?; let metas = vec![ AccountMeta::new_readonly( @@ -843,7 +843,7 @@ mod tests { } MockInstruction::UnbalancedPop => instruction_context .try_borrow_instruction_account(transaction_context, 0)? - .checked_add_lamports(1, &invoke_context.feature_set)?, + .checked_add_lamports(1)?, MockInstruction::ConsumeComputeUnits { compute_units_to_consume, desired_result, @@ -855,7 +855,7 @@ mod tests { } MockInstruction::Resize { new_len } => instruction_context .try_borrow_instruction_account(transaction_context, 0)? - .set_data(vec![0; new_len as usize], &invoke_context.feature_set)?, + .set_data(vec![0; new_len as usize])?, } } else { return Err(InstructionError::InvalidInstructionData); diff --git a/program-runtime/src/message_processor.rs b/program-runtime/src/message_processor.rs index 507197298479d9..e307609e096501 100644 --- a/program-runtime/src/message_processor.rs +++ b/program-runtime/src/message_processor.rs @@ -221,16 +221,16 @@ mod tests { MockSystemInstruction::TransferLamports { lamports } => { instruction_context .try_borrow_instruction_account(transaction_context, 0)? - .checked_sub_lamports(lamports, &invoke_context.feature_set)?; + .checked_sub_lamports(lamports)?; instruction_context .try_borrow_instruction_account(transaction_context, 1)? - .checked_add_lamports(lamports, &invoke_context.feature_set)?; + .checked_add_lamports(lamports)?; Ok(()) } MockSystemInstruction::ChangeData { data } => { instruction_context .try_borrow_instruction_account(transaction_context, 1)? - .set_data(vec![data], &invoke_context.feature_set)?; + .set_data(vec![data])?; Ok(()) } } @@ -444,14 +444,14 @@ mod tests { MockSystemInstruction::DoWork { lamports, data } => { let mut dup_account = instruction_context .try_borrow_instruction_account(transaction_context, 2)?; - dup_account.checked_sub_lamports(lamports, &invoke_context.feature_set)?; - to_account.checked_add_lamports(lamports, &invoke_context.feature_set)?; - dup_account.set_data(vec![data], &invoke_context.feature_set)?; + dup_account.checked_sub_lamports(lamports)?; + to_account.checked_add_lamports(lamports)?; + dup_account.set_data(vec![data])?; drop(dup_account); let mut from_account = instruction_context .try_borrow_instruction_account(transaction_context, 0)?; - from_account.checked_sub_lamports(lamports, &invoke_context.feature_set)?; - to_account.checked_add_lamports(lamports, &invoke_context.feature_set)?; + from_account.checked_sub_lamports(lamports)?; + to_account.checked_add_lamports(lamports)?; Ok(()) } } diff --git a/program-test/src/lib.rs b/program-test/src/lib.rs index 669cb15a595afb..f4fba5761d1332 100644 --- a/program-test/src/lib.rs +++ b/program-test/src/lib.rs @@ -133,7 +133,6 @@ pub fn invoke_builtin_function( .transaction_context .get_current_instruction_context()?, true, // copy_account_data // There is no VM so direct mapping can not be implemented here - &invoke_context.feature_set, )?; // Deserialize data back into instruction params @@ -164,25 +163,18 @@ pub fn invoke_builtin_function( if borrowed_account.is_writable() { if let Some(account_info) = account_info_map.get(borrowed_account.get_key()) { if borrowed_account.get_lamports() != account_info.lamports() { - borrowed_account - .set_lamports(account_info.lamports(), &invoke_context.feature_set)?; + borrowed_account.set_lamports(account_info.lamports())?; } if borrowed_account .can_data_be_resized(account_info.data_len()) .is_ok() - && borrowed_account - .can_data_be_changed(&invoke_context.feature_set) - .is_ok() + && borrowed_account.can_data_be_changed().is_ok() { - borrowed_account.set_data_from_slice( - &account_info.data.borrow(), - &invoke_context.feature_set, - )?; + borrowed_account.set_data_from_slice(&account_info.data.borrow())?; } if borrowed_account.get_owner() != account_info.owner { - borrowed_account - .set_owner(account_info.owner.as_ref(), &invoke_context.feature_set)?; + borrowed_account.set_owner(account_info.owner.as_ref())?; } } } @@ -293,17 +285,17 @@ impl solana_sdk::program_stubs::SyscallStubs for SyscallStubs { .unwrap(); if borrowed_account.get_lamports() != account_info.lamports() { borrowed_account - .set_lamports(account_info.lamports(), &invoke_context.feature_set) + .set_lamports(account_info.lamports()) .unwrap(); } let account_info_data = account_info.try_borrow_data().unwrap(); // The redundant check helps to avoid the expensive data comparison if we can match borrowed_account .can_data_be_resized(account_info_data.len()) - .and_then(|_| borrowed_account.can_data_be_changed(&invoke_context.feature_set)) + .and_then(|_| borrowed_account.can_data_be_changed()) { Ok(()) => borrowed_account - .set_data_from_slice(&account_info_data, &invoke_context.feature_set) + .set_data_from_slice(&account_info_data) .unwrap(), Err(err) if borrowed_account.get_data() != *account_info_data => { panic!("{err:?}"); @@ -313,7 +305,7 @@ impl solana_sdk::program_stubs::SyscallStubs for SyscallStubs { // Change the owner at the end so that we are allowed to change the lamports and data before if borrowed_account.get_owner() != account_info.owner { borrowed_account - .set_owner(account_info.owner.as_ref(), &invoke_context.feature_set) + .set_owner(account_info.owner.as_ref()) .unwrap(); } if instruction_account.is_writable { diff --git a/programs/address-lookup-table/src/processor.rs b/programs/address-lookup-table/src/processor.rs index 643310d316bf83..4db568c71a1a20 100644 --- a/programs/address-lookup-table/src/processor.rs +++ b/programs/address-lookup-table/src/processor.rs @@ -162,10 +162,9 @@ impl Processor { let instruction_context = transaction_context.get_current_instruction_context()?; let mut lookup_table_account = instruction_context.try_borrow_instruction_account(transaction_context, 0)?; - lookup_table_account.set_state( - &ProgramState::LookupTable(LookupTableMeta::new(authority_key)), - &invoke_context.feature_set, - )?; + lookup_table_account.set_state(&ProgramState::LookupTable(LookupTableMeta::new( + authority_key, + )))?; Ok(()) } @@ -214,7 +213,7 @@ impl Processor { let mut lookup_table_meta = lookup_table.meta; lookup_table_meta.authority = None; AddressLookupTable::overwrite_meta_data( - lookup_table_account.get_data_mut(&invoke_context.feature_set)?, + lookup_table_account.get_data_mut()?, lookup_table_meta, )?; @@ -306,12 +305,11 @@ impl Processor { )?; { AddressLookupTable::overwrite_meta_data( - lookup_table_account.get_data_mut(&invoke_context.feature_set)?, + lookup_table_account.get_data_mut()?, lookup_table_meta, )?; for new_address in new_addresses { - lookup_table_account - .extend_from_slice(new_address.as_ref(), &invoke_context.feature_set)?; + lookup_table_account.extend_from_slice(new_address.as_ref())?; } } drop(lookup_table_account); @@ -383,7 +381,7 @@ impl Processor { lookup_table_meta.deactivation_slot = clock.slot; AddressLookupTable::overwrite_meta_data( - lookup_table_account.get_data_mut(&invoke_context.feature_set)?, + lookup_table_account.get_data_mut()?, lookup_table_meta, )?; @@ -458,13 +456,13 @@ impl Processor { let mut recipient_account = instruction_context.try_borrow_instruction_account(transaction_context, 2)?; - recipient_account.checked_add_lamports(withdrawn_lamports, &invoke_context.feature_set)?; + recipient_account.checked_add_lamports(withdrawn_lamports)?; drop(recipient_account); let mut lookup_table_account = instruction_context.try_borrow_instruction_account(transaction_context, 0)?; - lookup_table_account.set_data_length(0, &invoke_context.feature_set)?; - lookup_table_account.set_lamports(0, &invoke_context.feature_set)?; + lookup_table_account.set_data_length(0)?; + lookup_table_account.set_lamports(0)?; Ok(()) } diff --git a/programs/bpf_loader/benches/serialization.rs b/programs/bpf_loader/benches/serialization.rs index abd0823b83497e..5d3c55a165e399 100644 --- a/programs/bpf_loader/benches/serialization.rs +++ b/programs/bpf_loader/benches/serialization.rs @@ -7,7 +7,6 @@ use { solana_sdk::{ account::{Account, AccountSharedData}, bpf_loader, bpf_loader_deprecated, - feature_set::FeatureSet, pubkey::Pubkey, sysvar::rent::Rent, transaction_context::{IndexOfAccount, InstructionAccount, TransactionContext}, @@ -127,13 +126,7 @@ fn bench_serialize_unaligned(bencher: &mut Bencher) { .get_current_instruction_context() .unwrap(); bencher.iter(|| { - let _ = serialize_parameters( - &transaction_context, - instruction_context, - false, - &FeatureSet::all_enabled(), - ) - .unwrap(); + let _ = serialize_parameters(&transaction_context, instruction_context, false).unwrap(); }); } @@ -144,13 +137,7 @@ fn bench_serialize_unaligned_copy_account_data(bencher: &mut Bencher) { .get_current_instruction_context() .unwrap(); bencher.iter(|| { - let _ = serialize_parameters( - &transaction_context, - instruction_context, - true, - &FeatureSet::all_enabled(), - ) - .unwrap(); + let _ = serialize_parameters(&transaction_context, instruction_context, true).unwrap(); }); } @@ -162,13 +149,7 @@ fn bench_serialize_aligned(bencher: &mut Bencher) { .unwrap(); bencher.iter(|| { - let _ = serialize_parameters( - &transaction_context, - instruction_context, - false, - &FeatureSet::all_enabled(), - ) - .unwrap(); + let _ = serialize_parameters(&transaction_context, instruction_context, false).unwrap(); }); } @@ -180,13 +161,7 @@ fn bench_serialize_aligned_copy_account_data(bencher: &mut Bencher) { .unwrap(); bencher.iter(|| { - let _ = serialize_parameters( - &transaction_context, - instruction_context, - true, - &FeatureSet::all_enabled(), - ) - .unwrap(); + let _ = serialize_parameters(&transaction_context, instruction_context, true).unwrap(); }); } @@ -197,13 +172,7 @@ fn bench_serialize_unaligned_max_accounts(bencher: &mut Bencher) { .get_current_instruction_context() .unwrap(); bencher.iter(|| { - let _ = serialize_parameters( - &transaction_context, - instruction_context, - false, - &FeatureSet::all_enabled(), - ) - .unwrap(); + let _ = serialize_parameters(&transaction_context, instruction_context, false).unwrap(); }); } @@ -215,12 +184,6 @@ fn bench_serialize_aligned_max_accounts(bencher: &mut Bencher) { .unwrap(); bencher.iter(|| { - let _ = serialize_parameters( - &transaction_context, - instruction_context, - false, - &FeatureSet::all_enabled(), - ) - .unwrap(); + let _ = serialize_parameters(&transaction_context, instruction_context, false).unwrap(); }); } diff --git a/programs/bpf_loader/src/lib.rs b/programs/bpf_loader/src/lib.rs index a9c34fbabfc6f6..2cae8b502efdb9 100644 --- a/programs/bpf_loader/src/lib.rs +++ b/programs/bpf_loader/src/lib.rs @@ -34,8 +34,7 @@ use { clock::Slot, entrypoint::{MAX_PERMITTED_DATA_INCREASE, SUCCESS}, feature_set::{ - bpf_account_data_direct_mapping, deprecate_executable_meta_update_in_bpf_loader, - enable_bpf_loader_set_authority_checked_ix, FeatureSet, + bpf_account_data_direct_mapping, enable_bpf_loader_set_authority_checked_ix, }, instruction::{AccountMeta, InstructionError}, loader_upgradeable_instruction::UpgradeableLoaderInstruction, @@ -172,7 +171,7 @@ fn write_program_data( let transaction_context = &invoke_context.transaction_context; let instruction_context = transaction_context.get_current_instruction_context()?; let mut program = instruction_context.try_borrow_instruction_account(transaction_context, 0)?; - let data = program.get_data_mut(&invoke_context.feature_set)?; + let data = program.get_data_mut()?; let write_offset = program_data_offset.saturating_add(bytes.len()); if data.len() < write_offset { ic_msg!( @@ -402,7 +401,7 @@ pub fn process_instruction_inner( } // Program Invocation - if !program_account.is_executable(&invoke_context.feature_set) { + if !program_account.is_executable() { ic_logger_msg!(log_collector, "Program is not executable"); return Err(Box::new(InstructionError::IncorrectProgramId)); } @@ -460,12 +459,9 @@ fn process_loader_upgradeable_instruction( instruction_context.get_index_of_instruction_account_in_transaction(1)?, )?); - buffer.set_state( - &UpgradeableLoaderState::Buffer { - authority_address: authority_key, - }, - &invoke_context.feature_set, - )?; + buffer.set_state(&UpgradeableLoaderState::Buffer { + authority_address: authority_key, + })?; } UpgradeableLoaderInstruction::Write { offset, bytes } => { instruction_context.check_number_of_instruction_accounts(2)?; @@ -589,8 +585,8 @@ fn process_loader_upgradeable_instruction( instruction_context.try_borrow_instruction_account(transaction_context, 3)?; let mut payer = instruction_context.try_borrow_instruction_account(transaction_context, 0)?; - payer.checked_add_lamports(buffer.get_lamports(), &invoke_context.feature_set)?; - buffer.set_lamports(0, &invoke_context.feature_set)?; + payer.checked_add_lamports(buffer.get_lamports())?; + buffer.set_lamports(0)?; } let owner_id = *program_id; @@ -644,15 +640,12 @@ fn process_loader_upgradeable_instruction( { let mut programdata = instruction_context.try_borrow_instruction_account(transaction_context, 1)?; - programdata.set_state( - &UpgradeableLoaderState::ProgramData { - slot: clock.slot, - upgrade_authority_address: authority_key, - }, - &invoke_context.feature_set, - )?; + programdata.set_state(&UpgradeableLoaderState::ProgramData { + slot: clock.slot, + upgrade_authority_address: authority_key, + })?; let dst_slice = programdata - .get_data_mut(&invoke_context.feature_set)? + .get_data_mut()? .get_mut( programdata_data_offset ..programdata_data_offset.saturating_add(buffer_data_len), @@ -665,30 +658,16 @@ fn process_loader_upgradeable_instruction( .get(buffer_data_offset..) .ok_or(InstructionError::AccountDataTooSmall)?; dst_slice.copy_from_slice(src_slice); - buffer.set_data_length( - UpgradeableLoaderState::size_of_buffer(0), - &invoke_context.feature_set, - )?; + buffer.set_data_length(UpgradeableLoaderState::size_of_buffer(0))?; } // Update the Program account let mut program = instruction_context.try_borrow_instruction_account(transaction_context, 2)?; - program.set_state( - &UpgradeableLoaderState::Program { - programdata_address: programdata_key, - }, - &invoke_context.feature_set, - )?; - - // Skip writing true to executable meta after bpf program deployment when - // `deprecate_executable_meta_update_in_bpf_loader` feature is activated. - if !invoke_context - .feature_set - .is_active(&deprecate_executable_meta_update_in_bpf_loader::id()) - { - program.set_executable(true)?; - } + program.set_state(&UpgradeableLoaderState::Program { + programdata_address: programdata_key, + })?; + program.set_executable(true)?; drop(program); ic_logger_msg!(log_collector, "Deployed program {:?}", new_program_id); @@ -710,7 +689,7 @@ fn process_loader_upgradeable_instruction( let program = instruction_context.try_borrow_instruction_account(transaction_context, 1)?; - if !program.is_executable(&invoke_context.feature_set) { + if !program.is_executable() { ic_logger_msg!(log_collector, "Program account not executable"); return Err(InstructionError::AccountNotExecutable); } @@ -841,15 +820,12 @@ fn process_loader_upgradeable_instruction( let mut programdata = instruction_context.try_borrow_instruction_account(transaction_context, 0)?; { - programdata.set_state( - &UpgradeableLoaderState::ProgramData { - slot: clock.slot, - upgrade_authority_address: authority_key, - }, - &invoke_context.feature_set, - )?; + programdata.set_state(&UpgradeableLoaderState::ProgramData { + slot: clock.slot, + upgrade_authority_address: authority_key, + })?; let dst_slice = programdata - .get_data_mut(&invoke_context.feature_set)? + .get_data_mut()? .get_mut( programdata_data_offset ..programdata_data_offset.saturating_add(buffer_data_len), @@ -864,7 +840,7 @@ fn process_loader_upgradeable_instruction( dst_slice.copy_from_slice(src_slice); } programdata - .get_data_mut(&invoke_context.feature_set)? + .get_data_mut()? .get_mut(programdata_data_offset.saturating_add(buffer_data_len)..) .ok_or(InstructionError::AccountDataTooSmall)? .fill(0); @@ -879,14 +855,10 @@ fn process_loader_upgradeable_instruction( .get_lamports() .saturating_add(buffer_lamports) .saturating_sub(programdata_balance_required), - &invoke_context.feature_set, - )?; - buffer.set_lamports(0, &invoke_context.feature_set)?; - programdata.set_lamports(programdata_balance_required, &invoke_context.feature_set)?; - buffer.set_data_length( - UpgradeableLoaderState::size_of_buffer(0), - &invoke_context.feature_set, )?; + buffer.set_lamports(0)?; + programdata.set_lamports(programdata_balance_required)?; + buffer.set_data_length(UpgradeableLoaderState::size_of_buffer(0))?; ic_logger_msg!(log_collector, "Upgraded program {:?}", new_program_id); } @@ -922,12 +894,9 @@ fn process_loader_upgradeable_instruction( ic_logger_msg!(log_collector, "Buffer authority did not sign"); return Err(InstructionError::MissingRequiredSignature); } - account.set_state( - &UpgradeableLoaderState::Buffer { - authority_address: new_authority.cloned(), - }, - &invoke_context.feature_set, - )?; + account.set_state(&UpgradeableLoaderState::Buffer { + authority_address: new_authority.cloned(), + })?; } UpgradeableLoaderState::ProgramData { slot, @@ -945,13 +914,10 @@ fn process_loader_upgradeable_instruction( ic_logger_msg!(log_collector, "Upgrade authority did not sign"); return Err(InstructionError::MissingRequiredSignature); } - account.set_state( - &UpgradeableLoaderState::ProgramData { - slot, - upgrade_authority_address: new_authority.cloned(), - }, - &invoke_context.feature_set, - )?; + account.set_state(&UpgradeableLoaderState::ProgramData { + slot, + upgrade_authority_address: new_authority.cloned(), + })?; } _ => { ic_logger_msg!(log_collector, "Account does not support authorities"); @@ -997,12 +963,9 @@ fn process_loader_upgradeable_instruction( ic_logger_msg!(log_collector, "New authority did not sign"); return Err(InstructionError::MissingRequiredSignature); } - account.set_state( - &UpgradeableLoaderState::Buffer { - authority_address: Some(*new_authority_key), - }, - &invoke_context.feature_set, - )?; + account.set_state(&UpgradeableLoaderState::Buffer { + authority_address: Some(*new_authority_key), + })?; } UpgradeableLoaderState::ProgramData { slot, @@ -1024,13 +987,10 @@ fn process_loader_upgradeable_instruction( ic_logger_msg!(log_collector, "New authority did not sign"); return Err(InstructionError::MissingRequiredSignature); } - account.set_state( - &UpgradeableLoaderState::ProgramData { - slot, - upgrade_authority_address: Some(*new_authority_key), - }, - &invoke_context.feature_set, - )?; + account.set_state(&UpgradeableLoaderState::ProgramData { + slot, + upgrade_authority_address: Some(*new_authority_key), + })?; } _ => { ic_logger_msg!(log_collector, "Account does not support authorities"); @@ -1055,19 +1015,13 @@ fn process_loader_upgradeable_instruction( instruction_context.try_borrow_instruction_account(transaction_context, 0)?; let close_key = *close_account.get_key(); let close_account_state = close_account.get_state()?; - close_account.set_data_length( - UpgradeableLoaderState::size_of_uninitialized(), - &invoke_context.feature_set, - )?; + close_account.set_data_length(UpgradeableLoaderState::size_of_uninitialized())?; match close_account_state { UpgradeableLoaderState::Uninitialized => { let mut recipient_account = instruction_context .try_borrow_instruction_account(transaction_context, 1)?; - recipient_account.checked_add_lamports( - close_account.get_lamports(), - &invoke_context.feature_set, - )?; - close_account.set_lamports(0, &invoke_context.feature_set)?; + recipient_account.checked_add_lamports(close_account.get_lamports())?; + close_account.set_lamports(0)?; ic_logger_msg!(log_collector, "Closed Uninitialized {}", close_key); } @@ -1079,7 +1033,6 @@ fn process_loader_upgradeable_instruction( transaction_context, instruction_context, &log_collector, - &invoke_context.feature_set, )?; ic_logger_msg!(log_collector, "Closed Buffer {}", close_key); @@ -1126,7 +1079,6 @@ fn process_loader_upgradeable_instruction( transaction_context, instruction_context, &log_collector, - &invoke_context.feature_set, )?; let clock = invoke_context.get_sysvar_cache().get_clock()?; invoke_context.programs_modified_by_tx.replenish( @@ -1277,7 +1229,7 @@ fn process_loader_upgradeable_instruction( let instruction_context = transaction_context.get_current_instruction_context()?; let mut programdata_account = instruction_context .try_borrow_instruction_account(transaction_context, PROGRAM_DATA_ACCOUNT_INDEX)?; - programdata_account.set_data_length(new_len, &invoke_context.feature_set)?; + programdata_account.set_data_length(new_len)?; let programdata_data_offset = UpgradeableLoaderState::size_of_programdata_metadata(); @@ -1298,13 +1250,10 @@ fn process_loader_upgradeable_instruction( let mut programdata_account = instruction_context .try_borrow_instruction_account(transaction_context, PROGRAM_DATA_ACCOUNT_INDEX)?; - programdata_account.set_state( - &UpgradeableLoaderState::ProgramData { - slot: clock_slot, - upgrade_authority_address, - }, - &invoke_context.feature_set, - )?; + programdata_account.set_state(&UpgradeableLoaderState::ProgramData { + slot: clock_slot, + upgrade_authority_address, + })?; ic_logger_msg!( log_collector, @@ -1322,7 +1271,6 @@ fn common_close_account( transaction_context: &TransactionContext, instruction_context: &InstructionContext, log_collector: &Option>>, - feature_set: &FeatureSet, ) -> Result<(), InstructionError> { if authority_address.is_none() { ic_logger_msg!(log_collector, "Account is immutable"); @@ -1346,9 +1294,9 @@ fn common_close_account( let mut recipient_account = instruction_context.try_borrow_instruction_account(transaction_context, 1)?; - recipient_account.checked_add_lamports(close_account.get_lamports(), feature_set)?; - close_account.set_lamports(0, feature_set)?; - close_account.set_state(&UpgradeableLoaderState::Uninitialized, feature_set)?; + recipient_account.checked_add_lamports(close_account.get_lamports())?; + close_account.set_lamports(0)?; + close_account.set_state(&UpgradeableLoaderState::Uninitialized)?; Ok(()) } @@ -1383,7 +1331,6 @@ fn execute<'a, 'b: 'a>( invoke_context.transaction_context, instruction_context, !direct_mapping, - &invoke_context.feature_set, )?; serialize_time.stop(); @@ -1464,15 +1411,13 @@ fn execute<'a, 'b: 'a>( instruction_account_index as IndexOfAccount, )?; - error = EbpfError::SyscallError(Box::new( - if account.is_executable(&invoke_context.feature_set) { - InstructionError::ExecutableDataModified - } else if account.is_writable() { - InstructionError::ExternalAccountDataModified - } else { - InstructionError::ReadonlyDataModified - }, - )); + error = EbpfError::SyscallError(Box::new(if account.is_executable() { + InstructionError::ExecutableDataModified + } else if account.is_writable() { + InstructionError::ExternalAccountDataModified + } else { + InstructionError::ReadonlyDataModified + })); } } } @@ -1500,7 +1445,6 @@ fn execute<'a, 'b: 'a>( copy_account_data, parameter_bytes, &invoke_context.get_syscall_context()?.accounts_metadata, - &invoke_context.feature_set, ) } @@ -1630,9 +1574,6 @@ mod tests { expected_result, Entrypoint::vm, |invoke_context| { - let mut features = FeatureSet::all_enabled(); - features.deactivate(&deprecate_executable_meta_update_in_bpf_loader::id()); - invoke_context.feature_set = Arc::new(features); test_utils::load_all_invoked_programs(invoke_context); }, |_invoke_context| {}, @@ -1721,9 +1662,6 @@ mod tests { Err(InstructionError::ProgramFailedToComplete), Entrypoint::vm, |invoke_context| { - let mut features = FeatureSet::all_enabled(); - features.deactivate(&deprecate_executable_meta_update_in_bpf_loader::id()); - invoke_context.feature_set = Arc::new(features); invoke_context.mock_set_remaining(0); test_utils::load_all_invoked_programs(invoke_context); }, @@ -2269,11 +2207,7 @@ mod tests { instruction_accounts, expected_result, Entrypoint::vm, - |invoke_context| { - let mut features = FeatureSet::all_enabled(); - features.deactivate(&deprecate_executable_meta_update_in_bpf_loader::id()); - invoke_context.feature_set = Arc::new(features); - }, + |_invoke_context| {}, |_invoke_context| {}, ) } diff --git a/programs/bpf_loader/src/serialization.rs b/programs/bpf_loader/src/serialization.rs index d4cbd09642f47c..f9cbc2e752c54d 100644 --- a/programs/bpf_loader/src/serialization.rs +++ b/programs/bpf_loader/src/serialization.rs @@ -11,7 +11,6 @@ use { solana_sdk::{ bpf_loader_deprecated, entrypoint::{BPF_ALIGN_OF_U128, MAX_PERMITTED_DATA_INCREASE, NON_DUP_MARKER}, - feature_set::FeatureSet, instruction::InstructionError, pubkey::Pubkey, system_instruction::MAX_PERMITTED_DATA_LENGTH, @@ -94,7 +93,6 @@ impl Serializer { fn write_account( &mut self, account: &mut BorrowedAccount<'_>, - feature_set: &FeatureSet, ) -> Result { let vm_data_addr = if self.copy_account_data { let vm_data_addr = self.vaddr.saturating_add(self.buffer.len() as u64); @@ -103,7 +101,7 @@ impl Serializer { } else { self.push_region(true); let vaddr = self.vaddr; - self.push_account_data_region(account, feature_set)?; + self.push_account_data_region(account)?; vaddr }; @@ -123,7 +121,7 @@ impl Serializer { .map_err(|_| InstructionError::InvalidArgument)?; self.region_start += BPF_ALIGN_OF_U128.saturating_sub(align_offset); // put the realloc padding in its own region - self.push_region(account.can_data_be_changed(feature_set).is_ok()); + self.push_region(account.can_data_be_changed().is_ok()); } } @@ -133,13 +131,12 @@ impl Serializer { fn push_account_data_region( &mut self, account: &mut BorrowedAccount<'_>, - feature_set: &FeatureSet, ) -> Result<(), InstructionError> { if !account.get_data().is_empty() { - let region = match account_data_region_memory_state(account, feature_set) { + let region = match account_data_region_memory_state(account) { MemoryState::Readable => MemoryRegion::new_readonly(account.get_data(), self.vaddr), MemoryState::Writable => { - MemoryRegion::new_writable(account.get_data_mut(feature_set)?, self.vaddr) + MemoryRegion::new_writable(account.get_data_mut()?, self.vaddr) } MemoryState::Cow(index_in_transaction) => { MemoryRegion::new_cow(account.get_data(), self.vaddr, index_in_transaction) @@ -194,7 +191,6 @@ pub fn serialize_parameters( transaction_context: &TransactionContext, instruction_context: &InstructionContext, copy_account_data: bool, - feature_set: &FeatureSet, ) -> Result< ( AlignedMemory, @@ -243,7 +239,6 @@ pub fn serialize_parameters( instruction_context.get_instruction_data(), &program_id, copy_account_data, - feature_set, ) } else { serialize_parameters_aligned( @@ -251,7 +246,6 @@ pub fn serialize_parameters( instruction_context.get_instruction_data(), &program_id, copy_account_data, - feature_set, ) } } @@ -262,7 +256,6 @@ pub fn deserialize_parameters( copy_account_data: bool, buffer: &[u8], accounts_metadata: &[SerializedAccountMetadata], - feature_set: &FeatureSet, ) -> Result<(), InstructionError> { let is_loader_deprecated = *instruction_context .try_borrow_last_program_account(transaction_context)? @@ -276,7 +269,6 @@ pub fn deserialize_parameters( copy_account_data, buffer, account_lengths, - feature_set, ) } else { deserialize_parameters_aligned( @@ -285,7 +277,6 @@ pub fn deserialize_parameters( copy_account_data, buffer, account_lengths, - feature_set, ) } } @@ -295,7 +286,6 @@ fn serialize_parameters_unaligned( instruction_data: &[u8], program_id: &Pubkey, copy_account_data: bool, - feature_set: &FeatureSet, ) -> Result< ( AlignedMemory, @@ -346,9 +336,9 @@ fn serialize_parameters_unaligned( let vm_key_addr = s.write_all(account.get_key().as_ref()); let vm_lamports_addr = s.write::(account.get_lamports().to_le()); s.write::((account.get_data().len() as u64).to_le()); - let vm_data_addr = s.write_account(&mut account, feature_set)?; + let vm_data_addr = s.write_account(&mut account)?; let vm_owner_addr = s.write_all(account.get_owner().as_ref()); - s.write::(account.is_executable(feature_set) as u8); + s.write::(account.is_executable() as u8); s.write::((account.get_rent_epoch()).to_le()); accounts_metadata.push(SerializedAccountMetadata { original_data_len: account.get_data().len(), @@ -374,7 +364,6 @@ pub fn deserialize_parameters_unaligned>( copy_account_data: bool, buffer: &[u8], account_lengths: I, - feature_set: &FeatureSet, ) -> Result<(), InstructionError> { let mut start = size_of::(); // number of accounts for (instruction_account_index, pre_len) in (0..instruction_context @@ -396,7 +385,7 @@ pub fn deserialize_parameters_unaligned>( .ok_or(InstructionError::InvalidArgument)?, ); if borrowed_account.get_lamports() != lamports { - borrowed_account.set_lamports(lamports, feature_set)?; + borrowed_account.set_lamports(lamports)?; } start += size_of::() // lamports + size_of::(); // data length @@ -407,9 +396,9 @@ pub fn deserialize_parameters_unaligned>( // The redundant check helps to avoid the expensive data comparison if we can match borrowed_account .can_data_be_resized(data.len()) - .and_then(|_| borrowed_account.can_data_be_changed(feature_set)) + .and_then(|_| borrowed_account.can_data_be_changed()) { - Ok(()) => borrowed_account.set_data_from_slice(data, feature_set)?, + Ok(()) => borrowed_account.set_data_from_slice(data)?, Err(err) if borrowed_account.get_data() != data => return Err(err), _ => {} } @@ -428,7 +417,6 @@ fn serialize_parameters_aligned( instruction_data: &[u8], program_id: &Pubkey, copy_account_data: bool, - feature_set: &FeatureSet, ) -> Result< ( AlignedMemory, @@ -478,13 +466,13 @@ fn serialize_parameters_aligned( s.write::(NON_DUP_MARKER); s.write::(borrowed_account.is_signer() as u8); s.write::(borrowed_account.is_writable() as u8); - s.write::(borrowed_account.is_executable(feature_set) as u8); + s.write::(borrowed_account.is_executable() as u8); s.write_all(&[0u8, 0, 0, 0]); let vm_key_addr = s.write_all(borrowed_account.get_key().as_ref()); let vm_owner_addr = s.write_all(borrowed_account.get_owner().as_ref()); let vm_lamports_addr = s.write::(borrowed_account.get_lamports().to_le()); s.write::((borrowed_account.get_data().len() as u64).to_le()); - let vm_data_addr = s.write_account(&mut borrowed_account, feature_set)?; + let vm_data_addr = s.write_account(&mut borrowed_account)?; s.write::((borrowed_account.get_rent_epoch()).to_le()); accounts_metadata.push(SerializedAccountMetadata { original_data_len: borrowed_account.get_data().len(), @@ -515,7 +503,6 @@ pub fn deserialize_parameters_aligned>( copy_account_data: bool, buffer: &[u8], account_lengths: I, - feature_set: &FeatureSet, ) -> Result<(), InstructionError> { let mut start = size_of::(); // number of accounts for (instruction_account_index, pre_len) in (0..instruction_context @@ -545,7 +532,7 @@ pub fn deserialize_parameters_aligned>( .ok_or(InstructionError::InvalidArgument)?, ); if borrowed_account.get_lamports() != lamports { - borrowed_account.set_lamports(lamports, feature_set)?; + borrowed_account.set_lamports(lamports)?; } start += size_of::(); // lamports let post_len = LittleEndian::read_u64( @@ -567,9 +554,9 @@ pub fn deserialize_parameters_aligned>( .ok_or(InstructionError::InvalidArgument)?; match borrowed_account .can_data_be_resized(post_len) - .and_then(|_| borrowed_account.can_data_be_changed(feature_set)) + .and_then(|_| borrowed_account.can_data_be_changed()) { - Ok(()) => borrowed_account.set_data_from_slice(data, feature_set)?, + Ok(()) => borrowed_account.set_data_from_slice(data)?, Err(err) if borrowed_account.get_data() != data => return Err(err), _ => {} } @@ -583,14 +570,14 @@ pub fn deserialize_parameters_aligned>( .ok_or(InstructionError::InvalidArgument)?; match borrowed_account .can_data_be_resized(post_len) - .and_then(|_| borrowed_account.can_data_be_changed(feature_set)) + .and_then(|_| borrowed_account.can_data_be_changed()) { Ok(()) => { - borrowed_account.set_data_length(post_len, feature_set)?; + borrowed_account.set_data_length(post_len)?; let allocated_bytes = post_len.saturating_sub(pre_len); if allocated_bytes > 0 { borrowed_account - .get_data_mut(feature_set)? + .get_data_mut()? .get_mut(pre_len..pre_len.saturating_add(allocated_bytes)) .ok_or(InstructionError::InvalidArgument)? .copy_from_slice( @@ -608,18 +595,15 @@ pub fn deserialize_parameters_aligned>( start += size_of::(); // rent_epoch if borrowed_account.get_owner().to_bytes() != owner { // Change the owner at the end so that we are allowed to change the lamports and data before - borrowed_account.set_owner(owner, feature_set)?; + borrowed_account.set_owner(owner)?; } } } Ok(()) } -pub(crate) fn account_data_region_memory_state( - account: &BorrowedAccount<'_>, - feature_set: &FeatureSet, -) -> MemoryState { - if account.can_data_be_changed(feature_set).is_ok() { +pub(crate) fn account_data_region_memory_state(account: &BorrowedAccount<'_>) -> MemoryState { + if account.can_data_be_changed().is_ok() { if account.is_shared() { MemoryState::Cow(account.get_index_in_transaction() as u64) } else { @@ -744,7 +728,6 @@ mod tests { invoke_context.transaction_context, instruction_context, copy_account_data, - &invoke_context.feature_set, ); assert_eq!( serialization_result.as_ref().err(), @@ -899,7 +882,6 @@ mod tests { invoke_context.transaction_context, instruction_context, copy_account_data, - &invoke_context.feature_set, ) .unwrap(); @@ -938,7 +920,7 @@ mod tests { assert_eq!(account.lamports(), account_info.lamports()); assert_eq!(account.data(), &account_info.data.borrow()[..]); assert_eq!(account.owner(), account_info.owner); - assert!(account_info.executable); + assert_eq!(account.executable(), account_info.executable); assert_eq!(account.rent_epoch(), account_info.rent_epoch); assert_eq!( @@ -961,7 +943,6 @@ mod tests { copy_account_data, serialized.as_slice(), &accounts_metadata, - &invoke_context.feature_set, ) .unwrap(); for (index_in_transaction, (_key, original_account)) in @@ -992,7 +973,6 @@ mod tests { invoke_context.transaction_context, instruction_context, copy_account_data, - &invoke_context.feature_set, ) .unwrap(); let mut serialized_regions = concat_regions(®ions); @@ -1023,7 +1003,7 @@ mod tests { assert_eq!(account.lamports(), account_info.lamports()); assert_eq!(account.data(), &account_info.data.borrow()[..]); assert_eq!(account.owner(), account_info.owner); - assert!(account_info.executable); + assert_eq!(account.executable(), account_info.executable); assert_eq!(account.rent_epoch(), account_info.rent_epoch); } @@ -1033,7 +1013,6 @@ mod tests { copy_account_data, serialized.as_slice(), &account_lengths, - &invoke_context.feature_set, ) .unwrap(); for (index_in_transaction, (_key, original_account)) in diff --git a/programs/bpf_loader/src/syscalls/cpi.rs b/programs/bpf_loader/src/syscalls/cpi.rs index b4368f2172e04f..13f9cbaf905275 100644 --- a/programs/bpf_loader/src/syscalls/cpi.rs +++ b/programs/bpf_loader/src/syscalls/cpi.rs @@ -8,7 +8,7 @@ use { memory_region::{MemoryRegion, MemoryState}, }, solana_sdk::{ - feature_set::{enable_bpf_loader_set_authority_checked_ix, FeatureSet}, + feature_set::enable_bpf_loader_set_authority_checked_ix, stable_layout::stable_instruction::StableInstruction, syscalls::{ MAX_CPI_ACCOUNT_INFOS, MAX_CPI_INSTRUCTION_ACCOUNTS, MAX_CPI_INSTRUCTION_DATA_LEN, @@ -883,7 +883,7 @@ where .transaction_context .get_key_of_account_at_index(instruction_account.index_in_transaction)?; - if callee_account.is_executable(&invoke_context.feature_set) { + if callee_account.is_executable() { // Use the known account consume_compute_meter( invoke_context, @@ -1139,7 +1139,6 @@ fn cpi_common( caller_account, &callee_account, is_loader_deprecated, - &invoke_context.feature_set, )?; } } @@ -1180,7 +1179,7 @@ fn update_callee_account( direct_mapping: bool, ) -> Result<(), Error> { if callee_account.get_lamports() != *caller_account.lamports { - callee_account.set_lamports(*caller_account.lamports, &invoke_context.feature_set)?; + callee_account.set_lamports(*caller_account.lamports)?; } if direct_mapping { @@ -1188,7 +1187,7 @@ fn update_callee_account( let post_len = *caller_account.ref_to_len_in_vm.get()? as usize; match callee_account .can_data_be_resized(post_len) - .and_then(|_| callee_account.can_data_be_changed(&invoke_context.feature_set)) + .and_then(|_| callee_account.can_data_be_changed()) { Ok(()) => { let realloc_bytes_used = post_len.saturating_sub(caller_account.original_data_len); @@ -1196,7 +1195,7 @@ fn update_callee_account( if is_loader_deprecated && realloc_bytes_used > 0 { return Err(InstructionError::InvalidRealloc.into()); } - callee_account.set_data_length(post_len, &invoke_context.feature_set)?; + callee_account.set_data_length(post_len)?; if realloc_bytes_used > 0 { let serialized_data = translate_slice::( memory_mapping, @@ -1207,7 +1206,7 @@ fn update_callee_account( invoke_context.get_check_aligned(), )?; callee_account - .get_data_mut(&invoke_context.feature_set)? + .get_data_mut()? .get_mut(caller_account.original_data_len..post_len) .ok_or(SyscallError::InvalidLength)? .copy_from_slice(serialized_data); @@ -1222,10 +1221,9 @@ fn update_callee_account( // The redundant check helps to avoid the expensive data comparison if we can match callee_account .can_data_be_resized(caller_account.serialized_data.len()) - .and_then(|_| callee_account.can_data_be_changed(&invoke_context.feature_set)) + .and_then(|_| callee_account.can_data_be_changed()) { - Ok(()) => callee_account - .set_data_from_slice(caller_account.serialized_data, &invoke_context.feature_set)?, + Ok(()) => callee_account.set_data_from_slice(caller_account.serialized_data)?, Err(err) if callee_account.get_data() != caller_account.serialized_data => { return Err(Box::new(err)); } @@ -1235,7 +1233,7 @@ fn update_callee_account( // Change the owner at the end so that we are allowed to change the lamports and data before if callee_account.get_owner() != caller_account.owner { - callee_account.set_owner(caller_account.owner.as_ref(), &invoke_context.feature_set)?; + callee_account.set_owner(caller_account.owner.as_ref())?; } Ok(()) @@ -1246,7 +1244,6 @@ fn update_caller_account_perms( caller_account: &CallerAccount, callee_account: &BorrowedAccount<'_>, is_loader_deprecated: bool, - feature_set: &FeatureSet, ) -> Result<(), Error> { let CallerAccount { original_data_len, @@ -1256,10 +1253,9 @@ fn update_caller_account_perms( let data_region = account_data_region(memory_mapping, *vm_data_addr, *original_data_len)?; if let Some(region) = data_region { - region.state.set(account_data_region_memory_state( - callee_account, - feature_set, - )); + region + .state + .set(account_data_region_memory_state(callee_account)); } let realloc_region = account_realloc_region( memory_mapping, @@ -1270,7 +1266,7 @@ fn update_caller_account_perms( if let Some(region) = realloc_region { region .state - .set(if callee_account.can_data_be_changed(feature_set).is_ok() { + .set(if callee_account.can_data_be_changed().is_ok() { MemoryState::Writable } else { MemoryState::Readable @@ -1818,11 +1814,9 @@ mod tests { let mut callee_account = borrow_instruction_account!(invoke_context, 0); + callee_account.set_lamports(42).unwrap(); callee_account - .set_lamports(42, &invoke_context.feature_set) - .unwrap(); - callee_account - .set_owner(Pubkey::new_unique().as_ref(), &invoke_context.feature_set) + .set_owner(Pubkey::new_unique().as_ref()) .unwrap(); update_caller_account( @@ -1891,9 +1885,7 @@ mod tests { (b"foobazbad".to_vec(), MAX_PERMITTED_DATA_INCREASE - 3), ] { assert_eq!(caller_account.serialized_data, callee_account.get_data()); - callee_account - .set_data_from_slice(&new_value, &invoke_context.feature_set) - .unwrap(); + callee_account.set_data_from_slice(&new_value).unwrap(); update_caller_account( &invoke_context, @@ -1921,10 +1913,7 @@ mod tests { } callee_account - .set_data_length( - original_data_len + MAX_PERMITTED_DATA_INCREASE, - &invoke_context.feature_set, - ) + .set_data_length(original_data_len + MAX_PERMITTED_DATA_INCREASE) .unwrap(); update_caller_account( &invoke_context, @@ -1940,10 +1929,7 @@ mod tests { assert!(is_zeroed(&data_slice[data_len..])); callee_account - .set_data_length( - original_data_len + MAX_PERMITTED_DATA_INCREASE + 1, - &invoke_context.feature_set, - ) + .set_data_length(original_data_len + MAX_PERMITTED_DATA_INCREASE + 1) .unwrap(); assert_matches!( update_caller_account( @@ -1958,11 +1944,9 @@ mod tests { ); // close the account + callee_account.set_data_length(0).unwrap(); callee_account - .set_data_length(0, &invoke_context.feature_set) - .unwrap(); - callee_account - .set_owner(system_program::id().as_ref(), &invoke_context.feature_set) + .set_owner(system_program::id().as_ref()) .unwrap(); update_caller_account( &invoke_context, @@ -2031,13 +2015,9 @@ mod tests { (vec![], 0), // check lower bound ] { if change_ptr { - callee_account - .set_data(new_value, &invoke_context.feature_set) - .unwrap(); + callee_account.set_data(new_value).unwrap(); } else { - callee_account - .set_data_from_slice(&new_value, &invoke_context.feature_set) - .unwrap(); + callee_account.set_data_from_slice(&new_value).unwrap(); } update_caller_account( @@ -2107,10 +2087,7 @@ mod tests { } callee_account - .set_data_length( - original_data_len + MAX_PERMITTED_DATA_INCREASE, - &invoke_context.feature_set, - ) + .set_data_length(original_data_len + MAX_PERMITTED_DATA_INCREASE) .unwrap(); update_caller_account( &invoke_context, @@ -2128,10 +2105,7 @@ mod tests { ); callee_account - .set_data_length( - original_data_len + MAX_PERMITTED_DATA_INCREASE + 1, - &invoke_context.feature_set, - ) + .set_data_length(original_data_len + MAX_PERMITTED_DATA_INCREASE + 1) .unwrap(); assert_matches!( update_caller_account( @@ -2146,11 +2120,9 @@ mod tests { ); // close the account + callee_account.set_data_length(0).unwrap(); callee_account - .set_data_length(0, &invoke_context.feature_set) - .unwrap(); - callee_account - .set_owner(system_program::id().as_ref(), &invoke_context.feature_set) + .set_owner(system_program::id().as_ref()) .unwrap(); update_caller_account( &invoke_context, @@ -2493,9 +2465,7 @@ mod tests { // this is done when a writable account is mapped, and it ensures // through make_data_mut() that the account is made writable and resized // with enough padding to hold the realloc padding - callee_account - .get_data_mut(&invoke_context.feature_set) - .unwrap(); + callee_account.get_data_mut().unwrap(); let serialized_data = translate_slice_mut::( &memory_mapping, diff --git a/programs/config/src/config_processor.rs b/programs/config/src/config_processor.rs index b85715eb171391..fd4b806567180d 100644 --- a/programs/config/src/config_processor.rs +++ b/programs/config/src/config_processor.rs @@ -127,7 +127,7 @@ declare_process_instruction!(Entrypoint, DEFAULT_COMPUTE_UNITS, |invoke_context| ic_msg!(invoke_context, "instruction data too large"); return Err(InstructionError::InvalidInstructionData); } - config_account.get_data_mut(&invoke_context.feature_set)?[..data.len()].copy_from_slice(data); + config_account.get_data_mut()?[..data.len()].copy_from_slice(data); Ok(()) }); diff --git a/programs/loader-v4/src/lib.rs b/programs/loader-v4/src/lib.rs index 4764b23fe65e50..9573f925085585 100644 --- a/programs/loader-v4/src/lib.rs +++ b/programs/loader-v4/src/lib.rs @@ -247,7 +247,7 @@ pub fn process_instruction_write( } let end_offset = (offset as usize).saturating_add(bytes.len()); program - .get_data_mut(&invoke_context.feature_set)? + .get_data_mut()? .get_mut( LoaderV4State::program_data_offset().saturating_add(offset as usize) ..LoaderV4State::program_data_offset().saturating_add(end_offset), @@ -325,20 +325,19 @@ pub fn process_instruction_truncate( return Err(InstructionError::InvalidArgument); } let lamports_to_receive = program.get_lamports().saturating_sub(required_lamports); - program.checked_sub_lamports(lamports_to_receive, &invoke_context.feature_set)?; - recipient.checked_add_lamports(lamports_to_receive, &invoke_context.feature_set)?; + program.checked_sub_lamports(lamports_to_receive)?; + recipient.checked_add_lamports(lamports_to_receive)?; } std::cmp::Ordering::Equal => {} } if new_size == 0 { - program.set_data_length(0, &invoke_context.feature_set)?; + program.set_data_length(0)?; } else { program.set_data_length( LoaderV4State::program_data_offset().saturating_add(new_size as usize), - &invoke_context.feature_set, )?; if is_initialization { - let state = get_state_mut(program.get_data_mut(&invoke_context.feature_set)?)?; + let state = get_state_mut(program.get_data_mut()?)?; state.slot = 0; state.status = LoaderV4Status::Retracted; state.authority_address = *authority_address; @@ -432,12 +431,12 @@ pub fn process_instruction_deploy( let rent = invoke_context.get_sysvar_cache().get_rent()?; let required_lamports = rent.minimum_balance(source_program.get_data().len()); let transfer_lamports = required_lamports.saturating_sub(program.get_lamports()); - program.set_data_from_slice(source_program.get_data(), &invoke_context.feature_set)?; - source_program.set_data_length(0, &invoke_context.feature_set)?; - source_program.checked_sub_lamports(transfer_lamports, &invoke_context.feature_set)?; - program.checked_add_lamports(transfer_lamports, &invoke_context.feature_set)?; + program.set_data_from_slice(source_program.get_data())?; + source_program.set_data_length(0)?; + source_program.checked_sub_lamports(transfer_lamports)?; + program.checked_add_lamports(transfer_lamports)?; } - let state = get_state_mut(program.get_data_mut(&invoke_context.feature_set)?)?; + let state = get_state_mut(program.get_data_mut()?)?; state.slot = current_slot; state.status = LoaderV4Status::Deployed; @@ -486,7 +485,7 @@ pub fn process_instruction_retract( ic_logger_msg!(log_collector, "Program is not deployed"); return Err(InstructionError::InvalidArgument); } - let state = get_state_mut(program.get_data_mut(&invoke_context.feature_set)?)?; + let state = get_state_mut(program.get_data_mut()?)?; state.status = LoaderV4Status::Retracted; Ok(()) } @@ -516,7 +515,7 @@ pub fn process_instruction_transfer_authority( ic_logger_msg!(log_collector, "New authority did not sign"); return Err(InstructionError::MissingRequiredSignature); } - let state = get_state_mut(program.get_data_mut(&invoke_context.feature_set)?)?; + let state = get_state_mut(program.get_data_mut()?)?; if let Some(new_authority_address) = new_authority_address { state.authority_address = new_authority_address; } else if matches!(state.status, LoaderV4Status::Deployed) { diff --git a/programs/sbf/benches/bpf_loader.rs b/programs/sbf/benches/bpf_loader.rs index 1dd827bbeb197b..cf8670cc86151a 100644 --- a/programs/sbf/benches/bpf_loader.rs +++ b/programs/sbf/benches/bpf_loader.rs @@ -38,7 +38,7 @@ use { bpf_loader, client::SyncClient, entrypoint::SUCCESS, - feature_set::{self, FeatureSet}, + feature_set::FeatureSet, instruction::{AccountMeta, Instruction}, message::Message, native_loader, @@ -189,15 +189,11 @@ fn bench_program_alu(bencher: &mut Bencher) { #[bench] fn bench_program_execute_noop(bencher: &mut Bencher) { let GenesisConfigInfo { - mut genesis_config, + genesis_config, mint_keypair, .. } = create_genesis_config(50); - genesis_config - .accounts - .remove(&feature_set::deprecate_executable_meta_update_in_bpf_loader::id()); - let bank = Bank::new_for_benches(&genesis_config); let (bank, bank_forks) = bank.wrap_with_bank_forks_for_tests(); let mut bank_client = BankClient::new_shared(bank.clone()); @@ -261,7 +257,6 @@ fn bench_create_vm(bencher: &mut Bencher) { .get_current_instruction_context() .unwrap(), !direct_mapping, // copy_account_data, - &invoke_context.feature_set, ) .unwrap(); @@ -296,7 +291,6 @@ fn bench_instruction_count_tuner(_bencher: &mut Bencher) { .get_current_instruction_context() .unwrap(), !direct_mapping, // copy_account_data - &invoke_context.feature_set, ) .unwrap(); diff --git a/programs/stake/src/stake_instruction.rs b/programs/stake/src/stake_instruction.rs index f52f978da324fe..b7ce459a541315 100644 --- a/programs/stake/src/stake_instruction.rs +++ b/programs/stake/src/stake_instruction.rs @@ -73,13 +73,7 @@ declare_process_instruction!(Entrypoint, DEFAULT_COMPUTE_UNITS, |invoke_context| Ok(StakeInstruction::Initialize(authorized, lockup)) => { let mut me = get_stake_account()?; let rent = get_sysvar_with_account_check::rent(invoke_context, instruction_context, 1)?; - initialize( - &mut me, - &authorized, - &lockup, - &rent, - &invoke_context.feature_set, - ) + initialize(&mut me, &authorized, &lockup, &rent) } Ok(StakeInstruction::Authorize(authorized_pubkey, stake_authorize)) => { let mut me = get_stake_account()?; @@ -96,7 +90,6 @@ declare_process_instruction!(Entrypoint, DEFAULT_COMPUTE_UNITS, |invoke_context| stake_authorize, &clock, custodian_pubkey, - &invoke_context.feature_set, ) } Ok(StakeInstruction::AuthorizeWithSeed(args)) => { @@ -118,7 +111,6 @@ declare_process_instruction!(Entrypoint, DEFAULT_COMPUTE_UNITS, |invoke_context| args.stake_authorize, &clock, custodian_pubkey, - &invoke_context.feature_set, ) } Ok(StakeInstruction::DelegateStake) => { @@ -221,7 +213,6 @@ declare_process_instruction!(Entrypoint, DEFAULT_COMPUTE_UNITS, |invoke_context| None }, new_warmup_cooldown_rate_epoch(invoke_context), - &invoke_context.feature_set, ) } Ok(StakeInstruction::Deactivate) => { @@ -233,13 +224,7 @@ declare_process_instruction!(Entrypoint, DEFAULT_COMPUTE_UNITS, |invoke_context| Ok(StakeInstruction::SetLockup(lockup)) => { let mut me = get_stake_account()?; let clock = invoke_context.get_sysvar_cache().get_clock()?; - set_lockup( - &mut me, - &lockup, - &signers, - &clock, - &invoke_context.feature_set, - ) + set_lockup(&mut me, &lockup, &signers, &clock) } Ok(StakeInstruction::InitializeChecked) => { let mut me = get_stake_account()?; @@ -260,13 +245,7 @@ declare_process_instruction!(Entrypoint, DEFAULT_COMPUTE_UNITS, |invoke_context| }; let rent = get_sysvar_with_account_check::rent(invoke_context, instruction_context, 1)?; - initialize( - &mut me, - &authorized, - &Lockup::default(), - &rent, - &invoke_context.feature_set, - ) + initialize(&mut me, &authorized, &Lockup::default(), &rent) } Ok(StakeInstruction::AuthorizeChecked(stake_authorize)) => { let mut me = get_stake_account()?; @@ -289,7 +268,6 @@ declare_process_instruction!(Entrypoint, DEFAULT_COMPUTE_UNITS, |invoke_context| stake_authorize, &clock, custodian_pubkey, - &invoke_context.feature_set, ) } Ok(StakeInstruction::AuthorizeCheckedWithSeed(args)) => { @@ -318,7 +296,6 @@ declare_process_instruction!(Entrypoint, DEFAULT_COMPUTE_UNITS, |invoke_context| args.stake_authorize, &clock, custodian_pubkey, - &invoke_context.feature_set, ) } Ok(StakeInstruction::SetLockupChecked(lockup_checked)) => { @@ -332,13 +309,7 @@ declare_process_instruction!(Entrypoint, DEFAULT_COMPUTE_UNITS, |invoke_context| custodian: custodian_pubkey.cloned(), }; let clock = invoke_context.get_sysvar_cache().get_clock()?; - set_lockup( - &mut me, - &lockup, - &signers, - &clock, - &invoke_context.feature_set, - ) + set_lockup(&mut me, &lockup, &signers, &clock) } Ok(StakeInstruction::GetMinimumDelegation) => { let feature_set = invoke_context.feature_set.as_ref(); diff --git a/programs/stake/src/stake_state.rs b/programs/stake/src/stake_state.rs index 68b03c9e1429a9..f20283cfbd8582 100644 --- a/programs/stake/src/stake_state.rs +++ b/programs/stake/src/stake_state.rs @@ -149,7 +149,6 @@ pub fn initialize( authorized: &Authorized, lockup: &Lockup, rent: &Rent, - feature_set: &FeatureSet, ) -> Result<(), InstructionError> { if stake_account.get_data().len() != StakeStateV2::size_of() { return Err(InstructionError::InvalidAccountData); @@ -158,14 +157,11 @@ pub fn initialize( if let StakeStateV2::Uninitialized = stake_account.get_state()? { let rent_exempt_reserve = rent.minimum_balance(stake_account.get_data().len()); if stake_account.get_lamports() >= rent_exempt_reserve { - stake_account.set_state( - &StakeStateV2::Initialized(Meta { - rent_exempt_reserve, - authorized: *authorized, - lockup: *lockup, - }), - feature_set, - ) + stake_account.set_state(&StakeStateV2::Initialized(Meta { + rent_exempt_reserve, + authorized: *authorized, + lockup: *lockup, + })) } else { Err(InstructionError::InsufficientFunds) } @@ -184,7 +180,6 @@ pub fn authorize( stake_authorize: StakeAuthorize, clock: &Clock, custodian: Option<&Pubkey>, - feature_set: &FeatureSet, ) -> Result<(), InstructionError> { match stake_account.get_state()? { StakeStateV2::Stake(mut meta, stake, stake_flags) => { @@ -194,7 +189,7 @@ pub fn authorize( stake_authorize, Some((&meta.lockup, clock, custodian)), )?; - stake_account.set_state(&StakeStateV2::Stake(meta, stake, stake_flags), feature_set) + stake_account.set_state(&StakeStateV2::Stake(meta, stake, stake_flags)) } StakeStateV2::Initialized(mut meta) => { meta.authorized.authorize( @@ -203,7 +198,7 @@ pub fn authorize( stake_authorize, Some((&meta.lockup, clock, custodian)), )?; - stake_account.set_state(&StakeStateV2::Initialized(meta), feature_set) + stake_account.set_state(&StakeStateV2::Initialized(meta)) } _ => Err(InstructionError::InvalidAccountData), } @@ -221,7 +216,6 @@ pub fn authorize_with_seed( stake_authorize: StakeAuthorize, clock: &Clock, custodian: Option<&Pubkey>, - feature_set: &FeatureSet, ) -> Result<(), InstructionError> { let mut signers = HashSet::default(); if instruction_context.is_instruction_account_signer(authority_base_index)? { @@ -242,7 +236,6 @@ pub fn authorize_with_seed( stake_authorize, clock, custodian, - feature_set, ) } @@ -280,10 +273,7 @@ pub fn delegate( &vote_state?.convert_to_current(), clock.epoch, ); - stake_account.set_state( - &StakeStateV2::Stake(meta, stake, StakeFlags::empty()), - feature_set, - ) + stake_account.set_state(&StakeStateV2::Stake(meta, stake, StakeFlags::empty())) } StakeStateV2::Stake(meta, mut stake, stake_flags) => { meta.authorized.check(signers, StakeAuthorize::Staker)?; @@ -298,7 +288,7 @@ pub fn delegate( clock, stake_history, )?; - stake_account.set_state(&StakeStateV2::Stake(meta, stake, stake_flags), feature_set) + stake_account.set_state(&StakeStateV2::Stake(meta, stake, stake_flags)) } _ => Err(InstructionError::InvalidAccountData), } @@ -354,10 +344,7 @@ pub fn deactivate( if let StakeStateV2::Stake(meta, mut stake, mut stake_flags) = stake_account.get_state()? { meta.authorized.check(signers, StakeAuthorize::Staker)?; deactivate_stake(invoke_context, &mut stake, &mut stake_flags, clock.epoch)?; - stake_account.set_state( - &StakeStateV2::Stake(meta, stake, stake_flags), - &invoke_context.feature_set, - ) + stake_account.set_state(&StakeStateV2::Stake(meta, stake, stake_flags)) } else { Err(InstructionError::InvalidAccountData) } @@ -368,16 +355,15 @@ pub fn set_lockup( lockup: &LockupArgs, signers: &HashSet, clock: &Clock, - feature_set: &FeatureSet, ) -> Result<(), InstructionError> { match stake_account.get_state()? { StakeStateV2::Initialized(mut meta) => { meta.set_lockup(lockup, signers, clock)?; - stake_account.set_state(&StakeStateV2::Initialized(meta), feature_set) + stake_account.set_state(&StakeStateV2::Initialized(meta)) } StakeStateV2::Stake(mut meta, stake, stake_flags) => { meta.set_lockup(lockup, signers, clock)?; - stake_account.set_state(&StakeStateV2::Stake(meta, stake, stake_flags), feature_set) + stake_account.set_state(&StakeStateV2::Stake(meta, stake, stake_flags)) } _ => Err(InstructionError::InvalidAccountData), } @@ -481,17 +467,11 @@ pub fn split( let mut stake_account = instruction_context .try_borrow_instruction_account(transaction_context, stake_account_index)?; - stake_account.set_state( - &StakeStateV2::Stake(meta, stake, stake_flags), - &invoke_context.feature_set, - )?; + stake_account.set_state(&StakeStateV2::Stake(meta, stake, stake_flags))?; drop(stake_account); let mut split = instruction_context .try_borrow_instruction_account(transaction_context, split_index)?; - split.set_state( - &StakeStateV2::Stake(split_meta, split_stake, stake_flags), - &invoke_context.feature_set, - )?; + split.set_state(&StakeStateV2::Stake(split_meta, split_stake, stake_flags))?; } StakeStateV2::Initialized(meta) => { meta.authorized.check(signers, StakeAuthorize::Staker)?; @@ -510,10 +490,7 @@ pub fn split( split_meta.rent_exempt_reserve = validated_split_info.destination_rent_exempt_reserve; let mut split = instruction_context .try_borrow_instruction_account(transaction_context, split_index)?; - split.set_state( - &StakeStateV2::Initialized(split_meta), - &invoke_context.feature_set, - )?; + split.set_state(&StakeStateV2::Initialized(split_meta))?; } StakeStateV2::Uninitialized => { let stake_pubkey = transaction_context.get_key_of_account_at_index( @@ -531,17 +508,17 @@ pub fn split( let mut stake_account = instruction_context .try_borrow_instruction_account(transaction_context, stake_account_index)?; if lamports == stake_account.get_lamports() { - stake_account.set_state(&StakeStateV2::Uninitialized, &invoke_context.feature_set)?; + stake_account.set_state(&StakeStateV2::Uninitialized)?; } drop(stake_account); let mut split = instruction_context.try_borrow_instruction_account(transaction_context, split_index)?; - split.checked_add_lamports(lamports, &invoke_context.feature_set)?; + split.checked_add_lamports(lamports)?; drop(split); let mut stake_account = instruction_context .try_borrow_instruction_account(transaction_context, stake_account_index)?; - stake_account.checked_sub_lamports(lamports, &invoke_context.feature_set)?; + stake_account.checked_sub_lamports(lamports)?; Ok(()) } @@ -597,16 +574,16 @@ pub fn merge( ic_msg!(invoke_context, "Merging stake accounts"); if let Some(merged_state) = stake_merge_kind.merge(invoke_context, source_merge_kind, clock)? { - stake_account.set_state(&merged_state, &invoke_context.feature_set)?; + stake_account.set_state(&merged_state)?; } // Source is about to be drained, deinitialize its state - source_account.set_state(&StakeStateV2::Uninitialized, &invoke_context.feature_set)?; + source_account.set_state(&StakeStateV2::Uninitialized)?; // Drain the source stake account let lamports = source_account.get_lamports(); - source_account.checked_sub_lamports(lamports, &invoke_context.feature_set)?; - stake_account.checked_add_lamports(lamports, &invoke_context.feature_set)?; + source_account.checked_sub_lamports(lamports)?; + stake_account.checked_add_lamports(lamports)?; Ok(()) } @@ -698,9 +675,8 @@ pub fn redelegate( deactivate(invoke_context, stake_account, &clock, signers)?; // transfer the effective stake to the uninitialized stake account - stake_account.checked_sub_lamports(effective_stake, &invoke_context.feature_set)?; - uninitialized_stake_account - .checked_add_lamports(effective_stake, &invoke_context.feature_set)?; + stake_account.checked_sub_lamports(effective_stake)?; + uninitialized_stake_account.checked_add_lamports(effective_stake)?; // initialize and schedule `uninitialized_stake_account` for activation let sysvar_cache = invoke_context.get_sysvar_cache(); @@ -714,19 +690,16 @@ pub fn redelegate( &uninitialized_stake_meta, &invoke_context.feature_set, )?; - uninitialized_stake_account.set_state( - &StakeStateV2::Stake( - uninitialized_stake_meta, - new_stake( - stake_amount, - &vote_pubkey, - &vote_state.convert_to_current(), - clock.epoch, - ), - StakeFlags::MUST_FULLY_ACTIVATE_BEFORE_DEACTIVATION_IS_PERMITTED, + uninitialized_stake_account.set_state(&StakeStateV2::Stake( + uninitialized_stake_meta, + new_stake( + stake_amount, + &vote_pubkey, + &vote_state.convert_to_current(), + clock.epoch, ), - &invoke_context.feature_set, - )?; + StakeFlags::MUST_FULLY_ACTIVATE_BEFORE_DEACTIVATION_IS_PERMITTED, + ))?; Ok(()) } @@ -743,7 +716,6 @@ pub fn withdraw( withdraw_authority_index: IndexOfAccount, custodian_index: Option, new_rate_activation_epoch: Option, - feature_set: &FeatureSet, ) -> Result<(), InstructionError> { let withdraw_authority_pubkey = transaction_context.get_key_of_account_at_index( instruction_context @@ -828,14 +800,14 @@ pub fn withdraw( // Deinitialize state upon zero balance if lamports == stake_account.get_lamports() { - stake_account.set_state(&StakeStateV2::Uninitialized, feature_set)?; + stake_account.set_state(&StakeStateV2::Uninitialized)?; } - stake_account.checked_sub_lamports(lamports, feature_set)?; + stake_account.checked_sub_lamports(lamports)?; drop(stake_account); let mut to = instruction_context.try_borrow_instruction_account(transaction_context, to_index)?; - to.checked_add_lamports(lamports, feature_set)?; + to.checked_add_lamports(lamports)?; Ok(()) } @@ -883,10 +855,7 @@ pub(crate) fn deactivate_delinquent( // voted in the last `MINIMUM_DELINQUENT_EPOCHS_FOR_DEACTIVATION` if eligible_for_deactivate_delinquent(&delinquent_vote_state.epoch_credits, current_epoch) { deactivate_stake(invoke_context, &mut stake, &mut stake_flags, current_epoch)?; - stake_account.set_state( - &StakeStateV2::Stake(meta, stake, stake_flags), - &invoke_context.feature_set, - ) + stake_account.set_state(&StakeStateV2::Stake(meta, stake, stake_flags)) } else { Err(StakeError::MinimumDelinquentEpochsForDeactivationNotMet.into()) } diff --git a/programs/system/src/system_instruction.rs b/programs/system/src/system_instruction.rs index 0c9daf22d4b024..95860379fb17a0 100644 --- a/programs/system/src/system_instruction.rs +++ b/programs/system/src/system_instruction.rs @@ -56,10 +56,7 @@ pub fn advance_nonce_account( next_durable_nonce, invoke_context.lamports_per_signature, ); - account.set_state( - &Versions::new(State::Initialized(new_data)), - &invoke_context.feature_set, - ) + account.set_state(&Versions::new(State::Initialized(new_data))) } State::Uninitialized => { ic_msg!( @@ -117,10 +114,7 @@ pub fn withdraw_nonce_account( ); return Err(SystemError::NonceBlockhashNotExpired.into()); } - from.set_state( - &Versions::new(State::Uninitialized), - &invoke_context.feature_set, - )?; + from.set_state(&Versions::new(State::Uninitialized))?; } else { let min_balance = rent.minimum_balance(from.get_data().len()); let amount = checked_add(lamports, min_balance)?; @@ -147,11 +141,11 @@ pub fn withdraw_nonce_account( return Err(InstructionError::MissingRequiredSignature); } - from.checked_sub_lamports(lamports, &invoke_context.feature_set)?; + from.checked_sub_lamports(lamports)?; drop(from); let mut to = instruction_context .try_borrow_instruction_account(transaction_context, to_account_index)?; - to.checked_add_lamports(lamports, &invoke_context.feature_set)?; + to.checked_add_lamports(lamports)?; Ok(()) } @@ -190,7 +184,7 @@ pub fn initialize_nonce_account( invoke_context.lamports_per_signature, ); let state = State::Initialized(data); - account.set_state(&Versions::new(state), &invoke_context.feature_set) + account.set_state(&Versions::new(state)) } State::Initialized(_) => { ic_msg!( @@ -221,7 +215,7 @@ pub fn authorize_nonce_account( .get_state::()? .authorize(signers, *nonce_authority) { - Ok(versions) => account.set_state(&versions, &invoke_context.feature_set), + Ok(versions) => account.set_state(&versions), Err(AuthorizeNonceError::Uninitialized) => { ic_msg!( invoke_context, @@ -1002,9 +996,7 @@ mod test { let mut nonce_account = instruction_context .try_borrow_instruction_account(transaction_context, NONCE_ACCOUNT_INDEX) .unwrap(); - nonce_account - .checked_sub_lamports(42 * 2, &invoke_context.feature_set) - .unwrap(); + nonce_account.checked_sub_lamports(42 * 2).unwrap(); set_invoke_context_blockhash!(invoke_context, 63); let authorized = *nonce_account.get_key(); let result = diff --git a/programs/system/src/system_processor.rs b/programs/system/src/system_processor.rs index 2a66b388103f9a..57cd8e546f13d8 100644 --- a/programs/system/src/system_processor.rs +++ b/programs/system/src/system_processor.rs @@ -104,7 +104,7 @@ fn allocate( return Err(SystemError::InvalidAccountDataLength.into()); } - account.set_data_length(space as usize, &invoke_context.feature_set)?; + account.set_data_length(space as usize)?; Ok(()) } @@ -126,7 +126,7 @@ fn assign( return Err(InstructionError::MissingRequiredSignature); } - account.set_owner(&owner.to_bytes(), &invoke_context.feature_set) + account.set_owner(&owner.to_bytes()) } fn allocate_and_assign( @@ -203,11 +203,11 @@ fn transfer_verified( return Err(SystemError::ResultWithNegativeLamports.into()); } - from.checked_sub_lamports(lamports, &invoke_context.feature_set)?; + from.checked_sub_lamports(lamports)?; drop(from); let mut to = instruction_context .try_borrow_instruction_account(transaction_context, to_account_index)?; - to.checked_add_lamports(lamports, &invoke_context.feature_set)?; + to.checked_add_lamports(lamports)?; Ok(()) } @@ -481,9 +481,7 @@ declare_process_instruction!(Entrypoint, DEFAULT_COMPUTE_UNITS, |invoke_context| let nonce_versions: nonce::state::Versions = nonce_account.get_state()?; match nonce_versions.upgrade() { None => Err(InstructionError::InvalidArgument), - Some(nonce_versions) => { - nonce_account.set_state(&nonce_versions, &invoke_context.feature_set) - } + Some(nonce_versions) => nonce_account.set_state(&nonce_versions), } } SystemInstruction::Allocate { space } => { @@ -2065,4 +2063,54 @@ mod tests { upgraded_nonce_account ); } + + #[test] + fn test_assign_native_loader_and_transfer() { + for size in [0, 10] { + let pubkey = Pubkey::new_unique(); + let account = AccountSharedData::new(100, size, &system_program::id()); + let accounts = process_instruction( + &bincode::serialize(&SystemInstruction::Assign { + owner: solana_sdk::native_loader::id(), + }) + .unwrap(), + vec![(pubkey, account.clone())], + vec![AccountMeta { + pubkey, + is_signer: true, + is_writable: true, + }], + Ok(()), + ); + assert_eq!(accounts[0].owner(), &solana_sdk::native_loader::id()); + assert_eq!(accounts[0].lamports(), 100); + + let pubkey2 = Pubkey::new_unique(); + let accounts = process_instruction( + &bincode::serialize(&SystemInstruction::Transfer { lamports: 50 }).unwrap(), + vec![ + ( + pubkey2, + AccountSharedData::new(100, 0, &system_program::id()), + ), + (pubkey, accounts[0].clone()), + ], + vec![ + AccountMeta { + pubkey: pubkey2, + is_signer: true, + is_writable: true, + }, + AccountMeta { + pubkey, + is_signer: false, + is_writable: true, + }, + ], + Ok(()), + ); + assert_eq!(accounts[1].owner(), &solana_sdk::native_loader::id()); + assert_eq!(accounts[1].lamports(), 150); + } + } } diff --git a/programs/vote/src/vote_state/mod.rs b/programs/vote/src/vote_state/mod.rs index b95f47e8c1b9c2..f5901374d9b6d9 100644 --- a/programs/vote/src/vote_state/mod.rs +++ b/programs/vote/src/vote_state/mod.rs @@ -156,24 +156,22 @@ fn set_vote_account_state( && (!vote_account .is_rent_exempt_at_data_length(VoteStateVersions::vote_state_size_of(true)) || vote_account - .set_data_length(VoteStateVersions::vote_state_size_of(true), feature_set) + .set_data_length(VoteStateVersions::vote_state_size_of(true)) .is_err()) { // Account cannot be resized to the size of a vote state as it will not be rent exempt, or failed to be // resized for other reasons. So store the V1_14_11 version. - return vote_account.set_state( - &VoteStateVersions::V1_14_11(Box::new(VoteState1_14_11::from(vote_state))), - feature_set, - ); + return vote_account.set_state(&VoteStateVersions::V1_14_11(Box::new( + VoteState1_14_11::from(vote_state), + ))); } // Vote account is large enough to store the newest version of vote state - vote_account.set_state(&VoteStateVersions::new_current(vote_state), feature_set) + vote_account.set_state(&VoteStateVersions::new_current(vote_state)) // Else when the vote_state_add_vote_latency feature is not enabled, then the V1_14_11 version is stored } else { - vote_account.set_state( - &VoteStateVersions::V1_14_11(Box::new(VoteState1_14_11::from(vote_state))), - feature_set, - ) + vote_account.set_state(&VoteStateVersions::V1_14_11(Box::new( + VoteState1_14_11::from(vote_state), + ))) } } @@ -1023,11 +1021,11 @@ pub fn withdraw( } } - vote_account.checked_sub_lamports(lamports, feature_set)?; + vote_account.checked_sub_lamports(lamports)?; drop(vote_account); let mut to_account = instruction_context .try_borrow_instruction_account(transaction_context, to_account_index)?; - to_account.checked_add_lamports(lamports, feature_set)?; + to_account.checked_add_lamports(lamports)?; Ok(()) } @@ -1373,7 +1371,7 @@ mod tests { // Test that when the feature is enabled, if the vote account does have sufficient lamports, the // new vote state is written out assert_eq!( - borrowed_account.set_lamports(rent.minimum_balance(VoteState::size_of()), &feature_set), + borrowed_account.set_lamports(rent.minimum_balance(VoteState::size_of()),), Ok(()) ); assert_eq!( diff --git a/programs/zk-token-proof/src/lib.rs b/programs/zk-token-proof/src/lib.rs index 21c09b4ef123f2..ba47d13624826e 100644 --- a/programs/zk-token-proof/src/lib.rs +++ b/programs/zk-token-proof/src/lib.rs @@ -130,8 +130,7 @@ where return Err(InstructionError::InvalidAccountData); } - proof_context_account - .set_data_from_slice(&context_state_data, &invoke_context.feature_set)?; + proof_context_account.set_data_from_slice(&context_state_data)?; } Ok(()) @@ -173,13 +172,10 @@ fn process_close_proof_context(invoke_context: &mut InvokeContext) -> Result<(), let mut destination_account = instruction_context.try_borrow_instruction_account(transaction_context, 1)?; - destination_account.checked_add_lamports( - proof_context_account.get_lamports(), - &invoke_context.feature_set, - )?; - proof_context_account.set_lamports(0, &invoke_context.feature_set)?; - proof_context_account.set_data_length(0, &invoke_context.feature_set)?; - proof_context_account.set_owner(system_program::id().as_ref(), &invoke_context.feature_set)?; + destination_account.checked_add_lamports(proof_context_account.get_lamports())?; + proof_context_account.set_lamports(0)?; + proof_context_account.set_data_length(0)?; + proof_context_account.set_owner(system_program::id().as_ref())?; Ok(()) } diff --git a/runtime/src/bank.rs b/runtime/src/bank.rs index b7329724a2558e..388c2f4a15f529 100644 --- a/runtime/src/bank.rs +++ b/runtime/src/bank.rs @@ -107,9 +107,8 @@ use { }, solana_sdk::{ account::{ - create_account_shared_data_with_fields as create_account, create_executable_meta, - from_account, Account, AccountSharedData, InheritableAccountFields, ReadableAccount, - WritableAccount, + create_account_shared_data_with_fields as create_account, from_account, Account, + AccountSharedData, InheritableAccountFields, ReadableAccount, WritableAccount, }, clock::{ BankId, Epoch, Slot, SlotCount, SlotIndex, UnixTimestamp, DEFAULT_HASHES_PER_TICK, @@ -3955,12 +3954,10 @@ impl Bank { // Add a bogus executable account, which will be loaded and ignored. let (lamports, rent_epoch) = self.inherit_specially_retained_account_fields(&None); - // Mock account_data with executable_meta so that the account is executable. - let account_data = create_executable_meta(&owner); let account = AccountSharedData::from(Account { lamports, owner, - data: account_data.to_vec(), + data: vec![], executable: true, rent_epoch, }); diff --git a/runtime/src/bank/tests.rs b/runtime/src/bank/tests.rs index 29dbdc2e5aeacd..6960f220244998 100644 --- a/runtime/src/bank/tests.rs +++ b/runtime/src/bank/tests.rs @@ -1051,7 +1051,6 @@ fn test_rent_exempt_executable_account() { let mut account = AccountSharedData::new(account_balance, 0, &solana_sdk::pubkey::new_rand()); account.set_executable(true); account.set_owner(bpf_loader_upgradeable::id()); - account.set_data(create_executable_meta(account.owner()).to_vec()); bank.store_account(&account_pubkey, &account); let transfer_lamports = 1; @@ -1089,10 +1088,10 @@ fn test_rent_complex() { MockInstruction::Deduction => { instruction_context .try_borrow_instruction_account(transaction_context, 1)? - .checked_add_lamports(1, &invoke_context.feature_set)?; + .checked_add_lamports(1)?; instruction_context .try_borrow_instruction_account(transaction_context, 2)? - .checked_sub_lamports(1, &invoke_context.feature_set)?; + .checked_sub_lamports(1)?; Ok(()) } } @@ -5994,16 +5993,16 @@ fn test_transaction_with_duplicate_accounts_in_instruction() { let lamports = u64::from_le_bytes(instruction_data.try_into().unwrap()); instruction_context .try_borrow_instruction_account(transaction_context, 2)? - .checked_sub_lamports(lamports, &invoke_context.feature_set)?; + .checked_sub_lamports(lamports)?; instruction_context .try_borrow_instruction_account(transaction_context, 1)? - .checked_add_lamports(lamports, &invoke_context.feature_set)?; + .checked_add_lamports(lamports)?; instruction_context .try_borrow_instruction_account(transaction_context, 0)? - .checked_sub_lamports(lamports, &invoke_context.feature_set)?; + .checked_sub_lamports(lamports)?; instruction_context .try_borrow_instruction_account(transaction_context, 1)? - .checked_add_lamports(lamports, &invoke_context.feature_set)?; + .checked_add_lamports(lamports)?; Ok(()) }); @@ -6473,25 +6472,26 @@ fn test_bank_hash_consistency() { if bank.slot == 0 { assert_eq!( bank.hash().to_string(), - "3VqF5pMe3XABLqzUaYw2UVXfAokMJgMkrdfvneFQkHbB", + "i5hGiQ3WtEehNrvhbfPFkUdm267t18fSpujcYtkBioW", ); } + if bank.slot == 32 { assert_eq!( bank.hash().to_string(), - "B8GsaBJ9aJrQcbhTTfgNVuV4uwb4v8nKT86HUjDLvNgk", + "7NmBtNvbhoqzatJv8NgBs84qWrm4ZhpuC75DCpbqwiS" ); } if bank.slot == 64 { assert_eq!( bank.hash().to_string(), - "Eg9VRE3zUwarxWyHXhitX9wLkg1vfNeiVqVQxSif6qEC" + "A1jjuUaENeDcsSvwejFGaZ5zWmnJ77doSzqdKtfzpoFk" ); } if bank.slot == 128 { assert_eq!( bank.hash().to_string(), - "5rLmK24zyxdeb8aLn5LDEnHLDQmxRd5gWZDVJGgsFX1c" + "ApnMkFt5Bs4yDJ8S2CCPsQRL1He6vWXw6vMzAyc5i811" ); break; } @@ -6507,7 +6507,7 @@ fn test_same_program_id_uses_unique_executable_accounts() { let instruction_context = transaction_context.get_current_instruction_context()?; instruction_context .try_borrow_program_account(transaction_context, 0)? - .set_data_length(2, &invoke_context.feature_set) + .set_data_length(2) }); let (genesis_config, mint_keypair) = create_genesis_config(50000); @@ -9477,7 +9477,7 @@ fn test_transfer_sysvar() { let instruction_context = transaction_context.get_current_instruction_context()?; instruction_context .try_borrow_instruction_account(transaction_context, 1)? - .set_data(vec![0; 40], &invoke_context.feature_set)?; + .set_data(vec![0; 40])?; Ok(()) }); @@ -10321,10 +10321,10 @@ declare_process_instruction!(MockTransferBuiltin, 1, |invoke_context| { MockTransferInstruction::Transfer(amount) => { instruction_context .try_borrow_instruction_account(transaction_context, 1)? - .checked_sub_lamports(amount, &invoke_context.feature_set)?; + .checked_sub_lamports(amount)?; instruction_context .try_borrow_instruction_account(transaction_context, 2)? - .checked_add_lamports(amount, &invoke_context.feature_set)?; + .checked_add_lamports(amount)?; Ok(()) } } @@ -11034,7 +11034,7 @@ declare_process_instruction!(MockReallocBuiltin, 1, |invoke_context| { // Set data length instruction_context .try_borrow_instruction_account(transaction_context, 1)? - .set_data_length(new_size, &invoke_context.feature_set)?; + .set_data_length(new_size)?; // set balance let current_balance = instruction_context @@ -11045,17 +11045,17 @@ declare_process_instruction!(MockReallocBuiltin, 1, |invoke_context| { if diff_balance.is_positive() { instruction_context .try_borrow_instruction_account(transaction_context, 0)? - .checked_sub_lamports(amount, &invoke_context.feature_set)?; + .checked_sub_lamports(amount)?; instruction_context .try_borrow_instruction_account(transaction_context, 1)? - .set_lamports(new_balance, &invoke_context.feature_set)?; + .set_lamports(new_balance)?; } else { instruction_context .try_borrow_instruction_account(transaction_context, 0)? - .checked_add_lamports(amount, &invoke_context.feature_set)?; + .checked_add_lamports(amount)?; instruction_context .try_borrow_instruction_account(transaction_context, 1)? - .set_lamports(new_balance, &invoke_context.feature_set)?; + .set_lamports(new_balance)?; } Ok(()) } diff --git a/sdk/src/account.rs b/sdk/src/account.rs index 96cdd5b90ce99b..f701e868ccf4e2 100644 --- a/sdk/src/account.rs +++ b/sdk/src/account.rs @@ -6,9 +6,8 @@ use { crate::{ bpf_loader, bpf_loader_deprecated, bpf_loader_upgradeable, clock::{Epoch, INITIAL_RENT_EPOCH}, - feature_set::{deprecate_executable_meta_update_in_bpf_loader, FeatureSet}, lamports::LamportsError, - loader_v4, native_loader, + loader_v4, pubkey::Pubkey, }, serde::{ @@ -40,9 +39,6 @@ pub struct Account { /// the program that owns this account. If executable, the program that loads this account. pub owner: Pubkey, /// this account's data contains a loaded program (and is now read-only) - /// - /// When feature `deprecate_executable_meta_update_in_bpf_loader` is active, - /// `executable` is deprecated, please use `fn is_executable(&account)` instead. pub executable: bool, /// the epoch at which this account will next owe rent pub rent_epoch: Epoch, @@ -767,94 +763,6 @@ pub const PROGRAM_OWNERS: &[Pubkey] = &[ loader_v4::id(), ]; -const LOADER_V4_STATUS_BYTE_OFFSET: usize = 40; - -/// Create executable account meta data based on account's `owner`. -/// -/// This function is only used for testing and an optimization during -/// transaction loading. -/// -/// When the program account is already present in the program cache, we don't -/// need to load the full account data during transaction loading. Instead, all -/// we need is a minimal executable account meta data, which is what this -/// function returns. -pub fn create_executable_meta(owner: &Pubkey) -> &[u8] { - // For upgradable program account, only `UpgradeableLoaderState::Program` - // variant (i.e. discriminant = 2) should *executable*, which means the - // discriminant for the enum at byte offset 0 in account data is 2. - const EXECUTABLE_META_FOR_BPF_LOADER_UPGRADABLE: [u8; 1] = [2]; - - // For loader v4 program, when LoaderV4Status (byte_offset = 40 in account - // data) is set, the program is executable. - const fn get_executable_meta_for_loader_v4() -> [u8; 41] { - let mut v = [0; LOADER_V4_STATUS_BYTE_OFFSET + 1]; - v[LOADER_V4_STATUS_BYTE_OFFSET] = 1; - v - } - const EXECUTABLE_META_FOR_LOADER_V4: [u8; LOADER_V4_STATUS_BYTE_OFFSET + 1] = - get_executable_meta_for_loader_v4(); - - // For other owners, simple returns a 1 byte array would make it executable. - const DEFAULT_EXECUTABLE_META: [u8; 1] = [1]; - - if bpf_loader_upgradeable::check_id(owner) { - &EXECUTABLE_META_FOR_BPF_LOADER_UPGRADABLE - } else if loader_v4::check_id(owner) { - &EXECUTABLE_META_FOR_LOADER_V4 - } else { - &DEFAULT_EXECUTABLE_META - } -} - -/// Return true if the account program is executable. -pub fn is_executable(account: &impl ReadableAccount, feature_set: &FeatureSet) -> bool { - if !feature_set.is_active(&deprecate_executable_meta_update_in_bpf_loader::id()) { - account.executable() - } else { - // First, check if the account is empty. Empty accounts are not executable. - if account.data().is_empty() { - return false; - } - - // bpf_loader/bpf_loader_deprecated still relies on `executable` on the - // program account. When the program account is finalized, the loader will - // mark `executable` flag on the account. We can't emulate `executable` for - // these two loaders. However, when `deprecate_executable` is true, we - // should have already disabled the deployment of bpf_loader and - // bpf_loader_deprecated. Therefore, we can safely assume that all those - // programs are `executable`. - if bpf_loader::check_id(account.owner()) || bpf_loader_deprecated::check_id(account.owner()) - { - return true; - } - - if bpf_loader_upgradeable::check_id(account.owner()) { - // For upgradable program account, only - // `UpgradeableLoaderState::Program` variant (i.e. discriminant = 2) is - // *executable*. - return account.data()[0] == 2; - } - - if loader_v4::check_id(account.owner()) { - // LoaderV4Status (byte_offset = 40) - // return account.data()[LOADER_V4_STATUS_BYTE_OFFSET] != 0; - return false; // TODO: return false for now - } - - false - } -} - -/// Return true if the account program is a builtin program. -/// -/// This function also ensures that all valid builtin programs have non-empty -/// program data. Typically, the program data contains only the "name" for the -/// program. If, for some reason, the program account's data is empty, we should -/// exclude such a program from `builtins`. -pub fn is_builtin(account: &impl ReadableAccount) -> bool { - native_loader::check_id(account.owner()) && !account.data().is_empty() -} - #[cfg(test)] pub mod tests { use super::*; diff --git a/sdk/src/feature_set.rs b/sdk/src/feature_set.rs index bb7c50f460fd81..55ce4c1253940a 100644 --- a/sdk/src/feature_set.rs +++ b/sdk/src/feature_set.rs @@ -756,10 +756,6 @@ pub mod disable_bpf_loader_instructions { solana_sdk::declare_id!("7WeS1vfPRgeeoXArLh7879YcB9mgE9ktjPDtajXeWfXn"); } -pub mod deprecate_executable_meta_update_in_bpf_loader { - solana_sdk::declare_id!("k6uR1J9VtKJnTukBV2Eo15BEy434MBg8bT6hHQgmU8v"); -} - pub mod enable_zk_proof_from_account { solana_sdk::declare_id!("zkiTNuzBKxrCLMKehzuQeKZyLtX2yvFcEKMML8nExU8"); } @@ -967,7 +963,6 @@ lazy_static! { (index_erasure_conflict_duplicate_proofs::id(), "generate duplicate proofs for index and erasure conflicts #34360"), (merkle_conflict_duplicate_proofs::id(), "generate duplicate proofs for merkle root conflicts #34270"), (disable_bpf_loader_instructions::id(), "disable bpf loader management instructions #34194"), - (deprecate_executable_meta_update_in_bpf_loader::id(), "deprecate executable meta flag update in bpf loader #34194"), (enable_zk_proof_from_account::id(), "Enable zk token proof program to read proof from accounts instead of instruction data #34750"), (curve25519_restrict_msm_length::id(), "restrict curve25519 multiscalar multiplication vector lengths #34763"), (cost_model_requested_write_lock_cost::id(), "cost model uses number of requested write locks #34819"), diff --git a/sdk/src/transaction_context.rs b/sdk/src/transaction_context.rs index 981f64870f6063..7df7fc96d67933 100644 --- a/sdk/src/transaction_context.rs +++ b/sdk/src/transaction_context.rs @@ -17,8 +17,7 @@ use { }; use { crate::{ - account::{is_builtin, is_executable, AccountSharedData, ReadableAccount}, - feature_set::FeatureSet, + account::{AccountSharedData, ReadableAccount}, instruction::InstructionError, pubkey::Pubkey, }, @@ -740,11 +739,7 @@ impl<'a> BorrowedAccount<'a> { /// Assignes the owner of this account (transaction wide) #[cfg(not(target_os = "solana"))] - pub fn set_owner( - &mut self, - pubkey: &[u8], - feature_set: &FeatureSet, - ) -> Result<(), InstructionError> { + pub fn set_owner(&mut self, pubkey: &[u8]) -> Result<(), InstructionError> { // Only the owner can assign a new owner if !self.is_owned_by_current_program() { return Err(InstructionError::ModifiedProgramId); @@ -754,7 +749,7 @@ impl<'a> BorrowedAccount<'a> { return Err(InstructionError::ModifiedProgramId); } // and only if the account is not executable - if self.is_executable(feature_set) { + if self.is_executable() { return Err(InstructionError::ModifiedProgramId); } // and only if the data is zero-initialized or empty @@ -778,11 +773,7 @@ impl<'a> BorrowedAccount<'a> { /// Overwrites the number of lamports of this account (transaction wide) #[cfg(not(target_os = "solana"))] - pub fn set_lamports( - &mut self, - lamports: u64, - feature_set: &FeatureSet, - ) -> Result<(), InstructionError> { + pub fn set_lamports(&mut self, lamports: u64) -> Result<(), InstructionError> { // An account not owned by the program cannot have its balance decrease if !self.is_owned_by_current_program() && lamports < self.get_lamports() { return Err(InstructionError::ExternalAccountLamportSpend); @@ -792,7 +783,7 @@ impl<'a> BorrowedAccount<'a> { return Err(InstructionError::ReadonlyLamportChange); } // The balance of executable accounts may not change - if self.is_executable(feature_set) { + if self.is_executable() { return Err(InstructionError::ExecutableLamportChange); } // don't touch the account if the lamports do not change @@ -806,31 +797,21 @@ impl<'a> BorrowedAccount<'a> { /// Adds lamports to this account (transaction wide) #[cfg(not(target_os = "solana"))] - pub fn checked_add_lamports( - &mut self, - lamports: u64, - feature_set: &FeatureSet, - ) -> Result<(), InstructionError> { + pub fn checked_add_lamports(&mut self, lamports: u64) -> Result<(), InstructionError> { self.set_lamports( self.get_lamports() .checked_add(lamports) .ok_or(InstructionError::ArithmeticOverflow)?, - feature_set, ) } /// Subtracts lamports from this account (transaction wide) #[cfg(not(target_os = "solana"))] - pub fn checked_sub_lamports( - &mut self, - lamports: u64, - feature_set: &FeatureSet, - ) -> Result<(), InstructionError> { + pub fn checked_sub_lamports(&mut self, lamports: u64) -> Result<(), InstructionError> { self.set_lamports( self.get_lamports() .checked_sub(lamports) .ok_or(InstructionError::ArithmeticOverflow)?, - feature_set, ) } @@ -842,11 +823,8 @@ impl<'a> BorrowedAccount<'a> { /// Returns a writable slice of the account data (transaction wide) #[cfg(not(target_os = "solana"))] - pub fn get_data_mut( - &mut self, - feature_set: &FeatureSet, - ) -> Result<&mut [u8], InstructionError> { - self.can_data_be_changed(feature_set)?; + pub fn get_data_mut(&mut self) -> Result<&mut [u8], InstructionError> { + self.can_data_be_changed()?; self.touch()?; self.make_data_mut(); Ok(self.account.data_as_mut_slice()) @@ -871,13 +849,9 @@ impl<'a> BorrowedAccount<'a> { not(target_os = "solana"), any(test, feature = "dev-context-only-utils") ))] - pub fn set_data( - &mut self, - data: Vec, - feature_set: &FeatureSet, - ) -> Result<(), InstructionError> { + pub fn set_data(&mut self, data: Vec) -> Result<(), InstructionError> { self.can_data_be_resized(data.len())?; - self.can_data_be_changed(feature_set)?; + self.can_data_be_changed()?; self.touch()?; self.update_accounts_resize_delta(data.len())?; @@ -890,18 +864,14 @@ impl<'a> BorrowedAccount<'a> { /// Call this when you have a slice of data you do not own and want to /// replace the account data with it. #[cfg(not(target_os = "solana"))] - pub fn set_data_from_slice( - &mut self, - data: &[u8], - feature_set: &FeatureSet, - ) -> Result<(), InstructionError> { + pub fn set_data_from_slice(&mut self, data: &[u8]) -> Result<(), InstructionError> { self.can_data_be_resized(data.len())?; - self.can_data_be_changed(feature_set)?; + self.can_data_be_changed()?; self.touch()?; self.update_accounts_resize_delta(data.len())?; // Calling make_data_mut() here guarantees that set_data_from_slice() // copies in places, extending the account capacity if necessary but - // never reducing it. This is required as the account might be directly + // never reducing it. This is required as the account migh be directly // mapped into a MemoryRegion, and therefore reducing capacity would // leave a hole in the vm address space. After CPI or upon program // termination, the runtime will zero the extra capacity. @@ -915,13 +885,9 @@ impl<'a> BorrowedAccount<'a> { /// /// Fills it with zeros at the end if is extended or truncates at the end otherwise. #[cfg(not(target_os = "solana"))] - pub fn set_data_length( - &mut self, - new_length: usize, - feature_set: &FeatureSet, - ) -> Result<(), InstructionError> { + pub fn set_data_length(&mut self, new_length: usize) -> Result<(), InstructionError> { self.can_data_be_resized(new_length)?; - self.can_data_be_changed(feature_set)?; + self.can_data_be_changed()?; // don't touch the account if the length does not change if self.get_data().len() == new_length { return Ok(()); @@ -934,14 +900,10 @@ impl<'a> BorrowedAccount<'a> { /// Appends all elements in a slice to the account #[cfg(not(target_os = "solana"))] - pub fn extend_from_slice( - &mut self, - data: &[u8], - feature_set: &FeatureSet, - ) -> Result<(), InstructionError> { + pub fn extend_from_slice(&mut self, data: &[u8]) -> Result<(), InstructionError> { let new_len = self.get_data().len().saturating_add(data.len()); self.can_data_be_resized(new_len)?; - self.can_data_be_changed(feature_set)?; + self.can_data_be_changed()?; if data.is_empty() { return Ok(()); @@ -995,7 +957,7 @@ impl<'a> BorrowedAccount<'a> { // about to write into it. Make the account mutable by copying it in a // buffer with MAX_PERMITTED_DATA_INCREASE capacity so that if the // transaction reallocs, we don't have to copy the whole account data a - // second time to fulfill the realloc. + // second time to fullfill the realloc. // // NOTE: The account memory region CoW code in bpf_loader::create_vm() implements the same // logic and must be kept in sync. @@ -1014,12 +976,8 @@ impl<'a> BorrowedAccount<'a> { /// Serializes a state into the account data #[cfg(not(target_os = "solana"))] - pub fn set_state( - &mut self, - state: &T, - feature_set: &FeatureSet, - ) -> Result<(), InstructionError> { - let data = self.get_data_mut(feature_set)?; + pub fn set_state(&mut self, state: &T) -> Result<(), InstructionError> { + let data = self.get_data_mut()?; let serialized_size = bincode::serialized_size(state).map_err(|_| InstructionError::GenericError)?; if serialized_size > data.len() as u64 { @@ -1040,8 +998,8 @@ impl<'a> BorrowedAccount<'a> { /// Returns whether this account is executable (transaction wide) #[inline] - pub fn is_executable(&self, feature_set: &FeatureSet) -> bool { - is_builtin(&*self.account) || is_executable(&*self.account, feature_set) + pub fn is_executable(&self) -> bool { + self.account.executable() } /// Configures whether this account is executable (transaction wide) @@ -1064,11 +1022,11 @@ impl<'a> BorrowedAccount<'a> { return Err(InstructionError::ExecutableModified); } // one can not clear the executable flag - if self.account.executable() && !is_executable { + if self.is_executable() && !is_executable { return Err(InstructionError::ExecutableModified); } // don't touch the account if the executable flag does not change - if self.account.executable() == is_executable { + if self.is_executable() == is_executable { return Ok(()); } self.touch()?; @@ -1119,9 +1077,9 @@ impl<'a> BorrowedAccount<'a> { /// Returns an error if the account data can not be mutated by the current program #[cfg(not(target_os = "solana"))] - pub fn can_data_be_changed(&self, feature_set: &FeatureSet) -> Result<(), InstructionError> { + pub fn can_data_be_changed(&self) -> Result<(), InstructionError> { // Only non-executable accounts data can be changed - if self.is_executable(feature_set) { + if self.is_executable() { return Err(InstructionError::ExecutableDataModified); } // and only if the account is writable diff --git a/svm/src/account_loader.rs b/svm/src/account_loader.rs index ee06dd5fbf2198..374fc756de31da 100644 --- a/svm/src/account_loader.rs +++ b/svm/src/account_loader.rs @@ -11,10 +11,7 @@ use { loaded_programs::LoadedProgramsForTxBatch, }, solana_sdk::{ - account::{ - create_executable_meta, is_builtin, is_executable, Account, AccountSharedData, - ReadableAccount, WritableAccount, - }, + account::{Account, AccountSharedData, ReadableAccount, WritableAccount}, feature_set::{ self, include_loaded_accounts_data_size_in_fee_calculation, remove_rounding_in_fee_calculation, @@ -336,7 +333,7 @@ fn load_transaction_accounts( return Err(TransactionError::ProgramAccountNotFound); } - if !(is_builtin(program_account) || is_executable(program_account, &feature_set)) { + if !program_account.executable() { error_counters.invalid_program_for_execution += 1; return Err(TransactionError::InvalidProgramForExecution); } @@ -356,8 +353,7 @@ fn load_transaction_accounts( let owner_index = accounts.len(); if let Some(owner_account) = callbacks.get_account_shared_data(owner_id) { if !native_loader::check_id(owner_account.owner()) - || !(is_builtin(&owner_account) - || is_executable(&owner_account, &feature_set)) + || !owner_account.executable() { error_counters.invalid_program_for_execution += 1; return Err(TransactionError::InvalidProgramForExecution); @@ -423,7 +419,6 @@ fn account_shared_data_from_program( .ok_or(TransactionError::AccountNotFound)?; program_account.set_owner(**program_owner); program_account.set_executable(true); - program_account.set_data_from_slice(create_executable_meta(program_owner)); Ok(program_account) } @@ -887,7 +882,7 @@ mod tests { let mut account = AccountSharedData::new(40, 1, &Pubkey::default()); account.set_owner(bpf_loader_upgradeable::id()); - account.set_data(create_executable_meta(account.owner()).to_vec()); + account.set_executable(true); accounts.push((key1, account)); let instructions = vec![CompiledInstruction::new(1, &(), vec![0])]; @@ -967,7 +962,6 @@ mod tests { account.set_executable(true); account.set_rent_epoch(1); account.set_owner(key1); - account.set_data(create_executable_meta(account.owner()).to_vec()); accounts.push((key2, account)); let instructions = vec![ @@ -1428,7 +1422,6 @@ mod tests { let mut expected = AccountSharedData::default(); expected.set_owner(other_key); expected.set_executable(true); - expected.set_data_from_slice(create_executable_meta(&other_key)); assert_eq!(result.unwrap(), expected); }