Skip to content

Commit 057d535

Browse files
starknet_os_flow_tests: migrate test_compiled_class_hash_migration
1 parent 717107f commit 057d535

File tree

3 files changed

+117
-5
lines changed

3 files changed

+117
-5
lines changed

crates/blockifier/src/context.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -116,11 +116,10 @@ impl GasCounter {
116116

117117
#[derive(Clone, Debug)]
118118
pub struct BlockContext {
119-
// TODO(Yoni, 1/10/2024): consider making these fields public.
120-
pub(crate) block_info: BlockInfo,
121-
pub(crate) chain_info: ChainInfo,
122-
pub(crate) versioned_constants: VersionedConstants,
123-
pub(crate) bouncer_config: BouncerConfig,
119+
pub block_info: BlockInfo,
120+
pub chain_info: ChainInfo,
121+
pub versioned_constants: VersionedConstants,
122+
pub bouncer_config: BouncerConfig,
124123
}
125124

126125
impl BlockContext {

crates/starknet_os_flow_tests/src/test_manager.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,10 @@ impl<S: FlowTestState> TestManager<S> {
344344
self.per_block_transactions.iter().map(|block| block.len()).sum()
345345
}
346346

347+
pub(crate) fn n_blocks(&self) -> usize {
348+
self.per_block_transactions.len()
349+
}
350+
347351
fn last_block_txs_mut(&mut self) -> &mut Vec<FlowTestTx> {
348352
self.per_block_transactions
349353
.last_mut()

crates/starknet_os_flow_tests/src/tests.rs

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ use crate::special_contracts::{
104104
V1_BOUND_CAIRO1_CONTRACT_SIERRA,
105105
};
106106
use crate::test_manager::{
107+
block_context_for_flow_tests,
107108
TestManager,
108109
TestParameters,
109110
FUNDED_ACCOUNT_ADDRESS,
@@ -2851,3 +2852,111 @@ async fn test_empty_multi_block() {
28512852
);
28522853
test_output.expect_hint_coverage("test_empty_multi_block");
28532854
}
2855+
2856+
/// Validates the migration flow for both declaring contract with casm hash v2, and migrating a
2857+
/// contract that was already declared with casm hash v1. This test covers:
2858+
/// 1. Declaring a contract with casm hash v2 and using it in the same block where it was declared.
2859+
/// 2. Using a contract that was previously declared with casm hash v1 (a migration should be
2860+
/// triggered in this case).
2861+
/// 3. Using the migrated contract in a block after the migration.
2862+
#[rstest]
2863+
#[tokio::test]
2864+
async fn test_compiled_class_hash_migration() {
2865+
let (mut test_manager, _) =
2866+
TestManager::<DictStateReader>::new_with_default_initial_state([]).await;
2867+
let use_kzg_da = true;
2868+
2869+
// Declare two contracts, with V1 and V2 hashes.
2870+
let test_contract = FeatureContract::TestContract(CairoVersion::Cairo1(RunnableCairo1::Casm));
2871+
let empty_contract = FeatureContract::Empty(CairoVersion::Cairo1(RunnableCairo1::Casm));
2872+
let test_contract_sierra = test_contract.get_sierra();
2873+
let empty_contract_sierra = empty_contract.get_sierra();
2874+
let test_class_hash = test_contract_sierra.calculate_class_hash();
2875+
let empty_class_hash = empty_contract_sierra.calculate_class_hash();
2876+
let compiled_test_class_hash_v1 = test_contract.get_compiled_class_hash(&HashVersion::V1);
2877+
let compiled_empty_class_hash_v2 = empty_contract.get_compiled_class_hash(&HashVersion::V2);
2878+
let declare_tx_args_v1 = declare_tx_args! {
2879+
sender_address: *FUNDED_ACCOUNT_ADDRESS,
2880+
class_hash: test_class_hash,
2881+
compiled_class_hash: compiled_test_class_hash_v1,
2882+
resource_bounds: *NON_TRIVIAL_RESOURCE_BOUNDS,
2883+
nonce: test_manager.next_nonce(*FUNDED_ACCOUNT_ADDRESS),
2884+
};
2885+
let account_declare_tx_v1 = declare_tx(declare_tx_args_v1);
2886+
let class_info = get_class_info_of_feature_contract(test_contract);
2887+
let tx_v1 =
2888+
DeclareTransaction::create(account_declare_tx_v1, class_info, &CHAIN_ID_FOR_TESTS).unwrap();
2889+
test_manager.add_cairo1_declare_tx(tx_v1, &test_contract_sierra);
2890+
2891+
// Block context for the first block. Migration and v1-declare-blocking should be disabled.
2892+
let mut next_block_number = test_manager.initial_state.next_block_number;
2893+
let mut block_context_0 = block_context_for_flow_tests(next_block_number, use_kzg_da);
2894+
block_context_0.versioned_constants.enable_casm_hash_migration = false;
2895+
block_context_0.versioned_constants.block_casm_hash_v1_declares = false;
2896+
test_manager.move_to_next_block();
2897+
next_block_number = BlockNumber(next_block_number.0 + 1);
2898+
2899+
// Declare the contract with V2 hash.
2900+
let declare_tx_args_v2 = declare_tx_args! {
2901+
sender_address: *FUNDED_ACCOUNT_ADDRESS,
2902+
class_hash: empty_class_hash,
2903+
compiled_class_hash: compiled_empty_class_hash_v2,
2904+
resource_bounds: *NON_TRIVIAL_RESOURCE_BOUNDS,
2905+
nonce: test_manager.next_nonce(*FUNDED_ACCOUNT_ADDRESS),
2906+
};
2907+
let account_declare_tx_v2 = declare_tx(declare_tx_args_v2);
2908+
let class_info = get_class_info_of_feature_contract(empty_contract);
2909+
let tx_v2 =
2910+
DeclareTransaction::create(account_declare_tx_v2, class_info, &CHAIN_ID_FOR_TESTS).unwrap();
2911+
test_manager.add_cairo1_declare_tx(tx_v2, &empty_contract_sierra);
2912+
2913+
// Move to the next block. After the V1 declare, enable migration and block V1 declares.
2914+
let block_context_1 = block_context_for_flow_tests(next_block_number, use_kzg_da);
2915+
// These should be true be default.
2916+
assert!(block_context_1.versioned_constants.enable_casm_hash_migration);
2917+
assert!(block_context_1.versioned_constants.block_casm_hash_v1_declares);
2918+
test_manager.move_to_next_block();
2919+
next_block_number = BlockNumber(next_block_number.0 + 1);
2920+
2921+
// Deploy the contract with V2 hash.
2922+
let (deploy_tx_v2, _address_v2) = get_deploy_contract_tx_and_address_with_salt(
2923+
empty_class_hash,
2924+
calldata![],
2925+
test_manager.next_nonce(*FUNDED_ACCOUNT_ADDRESS),
2926+
*NON_TRIVIAL_RESOURCE_BOUNDS,
2927+
ContractAddressSalt(Felt::ZERO),
2928+
);
2929+
test_manager.add_invoke_tx(deploy_tx_v2, None);
2930+
2931+
// Deploy the V1 contract.
2932+
let (deploy_tx_v1, address_v1) = get_deploy_contract_tx_and_address_with_salt(
2933+
test_class_hash,
2934+
calldata![Felt::ONE, Felt::TWO],
2935+
test_manager.next_nonce(*FUNDED_ACCOUNT_ADDRESS),
2936+
*NON_TRIVIAL_RESOURCE_BOUNDS,
2937+
ContractAddressSalt(Felt::ZERO),
2938+
);
2939+
test_manager.add_invoke_tx(deploy_tx_v1, None);
2940+
2941+
// Invoke some function on the V1 contract.
2942+
let calldata = create_calldata(address_v1, "return_result", &[Felt::from(3)]);
2943+
test_manager.add_funded_account_invoke(invoke_tx_args! { calldata });
2944+
2945+
// Create custom block contexts for the two blocks.
2946+
assert_eq!(test_manager.n_blocks(), 3);
2947+
let block_context_2 = block_context_for_flow_tests(next_block_number, use_kzg_da);
2948+
// These should be true be default.
2949+
assert!(block_context_2.versioned_constants.enable_casm_hash_migration);
2950+
assert!(block_context_2.versioned_constants.block_casm_hash_v1_declares);
2951+
let block_contexts = vec![block_context_0, block_context_1, block_context_2];
2952+
2953+
// Run the test and verify the storage changes.
2954+
let test_output = test_manager
2955+
.execute_test_with_block_contexts(
2956+
block_contexts,
2957+
&TestParameters { use_kzg_da, ..Default::default() },
2958+
)
2959+
.await;
2960+
test_output.perform_default_validations();
2961+
test_output.expect_hint_coverage("test_compiled_class_hash_migration");
2962+
}

0 commit comments

Comments
 (0)