Skip to content
7 changes: 7 additions & 0 deletions feature-set/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,8 @@ impl FeatureSet {
increase_tx_account_lock_limit: self.is_active(&increase_tx_account_lock_limit::id()),
disable_rent_fees_collection: self.is_active(&disable_rent_fees_collection::id()),
enable_extend_program_checked: self.is_active(&enable_extend_program_checked::id()),
formalize_loaded_transaction_data_size: self
.is_active(&formalize_loaded_transaction_data_size::id()),
}
}
}
Expand Down Expand Up @@ -1095,6 +1097,10 @@ pub mod enable_extend_program_checked {
solana_pubkey::declare_id!("97QCmR4QtfeQsAti9srfHFk5uMRFP95CvXG8EGr615HM");
}

pub mod formalize_loaded_transaction_data_size {
solana_pubkey::declare_id!("DeS7sR48ZcFTUmt5FFEVDr1v1bh73aAbZiZq3SYr8Eh8");
}

pub static FEATURE_NAMES: LazyLock<AHashMap<Pubkey, &'static str>> = LazyLock::new(|| {
[
(secp256k1_program_enabled::id(), "secp256k1 program"),
Expand Down Expand Up @@ -1330,6 +1336,7 @@ pub static FEATURE_NAMES: LazyLock<AHashMap<Pubkey, &'static str>> = LazyLock::n
(mask_out_rent_epoch_in_vm_serialization::id(), "SIMD-0267: Sets rent_epoch to a constant in the VM"),
(enshrine_slashing_program::id(), "SIMD-0204: Slashable event verification"),
(enable_extend_program_checked::id(), "Enable ExtendProgramChecked instruction"),
(formalize_loaded_transaction_data_size::id(), "SIMD-0186: Loaded transaction data size specification"),
/*************** ADD NEW FEATURES HERE ***************/
]
.iter()
Expand Down
102 changes: 70 additions & 32 deletions runtime/src/bank/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7177,11 +7177,15 @@ fn test_bank_load_program() {
}

#[allow(deprecated)]
#[test]
fn test_bpf_loader_upgradeable_deploy_with_max_len() {
#[test_case(false; "informal_loaded_size")]
#[test_case(true; "simd186_loaded_size")]
fn test_bpf_loader_upgradeable_deploy_with_max_len(formalize_loaded_transaction_data_size: bool) {
let (genesis_config, mint_keypair) = create_genesis_config_no_tx_fee(1_000_000_000);
let mut bank = Bank::new_for_tests(&genesis_config);
bank.feature_set = Arc::new(FeatureSet::all_enabled());
if !formalize_loaded_transaction_data_size {
bank.deactivate_feature(&feature_set::formalize_loaded_transaction_data_size::id());
}
let (bank, bank_forks) = bank.wrap_with_bank_forks_for_tests();
let mut bank_client = BankClient::new_shared(bank.clone());

Expand Down Expand Up @@ -8376,10 +8380,15 @@ fn test_timestamp_fast() {
}
}

#[test]
fn test_program_is_native_loader() {
#[test_case(false; "informal_loaded_size")]
#[test_case(true; "simd186_loaded_size")]
fn test_program_is_native_loader(formalize_loaded_transaction_data_size: bool) {
let (genesis_config, mint_keypair) = create_genesis_config(50000);
let (bank, _bank_forks) = Bank::new_with_bank_forks_for_tests(&genesis_config);
let mut bank = Bank::new_for_tests(&genesis_config);
if formalize_loaded_transaction_data_size {
bank.activate_feature(&feature_set::formalize_loaded_transaction_data_size::id());
}
let (bank, _bank_forks) = bank.wrap_with_bank_forks_for_tests();

let tx = Transaction::new_signed_with_payer(
&[Instruction::new_with_bincode(
Expand All @@ -8391,20 +8400,29 @@ fn test_program_is_native_loader() {
&[&mint_keypair],
bank.last_blockhash(),
);
assert_eq!(
bank.process_transaction(&tx),
Err(TransactionError::InstructionError(
0,
InstructionError::UnsupportedProgramId
))
);

let err = bank.process_transaction(&tx).unwrap_err();
if formalize_loaded_transaction_data_size {
assert_eq!(err, TransactionError::ProgramAccountNotFound);
} else {
assert_eq!(
err,
TransactionError::InstructionError(0, InstructionError::UnsupportedProgramId)
);
}
}

#[test]
fn test_invoke_non_program_account_owned_by_a_builtin() {
#[test_case(false; "informal_loaded_size")]
#[test_case(true; "simd186_loaded_size")]
fn test_invoke_non_program_account_owned_by_a_builtin(
formalize_loaded_transaction_data_size: bool,
) {
let (genesis_config, mint_keypair) = create_genesis_config(10000000);
let mut bank = Bank::new_for_tests(&genesis_config);
bank.activate_feature(&feature_set::remove_accounts_executable_flag_checks::id());
if formalize_loaded_transaction_data_size {
bank.activate_feature(&feature_set::formalize_loaded_transaction_data_size::id());
}
let (bank, _bank_forks) = bank.wrap_with_bank_forks_for_tests();

let bogus_program = Pubkey::new_unique();
Expand All @@ -8431,13 +8449,12 @@ fn test_invoke_non_program_account_owned_by_a_builtin() {
&[&mint_keypair, &created_account_keypair],
bank.last_blockhash(),
);
assert_eq!(
bank.process_transaction(&tx),
Err(TransactionError::InstructionError(
0,
InstructionError::UnsupportedProgramId
))
);
let expected_error = if formalize_loaded_transaction_data_size {
TransactionError::InvalidProgramForExecution
} else {
TransactionError::InstructionError(0, InstructionError::UnsupportedProgramId)
};
assert_eq!(bank.process_transaction(&tx), Err(expected_error),);
}

#[test]
Expand Down Expand Up @@ -10563,20 +10580,31 @@ fn test_calculate_fee_secp256k1() {
assert_eq!(calculate_test_fee(&message, 1, &fee_structure,), 11);
}

#[test]
fn test_an_empty_instruction_without_program() {
#[test_case(false; "informal_loaded_size")]
#[test_case(true; "simd186_loaded_size")]
fn test_an_empty_instruction_without_program(formalize_loaded_transaction_data_size: bool) {
let (genesis_config, mint_keypair) = create_genesis_config_no_tx_fee_no_rent(1);
let destination = solana_pubkey::new_rand();
let mut ix = system_instruction::transfer(&mint_keypair.pubkey(), &destination, 0);
ix.program_id = native_loader::id(); // Empty executable account chain
let message = Message::new(&[ix], Some(&mint_keypair.pubkey()));
let tx = Transaction::new(&[&mint_keypair], message, genesis_config.hash());

let (bank, _bank_forks) = Bank::new_with_bank_forks_for_tests(&genesis_config);
assert_eq!(
bank.process_transaction(&tx).unwrap_err(),
TransactionError::InstructionError(0, InstructionError::UnsupportedProgramId),
);
let mut bank = Bank::new_for_tests(&genesis_config);
if !formalize_loaded_transaction_data_size {
bank.deactivate_feature(&feature_set::formalize_loaded_transaction_data_size::id());
}
let (bank, _bank_forks) = bank.wrap_with_bank_forks_for_tests();

let err = bank.process_transaction(&tx).unwrap_err();
if formalize_loaded_transaction_data_size {
assert_eq!(err, TransactionError::ProgramAccountNotFound);
} else {
assert_eq!(
err,
TransactionError::InstructionError(0, InstructionError::UnsupportedProgramId)
);
}
}

#[test]
Expand Down Expand Up @@ -12224,8 +12252,11 @@ fn test_is_in_slot_hashes_history() {
assert!(!new_bank.is_in_slot_hashes_history(&0));
}

#[test]
fn test_feature_activation_loaded_programs_cache_preparation_phase() {
#[test_case(false; "informal_loaded_size")]
#[test_case(true; "simd186_loaded_size")]
fn test_feature_activation_loaded_programs_cache_preparation_phase(
formalize_loaded_transaction_data_size: bool,
) {
solana_logger::setup();

// Bank Setup
Expand All @@ -12234,6 +12265,9 @@ fn test_feature_activation_loaded_programs_cache_preparation_phase() {
let mut feature_set = FeatureSet::all_enabled();
feature_set.deactivate(&feature_set::disable_sbpf_v0_execution::id());
feature_set.deactivate(&feature_set::reenable_sbpf_v0_execution::id());
if !formalize_loaded_transaction_data_size {
feature_set.deactivate(&feature_set::formalize_loaded_transaction_data_size::id());
}
bank.feature_set = Arc::new(feature_set);
let (root_bank, bank_forks) = bank.wrap_with_bank_forks_for_tests();

Expand Down Expand Up @@ -13383,8 +13417,9 @@ fn test_deploy_last_epoch_slot() {
assert_eq!(result_with_feature_enabled, Ok(()));
}

#[test]
fn test_loader_v3_to_v4_migration() {
#[test_case(false; "informal_loaded_size")]
#[test_case(true; "simd186_loaded_size")]
fn test_loader_v3_to_v4_migration(formalize_loaded_transaction_data_size: bool) {
solana_logger::setup();

// Bank Setup
Expand All @@ -13395,6 +13430,9 @@ fn test_loader_v3_to_v4_migration() {
);
let mut bank = Bank::new_for_tests(&genesis_config);
bank.activate_feature(&feature_set::remove_accounts_executable_flag_checks::id());
if formalize_loaded_transaction_data_size {
bank.activate_feature(&feature_set::formalize_loaded_transaction_data_size::id());
}
let (bank, bank_forks) = bank.wrap_with_bank_forks_for_tests();
let fee_calculator = genesis_config.fee_rate_governor.create_fee_calculator();
let mut next_slot = 1;
Expand Down
2 changes: 2 additions & 0 deletions svm-feature-set/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ pub struct SVMFeatureSet {
pub increase_tx_account_lock_limit: bool,
pub disable_rent_fees_collection: bool,
pub enable_extend_program_checked: bool,
pub formalize_loaded_transaction_data_size: bool,
}

impl SVMFeatureSet {
Expand Down Expand Up @@ -77,6 +78,7 @@ impl SVMFeatureSet {
increase_tx_account_lock_limit: true,
disable_rent_fees_collection: true,
enable_extend_program_checked: true,
formalize_loaded_transaction_data_size: true,
}
}
}
Loading
Loading