Skip to content

Commit ea95b46

Browse files
starknet_os_flow_tests: migrate test_compiled_class_hash_migration
1 parent ded6eb6 commit ea95b46

File tree

3 files changed

+116
-5
lines changed

3 files changed

+116
-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: 108 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,
@@ -2852,3 +2853,110 @@ async fn test_empty_multi_block() {
28522853
);
28532854
test_output.expect_hint_coverage("test_empty_multi_block");
28542855
}
2856+
2857+
/// Validates the migration flow for both declaring contract with casm hash v2, and migrating a
2858+
/// contract that was already declared with casm hash v1. This test covers:
2859+
/// 1. Declaring a contract with casm hash v2 and using it in the same block where it was declared.
2860+
/// 2. Using a contract that was previously declared with casm hash v1 (a migration should be
2861+
/// triggered in this case).
2862+
/// 3. Using the migrated contract in a block after the migration.
2863+
#[rstest]
2864+
#[tokio::test]
2865+
async fn test_compiled_class_hash_migration() {
2866+
let (mut test_manager, _) =
2867+
TestManager::<DictStateReader>::new_with_default_initial_state([]).await;
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+
// Move to the next block.
2892+
test_manager.move_to_next_block();
2893+
2894+
// Declare the contract with V2 hash.
2895+
let declare_tx_args_v2 = declare_tx_args! {
2896+
sender_address: *FUNDED_ACCOUNT_ADDRESS,
2897+
class_hash: empty_class_hash,
2898+
compiled_class_hash: compiled_empty_class_hash_v2,
2899+
resource_bounds: *NON_TRIVIAL_RESOURCE_BOUNDS,
2900+
nonce: test_manager.next_nonce(*FUNDED_ACCOUNT_ADDRESS),
2901+
};
2902+
let account_declare_tx_v2 = declare_tx(declare_tx_args_v2);
2903+
let class_info = get_class_info_of_feature_contract(empty_contract);
2904+
let tx_v2 =
2905+
DeclareTransaction::create(account_declare_tx_v2, class_info, &CHAIN_ID_FOR_TESTS).unwrap();
2906+
test_manager.add_cairo1_declare_tx(tx_v2, &empty_contract_sierra);
2907+
2908+
// Move to the next block.
2909+
test_manager.move_to_next_block();
2910+
2911+
// Deploy the contract with V2 hash.
2912+
let (deploy_tx_v2, _address_v2) = get_deploy_contract_tx_and_address_with_salt(
2913+
empty_class_hash,
2914+
calldata![],
2915+
test_manager.next_nonce(*FUNDED_ACCOUNT_ADDRESS),
2916+
*NON_TRIVIAL_RESOURCE_BOUNDS,
2917+
ContractAddressSalt(Felt::ZERO),
2918+
);
2919+
test_manager.add_invoke_tx(deploy_tx_v2, None);
2920+
2921+
// Deploy the V1 contract.
2922+
let (deploy_tx_v1, address_v1) = get_deploy_contract_tx_and_address_with_salt(
2923+
test_class_hash,
2924+
calldata![Felt::ONE, Felt::TWO],
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_v1, None);
2930+
2931+
// Invoke some function on the V1 contract.
2932+
let calldata = create_calldata(address_v1, "return_result", &[Felt::from(3)]);
2933+
test_manager.add_funded_account_invoke(invoke_tx_args! { calldata });
2934+
2935+
// Create custom block contexts for the two blocks.
2936+
assert_eq!(test_manager.n_blocks(), 3);
2937+
let first_block_number = test_manager.initial_state.next_block_number.0;
2938+
let use_kzg_da = true;
2939+
let block_contexts = [0, 1, 2]
2940+
.iter()
2941+
.map(|i| {
2942+
let mut block_ctx = block_context_for_flow_tests(
2943+
BlockNumber(first_block_number + *i as u64),
2944+
use_kzg_da,
2945+
);
2946+
// Migration is enabled, and V1-declare should be enabled only for the first block.
2947+
block_ctx.versioned_constants.enable_casm_hash_migration = true;
2948+
block_ctx.versioned_constants.block_casm_hash_v1_declares = *i > 0;
2949+
block_ctx
2950+
})
2951+
.collect();
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)