@@ -11884,12 +11884,6 @@ fn test_feature_activation_loaded_programs_recompilation_phase() {
11884
11884
. remove ( & feature_set:: reject_callx_r10:: id ( ) ) ;
11885
11885
let ( root_bank, bank_forks) = Bank :: new_with_bank_forks_for_tests ( & genesis_config) ;
11886
11886
11887
- // Test a basic transfer
11888
- let amount = genesis_config. rent . minimum_balance ( 0 ) ;
11889
- let pubkey = solana_sdk:: pubkey:: new_rand ( ) ;
11890
- root_bank. transfer ( amount, & mint_keypair, & pubkey) . unwrap ( ) ;
11891
- assert_eq ! ( root_bank. get_balance( & pubkey) , amount) ;
11892
-
11893
11887
// Program Setup
11894
11888
let program_keypair = Keypair :: new ( ) ;
11895
11889
let program_data =
@@ -11903,26 +11897,19 @@ fn test_feature_activation_loaded_programs_recompilation_phase() {
11903
11897
} ) ;
11904
11898
root_bank. store_account ( & program_keypair. pubkey ( ) , & program_account) ;
11905
11899
11906
- // Compose instruction using the desired program
11907
- let instruction1 = Instruction :: new_with_bytes ( program_keypair. pubkey ( ) , & [ ] , Vec :: new ( ) ) ;
11908
- let message1 = Message :: new ( & [ instruction1] , Some ( & mint_keypair. pubkey ( ) ) ) ;
11909
- let binding1 = mint_keypair. insecure_clone ( ) ;
11910
- let signers1 = vec ! [ & binding1] ;
11911
- let transaction1 = Transaction :: new ( & signers1, message1, root_bank. last_blockhash ( ) ) ;
11900
+ // Compose message using the desired program.
11901
+ let instruction = Instruction :: new_with_bytes ( program_keypair. pubkey ( ) , & [ ] , Vec :: new ( ) ) ;
11902
+ let message = Message :: new ( & [ instruction] , Some ( & mint_keypair. pubkey ( ) ) ) ;
11903
+ let binding = mint_keypair. insecure_clone ( ) ;
11904
+ let signers = vec ! [ & binding] ;
11912
11905
11913
- // Advance the bank so the next transaction can be submitted .
11906
+ // Advance the bank so that the program becomes effective .
11914
11907
goto_end_of_slot ( root_bank. clone ( ) ) ;
11915
11908
let bank = new_from_parent_with_fork_next_slot ( root_bank, bank_forks. as_ref ( ) ) ;
11916
11909
11917
- // Compose second instruction using the same program with a different block hash
11918
- let instruction2 = Instruction :: new_with_bytes ( program_keypair. pubkey ( ) , & [ ] , Vec :: new ( ) ) ;
11919
- let message2 = Message :: new ( & [ instruction2] , Some ( & mint_keypair. pubkey ( ) ) ) ;
11920
- let binding2 = mint_keypair. insecure_clone ( ) ;
11921
- let signers2 = vec ! [ & binding2] ;
11922
- let transaction2 = Transaction :: new ( & signers2, message2, bank. last_blockhash ( ) ) ;
11923
-
11924
- // Execute before feature is enabled to get program into the cache.
11925
- let result_without_feature_enabled = bank. process_transaction ( & transaction1) ;
11910
+ // Load the program with the old environment.
11911
+ let transaction = Transaction :: new ( & signers, message. clone ( ) , bank. last_blockhash ( ) ) ;
11912
+ let result_without_feature_enabled = bank. process_transaction ( & transaction) ;
11926
11913
assert_eq ! (
11927
11914
result_without_feature_enabled,
11928
11915
Err ( TransactionError :: InstructionError (
@@ -11931,20 +11918,67 @@ fn test_feature_activation_loaded_programs_recompilation_phase() {
11931
11918
) )
11932
11919
) ;
11933
11920
11934
- // Activate feature
11921
+ // Schedule feature activation to trigger a change of environment at the epoch boundary.
11935
11922
let feature_account_balance =
11936
11923
std:: cmp:: max ( genesis_config. rent . minimum_balance ( Feature :: size_of ( ) ) , 1 ) ;
11937
11924
bank. store_account (
11938
11925
& feature_set:: reject_callx_r10:: id ( ) ,
11939
11926
& feature:: create_account ( & Feature { activated_at : None } , feature_account_balance) ,
11940
11927
) ;
11941
11928
11929
+ // Advance the bank to middle of epoch to start the recompilation phase.
11930
+ goto_end_of_slot ( bank. clone ( ) ) ;
11931
+ let bank = new_bank_from_parent_with_bank_forks ( & bank_forks, bank, & Pubkey :: default ( ) , 16 ) ;
11932
+ let current_env = bank
11933
+ . loaded_programs_cache
11934
+ . read ( )
11935
+ . unwrap ( )
11936
+ . get_environments_for_epoch ( 0 )
11937
+ . program_runtime_v1
11938
+ . clone ( ) ;
11939
+ let upcoming_env = bank
11940
+ . loaded_programs_cache
11941
+ . read ( )
11942
+ . unwrap ( )
11943
+ . get_environments_for_epoch ( 1 )
11944
+ . program_runtime_v1
11945
+ . clone ( ) ;
11946
+
11947
+ // Advance the bank to recompile the program.
11948
+ {
11949
+ let loaded_programs_cache = bank. loaded_programs_cache . read ( ) . unwrap ( ) ;
11950
+ let slot_versions =
11951
+ loaded_programs_cache. get_slot_versions_for_tests ( & program_keypair. pubkey ( ) ) ;
11952
+ assert_eq ! ( slot_versions. len( ) , 1 ) ;
11953
+ assert ! ( Arc :: ptr_eq(
11954
+ slot_versions[ 0 ] . program. get_environment( ) . unwrap( ) ,
11955
+ & current_env
11956
+ ) ) ;
11957
+ }
11958
+ goto_end_of_slot ( bank. clone ( ) ) ;
11959
+ let bank = new_from_parent_with_fork_next_slot ( bank, bank_forks. as_ref ( ) ) ;
11960
+ {
11961
+ let loaded_programs_cache = bank. loaded_programs_cache . read ( ) . unwrap ( ) ;
11962
+ let slot_versions =
11963
+ loaded_programs_cache. get_slot_versions_for_tests ( & program_keypair. pubkey ( ) ) ;
11964
+ assert_eq ! ( slot_versions. len( ) , 2 ) ;
11965
+ assert ! ( Arc :: ptr_eq(
11966
+ slot_versions[ 0 ] . program. get_environment( ) . unwrap( ) ,
11967
+ & current_env
11968
+ ) ) ;
11969
+ assert ! ( Arc :: ptr_eq(
11970
+ slot_versions[ 1 ] . program. get_environment( ) . unwrap( ) ,
11971
+ & upcoming_env
11972
+ ) ) ;
11973
+ }
11974
+
11975
+ // Advance the bank to cross the epoch boundary and activate the feature.
11942
11976
goto_end_of_slot ( bank. clone ( ) ) ;
11943
- // Advance to next epoch, which starts the recompilation phase
11944
- let bank = new_from_parent_next_epoch ( bank, bank_forks. as_ref ( ) , 1 ) ;
11977
+ let bank = new_bank_from_parent_with_bank_forks ( & bank_forks, bank, & Pubkey :: default ( ) , 33 ) ;
11945
11978
11946
- // Execute after feature is enabled to check it was filtered out and reverified.
11947
- let result_with_feature_enabled = bank. process_transaction ( & transaction2) ;
11979
+ // Load the program with the new environment.
11980
+ let transaction = Transaction :: new ( & signers, message, bank. last_blockhash ( ) ) ;
11981
+ let result_with_feature_enabled = bank. process_transaction ( & transaction) ;
11948
11982
assert_eq ! (
11949
11983
result_with_feature_enabled,
11950
11984
Err ( TransactionError :: InstructionError (
0 commit comments