Skip to content

Commit 5ab9e8a

Browse files
committed
SIMD-0186: Loaded Transaction Data Sizes (anza-xyz#6063)
implement a new version of `load_transaction_accounts()` which conforms to the simd186 transaction account data size algorithm also simplify accumulation of `program_indicies` and program owner checks; the program owner logic is functionally equivalent to the checks inside `InvokeContext` added by `remove_accounts_executable_flag_checks`, so it is an optimization rather than a new spec
1 parent a7cd56d commit 5ab9e8a

File tree

6 files changed

+802
-161
lines changed

6 files changed

+802
-161
lines changed

feature-set/src/lib.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,8 @@ impl FeatureSet {
153153
increase_tx_account_lock_limit: self.is_active(&increase_tx_account_lock_limit::id()),
154154
disable_rent_fees_collection: self.is_active(&disable_rent_fees_collection::id()),
155155
enable_extend_program_checked: self.is_active(&enable_extend_program_checked::id()),
156+
formalize_loaded_transaction_data_size: self
157+
.is_active(&formalize_loaded_transaction_data_size::id()),
156158
}
157159
}
158160
}
@@ -1095,6 +1097,10 @@ pub mod enable_extend_program_checked {
10951097
solana_pubkey::declare_id!("2oMRZEDWT2tqtYMofhmmfQ8SsjqUFzT6sYXppQDavxwz");
10961098
}
10971099

1100+
pub mod formalize_loaded_transaction_data_size {
1101+
solana_pubkey::declare_id!("DeS7sR48ZcFTUmt5FFEVDr1v1bh73aAbZiZq3SYr8Eh8");
1102+
}
1103+
10981104
pub static FEATURE_NAMES: LazyLock<AHashMap<Pubkey, &'static str>> = LazyLock::new(|| {
10991105
[
11001106
(secp256k1_program_enabled::id(), "secp256k1 program"),
@@ -1330,6 +1336,7 @@ pub static FEATURE_NAMES: LazyLock<AHashMap<Pubkey, &'static str>> = LazyLock::n
13301336
(mask_out_rent_epoch_in_vm_serialization::id(), "SIMD-0267: Sets rent_epoch to a constant in the VM"),
13311337
(enshrine_slashing_program::id(), "SIMD-0204: Slashable event verification"),
13321338
(enable_extend_program_checked::id(), "Enable ExtendProgramChecked instruction"),
1339+
(formalize_loaded_transaction_data_size::id(), "SIMD-0186: Loaded transaction data size specification"),
13331340
/*************** ADD NEW FEATURES HERE ***************/
13341341
]
13351342
.iter()

runtime/src/bank/tests.rs

Lines changed: 70 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -7190,11 +7190,15 @@ fn test_bank_load_program() {
71907190
}
71917191

71927192
#[allow(deprecated)]
7193-
#[test]
7194-
fn test_bpf_loader_upgradeable_deploy_with_max_len() {
7193+
#[test_case(false; "informal_loaded_size")]
7194+
#[test_case(true; "simd186_loaded_size")]
7195+
fn test_bpf_loader_upgradeable_deploy_with_max_len(formalize_loaded_transaction_data_size: bool) {
71957196
let (genesis_config, mint_keypair) = create_genesis_config_no_tx_fee(1_000_000_000);
71967197
let mut bank = Bank::new_for_tests(&genesis_config);
71977198
bank.feature_set = Arc::new(FeatureSet::all_enabled());
7199+
if !formalize_loaded_transaction_data_size {
7200+
bank.deactivate_feature(&feature_set::formalize_loaded_transaction_data_size::id());
7201+
}
71987202
let (bank, bank_forks) = bank.wrap_with_bank_forks_for_tests();
71997203
let mut bank_client = BankClient::new_shared(bank.clone());
72007204

@@ -8389,10 +8393,15 @@ fn test_timestamp_fast() {
83898393
}
83908394
}
83918395

8392-
#[test]
8393-
fn test_program_is_native_loader() {
8396+
#[test_case(false; "informal_loaded_size")]
8397+
#[test_case(true; "simd186_loaded_size")]
8398+
fn test_program_is_native_loader(formalize_loaded_transaction_data_size: bool) {
83948399
let (genesis_config, mint_keypair) = create_genesis_config(50000);
8395-
let (bank, _bank_forks) = Bank::new_with_bank_forks_for_tests(&genesis_config);
8400+
let mut bank = Bank::new_for_tests(&genesis_config);
8401+
if formalize_loaded_transaction_data_size {
8402+
bank.activate_feature(&feature_set::formalize_loaded_transaction_data_size::id());
8403+
}
8404+
let (bank, _bank_forks) = bank.wrap_with_bank_forks_for_tests();
83968405

83978406
let tx = Transaction::new_signed_with_payer(
83988407
&[Instruction::new_with_bincode(
@@ -8404,20 +8413,29 @@ fn test_program_is_native_loader() {
84048413
&[&mint_keypair],
84058414
bank.last_blockhash(),
84068415
);
8407-
assert_eq!(
8408-
bank.process_transaction(&tx),
8409-
Err(TransactionError::InstructionError(
8410-
0,
8411-
InstructionError::UnsupportedProgramId
8412-
))
8413-
);
8416+
8417+
let err = bank.process_transaction(&tx).unwrap_err();
8418+
if formalize_loaded_transaction_data_size {
8419+
assert_eq!(err, TransactionError::ProgramAccountNotFound);
8420+
} else {
8421+
assert_eq!(
8422+
err,
8423+
TransactionError::InstructionError(0, InstructionError::UnsupportedProgramId)
8424+
);
8425+
}
84148426
}
84158427

8416-
#[test]
8417-
fn test_invoke_non_program_account_owned_by_a_builtin() {
8428+
#[test_case(false; "informal_loaded_size")]
8429+
#[test_case(true; "simd186_loaded_size")]
8430+
fn test_invoke_non_program_account_owned_by_a_builtin(
8431+
formalize_loaded_transaction_data_size: bool,
8432+
) {
84188433
let (genesis_config, mint_keypair) = create_genesis_config(10000000);
84198434
let mut bank = Bank::new_for_tests(&genesis_config);
84208435
bank.activate_feature(&feature_set::remove_accounts_executable_flag_checks::id());
8436+
if formalize_loaded_transaction_data_size {
8437+
bank.activate_feature(&feature_set::formalize_loaded_transaction_data_size::id());
8438+
}
84218439
let (bank, _bank_forks) = bank.wrap_with_bank_forks_for_tests();
84228440

84238441
let bogus_program = Pubkey::new_unique();
@@ -8444,13 +8462,12 @@ fn test_invoke_non_program_account_owned_by_a_builtin() {
84448462
&[&mint_keypair, &created_account_keypair],
84458463
bank.last_blockhash(),
84468464
);
8447-
assert_eq!(
8448-
bank.process_transaction(&tx),
8449-
Err(TransactionError::InstructionError(
8450-
0,
8451-
InstructionError::UnsupportedProgramId
8452-
))
8453-
);
8465+
let expected_error = if formalize_loaded_transaction_data_size {
8466+
TransactionError::InvalidProgramForExecution
8467+
} else {
8468+
TransactionError::InstructionError(0, InstructionError::UnsupportedProgramId)
8469+
};
8470+
assert_eq!(bank.process_transaction(&tx), Err(expected_error),);
84548471
}
84558472

84568473
#[test]
@@ -10591,20 +10608,31 @@ fn test_calculate_fee_secp256k1() {
1059110608
assert_eq!(calculate_test_fee(&message, 1, &fee_structure,), 11);
1059210609
}
1059310610

10594-
#[test]
10595-
fn test_an_empty_instruction_without_program() {
10611+
#[test_case(false; "informal_loaded_size")]
10612+
#[test_case(true; "simd186_loaded_size")]
10613+
fn test_an_empty_instruction_without_program(formalize_loaded_transaction_data_size: bool) {
1059610614
let (genesis_config, mint_keypair) = create_genesis_config_no_tx_fee_no_rent(1);
1059710615
let destination = solana_pubkey::new_rand();
1059810616
let mut ix = system_instruction::transfer(&mint_keypair.pubkey(), &destination, 0);
1059910617
ix.program_id = native_loader::id(); // Empty executable account chain
1060010618
let message = Message::new(&[ix], Some(&mint_keypair.pubkey()));
1060110619
let tx = Transaction::new(&[&mint_keypair], message, genesis_config.hash());
1060210620

10603-
let (bank, _bank_forks) = Bank::new_with_bank_forks_for_tests(&genesis_config);
10604-
assert_eq!(
10605-
bank.process_transaction(&tx).unwrap_err(),
10606-
TransactionError::InstructionError(0, InstructionError::UnsupportedProgramId),
10607-
);
10621+
let mut bank = Bank::new_for_tests(&genesis_config);
10622+
if !formalize_loaded_transaction_data_size {
10623+
bank.deactivate_feature(&feature_set::formalize_loaded_transaction_data_size::id());
10624+
}
10625+
let (bank, _bank_forks) = bank.wrap_with_bank_forks_for_tests();
10626+
10627+
let err = bank.process_transaction(&tx).unwrap_err();
10628+
if formalize_loaded_transaction_data_size {
10629+
assert_eq!(err, TransactionError::ProgramAccountNotFound);
10630+
} else {
10631+
assert_eq!(
10632+
err,
10633+
TransactionError::InstructionError(0, InstructionError::UnsupportedProgramId)
10634+
);
10635+
}
1060810636
}
1060910637

1061010638
#[test]
@@ -12150,8 +12178,11 @@ fn test_is_in_slot_hashes_history() {
1215012178
assert!(!new_bank.is_in_slot_hashes_history(&0));
1215112179
}
1215212180

12153-
#[test]
12154-
fn test_feature_activation_loaded_programs_cache_preparation_phase() {
12181+
#[test_case(false; "informal_loaded_size")]
12182+
#[test_case(true; "simd186_loaded_size")]
12183+
fn test_feature_activation_loaded_programs_cache_preparation_phase(
12184+
formalize_loaded_transaction_data_size: bool,
12185+
) {
1215512186
solana_logger::setup();
1215612187

1215712188
// Bank Setup
@@ -12160,6 +12191,9 @@ fn test_feature_activation_loaded_programs_cache_preparation_phase() {
1216012191
let mut feature_set = FeatureSet::all_enabled();
1216112192
feature_set.deactivate(&feature_set::disable_sbpf_v0_execution::id());
1216212193
feature_set.deactivate(&feature_set::reenable_sbpf_v0_execution::id());
12194+
if !formalize_loaded_transaction_data_size {
12195+
feature_set.deactivate(&feature_set::formalize_loaded_transaction_data_size::id());
12196+
}
1216312197
bank.feature_set = Arc::new(feature_set);
1216412198
let (root_bank, bank_forks) = bank.wrap_with_bank_forks_for_tests();
1216512199

@@ -13316,8 +13350,9 @@ fn test_deploy_last_epoch_slot() {
1331613350
assert_eq!(result_with_feature_enabled, Ok(()));
1331713351
}
1331813352

13319-
#[test]
13320-
fn test_loader_v3_to_v4_migration() {
13353+
#[test_case(false; "informal_loaded_size")]
13354+
#[test_case(true; "simd186_loaded_size")]
13355+
fn test_loader_v3_to_v4_migration(formalize_loaded_transaction_data_size: bool) {
1332113356
solana_logger::setup();
1332213357

1332313358
// Bank Setup
@@ -13328,6 +13363,9 @@ fn test_loader_v3_to_v4_migration() {
1332813363
);
1332913364
let mut bank = Bank::new_for_tests(&genesis_config);
1333013365
bank.activate_feature(&feature_set::remove_accounts_executable_flag_checks::id());
13366+
if formalize_loaded_transaction_data_size {
13367+
bank.activate_feature(&feature_set::formalize_loaded_transaction_data_size::id());
13368+
}
1333113369
let (bank, bank_forks) = bank.wrap_with_bank_forks_for_tests();
1333213370
let fee_calculator = genesis_config.fee_rate_governor.create_fee_calculator();
1333313371
let mut next_slot = 1;

svm-feature-set/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ pub struct SVMFeatureSet {
3636
pub increase_tx_account_lock_limit: bool,
3737
pub disable_rent_fees_collection: bool,
3838
pub enable_extend_program_checked: bool,
39+
pub formalize_loaded_transaction_data_size: bool,
3940
}
4041

4142
impl SVMFeatureSet {
@@ -77,6 +78,7 @@ impl SVMFeatureSet {
7778
increase_tx_account_lock_limit: true,
7879
disable_rent_fees_collection: true,
7980
enable_extend_program_checked: true,
81+
formalize_loaded_transaction_data_size: true,
8082
}
8183
}
8284
}

0 commit comments

Comments
 (0)