From a766f69398035bcf75e1b1f9a0bc26131ccbc4f9 Mon Sep 17 00:00:00 2001 From: avivg-starkware Date: Thu, 27 Feb 2025 12:02:51 +0200 Subject: [PATCH 1/7] chore(blockifier): add native to transfers_benchmark (#4432) --- crates/blockifier/bench/blockifier_bench.rs | 7 +++++++ crates/blockifier/src/test_utils/transfers_generator.rs | 4 ++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/crates/blockifier/bench/blockifier_bench.rs b/crates/blockifier/bench/blockifier_bench.rs index 2097bb1cecb..3b969d09c14 100644 --- a/crates/blockifier/bench/blockifier_bench.rs +++ b/crates/blockifier/bench/blockifier_bench.rs @@ -6,17 +6,24 @@ //! of transfers between randomly created accounts, which are iterated over round-robin. //! //! Run the benchmarks using `cargo bench --bench blockifier_bench`. +//! +//! For Cairo Native compilation run the benchmarks using: +//! `cargo bench --bench blockifier_bench --features "cairo_native"`. use blockifier::test_utils::transfers_generator::{ RecipientGeneratorType, TransfersGenerator, TransfersGeneratorConfig, }; +#[cfg(feature = "cairo_native")] +use blockifier::test_utils::{CairoVersion, RunnableCairo1}; use criterion::{criterion_group, criterion_main, Criterion}; pub fn transfers_benchmark(c: &mut Criterion) { let transfers_generator_config = TransfersGeneratorConfig { recipient_generator_type: RecipientGeneratorType::Random, + #[cfg(feature = "cairo_native")] + cairo_version: CairoVersion::Cairo1(RunnableCairo1::Native), ..Default::default() }; let mut transfers_generator = TransfersGenerator::new(transfers_generator_config); diff --git a/crates/blockifier/src/test_utils/transfers_generator.rs b/crates/blockifier/src/test_utils/transfers_generator.rs index 98d7958b485..0d76148b30f 100644 --- a/crates/blockifier/src/test_utils/transfers_generator.rs +++ b/crates/blockifier/src/test_utils/transfers_generator.rs @@ -17,13 +17,13 @@ use crate::context::{BlockContext, ChainInfo}; use crate::test_utils::contracts::FeatureContract; use crate::test_utils::dict_state_reader::DictStateReader; use crate::test_utils::initial_test_state::test_state; -use crate::test_utils::{CairoVersion, BALANCE, MAX_FEE}; +use crate::test_utils::{CairoVersion, RunnableCairo1, BALANCE, MAX_FEE}; use crate::transaction::account_transaction::AccountTransaction; use crate::transaction::transaction_execution::Transaction; const N_ACCOUNTS: u16 = 10000; const N_TXS: usize = 1000; const RANDOMIZATION_SEED: u64 = 0; -const CAIRO_VERSION: CairoVersion = CairoVersion::Cairo0; +const CAIRO_VERSION: CairoVersion = CairoVersion::Cairo1(RunnableCairo1::Casm); const TRANSACTION_VERSION: TransactionVersion = TransactionVersion(Felt::THREE); const RECIPIENT_GENERATOR_TYPE: RecipientGeneratorType = RecipientGeneratorType::RoundRobin; From 7f8c728b36eeee3a7255b0418469141f7b8792b7 Mon Sep 17 00:00:00 2001 From: Noa Oved Date: Thu, 27 Feb 2025 15:40:36 +0200 Subject: [PATCH 2/7] open new branch: 0.13.5 --- scripts/merge_paths.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/merge_paths.json b/scripts/merge_paths.json index ca5dc1b4348..e34991cf9e5 100644 --- a/scripts/merge_paths.json +++ b/scripts/merge_paths.json @@ -1,4 +1,5 @@ { "main-v0.13.2": "main-v0.13.4", - "main-v0.13.4": "main" + "main-v0.13.4": "main-v0.13.5", + "main-v0.13.5": "main" } From ad4aa2e9bc857d8ff9a76ff9eaae514ac8541c1b Mon Sep 17 00:00:00 2001 From: Noa Oved <104720318+noaov1@users.noreply.github.com> Date: Thu, 27 Feb 2025 20:08:12 +0200 Subject: [PATCH 3/7] chore: update to version 0.13.5 (#4548) --- .../resources/versioned_constants_0_13_5.json | 562 ++++++++++++++++++ crates/blockifier/src/versioned_constants.rs | 1 + .../src/serialization/serializers.rs | 1 + crates/papyrus_test_utils/src/lib.rs | 1 + .../resources/central_state_diff.json | 2 +- crates/starknet_api/src/block.rs | 4 +- .../resources/reader/block_post_0_13_4.json | 4 +- 7 files changed, 571 insertions(+), 4 deletions(-) create mode 100644 crates/blockifier/resources/versioned_constants_0_13_5.json diff --git a/crates/blockifier/resources/versioned_constants_0_13_5.json b/crates/blockifier/resources/versioned_constants_0_13_5.json new file mode 100644 index 00000000000..8072d23852e --- /dev/null +++ b/crates/blockifier/resources/versioned_constants_0_13_5.json @@ -0,0 +1,562 @@ +{ + "tx_event_limits": { + "max_data_length": 300, + "max_keys_length": 50, + "max_n_emitted_events": 1000 + }, + "gateway": { + "max_calldata_length": 5000, + "max_contract_bytecode_size": 81920 + }, + "invoke_tx_max_n_steps": 10000000, + "deprecated_l2_resource_gas_costs": { + "gas_per_data_felt": [ + 128, + 1000 + ], + "event_key_factor": [ + 2, + 1 + ], + "gas_per_code_byte": [ + 32, + 1000 + ] + }, + "archival_data_gas_costs": { + "gas_per_data_felt": [ + 5120, + 1 + ], + "event_key_factor": [ + 2, + 1 + ], + "gas_per_code_byte": [ + 1280, + 1 + ] + }, + "disable_cairo0_redeclaration": true, + "enable_stateful_compression": true, + "comprehensive_state_diff": true, + "allocation_cost": { + "blob_cost": { + "l1_gas": 0, + "l1_data_gas": 32, + "l2_gas": 0 + }, + "gas_cost": { + "l1_gas": 551, + "l1_data_gas": 0, + "l2_gas": 0 + } + }, + "ignore_inner_event_resources": false, + "enable_reverts": true, + "max_recursion_depth": 50, + "segment_arena_cells": false, + "os_constants": { + "constructor_entry_point_selector": "0x28ffe4ff0f226a9107253e17a904099aa4f63a02a5621de0576e5aa71bc5194", + "default_entry_point_selector": 0, + "entry_point_initial_budget": { + "step_gas_cost": 100 + }, + "entry_point_type_constructor": 2, + "entry_point_type_external": 0, + "entry_point_type_l1_handler": 1, + "error_block_number_out_of_range": "Block number out of range", + "error_invalid_input_len": "Invalid input length", + "error_invalid_argument": "Invalid argument", + "error_out_of_gas": "Out of gas", + "error_entry_point_failed": "ENTRYPOINT_FAILED", + "error_entry_point_not_found": "ENTRYPOINT_NOT_FOUND", + "execute_entry_point_selector": "0x15d40a3d6ca2ac30f4031e42be28da9b056fef9bb7357ac5e85627ee876e5ad", + "execute_max_sierra_gas": 1000000000, + "default_initial_gas_cost": { + "step_gas_cost": 100000000 + }, + "l1_gas": "L1_GAS", + "l1_gas_index": 0, + "l1_handler_version": 0, + "l2_gas": "L2_GAS", + "l1_data_gas": "L1_DATA", + "l1_data_gas_index": 2, + "l2_gas_index": 1, + "memory_hole_gas_cost": 10, + "nop_entry_point_offset": -1, + "os_contract_addresses": { + "block_hash_contract_address": 1, + "alias_contract_address": 2, + "reserved_contract_address": 3 + }, + "builtin_gas_costs": { + "range_check": 70, + "range_check96": 56, + "keccak": 136189, + "pedersen": 4050, + "bitwise": 583, + "ecop": 4085, + "poseidon": 491, + "add_mod": 230, + "mul_mod": 604, + "ecdsa": 10561 + }, + "sierra_array_len_bound": 4294967296, + "step_gas_cost": 100, + "stored_block_hash_buffer": 10, + "syscall_base_gas_cost": { + "step_gas_cost": 100 + }, + "transfer_entry_point_selector": "0x83afd3f4caedc6eebf44246fe54e38c95e3179a5ec9ea81740eca5b482d12e", + "validate_declare_entry_point_selector": "0x289da278a8dc833409cabfdad1581e8e7d40e42dcaed693fa4008dcdb4963b3", + "validate_deploy_entry_point_selector": "0x36fcbf06cd96843058359e1a75928beacfac10727dab22a3972f0af8aa92895", + "validate_entry_point_selector": "0x162da33a4585851fe8d3af3c2a9c60b557814e221e0d4f30ff0b2189d9c7775", + "validate_max_sierra_gas": 100000000, + "validate_rounding_consts": { + "validate_block_number_rounding": 100, + "validate_timestamp_rounding": 3600 + }, + "validated": "VALID" + }, + "os_resources": { + "execute_syscalls": { + "CallContract": { + "n_steps": 866, + "builtin_instance_counter": { + "range_check_builtin": 15 + }, + "n_memory_holes": 0 + }, + "DelegateCall": { + "n_steps": 713, + "builtin_instance_counter": { + "range_check_builtin": 19 + }, + "n_memory_holes": 0 + }, + "DelegateL1Handler": { + "n_steps": 692, + "builtin_instance_counter": { + "range_check_builtin": 15 + }, + "n_memory_holes": 0 + }, + "Deploy": { + "n_steps": 1132, + "builtin_instance_counter": { + "pedersen_builtin": 7, + "range_check_builtin": 18 + }, + "n_memory_holes": 0 + }, + "EmitEvent": { + "n_steps": 61, + "builtin_instance_counter": { + "range_check_builtin": 1 + }, + "n_memory_holes": 0 + }, + "GetBlockHash": { + "n_steps": 104, + "builtin_instance_counter": { + "range_check_builtin": 2 + }, + "n_memory_holes": 0 + }, + "GetBlockNumber": { + "n_steps": 40, + "builtin_instance_counter": {}, + "n_memory_holes": 0 + }, + "GetBlockTimestamp": { + "n_steps": 38, + "builtin_instance_counter": {}, + "n_memory_holes": 0 + }, + "GetCallerAddress": { + "n_steps": 64, + "builtin_instance_counter": { + "range_check_builtin": 1 + }, + "n_memory_holes": 0 + }, + "GetContractAddress": { + "n_steps": 64, + "builtin_instance_counter": { + "range_check_builtin": 1 + }, + "n_memory_holes": 0 + }, + "GetExecutionInfo": { + "n_steps": 64, + "builtin_instance_counter": { + "range_check_builtin": 1 + }, + "n_memory_holes": 0 + }, + "GetSequencerAddress": { + "n_steps": 34, + "builtin_instance_counter": {}, + "n_memory_holes": 0 + }, + "GetTxInfo": { + "n_steps": 64, + "builtin_instance_counter": { + "range_check_builtin": 1 + }, + "n_memory_holes": 0 + }, + "GetTxSignature": { + "n_steps": 44, + "builtin_instance_counter": {}, + "n_memory_holes": 0 + }, + "KeccakRound": { + "n_steps": 281, + "builtin_instance_counter": { + "bitwise_builtin": 6, + "keccak_builtin": 1, + "range_check_builtin": 56 + }, + "n_memory_holes": 0 + }, + "Keccak": { + "n_steps": 100, + "builtin_instance_counter": {}, + "n_memory_holes": 0 + }, + "LibraryCall": { + "n_steps": 842, + "builtin_instance_counter": { + "range_check_builtin": 15 + }, + "n_memory_holes": 0 + }, + "LibraryCallL1Handler": { + "n_steps": 659, + "builtin_instance_counter": { + "range_check_builtin": 15 + }, + "n_memory_holes": 0 + }, + "ReplaceClass": { + "n_steps": 104, + "builtin_instance_counter": { + "range_check_builtin": 1 + }, + "n_memory_holes": 0 + }, + "Secp256k1Add": { + "n_steps": 410, + "builtin_instance_counter": { + "range_check_builtin": 29 + }, + "n_memory_holes": 0 + }, + "Secp256k1GetPointFromX": { + "n_steps": 395, + "builtin_instance_counter": { + "range_check_builtin": 30 + }, + "n_memory_holes": 0 + }, + "Secp256k1GetXy": { + "n_steps": 207, + "builtin_instance_counter": { + "range_check_builtin": 11 + }, + "n_memory_holes": 0 + }, + "Secp256k1Mul": { + "n_steps": 76505, + "builtin_instance_counter": { + "range_check_builtin": 7045 + }, + "n_memory_holes": 0 + }, + "Secp256k1New": { + "n_steps": 461, + "builtin_instance_counter": { + "range_check_builtin": 35 + }, + "n_memory_holes": 0 + }, + "Secp256r1Add": { + "n_steps": 593, + "builtin_instance_counter": { + "range_check_builtin": 57 + }, + "n_memory_holes": 0 + }, + "Secp256r1GetPointFromX": { + "n_steps": 514, + "builtin_instance_counter": { + "range_check_builtin": 44 + }, + "n_memory_holes": 0 + }, + "Secp256r1GetXy": { + "n_steps": 209, + "builtin_instance_counter": { + "range_check_builtin": 11 + }, + "n_memory_holes": 0 + }, + "Secp256r1Mul": { + "n_steps": 125344, + "builtin_instance_counter": { + "range_check_builtin": 13961 + }, + "n_memory_holes": 0 + }, + "Secp256r1New": { + "n_steps": 580, + "builtin_instance_counter": { + "range_check_builtin": 49 + }, + "n_memory_holes": 0 + }, + "SendMessageToL1": { + "n_steps": 141, + "builtin_instance_counter": { + "range_check_builtin": 1 + }, + "n_memory_holes": 0 + }, + "Sha256ProcessBlock": { + "n_steps": 1865, + "builtin_instance_counter": { + "range_check_builtin": 65, + "bitwise_builtin": 1115 + }, + "n_memory_holes": 0 + }, + "StorageRead": { + "n_steps": 87, + "builtin_instance_counter": { + "range_check_builtin": 1 + }, + "n_memory_holes": 0 + }, + "StorageWrite": { + "n_steps": 93, + "builtin_instance_counter": { + "range_check_builtin": 1 + }, + "n_memory_holes": 0 + }, + "GetClassHashAt": { + "n_steps": 89, + "builtin_instance_counter": { + "range_check_builtin": 1 + }, + "n_memory_holes": 0 + } + }, + "execute_txs_inner": { + "Declare": { + "deprecated_resources": { + "constant": { + "n_steps": 3203, + "builtin_instance_counter": { + "pedersen_builtin": 16, + "range_check_builtin": 56, + "poseidon_builtin": 4 + }, + "n_memory_holes": 0 + }, + "calldata_factor": { + "n_steps": 0, + "builtin_instance_counter": {}, + "n_memory_holes": 0 + } + }, + "resources": { + "constant": { + "n_steps": 3346, + "builtin_instance_counter": { + "pedersen_builtin": 4, + "range_check_builtin": 64, + "poseidon_builtin": 14 + }, + "n_memory_holes": 0 + }, + "calldata_factor": { + "n_steps": 0, + "builtin_instance_counter": {}, + "n_memory_holes": 0 + } + } + }, + "DeployAccount": { + "deprecated_resources": { + "constant": { + "n_steps": 4161, + "builtin_instance_counter": { + "pedersen_builtin": 23, + "range_check_builtin": 72 + }, + "n_memory_holes": 0 + }, + "calldata_factor": { + "n_steps": 21, + "builtin_instance_counter": { + "pedersen_builtin": 2 + }, + "n_memory_holes": 0 + } + }, + "resources": { + "constant": { + "n_steps": 4321, + "builtin_instance_counter": { + "pedersen_builtin": 11, + "range_check_builtin": 80, + "poseidon_builtin": 10 + }, + "n_memory_holes": 0 + }, + "calldata_factor": { + "n_steps": 21, + "builtin_instance_counter": { + "pedersen_builtin": 2 + }, + "n_memory_holes": 0 + } + } + }, + "InvokeFunction": { + "deprecated_resources": { + "constant": { + "n_steps": 3918, + "builtin_instance_counter": { + "pedersen_builtin": 14, + "range_check_builtin": 69 + }, + "n_memory_holes": 0 + }, + "calldata_factor": { + "n_steps": 8, + "builtin_instance_counter": { + "pedersen_builtin": 1 + }, + "n_memory_holes": 0 + } + }, + "resources": { + "constant": { + "n_steps": 4102, + "builtin_instance_counter": { + "pedersen_builtin": 4, + "range_check_builtin": 77, + "poseidon_builtin": 11 + }, + "n_memory_holes": 0 + }, + "calldata_factor": { + "n_steps": 8, + "builtin_instance_counter": { + "pedersen_builtin": 1 + }, + "n_memory_holes": 0 + } + } + }, + "L1Handler": { + "deprecated_resources": { + "constant": { + "n_steps": 1279, + "builtin_instance_counter": { + "pedersen_builtin": 11, + "range_check_builtin": 16 + }, + "n_memory_holes": 0 + }, + "calldata_factor": { + "n_steps": 13, + "builtin_instance_counter": { + "pedersen_builtin": 1 + }, + "n_memory_holes": 0 + } + }, + "resources": { + "constant": { + "n_steps": 0, + "builtin_instance_counter": {}, + "n_memory_holes": 0 + }, + "calldata_factor": { + "n_steps": 13, + "builtin_instance_counter": { + "pedersen_builtin": 1 + }, + "n_memory_holes": 0 + } + } + } + }, + "compute_os_kzg_commitment_info": { + "n_steps": 113, + "builtin_instance_counter": { + "range_check_builtin": 17 + }, + "n_memory_holes": 0 + } + }, + "validate_max_n_steps": 1000000, + "min_sierra_version_for_sierra_gas": "1.7.0", + "vm_resource_fee_cost": { + "builtins": { + "add_mod_builtin": [ + 4, + 100 + ], + "bitwise_builtin": [ + 16, + 100 + ], + "ec_op_builtin": [ + 256, + 100 + ], + "ecdsa_builtin": [ + 512, + 100 + ], + "keccak_builtin": [ + 512, + 100 + ], + "mul_mod_builtin": [ + 4, + 100 + ], + "output_builtin": [ + 0, + 1 + ], + "pedersen_builtin": [ + 8, + 100 + ], + "poseidon_builtin": [ + 8, + 100 + ], + "range_check_builtin": [ + 4, + 100 + ], + "range_check96_builtin": [ + 4, + 100 + ] + }, + "n_steps": [ + 25, + 10000 + ] + } +} \ No newline at end of file diff --git a/crates/blockifier/src/versioned_constants.rs b/crates/blockifier/src/versioned_constants.rs index e728d971194..c8f462c1b36 100644 --- a/crates/blockifier/src/versioned_constants.rs +++ b/crates/blockifier/src/versioned_constants.rs @@ -118,6 +118,7 @@ define_versioned_constants! { (V0_13_2_1, "../resources/versioned_constants_0_13_2_1.json"), (V0_13_3, "../resources/versioned_constants_0_13_3.json"), (V0_13_4, "../resources/versioned_constants_0_13_4.json"), + (V0_13_5, "../resources/versioned_constants_0_13_5.json"), } pub type ResourceCost = Ratio; diff --git a/crates/papyrus_storage/src/serialization/serializers.rs b/crates/papyrus_storage/src/serialization/serializers.rs index 8daf2510c2b..e6d6fc1a27c 100644 --- a/crates/papyrus_storage/src/serialization/serializers.rs +++ b/crates/papyrus_storage/src/serialization/serializers.rs @@ -412,6 +412,7 @@ auto_storage_serde! { V0_13_2_1 = 17, V0_13_3 = 18, V0_13_4 = 19, + V0_13_5 = 20, } pub struct StateDiffCommitment(pub PoseidonHash); pub struct Tip(pub u64); diff --git a/crates/papyrus_test_utils/src/lib.rs b/crates/papyrus_test_utils/src/lib.rs index ababd0a8318..ccd7c9d56e7 100644 --- a/crates/papyrus_test_utils/src/lib.rs +++ b/crates/papyrus_test_utils/src/lib.rs @@ -491,6 +491,7 @@ auto_impl_get_test_instance! { V0_13_2_1 = 17, V0_13_3 = 18, V0_13_4 = 19, + V0_13_5 = 20, } pub struct Calldata(pub Arc>); diff --git a/crates/sequencing/papyrus_consensus_orchestrator/resources/central_state_diff.json b/crates/sequencing/papyrus_consensus_orchestrator/resources/central_state_diff.json index 2a96fcf4414..36421d86b70 100644 --- a/crates/sequencing/papyrus_consensus_orchestrator/resources/central_state_diff.json +++ b/crates/sequencing/papyrus_consensus_orchestrator/resources/central_state_diff.json @@ -33,7 +33,7 @@ "price_in_fri": "0xd" }, "sequencer_address": "0x7", - "starknet_version": "0.13.4", + "starknet_version": "0.13.5", "use_kzg_da": true } } diff --git a/crates/starknet_api/src/block.rs b/crates/starknet_api/src/block.rs index dbd0fe78969..1759b08d6c6 100644 --- a/crates/starknet_api/src/block.rs +++ b/crates/starknet_api/src/block.rs @@ -98,7 +98,9 @@ starknet_version_enum! { (V0_13_2_1, 0, 13, 2, 1), (V0_13_3, 0, 13, 3), (V0_13_4, 0, 13, 4), - V0_13_4 + (V0_13_5, 0, 13, 5), + V0_13_5 + } impl Default for StarknetVersion { diff --git a/crates/starknet_client/resources/reader/block_post_0_13_4.json b/crates/starknet_client/resources/reader/block_post_0_13_4.json index aed0db13316..ed58f970c36 100644 --- a/crates/starknet_client/resources/reader/block_post_0_13_4.json +++ b/crates/starknet_client/resources/reader/block_post_0_13_4.json @@ -336,5 +336,5 @@ "actual_fee": "0xdc24bd9e78" } ], - "starknet_version": "0.13.4" -} + "starknet_version": "0.13.5" +} \ No newline at end of file From a920c870d640af6ead92ec23b3f17e0112b24631 Mon Sep 17 00:00:00 2001 From: dorimedini-starkware Date: Sun, 2 Mar 2025 12:36:06 +0200 Subject: [PATCH 4/7] feat(blockifier): make ArchivalDataResource fields public (#3824) Signed-off-by: Dori Medini --- crates/blockifier/src/fee/resources.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/blockifier/src/fee/resources.rs b/crates/blockifier/src/fee/resources.rs index ae2083fc0a6..83eeebc26f9 100644 --- a/crates/blockifier/src/fee/resources.rs +++ b/crates/blockifier/src/fee/resources.rs @@ -238,8 +238,8 @@ impl StateResources { pub struct ArchivalDataResources { pub event_summary: EventSummary, pub calldata_length: usize, - signature_length: usize, - code_size: usize, + pub signature_length: usize, + pub code_size: usize, } impl ArchivalDataResources { From 17891e8902a7cebb0d5465bf07b1ab624ececeeb Mon Sep 17 00:00:00 2001 From: Adi Yakovian <56866524+adi-yakovian-starkware@users.noreply.github.com> Date: Sun, 2 Mar 2025 13:20:00 +0200 Subject: [PATCH 5/7] chore(ci): remove load flag (#3849) (#4559) Co-Authored-By: Idan Shamam <161198342+idan-starkware@users.noreply.github.com> --- .github/workflows/papyrus_docker-publish.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/papyrus_docker-publish.yml b/.github/workflows/papyrus_docker-publish.yml index 48b6c15a6a0..838f8478ba4 100644 --- a/.github/workflows/papyrus_docker-publish.yml +++ b/.github/workflows/papyrus_docker-publish.yml @@ -92,5 +92,4 @@ jobs: push: ${{ github.event_name != 'pull_request' }} tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} - cache-from: type=gha - cache-to: type=gha,mode=max + no-cache: true From 31d72fcef90e3c970a6e30aace5e21c4fb374971 Mon Sep 17 00:00:00 2001 From: dorimedini-starkware Date: Mon, 3 Mar 2025 11:31:40 +0200 Subject: [PATCH 6/7] feat(blockifier): cherry pick v1 bound PRs (#4587) * feat(blockifier): cherry-pick cb70207d0 * feat(blockifier): resolve conflicts Signed-off-by: Dori Medini * feat(blockifier): cherry-pick 75d46404f * feat(blockifier): cherry-pick 89541211b * feat(blockifier): cherry-pick 31bd90391 * feat(blockifier): cherry-pick d14e3a6c3 * feat(blockifier): resolve conflicts Signed-off-by: Dori Medini * feat(blockifier): cherry-pick 86799f129 * feat(blockifier): cherry-pick 0d94643ed * feat(blockifier): cherry-pick 15a0d454e * feat(blockifier): cherry-pick 3de03424d * feat(blockifier): cherry-pick 70ab0ccf7 * feat(blockifier): resolve conflicts Signed-off-by: Dori Medini * feat(blockifier): cherry-pick e8edce104 --- .../resources/versioned_constants_0_13_0.json | 4 +- .../resources/versioned_constants_0_13_1.json | 4 +- .../versioned_constants_0_13_1_1.json | 4 +- .../resources/versioned_constants_0_13_2.json | 4 +- .../versioned_constants_0_13_2_1.json | 4 +- .../resources/versioned_constants_0_13_3.json | 6 +- .../resources/versioned_constants_0_13_4.json | 6 +- .../resources/versioned_constants_0_13_5.json | 10 ++- .../src/concurrency/fee_utils_test.rs | 2 +- crates/blockifier/src/context.rs | 2 +- .../src/execution/contract_class.rs | 23 ++--- .../deprecated_entry_point_execution.rs | 15 ++-- .../deprecated_syscalls_test.rs | 28 +++++-- .../deprecated_syscalls/hint_processor.rs | 31 ++++++- .../blockifier/src/execution/entry_point.rs | 83 ++++++++++++++++--- .../src/execution/entry_point_execution.rs | 12 +-- .../src/execution/execution_utils.rs | 8 +- .../src/execution/native/contract_class.rs | 6 +- .../execution/native/entry_point_execution.rs | 8 +- .../src/execution/native/syscall_handler.rs | 13 ++- .../src/execution/syscalls/hint_processor.rs | 35 ++++++-- .../src/execution/syscalls/syscall_base.rs | 34 +++++++- .../syscall_tests/get_execution_info.rs | 82 ++++++++++++++++-- crates/blockifier/src/test_utils/contracts.rs | 47 +++++++++-- .../src/test_utils/initial_test_state.rs | 29 ++++--- crates/blockifier/src/versioned_constants.rs | 16 +++- .../src/versioned_constants_test.rs | 2 + scripts/rust_fmt.sh | 0 28 files changed, 409 insertions(+), 109 deletions(-) mode change 100644 => 100755 scripts/rust_fmt.sh diff --git a/crates/blockifier/resources/versioned_constants_0_13_0.json b/crates/blockifier/resources/versioned_constants_0_13_0.json index 64253a472f7..5cc7a563cf6 100644 --- a/crates/blockifier/resources/versioned_constants_0_13_0.json +++ b/crates/blockifier/resources/versioned_constants_0_13_0.json @@ -212,7 +212,9 @@ "range_check": 0, "syscall_base_gas_cost": 0 } - } + }, + "v1_bound_accounts_cairo0": [], + "v1_bound_accounts_cairo1": [] }, "os_resources": { "execute_syscalls": { diff --git a/crates/blockifier/resources/versioned_constants_0_13_1.json b/crates/blockifier/resources/versioned_constants_0_13_1.json index 5ce21c089c3..934d4356364 100644 --- a/crates/blockifier/resources/versioned_constants_0_13_1.json +++ b/crates/blockifier/resources/versioned_constants_0_13_1.json @@ -218,7 +218,9 @@ "range_check": 0, "syscall_base_gas_cost": 0 } - } + }, + "v1_bound_accounts_cairo0": [], + "v1_bound_accounts_cairo1": [] }, "os_resources": { "execute_syscalls": { diff --git a/crates/blockifier/resources/versioned_constants_0_13_1_1.json b/crates/blockifier/resources/versioned_constants_0_13_1_1.json index 4449b6a519a..c9530da04ab 100644 --- a/crates/blockifier/resources/versioned_constants_0_13_1_1.json +++ b/crates/blockifier/resources/versioned_constants_0_13_1_1.json @@ -218,7 +218,9 @@ "range_check": 0, "syscall_base_gas_cost": 0 } - } + }, + "v1_bound_accounts_cairo0": [], + "v1_bound_accounts_cairo1": [] }, "os_resources": { "execute_syscalls": { diff --git a/crates/blockifier/resources/versioned_constants_0_13_2.json b/crates/blockifier/resources/versioned_constants_0_13_2.json index c0c0b892f24..42d68cdd0d5 100644 --- a/crates/blockifier/resources/versioned_constants_0_13_2.json +++ b/crates/blockifier/resources/versioned_constants_0_13_2.json @@ -219,7 +219,9 @@ "step_gas_cost": 0, "syscall_base_gas_cost": 0 } - } + }, + "v1_bound_accounts_cairo0": [], + "v1_bound_accounts_cairo1": [] }, "os_resources": { "execute_syscalls": { diff --git a/crates/blockifier/resources/versioned_constants_0_13_2_1.json b/crates/blockifier/resources/versioned_constants_0_13_2_1.json index 0a90bd0a755..d3743e3e865 100644 --- a/crates/blockifier/resources/versioned_constants_0_13_2_1.json +++ b/crates/blockifier/resources/versioned_constants_0_13_2_1.json @@ -219,7 +219,9 @@ "step_gas_cost": 0, "syscall_base_gas_cost": 0 } - } + }, + "v1_bound_accounts_cairo0": [], + "v1_bound_accounts_cairo1": [] }, "os_resources": { "execute_syscalls": { diff --git a/crates/blockifier/resources/versioned_constants_0_13_3.json b/crates/blockifier/resources/versioned_constants_0_13_3.json index 4dab2471ab1..d3743e3e865 100644 --- a/crates/blockifier/resources/versioned_constants_0_13_3.json +++ b/crates/blockifier/resources/versioned_constants_0_13_3.json @@ -219,7 +219,9 @@ "step_gas_cost": 0, "syscall_base_gas_cost": 0 } - } + }, + "v1_bound_accounts_cairo0": [], + "v1_bound_accounts_cairo1": [] }, "os_resources": { "execute_syscalls": { @@ -658,4 +660,4 @@ 10000 ] } -} \ No newline at end of file +} diff --git a/crates/blockifier/resources/versioned_constants_0_13_4.json b/crates/blockifier/resources/versioned_constants_0_13_4.json index 8072d23852e..2429e644b53 100644 --- a/crates/blockifier/resources/versioned_constants_0_13_4.json +++ b/crates/blockifier/resources/versioned_constants_0_13_4.json @@ -117,7 +117,9 @@ "validate_block_number_rounding": 100, "validate_timestamp_rounding": 3600 }, - "validated": "VALID" + "validated": "VALID", + "v1_bound_accounts_cairo0": [], + "v1_bound_accounts_cairo1": [] }, "os_resources": { "execute_syscalls": { @@ -559,4 +561,4 @@ 10000 ] } -} \ No newline at end of file +} diff --git a/crates/blockifier/resources/versioned_constants_0_13_5.json b/crates/blockifier/resources/versioned_constants_0_13_5.json index 8072d23852e..cc64b09c93c 100644 --- a/crates/blockifier/resources/versioned_constants_0_13_5.json +++ b/crates/blockifier/resources/versioned_constants_0_13_5.json @@ -117,7 +117,13 @@ "validate_block_number_rounding": 100, "validate_timestamp_rounding": 3600 }, - "validated": "VALID" + "validated": "VALID", + "v1_bound_accounts_cairo0": [ + "0x01a7820094feaf82d53f53f214b81292d717e7bb9a92bb2488092cd306f3993f" + ], + "v1_bound_accounts_cairo1": [ + "0x04c6d6cf894f8bc96bb9c525e6853e5483177841f7388f74a46cfda6f028c755" + ] }, "os_resources": { "execute_syscalls": { @@ -559,4 +565,4 @@ 10000 ] } -} \ No newline at end of file +} diff --git a/crates/blockifier/src/concurrency/fee_utils_test.rs b/crates/blockifier/src/concurrency/fee_utils_test.rs index 4524ce34498..6ef938efe32 100644 --- a/crates/blockifier/src/concurrency/fee_utils_test.rs +++ b/crates/blockifier/src/concurrency/fee_utils_test.rs @@ -35,7 +35,7 @@ pub fn test_fill_sequencer_balance_reads( resource_bounds: default_all_resource_bounds, }); let chain_info = &block_context.chain_info; - let state = &mut test_state_inner(chain_info, BALANCE, &[(account, 1)], erc20_version); + let state = &mut test_state_inner(chain_info, BALANCE, &[(account.into(), 1)], erc20_version); let sequencer_balance = Fee(100); let sequencer_address = block_context.block_info.sequencer_address; diff --git a/crates/blockifier/src/context.rs b/crates/blockifier/src/context.rs index fdf6be73b2d..11f66891308 100644 --- a/crates/blockifier/src/context.rs +++ b/crates/blockifier/src/context.rs @@ -158,7 +158,7 @@ impl BlockContext { execute_max_gas: Option, validate_max_gas: Option, ) { - let mut new_os_constants = *self.versioned_constants.os_constants.clone(); + let mut new_os_constants = (*self.versioned_constants.os_constants).clone(); if let Some(execute_max_gas) = execute_max_gas { new_os_constants.execute_max_sierra_gas = execute_max_gas; } diff --git a/crates/blockifier/src/execution/contract_class.rs b/crates/blockifier/src/execution/contract_class.rs index d190b83c3ba..1b40de15035 100644 --- a/crates/blockifier/src/execution/contract_class.rs +++ b/crates/blockifier/src/execution/contract_class.rs @@ -31,7 +31,7 @@ use starknet_api::deprecated_contract_class::{ use starknet_types_core::felt::Felt; use crate::abi::constants::{self}; -use crate::execution::entry_point::{CallEntryPoint, EntryPointExecutionContext}; +use crate::execution::entry_point::{EntryPointExecutionContext, EntryPointTypeAndSelector}; use crate::execution::errors::PreExecutionError; use crate::execution::execution_utils::{poseidon_hash_many_cost, sn_api_to_cairo_vm_program}; #[cfg(feature = "cairo_native")] @@ -253,9 +253,9 @@ impl CompiledClassV1 { pub fn get_entry_point( &self, - call: &CallEntryPoint, + entry_point: &EntryPointTypeAndSelector, ) -> Result { - self.entry_points_by_type.get_entry_point(call) + self.entry_points_by_type.get_entry_point(entry_point) } /// Returns whether this contract should run using Cairo steps or Sierra gas. @@ -522,21 +522,24 @@ pub struct EntryPointsByType { } impl EntryPointsByType { - pub fn get_entry_point(&self, call: &CallEntryPoint) -> Result { - call.verify_constructor()?; + pub fn get_entry_point( + &self, + entry_point: &EntryPointTypeAndSelector, + ) -> Result { + entry_point.verify_constructor()?; - let entry_points_of_same_type = &self[call.entry_point_type]; + let entry_points_of_same_type = &self[entry_point.entry_point_type]; let filtered_entry_points: Vec<_> = entry_points_of_same_type .iter() - .filter(|ep| *ep.selector() == call.entry_point_selector) + .filter(|ep| *ep.selector() == entry_point.entry_point_selector) .collect(); match filtered_entry_points[..] { - [] => Err(PreExecutionError::EntryPointNotFound(call.entry_point_selector)), + [] => Err(PreExecutionError::EntryPointNotFound(entry_point.entry_point_selector)), [entry_point] => Ok(entry_point.clone()), _ => Err(PreExecutionError::DuplicatedEntryPointSelector { - selector: call.entry_point_selector, - typ: call.entry_point_type, + selector: entry_point.entry_point_selector, + typ: entry_point.entry_point_type, }), } } diff --git a/crates/blockifier/src/execution/deprecated_entry_point_execution.rs b/crates/blockifier/src/execution/deprecated_entry_point_execution.rs index 0f7560aca69..f0a6ced784e 100644 --- a/crates/blockifier/src/execution/deprecated_entry_point_execution.rs +++ b/crates/blockifier/src/execution/deprecated_entry_point_execution.rs @@ -16,9 +16,9 @@ use crate::execution::call_info::{CallExecution, CallInfo}; use crate::execution::contract_class::{CompiledClassV0, TrackedResource}; use crate::execution::deprecated_syscalls::hint_processor::DeprecatedSyscallHintProcessor; use crate::execution::entry_point::{ - CallEntryPoint, EntryPointExecutionContext, EntryPointExecutionResult, + ExecutableCallEntryPoint, }; use crate::execution::errors::{PostExecutionError, PreExecutionError}; use crate::execution::execution_utils::{read_execution_retdata, Args, ReadOnlySegments}; @@ -42,7 +42,7 @@ pub const CAIRO0_BUILTINS_NAMES: [BuiltinName; 6] = [ /// Executes a specific call to a contract entry point and returns its output. pub fn execute_entry_point_call( - call: CallEntryPoint, + call: ExecutableCallEntryPoint, compiled_class: CompiledClassV0, state: &mut dyn State, context: &mut EntryPointExecutionContext, @@ -65,7 +65,7 @@ pub fn execute_entry_point_call( } pub fn initialize_execution_context<'a>( - call: &CallEntryPoint, + call: &ExecutableCallEntryPoint, compiled_class: CompiledClassV0, state: &'a mut dyn State, context: &'a mut EntryPointExecutionContext, @@ -102,13 +102,14 @@ pub fn initialize_execution_context<'a>( initial_syscall_ptr, call.storage_address, call.caller_address, + call.class_hash, ); Ok(VmExecutionContext { runner, syscall_handler, initial_syscall_ptr, entry_point_pc }) } pub fn resolve_entry_point_pc( - call: &CallEntryPoint, + call: &ExecutableCallEntryPoint, compiled_class: &CompiledClassV0, ) -> Result { if call.entry_point_type == EntryPointType::Constructor @@ -156,7 +157,7 @@ pub fn resolve_entry_point_pc( } pub fn prepare_call_arguments( - call: &CallEntryPoint, + call: &ExecutableCallEntryPoint, runner: &mut CairoRunner, initial_syscall_ptr: Relocatable, read_only_segments: &mut ReadOnlySegments, @@ -217,7 +218,7 @@ pub fn run_entry_point( pub fn finalize_execution( mut runner: CairoRunner, syscall_handler: DeprecatedSyscallHintProcessor<'_>, - call: CallEntryPoint, + call: ExecutableCallEntryPoint, implicit_args: Vec, n_total_args: usize, ) -> Result { @@ -257,7 +258,7 @@ pub fn finalize_execution( + &CallInfo::summarize_vm_resources(syscall_handler.inner_calls.iter()); Ok(CallInfo { - call, + call: call.into(), execution: CallExecution { retdata: read_execution_retdata(&runner, retdata_size, &retdata_ptr)?, events: syscall_handler.events, diff --git a/crates/blockifier/src/execution/deprecated_syscalls/deprecated_syscalls_test.rs b/crates/blockifier/src/execution/deprecated_syscalls/deprecated_syscalls_test.rs index 9dc2a7c04cf..fb9537a9557 100644 --- a/crates/blockifier/src/execution/deprecated_syscalls/deprecated_syscalls_test.rs +++ b/crates/blockifier/src/execution/deprecated_syscalls/deprecated_syscalls_test.rs @@ -34,8 +34,8 @@ use crate::execution::entry_point::{CallEntryPoint, CallType}; use crate::execution::errors::EntryPointExecutionError; use crate::execution::syscalls::hint_processor::EmitEventError; use crate::state::state_api::StateReader; -use crate::test_utils::contracts::FeatureContract; -use crate::test_utils::initial_test_state::test_state; +use crate::test_utils::contracts::{FeatureContract, FeatureContractData}; +use crate::test_utils::initial_test_state::{test_state, test_state_ex}; use crate::test_utils::{ calldata_for_deploy_test, get_syscall_resources, @@ -452,20 +452,34 @@ fn test_block_info_syscalls( } #[rstest] -fn test_tx_info(#[values(false, true)] only_query: bool) { +fn test_tx_info( + #[values(false, true)] only_query: bool, + #[values(false, true)] v1_bound_account: bool, +) { let test_contract = FeatureContract::TestContract(CairoVersion::Cairo0); - let mut state = test_state(&ChainInfo::create_for_testing(), Fee(0), &[(test_contract, 1)]); - let mut version = felt!(1_u8); + let mut test_contract_data: FeatureContractData = test_contract.into(); + if v1_bound_account { + let optional_class_hash = + VersionedConstants::latest_constants().os_constants.v1_bound_accounts_cairo0.first(); + test_contract_data.class_hash = + *optional_class_hash.expect("No v1 bound accounts found in versioned constants."); + } + + let mut state = + test_state_ex(&ChainInfo::create_for_testing(), Fee(0), &[(test_contract_data, 1)]); + let mut version = felt!(3_u8); + let mut expected_version = if v1_bound_account { felt!(1_u8) } else { version }; if only_query { let simulate_version_base = *QUERY_VERSION_BASE; version += simulate_version_base; + expected_version += simulate_version_base; } let tx_hash = tx_hash!(1991); let max_fee = Fee(0); let nonce = nonce!(3_u16); let sender_address = test_contract.get_instance_address(0); let expected_tx_info = calldata![ - version, // Transaction version. + expected_version, // Transaction version. *sender_address.0.key(), // Account address. felt!(max_fee.0), // Max fee. tx_hash.0, // Transaction hash. @@ -481,7 +495,7 @@ fn test_tx_info(#[values(false, true)] only_query: bool) { let tx_info = TransactionInfo::Deprecated(DeprecatedTransactionInfo { common_fields: CommonAccountFields { transaction_hash: tx_hash, - version: TransactionVersion::ONE, + version: TransactionVersion::THREE, nonce, sender_address, only_query, diff --git a/crates/blockifier/src/execution/deprecated_syscalls/hint_processor.rs b/crates/blockifier/src/execution/deprecated_syscalls/hint_processor.rs index 3521fdfcf2c..a193665b6b6 100644 --- a/crates/blockifier/src/execution/deprecated_syscalls/hint_processor.rs +++ b/crates/blockifier/src/execution/deprecated_syscalls/hint_processor.rs @@ -22,6 +22,7 @@ use starknet_api::contract_class::EntryPointType; use starknet_api::core::{ClassHash, ContractAddress, EntryPointSelector}; use starknet_api::state::StorageKey; use starknet_api::transaction::fields::Calldata; +use starknet_api::transaction::{signed_tx_version, TransactionOptions, TransactionVersion}; use starknet_api::StarknetApiError; use starknet_types_core::felt::{Felt, FromStrError}; use thiserror::Error; @@ -164,6 +165,7 @@ pub struct DeprecatedSyscallHintProcessor<'a> { pub context: &'a mut EntryPointExecutionContext, pub storage_address: ContractAddress, pub caller_address: ContractAddress, + pub class_hash: ClassHash, // Execution results. /// Inner calls invoked by the current execution. @@ -195,12 +197,14 @@ impl<'a> DeprecatedSyscallHintProcessor<'a> { initial_syscall_ptr: Relocatable, storage_address: ContractAddress, caller_address: ContractAddress, + class_hash: ClassHash, ) -> Self { DeprecatedSyscallHintProcessor { state, context, storage_address, caller_address, + class_hash, inner_calls: vec![], events: vec![], l2_to_l1_messages: vec![], @@ -317,10 +321,28 @@ impl<'a> DeprecatedSyscallHintProcessor<'a> { &mut self, vm: &mut VirtualMachine, ) -> DeprecatedSyscallResult { + let tx_context = &self.context.tx_context; + // The transaction version, ignoring the only_query bit. + let version = tx_context.tx_info.version(); + let versioned_constants = &tx_context.block_context.versioned_constants; + // The set of v1-bound-accounts. + let v1_bound_accounts = &versioned_constants.os_constants.v1_bound_accounts_cairo0; + + // If the transaction version is 3 and the account is in the v1-bound-accounts set, + // the syscall should return transaction version 1 instead. + // In such a case, `self.tx_info_start_ptr` is not used. + if version == TransactionVersion::THREE && v1_bound_accounts.contains(&self.class_hash) { + let modified_version = signed_tx_version( + &TransactionVersion::ONE, + &TransactionOptions { only_query: tx_context.tx_info.only_query() }, + ); + return self.allocate_tx_info_segment(vm, Some(modified_version)); + } + match self.tx_info_start_ptr { Some(tx_info_start_ptr) => Ok(tx_info_start_ptr), None => { - let tx_info_start_ptr = self.allocate_tx_info_segment(vm)?; + let tx_info_start_ptr = self.allocate_tx_info_segment(vm, None)?; self.tx_info_start_ptr = Some(tx_info_start_ptr); Ok(tx_info_start_ptr) } @@ -372,15 +394,20 @@ impl<'a> DeprecatedSyscallHintProcessor<'a> { Ok(signature_segment_start_ptr) } + /// Allocates and populates a segment with the transaction info. + /// + /// If `tx_version` is given, it will be used instead of the real value. fn allocate_tx_info_segment( &mut self, vm: &mut VirtualMachine, + tx_version_override: Option, ) -> DeprecatedSyscallResult { let tx_signature_start_ptr = self.get_or_allocate_tx_signature_segment(vm)?; let TransactionContext { block_context, tx_info } = self.context.tx_context.as_ref(); let tx_signature_length = tx_info.signature().0.len(); + let tx_version = tx_version_override.unwrap_or(tx_info.signed_version()); let tx_info: Vec = vec![ - tx_info.signed_version().0.into(), + tx_version.0.into(), (*tx_info.sender_address().0.key()).into(), Felt::from(tx_info.max_fee_for_execution_info_syscall().0).into(), tx_signature_length.into(), diff --git a/crates/blockifier/src/execution/entry_point.rs b/crates/blockifier/src/execution/entry_point.rs index c3b23fd5f60..afdc90981b0 100644 --- a/crates/blockifier/src/execution/entry_point.rs +++ b/crates/blockifier/src/execution/entry_point.rs @@ -93,12 +93,35 @@ pub enum CallType { Call = 0, Delegate = 1, } + +pub struct EntryPointTypeAndSelector { + pub entry_point_type: EntryPointType, + pub entry_point_selector: EntryPointSelector, +} + +impl EntryPointTypeAndSelector { + pub fn verify_constructor(&self) -> Result<(), PreExecutionError> { + if self.entry_point_type == EntryPointType::Constructor + && self.entry_point_selector != selector_from_name(CONSTRUCTOR_ENTRY_POINT_NAME) + { + Err(PreExecutionError::InvalidConstructorEntryPointName) + } else { + Ok(()) + } + } +} + /// Represents a call to an entry point of a Starknet contract. #[cfg_attr(feature = "transaction_serde", derive(serde::Deserialize))] #[derive(Clone, Debug, Default, Eq, PartialEq, Serialize)] -pub struct CallEntryPoint { - // The class hash is not given if it can be deduced from the storage address. - pub class_hash: Option, +pub struct CallEntryPointVariant { + /// The class hash of the entry point. + /// The type is `ClassHash` in the case of [ExecutableCallEntryPoint] and `Option` + /// in the case of [CallEntryPoint]. + /// + /// The class hash is not given if it can be deduced from the storage address. + /// It is resolved prior to entry point's execution. + pub class_hash: TClassHash, // Optional, since there is no address to the code implementation in a library call. // and for outermost calls (triggered by the transaction itself). // TODO: BACKWARD-COMPATIBILITY. @@ -113,6 +136,25 @@ pub struct CallEntryPoint { pub initial_gas: u64, } +pub type CallEntryPoint = CallEntryPointVariant>; +pub type ExecutableCallEntryPoint = CallEntryPointVariant; + +impl From for CallEntryPoint { + fn from(call: ExecutableCallEntryPoint) -> Self { + Self { + class_hash: Some(call.class_hash), + code_address: call.code_address, + entry_point_type: call.entry_point_type, + entry_point_selector: call.entry_point_selector, + calldata: call.calldata, + storage_address: call.storage_address, + caller_address: call.caller_address, + call_type: call.call_type, + initial_gas: call.initial_gas, + } + } +} + impl CallEntryPoint { pub fn execute( mut self, @@ -158,7 +200,13 @@ impl CallEntryPoint { )); // This is the last operation of this function. - execute_entry_point_call_wrapper(self, compiled_class, state, context, remaining_gas) + execute_entry_point_call_wrapper( + self.into_executable(class_hash), + compiled_class, + state, + context, + remaining_gas, + ) } /// Similar to `execute`, but returns an error if the outer call is reverted. @@ -190,13 +238,26 @@ impl CallEntryPoint { execution_result } - pub fn verify_constructor(&self) -> Result<(), PreExecutionError> { - if self.entry_point_type == EntryPointType::Constructor - && self.entry_point_selector != selector_from_name(CONSTRUCTOR_ENTRY_POINT_NAME) - { - Err(PreExecutionError::InvalidConstructorEntryPointName) - } else { - Ok(()) + fn into_executable(self, class_hash: ClassHash) -> ExecutableCallEntryPoint { + ExecutableCallEntryPoint { + class_hash, + code_address: self.code_address, + entry_point_type: self.entry_point_type, + entry_point_selector: self.entry_point_selector, + calldata: self.calldata, + storage_address: self.storage_address, + caller_address: self.caller_address, + call_type: self.call_type, + initial_gas: self.initial_gas, + } + } +} + +impl ExecutableCallEntryPoint { + pub fn type_and_selector(&self) -> EntryPointTypeAndSelector { + EntryPointTypeAndSelector { + entry_point_type: self.entry_point_type, + entry_point_selector: self.entry_point_selector, } } } diff --git a/crates/blockifier/src/execution/entry_point_execution.rs b/crates/blockifier/src/execution/entry_point_execution.rs index 3fde0bf7c8c..e40ec754ebf 100644 --- a/crates/blockifier/src/execution/entry_point_execution.rs +++ b/crates/blockifier/src/execution/entry_point_execution.rs @@ -13,9 +13,9 @@ use starknet_types_core::felt::Felt; use crate::execution::call_info::{CallExecution, CallInfo, Retdata}; use crate::execution::contract_class::{CompiledClassV1, EntryPointV1, TrackedResource}; use crate::execution::entry_point::{ - CallEntryPoint, EntryPointExecutionContext, EntryPointExecutionResult, + ExecutableCallEntryPoint, }; use crate::execution::errors::{EntryPointExecutionError, PostExecutionError, PreExecutionError}; use crate::execution::execution_utils::{ @@ -53,7 +53,7 @@ pub struct CallResult { /// Executes a specific call to a contract entry point and returns its output. pub fn execute_entry_point_call( - call: CallEntryPoint, + call: ExecutableCallEntryPoint, compiled_class: CompiledClassV1, state: &mut dyn State, context: &mut EntryPointExecutionContext, @@ -96,12 +96,12 @@ pub fn execute_entry_point_call( } pub fn initialize_execution_context<'a>( - call: CallEntryPoint, + call: ExecutableCallEntryPoint, compiled_class: &'a CompiledClassV1, state: &'a mut dyn State, context: &'a mut EntryPointExecutionContext, ) -> Result, PreExecutionError> { - let entry_point = compiled_class.get_entry_point(&call)?; + let entry_point = compiled_class.get_entry_point(&call.type_and_selector())?; // Instantiate Cairo runner. let proof_mode = false; @@ -178,7 +178,7 @@ fn prepare_program_extra_data( } pub fn prepare_call_arguments( - call: &CallEntryPoint, + call: &ExecutableCallEntryPoint, runner: &mut CairoRunner, initial_syscall_ptr: Relocatable, read_only_segments: &mut ReadOnlySegments, @@ -376,7 +376,7 @@ pub fn finalize_execution( + &CallInfo::summarize_vm_resources(syscall_handler.base.inner_calls.iter()); let syscall_handler_base = syscall_handler.base; Ok(CallInfo { - call: syscall_handler_base.call, + call: syscall_handler_base.call.into(), execution: CallExecution { retdata: call_result.retdata, events: syscall_handler_base.events, diff --git a/crates/blockifier/src/execution/execution_utils.rs b/crates/blockifier/src/execution/execution_utils.rs index c04054ba46e..7dfc38fa694 100644 --- a/crates/blockifier/src/execution/execution_utils.rs +++ b/crates/blockifier/src/execution/execution_utils.rs @@ -25,11 +25,11 @@ use crate::execution::call_info::{CallExecution, CallInfo, Retdata}; use crate::execution::contract_class::{RunnableCompiledClass, TrackedResource}; use crate::execution::entry_point::{ execute_constructor_entry_point, - CallEntryPoint, ConstructorContext, ConstructorEntryPointExecutionResult, EntryPointExecutionContext, EntryPointExecutionResult, + ExecutableCallEntryPoint, }; use crate::execution::errors::{ ConstructorEntryPointExecutionError, @@ -51,7 +51,7 @@ pub const SEGMENT_ARENA_BUILTIN_SIZE: usize = 3; /// A wrapper for execute_entry_point_call that performs pre and post-processing. pub fn execute_entry_point_call_wrapper( - mut call: CallEntryPoint, + mut call: ExecutableCallEntryPoint, compiled_class: RunnableCompiledClass, state: &mut dyn State, context: &mut EntryPointExecutionContext, @@ -93,7 +93,7 @@ pub fn execute_entry_point_call_wrapper( _ => return Err(err.into()), }; Ok(CallInfo { - call: orig_call, + call: orig_call.into(), execution: CallExecution { retdata: Retdata(vec![Felt::from_hex(error_code).unwrap()]), failed: true, @@ -110,7 +110,7 @@ pub fn execute_entry_point_call_wrapper( /// Executes a specific call to a contract entry point and returns its output. pub fn execute_entry_point_call( - call: CallEntryPoint, + call: ExecutableCallEntryPoint, compiled_class: RunnableCompiledClass, state: &mut dyn State, context: &mut EntryPointExecutionContext, diff --git a/crates/blockifier/src/execution/native/contract_class.rs b/crates/blockifier/src/execution/native/contract_class.rs index 6139e02fcaf..d757538d96d 100644 --- a/crates/blockifier/src/execution/native/contract_class.rs +++ b/crates/blockifier/src/execution/native/contract_class.rs @@ -5,7 +5,7 @@ use cairo_native::executor::AotContractExecutor; use starknet_api::core::EntryPointSelector; use crate::execution::contract_class::{CompiledClassV1, EntryPointV1}; -use crate::execution::entry_point::CallEntryPoint; +use crate::execution::entry_point::EntryPointTypeAndSelector; use crate::execution::errors::PreExecutionError; #[derive(Clone, Debug, PartialEq, Eq)] pub struct NativeCompiledClassV1(pub Arc); @@ -34,9 +34,9 @@ impl NativeCompiledClassV1 { pub fn get_entry_point( &self, - call: &CallEntryPoint, + entry_point: &EntryPointTypeAndSelector, ) -> Result { - self.casm.get_entry_point(call) + self.casm.get_entry_point(entry_point) } pub fn casm(&self) -> CompiledClassV1 { diff --git a/crates/blockifier/src/execution/native/entry_point_execution.rs b/crates/blockifier/src/execution/native/entry_point_execution.rs index 564d188d677..e5581c9a4d7 100644 --- a/crates/blockifier/src/execution/native/entry_point_execution.rs +++ b/crates/blockifier/src/execution/native/entry_point_execution.rs @@ -4,9 +4,9 @@ use cairo_native::utils::BuiltinCosts; use crate::execution::call_info::{CallExecution, CallInfo, Retdata}; use crate::execution::contract_class::TrackedResource; use crate::execution::entry_point::{ - CallEntryPoint, EntryPointExecutionContext, EntryPointExecutionResult, + ExecutableCallEntryPoint, }; use crate::execution::errors::{EntryPointExecutionError, PostExecutionError, PreExecutionError}; use crate::execution::native::contract_class::NativeCompiledClassV1; @@ -15,12 +15,12 @@ use crate::state::state_api::State; // todo(rodrigo): add an `entry point not found` test for Native pub fn execute_entry_point_call( - call: CallEntryPoint, + call: ExecutableCallEntryPoint, compiled_class: NativeCompiledClassV1, state: &mut dyn State, context: &mut EntryPointExecutionContext, ) -> EntryPointExecutionResult { - let entry_point = compiled_class.get_entry_point(&call)?; + let entry_point = compiled_class.get_entry_point(&call.type_and_selector())?; let mut syscall_handler: NativeSyscallHandler<'_> = NativeSyscallHandler::new(call, state, context); @@ -87,7 +87,7 @@ fn create_callinfo( let vm_resources = CallInfo::summarize_vm_resources(syscall_handler.base.inner_calls.iter()); Ok(CallInfo { - call: syscall_handler.base.call, + call: syscall_handler.base.call.into(), execution: CallExecution { retdata: Retdata(call_result.return_values), events: syscall_handler.base.events, diff --git a/crates/blockifier/src/execution/native/syscall_handler.rs b/crates/blockifier/src/execution/native/syscall_handler.rs index 73b8ebfd3ff..0de8ed07945 100644 --- a/crates/blockifier/src/execution/native/syscall_handler.rs +++ b/crates/blockifier/src/execution/native/syscall_handler.rs @@ -27,7 +27,12 @@ use starknet_types_core::felt::Felt; use crate::execution::call_info::{MessageToL1, Retdata}; use crate::execution::common_hints::ExecutionMode; -use crate::execution::entry_point::{CallEntryPoint, CallType, EntryPointExecutionContext}; +use crate::execution::entry_point::{ + CallEntryPoint, + CallType, + EntryPointExecutionContext, + ExecutableCallEntryPoint, +}; use crate::execution::errors::EntryPointExecutionError; use crate::execution::native::utils::{calculate_resource_bounds, default_tx_v2_info}; use crate::execution::secp; @@ -48,7 +53,7 @@ pub struct NativeSyscallHandler<'state> { impl<'state> NativeSyscallHandler<'state> { pub fn new( - call: CallEntryPoint, + call: ExecutableCallEntryPoint, state: &'state mut dyn State, context: &'state mut EntryPointExecutionContext, ) -> NativeSyscallHandler<'state> { @@ -166,7 +171,7 @@ impl<'state> NativeSyscallHandler<'state> { fn get_tx_info_v1(&self) -> TxInfo { let tx_info = &self.base.context.tx_context.tx_info; TxInfo { - version: tx_info.signed_version().0, + version: self.base.tx_version_for_get_execution_info().0, account_contract_address: Felt::from(tx_info.sender_address()), max_fee: tx_info.max_fee_for_execution_info_syscall().0, signature: tx_info.signature().0, @@ -196,7 +201,7 @@ impl<'state> NativeSyscallHandler<'state> { fn get_tx_info_v2(&self) -> SyscallResult { let tx_info = &self.base.context.tx_context.tx_info; let native_tx_info = TxV2Info { - version: tx_info.signed_version().0, + version: self.base.tx_version_for_get_execution_info().0, account_contract_address: Felt::from(tx_info.sender_address()), max_fee: tx_info.max_fee_for_execution_info_syscall().0, signature: tx_info.signature().0, diff --git a/crates/blockifier/src/execution/syscalls/hint_processor.rs b/crates/blockifier/src/execution/syscalls/hint_processor.rs index 65825bdb376..6350eed111d 100644 --- a/crates/blockifier/src/execution/syscalls/hint_processor.rs +++ b/crates/blockifier/src/execution/syscalls/hint_processor.rs @@ -21,6 +21,7 @@ use starknet_api::transaction::fields::{ Resource, ValidResourceBounds, }; +use starknet_api::transaction::TransactionVersion; use starknet_api::StarknetApiError; use starknet_types_core::felt::{Felt, FromStrError}; use thiserror::Error; @@ -28,7 +29,11 @@ use thiserror::Error; use crate::abi::sierra_types::SierraTypeError; use crate::execution::common_hints::{ExecutionMode, HintExecutionResult}; use crate::execution::contract_class::TrackedResource; -use crate::execution::entry_point::{CallEntryPoint, EntryPointExecutionContext}; +use crate::execution::entry_point::{ + CallEntryPoint, + EntryPointExecutionContext, + ExecutableCallEntryPoint, +}; use crate::execution::errors::{ConstructorEntryPointExecutionError, EntryPointExecutionError}; use crate::execution::execution_utils::{ felt_from_ptr, @@ -255,7 +260,7 @@ impl<'a> SyscallHintProcessor<'a> { state: &'a mut dyn State, context: &'a mut EntryPointExecutionContext, initial_syscall_ptr: Relocatable, - call: CallEntryPoint, + call: ExecutableCallEntryPoint, hints: &'a HashMap, read_only_segments: ReadOnlySegments, ) -> Self { @@ -280,6 +285,10 @@ impl<'a> SyscallHintProcessor<'a> { self.base.call.caller_address } + pub fn class_hash(&self) -> ClassHash { + self.base.call.class_hash + } + pub fn entry_point_selector(&self) -> EntryPointSelector { self.base.call.entry_point_selector } @@ -413,10 +422,19 @@ impl<'a> SyscallHintProcessor<'a> { &mut self, vm: &mut VirtualMachine, ) -> SyscallResult { + let returned_version = self.base.tx_version_for_get_execution_info(); + let original_version = self.base.context.tx_context.tx_info.signed_version(); + + // If the transaction version was overridden, `self.execution_info_ptr` cannot be used. + if returned_version != original_version { + return self.allocate_execution_info_segment(vm, returned_version); + } + match self.execution_info_ptr { Some(execution_info_ptr) => Ok(execution_info_ptr), None => { - let execution_info_ptr = self.allocate_execution_info_segment(vm)?; + let execution_info_ptr = + self.allocate_execution_info_segment(vm, original_version)?; self.execution_info_ptr = Some(execution_info_ptr); Ok(execution_info_ptr) } @@ -541,9 +559,10 @@ impl<'a> SyscallHintProcessor<'a> { fn allocate_execution_info_segment( &mut self, vm: &mut VirtualMachine, + tx_version_override: TransactionVersion, ) -> SyscallResult { let block_info_ptr = self.allocate_block_info_segment(vm)?; - let tx_info_ptr = self.allocate_tx_info_segment(vm)?; + let tx_info_ptr = self.allocate_tx_info_segment(vm, tx_version_override)?; let additional_info: Vec = vec![ block_info_ptr.into(), @@ -589,13 +608,17 @@ impl<'a> SyscallHintProcessor<'a> { Ok((data_segment_start_ptr, data_segment_end_ptr)) } - fn allocate_tx_info_segment(&mut self, vm: &mut VirtualMachine) -> SyscallResult { + fn allocate_tx_info_segment( + &mut self, + vm: &mut VirtualMachine, + tx_version_override: TransactionVersion, + ) -> SyscallResult { let tx_info = &self.base.context.tx_context.clone().tx_info; let (tx_signature_start_ptr, tx_signature_end_ptr) = &self.allocate_data_segment(vm, &tx_info.signature().0)?; let mut tx_data: Vec = vec![ - tx_info.signed_version().0.into(), + tx_version_override.0.into(), tx_info.sender_address().0.key().into(), Felt::from(tx_info.max_fee_for_execution_info_syscall().0).into(), tx_signature_start_ptr.into(), diff --git a/crates/blockifier/src/execution/syscalls/syscall_base.rs b/crates/blockifier/src/execution/syscalls/syscall_base.rs index 8a092a9aecf..dfeb70b12d7 100644 --- a/crates/blockifier/src/execution/syscalls/syscall_base.rs +++ b/crates/blockifier/src/execution/syscalls/syscall_base.rs @@ -5,7 +5,12 @@ use std::convert::From; use starknet_api::core::{calculate_contract_address, ClassHash, ContractAddress}; use starknet_api::state::StorageKey; use starknet_api::transaction::fields::{Calldata, ContractAddressSalt}; -use starknet_api::transaction::EventContent; +use starknet_api::transaction::{ + signed_tx_version, + EventContent, + TransactionOptions, + TransactionVersion, +}; use starknet_types_core::felt::Felt; use super::exceeds_event_size_limit; @@ -16,6 +21,7 @@ use crate::execution::entry_point::{ CallEntryPoint, ConstructorContext, EntryPointExecutionContext, + ExecutableCallEntryPoint, }; use crate::execution::execution_utils::execute_deployment; use crate::execution::syscalls::hint_processor::{ @@ -35,7 +41,7 @@ pub struct SyscallHandlerBase<'state> { // Input for execution. pub state: &'state mut dyn State, pub context: &'state mut EntryPointExecutionContext, - pub call: CallEntryPoint, + pub call: ExecutableCallEntryPoint, // Execution results. pub events: Vec, @@ -58,7 +64,7 @@ pub struct SyscallHandlerBase<'state> { impl<'state> SyscallHandlerBase<'state> { pub fn new( - call: CallEntryPoint, + call: ExecutableCallEntryPoint, state: &'state mut dyn State, context: &'state mut EntryPointExecutionContext, ) -> SyscallHandlerBase<'state> { @@ -173,6 +179,28 @@ impl<'state> SyscallHandlerBase<'state> { Ok(class_hash) } + /// Returns the transaction version for the `get_execution_info` syscall. + pub fn tx_version_for_get_execution_info(&self) -> TransactionVersion { + let tx_context = &self.context.tx_context; + // The transaction version, ignoring the only_query bit. + let version = tx_context.tx_info.version(); + let versioned_constants = &tx_context.block_context.versioned_constants; + // The set of v1-bound-accounts. + let v1_bound_accounts = &versioned_constants.os_constants.v1_bound_accounts_cairo1; + let class_hash = &self.call.class_hash; + + // If the transaction version is 3 and the account is in the v1-bound-accounts set, + // the syscall should return transaction version 1 instead. + if version == TransactionVersion::THREE && v1_bound_accounts.contains(class_hash) { + signed_tx_version( + &TransactionVersion::ONE, + &TransactionOptions { only_query: tx_context.tx_info.only_query() }, + ) + } else { + tx_context.tx_info.signed_version() + } + } + pub fn emit_event(&mut self, event: EventContent) -> SyscallResult<()> { exceeds_event_size_limit( self.context.versioned_constants(), diff --git a/crates/blockifier/src/execution/syscalls/syscall_tests/get_execution_info.rs b/crates/blockifier/src/execution/syscalls/syscall_tests/get_execution_info.rs index 82fa77c33cd..de1cabc8ecb 100644 --- a/crates/blockifier/src/execution/syscalls/syscall_tests/get_execution_info.rs +++ b/crates/blockifier/src/execution/syscalls/syscall_tests/get_execution_info.rs @@ -28,8 +28,8 @@ use test_case::test_case; use crate::context::ChainInfo; use crate::execution::common_hints::ExecutionMode; use crate::execution::entry_point::CallEntryPoint; -use crate::test_utils::contracts::FeatureContract; -use crate::test_utils::initial_test_state::test_state; +use crate::test_utils::contracts::{FeatureContract, FeatureContractData}; +use crate::test_utils::initial_test_state::test_state_ex; use crate::test_utils::{ trivial_external_entry_point_with_address, CairoVersion, @@ -42,6 +42,7 @@ use crate::transaction::objects::{ DeprecatedTransactionInfo, TransactionInfo, }; +use crate::versioned_constants::VersionedConstants; #[cfg_attr( feature = "cairo_native", @@ -49,6 +50,7 @@ use crate::transaction::objects::{ FeatureContract::SierraExecutionInfoV1Contract(RunnableCairo1::Native), ExecutionMode::Validate, TransactionVersion::ONE, + false, false; "Native: Validate execution mode: block info fields should be zeroed. Transaction V1." ) @@ -59,6 +61,7 @@ use crate::transaction::objects::{ FeatureContract::SierraExecutionInfoV1Contract(RunnableCairo1::Native), ExecutionMode::Execute, TransactionVersion::ONE, + false, false; "Native: Execute execution mode: block info should be as usual. Transaction V1." ) @@ -69,6 +72,7 @@ use crate::transaction::objects::{ FeatureContract::TestContract(CairoVersion::Cairo1(RunnableCairo1::Native)), ExecutionMode::Validate, TransactionVersion::THREE, + false, false; "Native: Validate execution mode: block info fields should be zeroed. Transaction V3." ) @@ -79,6 +83,7 @@ use crate::transaction::objects::{ FeatureContract::TestContract(CairoVersion::Cairo1(RunnableCairo1::Native)), ExecutionMode::Execute, TransactionVersion::THREE, + false, false; "Native: Execute execution mode: block info should be as usual. Transaction V3." ) @@ -89,8 +94,10 @@ use crate::transaction::objects::{ FeatureContract::LegacyTestContract, ExecutionMode::Execute, TransactionVersion::ONE, + false, false; - "Native: Legacy contract. Execute execution mode: block info should be as usual. Transaction V1." + "Native: Legacy contract. Execute execution mode: block info should be as usual. Transaction + V1." ) )] #[cfg_attr( @@ -99,8 +106,10 @@ use crate::transaction::objects::{ FeatureContract::LegacyTestContract, ExecutionMode::Execute, TransactionVersion::THREE, + false, false; - "Native: Legacy contract. Execute execution mode: block info should be as usual. Transaction V3." + "Native: Legacy contract. Execute execution mode: block info should be as usual. Transaction + V3." ) )] #[cfg_attr( @@ -109,59 +118,112 @@ use crate::transaction::objects::{ FeatureContract::TestContract(CairoVersion::Cairo1(RunnableCairo1::Native)), ExecutionMode::Execute, TransactionVersion::THREE, - true; + true, + false; "Native: Execute execution mode: block info should be as usual. Transaction V3. Query" ) )] +#[cfg_attr( + feature = "cairo_native", + test_case( + FeatureContract::TestContract(CairoVersion::Cairo1(RunnableCairo1::Native)), + ExecutionMode::Execute, + TransactionVersion::THREE, + false, + true; + "Native: V1 bound account: execute" + ) +)] +#[cfg_attr( + feature = "cairo_native", + test_case( + FeatureContract::TestContract(CairoVersion::Cairo1(RunnableCairo1::Native)), + ExecutionMode::Execute, + TransactionVersion::THREE, + true, + true; + "Native: V1 bound account: query" + ) +)] #[test_case( FeatureContract::TestContract(CairoVersion::Cairo1(RunnableCairo1::Casm)), ExecutionMode::Validate, TransactionVersion::ONE, + false, false; "Validate execution mode: block info fields should be zeroed. Transaction V1.")] #[test_case( FeatureContract::TestContract(CairoVersion::Cairo1(RunnableCairo1::Casm)), ExecutionMode::Execute, TransactionVersion::ONE, + false, false; "Execute execution mode: block info should be as usual. Transaction V1.")] #[test_case( FeatureContract::TestContract(CairoVersion::Cairo1(RunnableCairo1::Casm)), ExecutionMode::Validate, TransactionVersion::THREE, + false, false; "Validate execution mode: block info fields should be zeroed. Transaction V3.")] #[test_case( FeatureContract::TestContract(CairoVersion::Cairo1(RunnableCairo1::Casm)), ExecutionMode::Execute, TransactionVersion::THREE, + false, false; "Execute execution mode: block info should be as usual. Transaction V3.")] #[test_case( FeatureContract::LegacyTestContract, ExecutionMode::Execute, TransactionVersion::ONE, + false, false; "Legacy contract. Execute execution mode: block info should be as usual. Transaction V1.")] #[test_case( FeatureContract::LegacyTestContract, ExecutionMode::Execute, TransactionVersion::THREE, + false, false; "Legacy contract. Execute execution mode: block info should be as usual. Transaction V3.")] #[test_case( FeatureContract::TestContract(CairoVersion::Cairo1(RunnableCairo1::Casm)), ExecutionMode::Execute, TransactionVersion::THREE, - true; + true, + false; "Execute execution mode: block info should be as usual. Transaction V3. Query.")] +#[test_case( + FeatureContract::TestContract(CairoVersion::Cairo1(RunnableCairo1::Casm)), + ExecutionMode::Execute, + TransactionVersion::THREE, + false, + true; + "V1 bound account: execute")] +#[test_case( + FeatureContract::TestContract(CairoVersion::Cairo1(RunnableCairo1::Casm)), + ExecutionMode::Execute, + TransactionVersion::THREE, + true, + true; + "V1 bound account: query")] fn test_get_execution_info( test_contract: FeatureContract, execution_mode: ExecutionMode, mut version: TransactionVersion, only_query: bool, + v1_bound_account: bool, ) { - let state = &mut test_state(&ChainInfo::create_for_testing(), BALANCE, &[(test_contract, 1)]); + let mut test_contract_data: FeatureContractData = test_contract.into(); + if v1_bound_account { + let optional_class_hash = + VersionedConstants::latest_constants().os_constants.v1_bound_accounts_cairo1.first(); + test_contract_data.class_hash = + *optional_class_hash.expect("No v1 bound accounts found in versioned constants."); + } + let state = + &mut test_state_ex(&ChainInfo::create_for_testing(), BALANCE, &[(test_contract_data, 1)]); let expected_block_info = match execution_mode { ExecutionMode::Validate => [ // Rounded block number. @@ -207,10 +269,12 @@ fn test_get_execution_info( } }; + let mut expected_version = if v1_bound_account { 1.into() } else { version.0 }; if only_query { let simulate_version_base = *QUERY_VERSION_BASE; let query_version = simulate_version_base + version.0; version = TransactionVersion(query_version); + expected_version += simulate_version_base; } let tx_hash = tx_hash!(1991); @@ -243,7 +307,7 @@ fn test_get_execution_info( let tx_info: TransactionInfo; if version == TransactionVersion::ONE { expected_tx_info = vec![ - version.0, /* Transaction + expected_version, /* Transaction * version. */ *sender_address.0.key(), // Account address. felt!(max_fee.0), // Max fee. @@ -266,7 +330,7 @@ fn test_get_execution_info( }); } else { expected_tx_info = vec![ - version.0, /* Transaction + expected_version, /* Transaction * version. */ *sender_address.0.key(), // Account address. Felt::ZERO, // Max fee. diff --git a/crates/blockifier/src/test_utils/contracts.rs b/crates/blockifier/src/test_utils/contracts.rs index 6bec15ea0f1..fccabab658a 100644 --- a/crates/blockifier/src/test_utils/contracts.rs +++ b/crates/blockifier/src/test_utils/contracts.rs @@ -18,7 +18,7 @@ use strum::IntoEnumIterator; use strum_macros::EnumIter; use crate::execution::contract_class::RunnableCompiledClass; -use crate::execution::entry_point::CallEntryPoint; +use crate::execution::entry_point::EntryPointTypeAndSelector; #[cfg(feature = "cairo_native")] use crate::execution::native::contract_class::NativeCompiledClassV1; use crate::test_utils::cairo_compile::{cairo0_compile, cairo1_compile, CompilationArtifacts}; @@ -158,10 +158,14 @@ impl FeatureContract { } } + /// Returns the address of the instance with the given instance ID. + pub fn instance_address(integer_base: u32, instance_id: u32) -> ContractAddress { + contract_address!(integer_base + instance_id + ADDRESS_BIT) + } + /// Returns the address of the instance with the given instance ID. pub fn get_instance_address(&self, instance_id: u16) -> ContractAddress { - let instance_id_as_u32: u32 = instance_id.into(); - contract_address!(self.get_integer_base() + instance_id_as_u32 + ADDRESS_BIT) + Self::instance_address(self.get_integer_base(), instance_id.into()) } pub fn get_class(&self) -> ContractClass { @@ -393,10 +397,9 @@ impl FeatureContract { RunnableCompiledClass::V1(class) => { class .entry_points_by_type - .get_entry_point(&CallEntryPoint { + .get_entry_point(&EntryPointTypeAndSelector { entry_point_type, entry_point_selector, - ..Default::default() }) .unwrap() .offset @@ -491,3 +494,37 @@ impl FeatureContract { .into_group_map() } } + +/// The information needed to test a [FeatureContract]. +pub struct FeatureContractData { + pub class_hash: ClassHash, + pub runnable_class: RunnableCompiledClass, + pub require_funding: bool, + integer_base: u32, +} +impl FeatureContractData { + pub fn get_instance_address(&self, instance: u16) -> ContractAddress { + // If a test requires overriding the contract address, replace storing `integer_base` in the + // struct with storing a callback function that computes the address. + // A test will then be able to override the callback function to return the desired address. + FeatureContract::instance_address(self.integer_base, instance.into()) + } +} + +impl From for FeatureContractData { + fn from(contract: FeatureContract) -> Self { + let require_funding = matches!( + contract, + FeatureContract::AccountWithLongValidate(_) + | FeatureContract::AccountWithoutValidations(_) + | FeatureContract::FaultyAccount(_) + ); + + Self { + class_hash: contract.get_class_hash(), + runnable_class: contract.get_runnable_class(), + require_funding, + integer_base: contract.get_integer_base(), + } + } +} diff --git a/crates/blockifier/src/test_utils/initial_test_state.rs b/crates/blockifier/src/test_utils/initial_test_state.rs index 0beeb1a36d5..e45860900a3 100644 --- a/crates/blockifier/src/test_utils/initial_test_state.rs +++ b/crates/blockifier/src/test_utils/initial_test_state.rs @@ -9,7 +9,7 @@ use strum::IntoEnumIterator; use crate::context::ChainInfo; use crate::state::cached_state::CachedState; -use crate::test_utils::contracts::FeatureContract; +use crate::test_utils::contracts::{FeatureContract, FeatureContractData}; use crate::test_utils::dict_state_reader::DictStateReader; use crate::test_utils::CairoVersion; @@ -41,7 +41,7 @@ pub fn fund_account( pub fn test_state_inner( chain_info: &ChainInfo, initial_balances: Fee, - contract_instances: &[(FeatureContract, u16)], + contract_instances: &[(FeatureContractData, u16)], erc20_contract_version: CairoVersion, ) -> CachedState { let mut class_hash_to_class = HashMap::new(); @@ -57,8 +57,8 @@ pub fn test_state_inner( // Set up the rest of the requested contracts. for (contract, n_instances) in contract_instances.iter() { - let class_hash = contract.get_class_hash(); - class_hash_to_class.insert(class_hash, contract.get_runnable_class()); + let class_hash = contract.class_hash; + class_hash_to_class.insert(class_hash, contract.runnable_class.clone()); for instance in 0..*n_instances { let instance_address = contract.get_instance_address(instance); address_to_class_hash.insert(instance_address, class_hash); @@ -72,13 +72,8 @@ pub fn test_state_inner( for (contract, n_instances) in contract_instances.iter() { for instance in 0..*n_instances { let instance_address = contract.get_instance_address(instance); - match contract { - FeatureContract::AccountWithLongValidate(_) - | FeatureContract::AccountWithoutValidations(_) - | FeatureContract::FaultyAccount(_) => { - fund_account(chain_info, instance_address, initial_balances, &mut state_reader); - } - _ => (), + if contract.require_funding { + fund_account(chain_info, instance_address, initial_balances, &mut state_reader); } } } @@ -90,6 +85,18 @@ pub fn test_state( chain_info: &ChainInfo, initial_balances: Fee, contract_instances: &[(FeatureContract, u16)], +) -> CachedState { + let contract_instances_vec: Vec<(FeatureContractData, u16)> = contract_instances + .iter() + .map(|(feature_contract, i)| ((*feature_contract).into(), *i)) + .collect(); + test_state_ex(chain_info, initial_balances, &contract_instances_vec[..]) +} + +pub fn test_state_ex( + chain_info: &ChainInfo, + initial_balances: Fee, + contract_instances: &[(FeatureContractData, u16)], ) -> CachedState { test_state_inner(chain_info, initial_balances, contract_instances, CairoVersion::Cairo0) } diff --git a/crates/blockifier/src/versioned_constants.rs b/crates/blockifier/src/versioned_constants.rs index c8f462c1b36..3261c45ec20 100644 --- a/crates/blockifier/src/versioned_constants.rs +++ b/crates/blockifier/src/versioned_constants.rs @@ -17,7 +17,7 @@ use serde::{Deserialize, Deserializer, Serialize}; use serde_json::{Map, Number, Value}; use starknet_api::block::{GasPrice, StarknetVersion}; use starknet_api::contract_class::SierraVersion; -use starknet_api::core::ContractAddress; +use starknet_api::core::{ClassHash, ContractAddress}; use starknet_api::execution_resources::{GasAmount, GasVector}; use starknet_api::transaction::fields::GasVectorComputationMode; use starknet_infra_utils::compile_time_cargo_manifest_dir; @@ -844,9 +844,9 @@ pub struct GasCosts { // Below, serde first deserializes the json into a regular IndexMap wrapped by the newtype // `OsConstantsRawJson`, then calls the `try_from` of the newtype, which handles the // conversion into actual values. -// TODO: consider encoding the * and + operations inside the json file, instead of hardcoded below -// in the `try_from`. -#[cfg_attr(any(test, feature = "testing"), derive(Clone, Copy))] +// TODO(Dori): consider encoding the * and + operations inside the json file, instead of hardcoded +// below in the `try_from`. +#[cfg_attr(any(test, feature = "testing"), derive(Clone))] #[derive(Debug, Default, Deserialize)] #[serde(try_from = "OsConstantsRawJson")] pub struct OsConstants { @@ -855,6 +855,8 @@ pub struct OsConstants { pub os_contract_addresses: OsContractAddresses, pub validate_max_sierra_gas: GasAmount, pub execute_max_sierra_gas: GasAmount, + pub v1_bound_accounts_cairo0: Vec, + pub v1_bound_accounts_cairo1: Vec, } impl OsConstants { @@ -939,12 +941,16 @@ impl TryFrom for OsConstants { .ok_or_else(|| OsConstantsSerdeError::KeyNotFoundInFile(key.to_string()))? .clone(), )?); + let v1_bound_accounts_cairo0 = raw_json_data.v1_bound_accounts_cairo0; + let v1_bound_accounts_cairo1 = raw_json_data.v1_bound_accounts_cairo1; let os_constants = OsConstants { gas_costs, validate_rounding_consts, os_contract_addresses, validate_max_sierra_gas, execute_max_sierra_gas, + v1_bound_accounts_cairo0, + v1_bound_accounts_cairo1, }; Ok(os_constants) } @@ -985,6 +991,8 @@ struct OsConstantsRawJson { #[serde(default)] validate_rounding_consts: ValidateRoundingConsts, os_contract_addresses: OsContractAddresses, + v1_bound_accounts_cairo0: Vec, + v1_bound_accounts_cairo1: Vec, } impl OsConstantsRawJson { diff --git a/crates/blockifier/src/versioned_constants_test.rs b/crates/blockifier/src/versioned_constants_test.rs index 16a3643542e..1ab0ccc14ed 100644 --- a/crates/blockifier/src/versioned_constants_test.rs +++ b/crates/blockifier/src/versioned_constants_test.rs @@ -88,6 +88,8 @@ fn check_constants_serde_error(json_data: &str, expected_error_message: &str) { "os_contract_addresses".to_string(), serde_json::to_value(OsContractAddresses::default()).unwrap(), ); + json_data_raw.insert("v1_bound_accounts_cairo0".to_string(), serde_json::Value::Array(vec![])); + json_data_raw.insert("v1_bound_accounts_cairo1".to_string(), serde_json::Value::Array(vec![])); let json_data = &serde_json::to_string(&json_data_raw).unwrap(); diff --git a/scripts/rust_fmt.sh b/scripts/rust_fmt.sh old mode 100644 new mode 100755 From 9a43758c96fe3d4d0475d16a20e8cef173828dd9 Mon Sep 17 00:00:00 2001 From: Dori Medini Date: Mon, 3 Mar 2025 11:47:37 +0200 Subject: [PATCH 7/7] chore: fix conflicts Signed-off-by: Dori Medini --- crates/blockifier/benches/main.rs | 8 +- ...lockifier_versioned_constants_0_13_5.json} | 0 .../src/blockifier_versioned_constants.rs | 178 +---- .../deprecated_syscalls_test.rs | 24 - crates/blockifier/src/test_utils/contracts.rs | 732 ------------------ .../src/test_utils/initial_test_state.rs | 6 - .../src/test_utils/transfers_generator.rs | 8 +- .../src/serialization/serializers.rs | 6 +- crates/papyrus_test_utils/src/lib.rs | 6 +- crates/starknet_api/src/block.rs | 9 +- .../resources/central_state_diff.json | 6 - 11 files changed, 6 insertions(+), 977 deletions(-) rename crates/blockifier/resources/{versioned_constants_0_13_5.json => blockifier_versioned_constants_0_13_5.json} (100%) diff --git a/crates/blockifier/benches/main.rs b/crates/blockifier/benches/main.rs index e1966666ef8..af845a6923a 100644 --- a/crates/blockifier/benches/main.rs +++ b/crates/blockifier/benches/main.rs @@ -5,16 +5,10 @@ //! The main benchmark function is `transfers_benchmark`, which measures the performance //! of transfers between randomly created accounts, which are iterated over round-robin. //! -<<<<<<< HEAD:crates/blockifier/benches/main.rs //! Run the benchmarks using `cargo bench --bench blockifier`. -||||||| f39b2b272:crates/blockifier/bench/blockifier_bench.rs -//! Run the benchmarks using `cargo bench --bench blockifier_bench`. -======= -//! Run the benchmarks using `cargo bench --bench blockifier_bench`. //! //! For Cairo Native compilation run the benchmarks using: -//! `cargo bench --bench blockifier_bench --features "cairo_native"`. ->>>>>>> origin/main-v0.13.5:crates/blockifier/bench/blockifier_bench.rs +//! `cargo bench --bench blockifier --features "cairo_native"`. use blockifier::test_utils::transfers_generator::{ RecipientGeneratorType, diff --git a/crates/blockifier/resources/versioned_constants_0_13_5.json b/crates/blockifier/resources/blockifier_versioned_constants_0_13_5.json similarity index 100% rename from crates/blockifier/resources/versioned_constants_0_13_5.json rename to crates/blockifier/resources/blockifier_versioned_constants_0_13_5.json diff --git a/crates/blockifier/src/blockifier_versioned_constants.rs b/crates/blockifier/src/blockifier_versioned_constants.rs index e0e1063c970..61d71fa412c 100644 --- a/crates/blockifier/src/blockifier_versioned_constants.rs +++ b/crates/blockifier/src/blockifier_versioned_constants.rs @@ -16,14 +16,8 @@ use serde::{Deserialize, Deserializer, Serialize}; use serde_json::{Map, Number, Value}; use starknet_api::block::{GasPrice, StarknetVersion}; use starknet_api::contract_class::SierraVersion; -<<<<<<< HEAD:crates/blockifier/src/blockifier_versioned_constants.rs use starknet_api::core::{ClassHash, ContractAddress}; use starknet_api::define_versioned_constants; -||||||| f39b2b272:crates/blockifier/src/versioned_constants.rs -use starknet_api::core::ContractAddress; -======= -use starknet_api::core::{ClassHash, ContractAddress}; ->>>>>>> origin/main-v0.13.5:crates/blockifier/src/versioned_constants.rs use starknet_api::execution_resources::{GasAmount, GasVector}; use starknet_api::transaction::fields::GasVectorComputationMode; use strum::IntoEnumIterator; @@ -41,7 +35,6 @@ use crate::utils::u64_from_usize; #[path = "versioned_constants_test.rs"] pub mod test; -<<<<<<< HEAD:crates/blockifier/src/blockifier_versioned_constants.rs define_versioned_constants!( VersionedConstants, VersionedConstantsError, @@ -52,178 +45,9 @@ define_versioned_constants!( (V0_13_2_1, "../resources/blockifier_versioned_constants_0_13_2_1.json"), (V0_13_3, "../resources/blockifier_versioned_constants_0_13_3.json"), (V0_13_4, "../resources/blockifier_versioned_constants_0_13_4.json"), + (V0_13_5, "../resources/blockifier_versioned_constants_0_13_5.json"), (V0_14_0, "../resources/blockifier_versioned_constants_0_14_0.json"), ); -||||||| f39b2b272:crates/blockifier/src/versioned_constants.rs -/// Auto-generate getters for listed versioned constants versions. -macro_rules! define_versioned_constants { - ($(($variant:ident, $path_to_json:expr)),* $(,)?) => { - // Static (lazy) instances of the versioned constants. - // For internal use only; for access to a static instance use the `StarknetVersion` enum. - paste! { - $( - pub(crate) const []: &str = - include_str!($path_to_json); - pub static []: LazyLock = LazyLock::new(|| { - serde_json::from_str([]) - .expect(&format!("Versioned constants {} is malformed.", $path_to_json)) - }); - )* - } - - /// API to access a static instance of the versioned constants. - impl TryFrom for &'static VersionedConstants { - type Error = VersionedConstantsError; - - fn try_from(version: StarknetVersion) -> VersionedConstantsResult { - match version { - $( - StarknetVersion::$variant => { - Ok(& paste! { [] }) - } - )* - _ => Err(VersionedConstantsError::InvalidStarknetVersion(version)), - } - } - } - - impl VersionedConstants { - pub fn path_to_json(version: &StarknetVersion) -> VersionedConstantsResult<&'static str> { - match version { - $(StarknetVersion::$variant => Ok($path_to_json),)* - _ => Err(VersionedConstantsError::InvalidStarknetVersion(*version)), - } - } - - /// Gets the constants that shipped with the current version of the Blockifier. - /// To use custom constants, initialize the struct from a file using `from_path`. - pub fn latest_constants() -> &'static Self { - Self::get(&StarknetVersion::LATEST) - .expect("Latest version should support VC.") - } - - /// Gets the constants for the specified Starknet version. - pub fn get(version: &StarknetVersion) -> VersionedConstantsResult<&'static Self> { - match version { - $( - StarknetVersion::$variant => Ok( - & paste! { [] } - ), - )* - _ => Err(VersionedConstantsError::InvalidStarknetVersion(*version)), - } - } - } - - pub static VERSIONED_CONSTANTS_LATEST_JSON: LazyLock = LazyLock::new(|| { - let latest_variant = StarknetVersion::LATEST; - let path_to_json: PathBuf = [ - compile_time_cargo_manifest_dir!(), - "src".into(), - VersionedConstants::path_to_json(&latest_variant) - .expect("Latest variant should have a path to json.").into() - ].iter().collect(); - fs::read_to_string(path_to_json.clone()) - .expect(&format!("Failed to read file {}.", path_to_json.display())) - }); - }; -} - -define_versioned_constants! { - (V0_13_0, "../resources/versioned_constants_0_13_0.json"), - (V0_13_1, "../resources/versioned_constants_0_13_1.json"), - (V0_13_1_1, "../resources/versioned_constants_0_13_1_1.json"), - (V0_13_2, "../resources/versioned_constants_0_13_2.json"), - (V0_13_2_1, "../resources/versioned_constants_0_13_2_1.json"), - (V0_13_3, "../resources/versioned_constants_0_13_3.json"), - (V0_13_4, "../resources/versioned_constants_0_13_4.json"), -} -======= -/// Auto-generate getters for listed versioned constants versions. -macro_rules! define_versioned_constants { - ($(($variant:ident, $path_to_json:expr)),* $(,)?) => { - // Static (lazy) instances of the versioned constants. - // For internal use only; for access to a static instance use the `StarknetVersion` enum. - paste! { - $( - pub(crate) const []: &str = - include_str!($path_to_json); - pub static []: LazyLock = LazyLock::new(|| { - serde_json::from_str([]) - .expect(&format!("Versioned constants {} is malformed.", $path_to_json)) - }); - )* - } - - /// API to access a static instance of the versioned constants. - impl TryFrom for &'static VersionedConstants { - type Error = VersionedConstantsError; - - fn try_from(version: StarknetVersion) -> VersionedConstantsResult { - match version { - $( - StarknetVersion::$variant => { - Ok(& paste! { [] }) - } - )* - _ => Err(VersionedConstantsError::InvalidStarknetVersion(version)), - } - } - } - - impl VersionedConstants { - pub fn path_to_json(version: &StarknetVersion) -> VersionedConstantsResult<&'static str> { - match version { - $(StarknetVersion::$variant => Ok($path_to_json),)* - _ => Err(VersionedConstantsError::InvalidStarknetVersion(*version)), - } - } - - /// Gets the constants that shipped with the current version of the Blockifier. - /// To use custom constants, initialize the struct from a file using `from_path`. - pub fn latest_constants() -> &'static Self { - Self::get(&StarknetVersion::LATEST) - .expect("Latest version should support VC.") - } - - /// Gets the constants for the specified Starknet version. - pub fn get(version: &StarknetVersion) -> VersionedConstantsResult<&'static Self> { - match version { - $( - StarknetVersion::$variant => Ok( - & paste! { [] } - ), - )* - _ => Err(VersionedConstantsError::InvalidStarknetVersion(*version)), - } - } - } - - pub static VERSIONED_CONSTANTS_LATEST_JSON: LazyLock = LazyLock::new(|| { - let latest_variant = StarknetVersion::LATEST; - let path_to_json: PathBuf = [ - compile_time_cargo_manifest_dir!(), - "src".into(), - VersionedConstants::path_to_json(&latest_variant) - .expect("Latest variant should have a path to json.").into() - ].iter().collect(); - fs::read_to_string(path_to_json.clone()) - .expect(&format!("Failed to read file {}.", path_to_json.display())) - }); - }; -} - -define_versioned_constants! { - (V0_13_0, "../resources/versioned_constants_0_13_0.json"), - (V0_13_1, "../resources/versioned_constants_0_13_1.json"), - (V0_13_1_1, "../resources/versioned_constants_0_13_1_1.json"), - (V0_13_2, "../resources/versioned_constants_0_13_2.json"), - (V0_13_2_1, "../resources/versioned_constants_0_13_2_1.json"), - (V0_13_3, "../resources/versioned_constants_0_13_3.json"), - (V0_13_4, "../resources/versioned_constants_0_13_4.json"), - (V0_13_5, "../resources/versioned_constants_0_13_5.json"), -} ->>>>>>> origin/main-v0.13.5:crates/blockifier/src/versioned_constants.rs pub type ResourceCost = Ratio; diff --git a/crates/blockifier/src/execution/deprecated_syscalls/deprecated_syscalls_test.rs b/crates/blockifier/src/execution/deprecated_syscalls/deprecated_syscalls_test.rs index 0168bbe0ad2..87102300780 100644 --- a/crates/blockifier/src/execution/deprecated_syscalls/deprecated_syscalls_test.rs +++ b/crates/blockifier/src/execution/deprecated_syscalls/deprecated_syscalls_test.rs @@ -38,16 +38,8 @@ use crate::execution::entry_point::{CallEntryPoint, CallType}; use crate::execution::errors::EntryPointExecutionError; use crate::execution::syscalls::hint_processor::EmitEventError; use crate::state::state_api::StateReader; -<<<<<<< HEAD -use crate::test_utils::contracts::FeatureContractData; -use crate::test_utils::initial_test_state::{test_state, test_state_ex}; -||||||| f39b2b272 -use crate::test_utils::contracts::FeatureContract; -use crate::test_utils::initial_test_state::test_state; -======= use crate::test_utils::contracts::{FeatureContract, FeatureContractData}; use crate::test_utils::initial_test_state::{test_state, test_state_ex}; ->>>>>>> origin/main-v0.13.5 use crate::test_utils::{ calldata_for_deploy_test, get_syscall_resources, @@ -498,28 +490,12 @@ fn test_tx_info( let nonce = nonce!(3_u16); let sender_address = test_contract.get_instance_address(0); let expected_tx_info = calldata![ -<<<<<<< HEAD expected_version, // Transaction version. *sender_address.0.key(), // Account address. felt!(max_fee.0), // Max fee. tx_hash.0, // Transaction hash. felt!(&*CHAIN_ID_FOR_TESTS.as_hex()), // Chain ID. nonce.0 // Nonce. -||||||| f39b2b272 - version, // Transaction version. - *sender_address.0.key(), // Account address. - felt!(max_fee.0), // Max fee. - tx_hash.0, // Transaction hash. - felt!(&*ChainId::create_for_testing().as_hex()), // Chain ID. - nonce.0 // Nonce. -======= - expected_version, // Transaction version. - *sender_address.0.key(), // Account address. - felt!(max_fee.0), // Max fee. - tx_hash.0, // Transaction hash. - felt!(&*ChainId::create_for_testing().as_hex()), // Chain ID. - nonce.0 // Nonce. ->>>>>>> origin/main-v0.13.5 ]; let entry_point_selector = selector_from_name("test_get_tx_info"); let entry_point_call = CallEntryPoint { diff --git a/crates/blockifier/src/test_utils/contracts.rs b/crates/blockifier/src/test_utils/contracts.rs index a24e25f3f3f..e66d8b4fb76 100644 --- a/crates/blockifier/src/test_utils/contracts.rs +++ b/crates/blockifier/src/test_utils/contracts.rs @@ -16,707 +16,9 @@ use crate::execution::entry_point::EntryPointTypeAndSelector; use crate::execution::native::contract_class::NativeCompiledClassV1; use crate::test_utils::struct_impls::LoadContractFromFile; -<<<<<<< HEAD pub trait FeatureContractTrait { fn get_class(&self) -> ContractClass; fn get_runnable_class(&self) -> RunnableCompiledClass; -||||||| f39b2b272 -pub const CAIRO1_FEATURE_CONTRACTS_DIR: &str = "feature_contracts/cairo1"; -pub const SIERRA_CONTRACTS_SUBDIR: &str = "sierra"; - -// This file contains featured contracts, used for tests. Use the function 'test_state' in -// initial_test_state.rs to initialize a state with these contracts. -// -// Use the mock class hashes and addresses to interact with the contracts in tests. -// The structure of such mock address / class hash is as follows: -// +-+-+-----------+---------------+---------------+---------------+ -// |v|a| reserved | 8 bits: class | 16 bits : address | -// +-+-+-----------+---------------+---------------+---------------+ -// v: 1 bit. 0 for Cairo0, 1 for Cairo1. bit 31. -// a: 1 bit. 0 for class hash, 1 for address. bit 30. -// reserved: Must be 0. bit 29-24. -// class: 8 bits. The class hash of the contract. bit 23-16. allows up to 256 unique contracts. -// address: 16 bits. The instance ID of the contract. bit 15-0. allows up to 65536 instances of each -// contract. - -// Bit to set on class hashes and addresses of feature contracts to indicate the Cairo1 variant. -const CAIRO1_BIT: u32 = 1 << 31; - -// Bit to set on a class hash to convert it to the respective address. -const ADDRESS_BIT: u32 = 1 << 30; - -// Mock class hashes of the feature contract. Keep the bottom 16 bits of each class hash unset, to -// allow up to 65536 deployed instances of each contract. -const CLASS_HASH_BASE: u32 = 1 << 16; -const ACCOUNT_LONG_VALIDATE_BASE: u32 = CLASS_HASH_BASE; -const ACCOUNT_WITHOUT_VALIDATIONS_BASE: u32 = 2 * CLASS_HASH_BASE; -const EMPTY_CONTRACT_BASE: u32 = 3 * CLASS_HASH_BASE; -const FAULTY_ACCOUNT_BASE: u32 = 4 * CLASS_HASH_BASE; -const LEGACY_CONTRACT_BASE: u32 = 5 * CLASS_HASH_BASE; -const SECURITY_TEST_CONTRACT_BASE: u32 = 6 * CLASS_HASH_BASE; -const TEST_CONTRACT_BASE: u32 = 7 * CLASS_HASH_BASE; -const ERC20_CONTRACT_BASE: u32 = 8 * CLASS_HASH_BASE; -const CAIRO_STEPS_TEST_CONTRACT_BASE: u32 = 9 * CLASS_HASH_BASE; -const SIERRA_EXECUTION_INFO_V1_CONTRACT_BASE: u32 = 10 * CLASS_HASH_BASE; - -// Contract names. -const ACCOUNT_LONG_VALIDATE_NAME: &str = "account_with_long_validate"; -const ACCOUNT_WITHOUT_VALIDATIONS_NAME: &str = "account_with_dummy_validate"; -const EMPTY_CONTRACT_NAME: &str = "empty_contract"; -const FAULTY_ACCOUNT_NAME: &str = "account_faulty"; -const LEGACY_CONTRACT_NAME: &str = "legacy_test_contract"; -const SECURITY_TEST_CONTRACT_NAME: &str = "security_tests_contract"; -const TEST_CONTRACT_NAME: &str = "test_contract"; -const CAIRO_STEPS_TEST_CONTRACT_NAME: &str = "cairo_steps_test_contract"; -const EXECUTION_INFO_V1_CONTRACT_NAME: &str = "test_contract_execution_info_v1"; - -// ERC20 contract is in a unique location. -const ERC20_CAIRO0_CONTRACT_SOURCE_PATH: &str = - "./ERC20/ERC20_Cairo0/ERC20_without_some_syscalls/ERC20/ERC20.cairo"; -const ERC20_CAIRO0_CONTRACT_PATH: &str = "./ERC20/ERC20_Cairo0/ERC20_without_some_syscalls/ERC20/\ - erc20_contract_without_some_syscalls_compiled.json"; -const ERC20_CAIRO1_CONTRACT_SOURCE_PATH: &str = "./ERC20/ERC20_Cairo1/ERC20.cairo"; -const ERC20_SIERRA_CONTRACT_PATH: &str = "./ERC20/ERC20_Cairo1/erc20.sierra.json"; -const ERC20_CAIRO1_CONTRACT_PATH: &str = "./ERC20/ERC20_Cairo1/erc20.casm.json"; - -// The following contracts are compiled with a fixed version of the compiler. This compiler version -// no longer compiles with stable rust, so the toolchain is also fixed. -const LEGACY_CONTRACT_COMPILER_TAG: &str = "v2.1.0"; -const LEGACY_CONTRACT_RUST_TOOLCHAIN: &str = "2023-07-05"; - -const CAIRO_STEPS_TEST_CONTRACT_COMPILER_TAG: &str = "v2.7.0"; -const CAIRO_STEPS_TEST_CONTRACT_RUST_TOOLCHAIN: &str = "2024-04-29"; - -pub type TagAndToolchain = (Option, Option); -pub type TagToContractsMapping = HashMap>; - -/// Enum representing all feature contracts. -/// The contracts that are implemented in both Cairo versions include a version field. -#[derive(Clone, Copy, Debug, EnumIter, Hash, PartialEq, Eq)] -pub enum FeatureContract { - AccountWithLongValidate(CairoVersion), - AccountWithoutValidations(CairoVersion), - ERC20(CairoVersion), - Empty(CairoVersion), - FaultyAccount(CairoVersion), - LegacyTestContract, - SecurityTests, - TestContract(CairoVersion), - CairoStepsTestContract, - SierraExecutionInfoV1Contract(RunnableCairo1), -} - -impl FeatureContract { - pub fn cairo_version(&self) -> CairoVersion { - match self { - Self::AccountWithLongValidate(version) - | Self::AccountWithoutValidations(version) - | Self::Empty(version) - | Self::FaultyAccount(version) - | Self::TestContract(version) - | Self::ERC20(version) => *version, - Self::SecurityTests => CairoVersion::Cairo0, - Self::LegacyTestContract | Self::CairoStepsTestContract => { - CairoVersion::Cairo1(RunnableCairo1::Casm) - } - Self::SierraExecutionInfoV1Contract(runnable_version) => { - CairoVersion::Cairo1(*runnable_version) - } - } - } - - pub fn set_cairo_version(&mut self, version: CairoVersion) { - match self { - Self::AccountWithLongValidate(v) - | Self::AccountWithoutValidations(v) - | Self::Empty(v) - | Self::FaultyAccount(v) - | Self::TestContract(v) - | Self::ERC20(v) => *v = version, - Self::SierraExecutionInfoV1Contract(rv) => match version { - CairoVersion::Cairo0 => panic!("SierraExecutionInfoV1Contract must be Cairo1"), - CairoVersion::Cairo1(runnable) => *rv = runnable, - }, - Self::SecurityTests | Self::CairoStepsTestContract | Self::LegacyTestContract => { - panic!("{self:?} contract has no configurable version.") - } - } - } - - pub fn get_class_hash(&self) -> ClassHash { - class_hash!(self.get_integer_base()) - } - - pub fn get_compiled_class_hash(&self) -> CompiledClassHash { - match self.cairo_version() { - CairoVersion::Cairo0 => CompiledClassHash(Felt::ZERO), - CairoVersion::Cairo1(_) => CompiledClassHash(felt!(self.get_integer_base())), - } - } - - /// Returns the address of the instance with the given instance ID. - pub fn get_instance_address(&self, instance_id: u16) -> ContractAddress { - let instance_id_as_u32: u32 = instance_id.into(); - contract_address!(self.get_integer_base() + instance_id_as_u32 + ADDRESS_BIT) - } - - pub fn get_class(&self) -> ContractClass { - match self.cairo_version() { - CairoVersion::Cairo0 => { - ContractClass::V0(DeprecatedContractClass::from_file(&self.get_compiled_path())) - } - CairoVersion::Cairo1(RunnableCairo1::Casm) => ContractClass::V1(( - CasmContractClass::from_file(&self.get_compiled_path()), - self.get_sierra_version(), - )), - #[cfg(feature = "cairo_native")] - CairoVersion::Cairo1(RunnableCairo1::Native) => { - panic!("Native contracts are not supported by this function.") - } - } - } - - pub fn get_runnable_class(&self) -> RunnableCompiledClass { - #[cfg(feature = "cairo_native")] - if CairoVersion::Cairo1(RunnableCairo1::Native) == self.cairo_version() { - let native_contract_class = - NativeCompiledClassV1::compile_or_get_cached(&self.get_compiled_path()); - return RunnableCompiledClass::V1Native(native_contract_class); - } - - self.get_class().try_into().unwrap() - } - - pub fn get_raw_sierra(&self) -> String { - if self.cairo_version() == CairoVersion::Cairo0 { - panic!("The sierra contract is only available for Cairo1."); - } - - get_raw_contract_class(&self.get_sierra_path()) - } - - pub fn get_sierra(&self) -> SierraContractClass { - let raw_sierra = self.get_raw_sierra(); - let cairo_contract_class: CairoLangContractClass = - serde_json::from_str(&raw_sierra).unwrap(); - SierraContractClass::from(cairo_contract_class) - } - - pub fn get_sierra_version(&self) -> SierraVersion { - SierraVersion::extract_from_program(&self.get_sierra().sierra_program).unwrap() - } - - pub fn get_raw_class(&self) -> String { - get_raw_contract_class(&self.get_compiled_path()) - } - - fn get_cairo_version_bit(&self) -> u32 { - match self.cairo_version() { - CairoVersion::Cairo0 => 0, - CairoVersion::Cairo1(_) => CAIRO1_BIT, - } - } - - /// Some contracts are designed to test behavior of code compiled with a - /// specific (old) compiler tag. To run the (old) compiler, older rust - /// version is required. - pub fn fixed_tag_and_rust_toolchain(&self) -> TagAndToolchain { - match self { - Self::LegacyTestContract => ( - Some(LEGACY_CONTRACT_COMPILER_TAG.into()), - Some(LEGACY_CONTRACT_RUST_TOOLCHAIN.into()), - ), - Self::CairoStepsTestContract => ( - Some(CAIRO_STEPS_TEST_CONTRACT_COMPILER_TAG.into()), - Some(CAIRO_STEPS_TEST_CONTRACT_RUST_TOOLCHAIN.into()), - ), - _ => (None, None), - } - } - - /// Unique integer representing each unique contract. Used to derive "class hash" and "address". - fn get_integer_base(self) -> u32 { - self.get_cairo_version_bit() - + match self { - Self::AccountWithLongValidate(_) => ACCOUNT_LONG_VALIDATE_BASE, - Self::AccountWithoutValidations(_) => ACCOUNT_WITHOUT_VALIDATIONS_BASE, - Self::Empty(_) => EMPTY_CONTRACT_BASE, - Self::ERC20(_) => ERC20_CONTRACT_BASE, - Self::FaultyAccount(_) => FAULTY_ACCOUNT_BASE, - Self::LegacyTestContract => LEGACY_CONTRACT_BASE, - Self::SecurityTests => SECURITY_TEST_CONTRACT_BASE, - Self::TestContract(_) => TEST_CONTRACT_BASE, - Self::CairoStepsTestContract => CAIRO_STEPS_TEST_CONTRACT_BASE, - Self::SierraExecutionInfoV1Contract(_) => SIERRA_EXECUTION_INFO_V1_CONTRACT_BASE, - } - } - - fn get_non_erc20_base_name(&self) -> &str { - match self { - Self::AccountWithLongValidate(_) => ACCOUNT_LONG_VALIDATE_NAME, - Self::AccountWithoutValidations(_) => ACCOUNT_WITHOUT_VALIDATIONS_NAME, - Self::Empty(_) => EMPTY_CONTRACT_NAME, - Self::FaultyAccount(_) => FAULTY_ACCOUNT_NAME, - Self::LegacyTestContract => LEGACY_CONTRACT_NAME, - Self::SecurityTests => SECURITY_TEST_CONTRACT_NAME, - Self::TestContract(_) => TEST_CONTRACT_NAME, - Self::CairoStepsTestContract => CAIRO_STEPS_TEST_CONTRACT_NAME, - Self::SierraExecutionInfoV1Contract(_) => EXECUTION_INFO_V1_CONTRACT_NAME, - Self::ERC20(_) => unreachable!(), - } - } - - pub fn get_source_path(&self) -> String { - // Special case: ERC20 contract in a different location. - if let Self::ERC20(cairo_version) = self { - match cairo_version { - CairoVersion::Cairo0 => ERC20_CAIRO0_CONTRACT_SOURCE_PATH, - CairoVersion::Cairo1(RunnableCairo1::Casm) => ERC20_CAIRO1_CONTRACT_SOURCE_PATH, - #[cfg(feature = "cairo_native")] - CairoVersion::Cairo1(RunnableCairo1::Native) => { - todo!("ERC20 contract is not supported by Native yet") - } - } - .into() - } else { - format!( - "feature_contracts/cairo{}/{}.cairo", - match self.cairo_version() { - CairoVersion::Cairo0 => "0", - CairoVersion::Cairo1(_) => "1", - }, - self.get_non_erc20_base_name() - ) - } - } - - pub fn get_sierra_path(&self) -> String { - assert_ne!(self.cairo_version(), CairoVersion::Cairo0); - // This is not the compiled Sierra file of the existing ERC20 contract, - // but a file that was taken from the compiler repo of another ERC20 contract. - if matches!(self, &Self::ERC20(CairoVersion::Cairo1(_))) { - return ERC20_SIERRA_CONTRACT_PATH.to_string(); - } - - format!( - "{CAIRO1_FEATURE_CONTRACTS_DIR}/{SIERRA_CONTRACTS_SUBDIR}/{}.sierra.json", - self.get_non_erc20_base_name() - ) - } - - pub fn get_compiled_path(&self) -> String { - // ERC20 is a special case - not in the feature_contracts directory. - if let Self::ERC20(cairo_version) = self { - match cairo_version { - CairoVersion::Cairo0 => ERC20_CAIRO0_CONTRACT_PATH, - CairoVersion::Cairo1(RunnableCairo1::Casm) => ERC20_CAIRO1_CONTRACT_PATH, - #[cfg(feature = "cairo_native")] - CairoVersion::Cairo1(RunnableCairo1::Native) => { - todo!("ERC20 cannot be tested with Native") - } - } - .into() - } else { - let cairo_version = self.cairo_version(); - format!( - "feature_contracts/cairo{}/{}{}.json", - match cairo_version { - CairoVersion::Cairo0 => "0/compiled", - CairoVersion::Cairo1(RunnableCairo1::Casm) => "1/compiled", - #[cfg(feature = "cairo_native")] - CairoVersion::Cairo1(RunnableCairo1::Native) => "1/sierra", - }, - self.get_non_erc20_base_name(), - match cairo_version { - CairoVersion::Cairo0 => "_compiled", - CairoVersion::Cairo1(RunnableCairo1::Casm) => ".casm", - #[cfg(feature = "cairo_native")] - CairoVersion::Cairo1(RunnableCairo1::Native) => ".sierra", - } - ) - } - } - - /// Compiles the feature contract and returns the compiled contract as a byte vector. - /// Panics if the contract is ERC20, as ERC20 contract recompilation is not supported. - pub fn compile(&self) -> CompilationArtifacts { - if matches!(self, Self::ERC20(_)) { - panic!("ERC20 contract recompilation not supported."); - } - match self.cairo_version() { - CairoVersion::Cairo0 => { - let extra_arg: Option = match self { - // Account contracts require the account_contract flag. - FeatureContract::AccountWithLongValidate(_) - | FeatureContract::AccountWithoutValidations(_) - | FeatureContract::FaultyAccount(_) => Some("--account_contract".into()), - FeatureContract::SecurityTests => Some("--disable_hint_validation".into()), - FeatureContract::Empty(_) - | FeatureContract::TestContract(_) - | FeatureContract::LegacyTestContract - | FeatureContract::CairoStepsTestContract - | FeatureContract::SierraExecutionInfoV1Contract(_) => None, - FeatureContract::ERC20(_) => unreachable!(), - }; - cairo0_compile(self.get_source_path(), extra_arg, false) - } - CairoVersion::Cairo1(_) => { - let (tag_override, cargo_nightly_arg) = self.fixed_tag_and_rust_toolchain(); - cairo1_compile(self.get_source_path(), tag_override, cargo_nightly_arg) - } - } - } -======= -pub const CAIRO1_FEATURE_CONTRACTS_DIR: &str = "feature_contracts/cairo1"; -pub const SIERRA_CONTRACTS_SUBDIR: &str = "sierra"; - -// This file contains featured contracts, used for tests. Use the function 'test_state' in -// initial_test_state.rs to initialize a state with these contracts. -// -// Use the mock class hashes and addresses to interact with the contracts in tests. -// The structure of such mock address / class hash is as follows: -// +-+-+-----------+---------------+---------------+---------------+ -// |v|a| reserved | 8 bits: class | 16 bits : address | -// +-+-+-----------+---------------+---------------+---------------+ -// v: 1 bit. 0 for Cairo0, 1 for Cairo1. bit 31. -// a: 1 bit. 0 for class hash, 1 for address. bit 30. -// reserved: Must be 0. bit 29-24. -// class: 8 bits. The class hash of the contract. bit 23-16. allows up to 256 unique contracts. -// address: 16 bits. The instance ID of the contract. bit 15-0. allows up to 65536 instances of each -// contract. - -// Bit to set on class hashes and addresses of feature contracts to indicate the Cairo1 variant. -const CAIRO1_BIT: u32 = 1 << 31; - -// Bit to set on a class hash to convert it to the respective address. -const ADDRESS_BIT: u32 = 1 << 30; - -// Mock class hashes of the feature contract. Keep the bottom 16 bits of each class hash unset, to -// allow up to 65536 deployed instances of each contract. -const CLASS_HASH_BASE: u32 = 1 << 16; -const ACCOUNT_LONG_VALIDATE_BASE: u32 = CLASS_HASH_BASE; -const ACCOUNT_WITHOUT_VALIDATIONS_BASE: u32 = 2 * CLASS_HASH_BASE; -const EMPTY_CONTRACT_BASE: u32 = 3 * CLASS_HASH_BASE; -const FAULTY_ACCOUNT_BASE: u32 = 4 * CLASS_HASH_BASE; -const LEGACY_CONTRACT_BASE: u32 = 5 * CLASS_HASH_BASE; -const SECURITY_TEST_CONTRACT_BASE: u32 = 6 * CLASS_HASH_BASE; -const TEST_CONTRACT_BASE: u32 = 7 * CLASS_HASH_BASE; -const ERC20_CONTRACT_BASE: u32 = 8 * CLASS_HASH_BASE; -const CAIRO_STEPS_TEST_CONTRACT_BASE: u32 = 9 * CLASS_HASH_BASE; -const SIERRA_EXECUTION_INFO_V1_CONTRACT_BASE: u32 = 10 * CLASS_HASH_BASE; - -// Contract names. -const ACCOUNT_LONG_VALIDATE_NAME: &str = "account_with_long_validate"; -const ACCOUNT_WITHOUT_VALIDATIONS_NAME: &str = "account_with_dummy_validate"; -const EMPTY_CONTRACT_NAME: &str = "empty_contract"; -const FAULTY_ACCOUNT_NAME: &str = "account_faulty"; -const LEGACY_CONTRACT_NAME: &str = "legacy_test_contract"; -const SECURITY_TEST_CONTRACT_NAME: &str = "security_tests_contract"; -const TEST_CONTRACT_NAME: &str = "test_contract"; -const CAIRO_STEPS_TEST_CONTRACT_NAME: &str = "cairo_steps_test_contract"; -const EXECUTION_INFO_V1_CONTRACT_NAME: &str = "test_contract_execution_info_v1"; - -// ERC20 contract is in a unique location. -const ERC20_CAIRO0_CONTRACT_SOURCE_PATH: &str = - "./ERC20/ERC20_Cairo0/ERC20_without_some_syscalls/ERC20/ERC20.cairo"; -const ERC20_CAIRO0_CONTRACT_PATH: &str = "./ERC20/ERC20_Cairo0/ERC20_without_some_syscalls/ERC20/\ - erc20_contract_without_some_syscalls_compiled.json"; -const ERC20_CAIRO1_CONTRACT_SOURCE_PATH: &str = "./ERC20/ERC20_Cairo1/ERC20.cairo"; -const ERC20_SIERRA_CONTRACT_PATH: &str = "./ERC20/ERC20_Cairo1/erc20.sierra.json"; -const ERC20_CAIRO1_CONTRACT_PATH: &str = "./ERC20/ERC20_Cairo1/erc20.casm.json"; - -// The following contracts are compiled with a fixed version of the compiler. This compiler version -// no longer compiles with stable rust, so the toolchain is also fixed. -const LEGACY_CONTRACT_COMPILER_TAG: &str = "v2.1.0"; -const LEGACY_CONTRACT_RUST_TOOLCHAIN: &str = "2023-07-05"; - -const CAIRO_STEPS_TEST_CONTRACT_COMPILER_TAG: &str = "v2.7.0"; -const CAIRO_STEPS_TEST_CONTRACT_RUST_TOOLCHAIN: &str = "2024-04-29"; - -pub type TagAndToolchain = (Option, Option); -pub type TagToContractsMapping = HashMap>; - -/// Enum representing all feature contracts. -/// The contracts that are implemented in both Cairo versions include a version field. -#[derive(Clone, Copy, Debug, EnumIter, Hash, PartialEq, Eq)] -pub enum FeatureContract { - AccountWithLongValidate(CairoVersion), - AccountWithoutValidations(CairoVersion), - ERC20(CairoVersion), - Empty(CairoVersion), - FaultyAccount(CairoVersion), - LegacyTestContract, - SecurityTests, - TestContract(CairoVersion), - CairoStepsTestContract, - SierraExecutionInfoV1Contract(RunnableCairo1), -} - -impl FeatureContract { - pub fn cairo_version(&self) -> CairoVersion { - match self { - Self::AccountWithLongValidate(version) - | Self::AccountWithoutValidations(version) - | Self::Empty(version) - | Self::FaultyAccount(version) - | Self::TestContract(version) - | Self::ERC20(version) => *version, - Self::SecurityTests => CairoVersion::Cairo0, - Self::LegacyTestContract | Self::CairoStepsTestContract => { - CairoVersion::Cairo1(RunnableCairo1::Casm) - } - Self::SierraExecutionInfoV1Contract(runnable_version) => { - CairoVersion::Cairo1(*runnable_version) - } - } - } - - pub fn set_cairo_version(&mut self, version: CairoVersion) { - match self { - Self::AccountWithLongValidate(v) - | Self::AccountWithoutValidations(v) - | Self::Empty(v) - | Self::FaultyAccount(v) - | Self::TestContract(v) - | Self::ERC20(v) => *v = version, - Self::SierraExecutionInfoV1Contract(rv) => match version { - CairoVersion::Cairo0 => panic!("SierraExecutionInfoV1Contract must be Cairo1"), - CairoVersion::Cairo1(runnable) => *rv = runnable, - }, - Self::SecurityTests | Self::CairoStepsTestContract | Self::LegacyTestContract => { - panic!("{self:?} contract has no configurable version.") - } - } - } - - pub fn get_class_hash(&self) -> ClassHash { - class_hash!(self.get_integer_base()) - } - - pub fn get_compiled_class_hash(&self) -> CompiledClassHash { - match self.cairo_version() { - CairoVersion::Cairo0 => CompiledClassHash(Felt::ZERO), - CairoVersion::Cairo1(_) => CompiledClassHash(felt!(self.get_integer_base())), - } - } - - /// Returns the address of the instance with the given instance ID. - pub fn instance_address(integer_base: u32, instance_id: u32) -> ContractAddress { - contract_address!(integer_base + instance_id + ADDRESS_BIT) - } - - /// Returns the address of the instance with the given instance ID. - pub fn get_instance_address(&self, instance_id: u16) -> ContractAddress { - Self::instance_address(self.get_integer_base(), instance_id.into()) - } - - pub fn get_class(&self) -> ContractClass { - match self.cairo_version() { - CairoVersion::Cairo0 => { - ContractClass::V0(DeprecatedContractClass::from_file(&self.get_compiled_path())) - } - CairoVersion::Cairo1(RunnableCairo1::Casm) => ContractClass::V1(( - CasmContractClass::from_file(&self.get_compiled_path()), - self.get_sierra_version(), - )), - #[cfg(feature = "cairo_native")] - CairoVersion::Cairo1(RunnableCairo1::Native) => { - panic!("Native contracts are not supported by this function.") - } - } - } - - pub fn get_runnable_class(&self) -> RunnableCompiledClass { - #[cfg(feature = "cairo_native")] - if CairoVersion::Cairo1(RunnableCairo1::Native) == self.cairo_version() { - let native_contract_class = - NativeCompiledClassV1::compile_or_get_cached(&self.get_compiled_path()); - return RunnableCompiledClass::V1Native(native_contract_class); - } - - self.get_class().try_into().unwrap() - } - - pub fn get_raw_sierra(&self) -> String { - if self.cairo_version() == CairoVersion::Cairo0 { - panic!("The sierra contract is only available for Cairo1."); - } - - get_raw_contract_class(&self.get_sierra_path()) - } - - pub fn get_sierra(&self) -> SierraContractClass { - let raw_sierra = self.get_raw_sierra(); - let cairo_contract_class: CairoLangContractClass = - serde_json::from_str(&raw_sierra).unwrap(); - SierraContractClass::from(cairo_contract_class) - } - - pub fn get_sierra_version(&self) -> SierraVersion { - SierraVersion::extract_from_program(&self.get_sierra().sierra_program).unwrap() - } - - pub fn get_raw_class(&self) -> String { - get_raw_contract_class(&self.get_compiled_path()) - } - - fn get_cairo_version_bit(&self) -> u32 { - match self.cairo_version() { - CairoVersion::Cairo0 => 0, - CairoVersion::Cairo1(_) => CAIRO1_BIT, - } - } - - /// Some contracts are designed to test behavior of code compiled with a - /// specific (old) compiler tag. To run the (old) compiler, older rust - /// version is required. - pub fn fixed_tag_and_rust_toolchain(&self) -> TagAndToolchain { - match self { - Self::LegacyTestContract => ( - Some(LEGACY_CONTRACT_COMPILER_TAG.into()), - Some(LEGACY_CONTRACT_RUST_TOOLCHAIN.into()), - ), - Self::CairoStepsTestContract => ( - Some(CAIRO_STEPS_TEST_CONTRACT_COMPILER_TAG.into()), - Some(CAIRO_STEPS_TEST_CONTRACT_RUST_TOOLCHAIN.into()), - ), - _ => (None, None), - } - } - - /// Unique integer representing each unique contract. Used to derive "class hash" and "address". - fn get_integer_base(self) -> u32 { - self.get_cairo_version_bit() - + match self { - Self::AccountWithLongValidate(_) => ACCOUNT_LONG_VALIDATE_BASE, - Self::AccountWithoutValidations(_) => ACCOUNT_WITHOUT_VALIDATIONS_BASE, - Self::Empty(_) => EMPTY_CONTRACT_BASE, - Self::ERC20(_) => ERC20_CONTRACT_BASE, - Self::FaultyAccount(_) => FAULTY_ACCOUNT_BASE, - Self::LegacyTestContract => LEGACY_CONTRACT_BASE, - Self::SecurityTests => SECURITY_TEST_CONTRACT_BASE, - Self::TestContract(_) => TEST_CONTRACT_BASE, - Self::CairoStepsTestContract => CAIRO_STEPS_TEST_CONTRACT_BASE, - Self::SierraExecutionInfoV1Contract(_) => SIERRA_EXECUTION_INFO_V1_CONTRACT_BASE, - } - } - - fn get_non_erc20_base_name(&self) -> &str { - match self { - Self::AccountWithLongValidate(_) => ACCOUNT_LONG_VALIDATE_NAME, - Self::AccountWithoutValidations(_) => ACCOUNT_WITHOUT_VALIDATIONS_NAME, - Self::Empty(_) => EMPTY_CONTRACT_NAME, - Self::FaultyAccount(_) => FAULTY_ACCOUNT_NAME, - Self::LegacyTestContract => LEGACY_CONTRACT_NAME, - Self::SecurityTests => SECURITY_TEST_CONTRACT_NAME, - Self::TestContract(_) => TEST_CONTRACT_NAME, - Self::CairoStepsTestContract => CAIRO_STEPS_TEST_CONTRACT_NAME, - Self::SierraExecutionInfoV1Contract(_) => EXECUTION_INFO_V1_CONTRACT_NAME, - Self::ERC20(_) => unreachable!(), - } - } - - pub fn get_source_path(&self) -> String { - // Special case: ERC20 contract in a different location. - if let Self::ERC20(cairo_version) = self { - match cairo_version { - CairoVersion::Cairo0 => ERC20_CAIRO0_CONTRACT_SOURCE_PATH, - CairoVersion::Cairo1(RunnableCairo1::Casm) => ERC20_CAIRO1_CONTRACT_SOURCE_PATH, - #[cfg(feature = "cairo_native")] - CairoVersion::Cairo1(RunnableCairo1::Native) => { - todo!("ERC20 contract is not supported by Native yet") - } - } - .into() - } else { - format!( - "feature_contracts/cairo{}/{}.cairo", - match self.cairo_version() { - CairoVersion::Cairo0 => "0", - CairoVersion::Cairo1(_) => "1", - }, - self.get_non_erc20_base_name() - ) - } - } - - pub fn get_sierra_path(&self) -> String { - assert_ne!(self.cairo_version(), CairoVersion::Cairo0); - // This is not the compiled Sierra file of the existing ERC20 contract, - // but a file that was taken from the compiler repo of another ERC20 contract. - if matches!(self, &Self::ERC20(CairoVersion::Cairo1(_))) { - return ERC20_SIERRA_CONTRACT_PATH.to_string(); - } - - format!( - "{CAIRO1_FEATURE_CONTRACTS_DIR}/{SIERRA_CONTRACTS_SUBDIR}/{}.sierra.json", - self.get_non_erc20_base_name() - ) - } - - pub fn get_compiled_path(&self) -> String { - // ERC20 is a special case - not in the feature_contracts directory. - if let Self::ERC20(cairo_version) = self { - match cairo_version { - CairoVersion::Cairo0 => ERC20_CAIRO0_CONTRACT_PATH, - CairoVersion::Cairo1(RunnableCairo1::Casm) => ERC20_CAIRO1_CONTRACT_PATH, - #[cfg(feature = "cairo_native")] - CairoVersion::Cairo1(RunnableCairo1::Native) => { - todo!("ERC20 cannot be tested with Native") - } - } - .into() - } else { - let cairo_version = self.cairo_version(); - format!( - "feature_contracts/cairo{}/{}{}.json", - match cairo_version { - CairoVersion::Cairo0 => "0/compiled", - CairoVersion::Cairo1(RunnableCairo1::Casm) => "1/compiled", - #[cfg(feature = "cairo_native")] - CairoVersion::Cairo1(RunnableCairo1::Native) => "1/sierra", - }, - self.get_non_erc20_base_name(), - match cairo_version { - CairoVersion::Cairo0 => "_compiled", - CairoVersion::Cairo1(RunnableCairo1::Casm) => ".casm", - #[cfg(feature = "cairo_native")] - CairoVersion::Cairo1(RunnableCairo1::Native) => ".sierra", - } - ) - } - } - - /// Compiles the feature contract and returns the compiled contract as a byte vector. - /// Panics if the contract is ERC20, as ERC20 contract recompilation is not supported. - pub fn compile(&self) -> CompilationArtifacts { - if matches!(self, Self::ERC20(_)) { - panic!("ERC20 contract recompilation not supported."); - } - match self.cairo_version() { - CairoVersion::Cairo0 => { - let extra_arg: Option = match self { - // Account contracts require the account_contract flag. - FeatureContract::AccountWithLongValidate(_) - | FeatureContract::AccountWithoutValidations(_) - | FeatureContract::FaultyAccount(_) => Some("--account_contract".into()), - FeatureContract::SecurityTests => Some("--disable_hint_validation".into()), - FeatureContract::Empty(_) - | FeatureContract::TestContract(_) - | FeatureContract::LegacyTestContract - | FeatureContract::CairoStepsTestContract - | FeatureContract::SierraExecutionInfoV1Contract(_) => None, - FeatureContract::ERC20(_) => unreachable!(), - }; - cairo0_compile(self.get_source_path(), extra_arg, false) - } - CairoVersion::Cairo1(_) => { - let (tag_override, cargo_nightly_arg) = self.fixed_tag_and_rust_toolchain(); - cairo1_compile(self.get_source_path(), tag_override, cargo_nightly_arg) - } - } - } ->>>>>>> origin/main-v0.13.5 /// Fetch PC locations from the compiled contract to compute the expected PC locations in the /// traceback. Computation is not robust, but as long as the cairo function itself is not @@ -830,37 +132,3 @@ impl From for FeatureContractData { } } } - -/// The information needed to test a [FeatureContract]. -pub struct FeatureContractData { - pub class_hash: ClassHash, - pub runnable_class: RunnableCompiledClass, - pub require_funding: bool, - integer_base: u32, -} -impl FeatureContractData { - pub fn get_instance_address(&self, instance: u16) -> ContractAddress { - // If a test requires overriding the contract address, replace storing `integer_base` in the - // struct with storing a callback function that computes the address. - // A test will then be able to override the callback function to return the desired address. - FeatureContract::instance_address(self.integer_base, instance.into()) - } -} - -impl From for FeatureContractData { - fn from(contract: FeatureContract) -> Self { - let require_funding = matches!( - contract, - FeatureContract::AccountWithLongValidate(_) - | FeatureContract::AccountWithoutValidations(_) - | FeatureContract::FaultyAccount(_) - ); - - Self { - class_hash: contract.get_class_hash(), - runnable_class: contract.get_runnable_class(), - require_funding, - integer_base: contract.get_integer_base(), - } - } -} diff --git a/crates/blockifier/src/test_utils/initial_test_state.rs b/crates/blockifier/src/test_utils/initial_test_state.rs index 6536eb549b2..32e6b1f3f70 100644 --- a/crates/blockifier/src/test_utils/initial_test_state.rs +++ b/crates/blockifier/src/test_utils/initial_test_state.rs @@ -11,13 +11,7 @@ use strum::IntoEnumIterator; use crate::context::ChainInfo; use crate::state::cached_state::CachedState; -<<<<<<< HEAD use crate::test_utils::contracts::{FeatureContractData, FeatureContractTrait}; -||||||| f39b2b272 -use crate::test_utils::contracts::FeatureContract; -======= -use crate::test_utils::contracts::{FeatureContract, FeatureContractData}; ->>>>>>> origin/main-v0.13.5 use crate::test_utils::dict_state_reader::DictStateReader; /// Utility to fund an account. diff --git a/crates/blockifier/src/test_utils/transfers_generator.rs b/crates/blockifier/src/test_utils/transfers_generator.rs index b359ff22516..3c1f0788c7c 100644 --- a/crates/blockifier/src/test_utils/transfers_generator.rs +++ b/crates/blockifier/src/test_utils/transfers_generator.rs @@ -1,4 +1,4 @@ -use blockifier_test_utils::cairo_versions::CairoVersion; +use blockifier_test_utils::cairo_versions::{CairoVersion, RunnableCairo1}; use blockifier_test_utils::contracts::FeatureContract; use rand::rngs::StdRng; use rand::{Rng, SeedableRng}; @@ -18,13 +18,7 @@ use crate::blockifier::transaction_executor::{TransactionExecutor, DEFAULT_STACK use crate::context::{BlockContext, ChainInfo}; use crate::test_utils::dict_state_reader::DictStateReader; use crate::test_utils::initial_test_state::test_state; -<<<<<<< HEAD use crate::test_utils::{BALANCE, MAX_FEE}; -||||||| f39b2b272 -use crate::test_utils::{CairoVersion, BALANCE, MAX_FEE}; -======= -use crate::test_utils::{CairoVersion, RunnableCairo1, BALANCE, MAX_FEE}; ->>>>>>> origin/main-v0.13.5 use crate::transaction::account_transaction::AccountTransaction; use crate::transaction::transaction_execution::Transaction; const N_ACCOUNTS: u16 = 10000; diff --git a/crates/papyrus_storage/src/serialization/serializers.rs b/crates/papyrus_storage/src/serialization/serializers.rs index a2f55b2bfe9..5389e74b29b 100644 --- a/crates/papyrus_storage/src/serialization/serializers.rs +++ b/crates/papyrus_storage/src/serialization/serializers.rs @@ -413,12 +413,8 @@ auto_storage_serde! { V0_13_2_1 = 17, V0_13_3 = 18, V0_13_4 = 19, -<<<<<<< HEAD - V0_14_0 = 20, -||||||| f39b2b272 -======= V0_13_5 = 20, ->>>>>>> origin/main-v0.13.5 + V0_14_0 = 21, } pub struct StateDiffCommitment(pub PoseidonHash); pub struct Tip(pub u64); diff --git a/crates/papyrus_test_utils/src/lib.rs b/crates/papyrus_test_utils/src/lib.rs index 3c2545666f9..51e4ee43314 100644 --- a/crates/papyrus_test_utils/src/lib.rs +++ b/crates/papyrus_test_utils/src/lib.rs @@ -494,12 +494,8 @@ auto_impl_get_test_instance! { V0_13_2_1 = 17, V0_13_3 = 18, V0_13_4 = 19, -<<<<<<< HEAD - V0_14_0 = 20, -||||||| f39b2b272 -======= V0_13_5 = 20, ->>>>>>> origin/main-v0.13.5 + V0_14_0 = 21, } pub struct Calldata(pub Arc>); diff --git a/crates/starknet_api/src/block.rs b/crates/starknet_api/src/block.rs index 886dfab7ec6..e24a8ef6d37 100644 --- a/crates/starknet_api/src/block.rs +++ b/crates/starknet_api/src/block.rs @@ -99,16 +99,9 @@ starknet_version_enum! { (V0_13_2_1, 0, 13, 2, 1), (V0_13_3, 0, 13, 3), (V0_13_4, 0, 13, 4), -<<<<<<< HEAD + (V0_13_5, 0, 13, 5), (V0_14_0, 0, 14, 0), V0_14_0 -||||||| f39b2b272 - V0_13_4 -======= - (V0_13_5, 0, 13, 5), - V0_13_5 - ->>>>>>> origin/main-v0.13.5 } impl Default for StarknetVersion { diff --git a/crates/starknet_consensus_orchestrator/resources/central_state_diff.json b/crates/starknet_consensus_orchestrator/resources/central_state_diff.json index 555d3a4e6c9..65a92abddcd 100644 --- a/crates/starknet_consensus_orchestrator/resources/central_state_diff.json +++ b/crates/starknet_consensus_orchestrator/resources/central_state_diff.json @@ -34,13 +34,7 @@ "price_in_fri": "0xd" }, "sequencer_address": "0x7", -<<<<<<< HEAD:crates/starknet_consensus_orchestrator/resources/central_state_diff.json "starknet_version": "0.14.0", -||||||| f39b2b272:crates/sequencing/papyrus_consensus_orchestrator/resources/central_state_diff.json - "starknet_version": "0.13.4", -======= - "starknet_version": "0.13.5", ->>>>>>> origin/main-v0.13.5:crates/sequencing/papyrus_consensus_orchestrator/resources/central_state_diff.json "use_kzg_da": true } }