From 75e935f91e5bae473366d12dfcbbf1873ec4682a Mon Sep 17 00:00:00 2001 From: Rodrigo Date: Tue, 29 Oct 2024 09:09:18 +0000 Subject: [PATCH] chore: add Native as a compilation feature --- .../src/execution/stack_trace_test.rs | 6 ++++ crates/blockifier/src/test_utils.rs | 18 ++++++++++- crates/blockifier/src/test_utils/contracts.rs | 30 ++++++++++++------- .../blockifier/src/test_utils/struct_impls.rs | 11 +++++-- .../src/transaction/transactions_test.rs | 10 +++++-- .../feature_contracts_compatibility_test.rs | 3 ++ crates/tests-integration/Cargo.toml | 3 ++ crates/tests-integration/src/state_reader.rs | 8 +++-- 8 files changed, 71 insertions(+), 18 deletions(-) diff --git a/crates/blockifier/src/execution/stack_trace_test.rs b/crates/blockifier/src/execution/stack_trace_test.rs index b96d370055..53695400e5 100644 --- a/crates/blockifier/src/execution/stack_trace_test.rs +++ b/crates/blockifier/src/execution/stack_trace_test.rs @@ -245,6 +245,7 @@ Error in contract (contract address: {test_contract_address_2_felt:#064x}, class let expected_trace = match cairo_version { CairoVersion::Cairo0 => expected_trace_cairo0, CairoVersion::Cairo1 => expected_trace_cairo1, + #[cfg(feature = "cairo_native")] CairoVersion::Native => panic!("Cairo Native contracts are not supported"), }; @@ -366,6 +367,7 @@ Error in contract (contract address: {contract_address_felt:#064x}, class hash: " ) } + #[cfg(feature = "cairo_native")] CairoVersion::Native => { todo!("Cairo Native is not yet supported here") } @@ -524,6 +526,7 @@ Error in contract (contract address: {address_felt:#064x}, class hash: {test_con " ) } + #[cfg(feature = "cairo_native")] CairoVersion::Native => { todo!("Cairo Native not yet supported here.") } @@ -627,6 +630,7 @@ Error in contract (contract address: {contract_address:#064x}, class hash: {:#06 0x496e76616c6964207363656e6172696f ('Invalid scenario').", class_hash.0 ), + #[cfg(feature = "cairo_native")] CairoVersion::Native => todo!("Cairo Native is not yet supported here."), }; @@ -700,6 +704,7 @@ Error in contract (contract address: {expected_address:#064x}, class hash: {:#06 class_hash.0 ) .to_string(), + #[cfg(feature = "cairo_native")] CairoVersion::Native => { todo!("Cairo Native not yet supported here.") } @@ -840,6 +845,7 @@ Error in contract (contract address: {expected_address:#064x}, class hash: {:#06 ctor_selector.0 ) } + #[cfg(feature = "cairo_native")] CairoVersion::Native => { todo!("Cairo Native not yet supported here.") } diff --git a/crates/blockifier/src/test_utils.rs b/crates/blockifier/src/test_utils.rs index c86c890c79..28c0aba004 100644 --- a/crates/blockifier/src/test_utils.rs +++ b/crates/blockifier/src/test_utils.rs @@ -64,6 +64,7 @@ pub const ERC20_CONTRACT_PATH: &str = "./ERC20/ERC20_Cairo0/ERC20_without_some_s pub enum CairoVersion { Cairo0, Cairo1, + #[cfg(feature = "cairo_native")] Native, } @@ -91,6 +92,7 @@ impl CairoVersion { match self { Self::Cairo0 => Self::Cairo1, Self::Cairo1 => Self::Cairo0, + #[cfg(feature = "cairo_native")] Self::Native => todo!("who should be your other?"), } } @@ -118,6 +120,8 @@ impl CompilerBasedVersion { TrackedResource::CairoSteps } Self::CairoVersion(CairoVersion::Cairo1) => TrackedResource::SierraGas, + #[cfg(feature = "cairo_native")] + Self::CairoVersion(CairoVersion::Native) => TrackedResource::SierraGas, } } } @@ -328,7 +332,19 @@ macro_rules! check_tx_execution_error_for_invalid_scenario { $validate_constructor, ); } - CairoVersion::Cairo1 | CairoVersion::Native => { + CairoVersion::Cairo1 => { + if let $crate::transaction::errors::TransactionExecutionError::ValidateTransactionError { + error, .. + } = $error { + assert_eq!( + error.to_string(), + "Execution failed. Failure reason: 0x496e76616c6964207363656e6172696f \ + ('Invalid scenario')." + ) + } + } + #[cfg(feature = "cairo_native")] + CairoVersion::Native => { if let $crate::transaction::errors::TransactionExecutionError::ValidateTransactionError { error, .. } = $error { diff --git a/crates/blockifier/src/test_utils/contracts.rs b/crates/blockifier/src/test_utils/contracts.rs index 0ebd2d18c1..cb3ae66600 100644 --- a/crates/blockifier/src/test_utils/contracts.rs +++ b/crates/blockifier/src/test_utils/contracts.rs @@ -17,14 +17,13 @@ use strum_macros::EnumIter; use crate::abi::abi_utils::selector_from_name; use crate::abi::constants::CONSTRUCTOR_ENTRY_POINT_NAME; -use crate::execution::contract_class::{ - ContractClass, - ContractClassV0, - ContractClassV1, - NativeContractClassV1, -}; +use crate::execution::contract_class::{ContractClass, ContractClassV0, ContractClassV1}; use crate::execution::entry_point::CallEntryPoint; -use crate::test_utils::cairo_compile::{cairo0_compile, cairo1_compile, starknet_compile}; +#[cfg(feature = "cairo_native")] +use crate::execution::native::contract_class::NativeContractClassV1; +#[cfg(feature = "cairo_native")] +use crate::test_utils::cairo_compile::starknet_compile; +use crate::test_utils::cairo_compile::{cairo0_compile, cairo1_compile}; use crate::test_utils::{get_raw_contract_class, CairoVersion}; // This file contains featured contracts, used for tests. Use the function 'test_state' in @@ -149,9 +148,9 @@ impl FeatureContract { pub fn get_compiled_class_hash(&self) -> CompiledClassHash { match self.cairo_version() { CairoVersion::Cairo0 => CompiledClassHash(Felt::ZERO), - CairoVersion::Cairo1 | CairoVersion::Native => { - CompiledClassHash(felt!(self.get_integer_base())) - } + CairoVersion::Cairo1 => CompiledClassHash(felt!(self.get_integer_base())), + #[cfg(feature = "cairo_native")] + CairoVersion::Native => CompiledClassHash(felt!(self.get_integer_base())), } } @@ -165,6 +164,7 @@ impl FeatureContract { match self.cairo_version() { CairoVersion::Cairo0 => ContractClassV0::from_file(&self.get_compiled_path()).into(), CairoVersion::Cairo1 => ContractClassV1::from_file(&self.get_compiled_path()).into(), + #[cfg(feature = "cairo_native")] CairoVersion::Native => { NativeContractClassV1::from_file(&self.get_compiled_path()).into() } @@ -193,7 +193,9 @@ impl FeatureContract { fn get_cairo_version_bit(&self) -> u32 { match self.cairo_version() { CairoVersion::Cairo0 => 0, - CairoVersion::Cairo1 | CairoVersion::Native => CAIRO1_BIT, + CairoVersion::Cairo1 => CAIRO1_BIT, + #[cfg(feature = "cairo_native")] + CairoVersion::Native => CAIRO1_BIT, } } @@ -250,6 +252,7 @@ impl FeatureContract { match cairo_version { CairoVersion::Cairo0 => ERC20_CAIRO0_CONTRACT_SOURCE_PATH, CairoVersion::Cairo1 => ERC20_CAIRO1_CONTRACT_SOURCE_PATH, + #[cfg(feature = "cairo_native")] CairoVersion::Native => todo!("ERC20 cannot be tested with Native"), } .into() @@ -259,6 +262,7 @@ impl FeatureContract { match self.cairo_version() { CairoVersion::Cairo0 => "0", CairoVersion::Cairo1 => "1", + #[cfg(feature = "cairo_native")] CairoVersion::Native => "_native", }, self.get_non_erc20_base_name() @@ -272,6 +276,7 @@ impl FeatureContract { match cairo_version { CairoVersion::Cairo0 => ERC20_CAIRO0_CONTRACT_PATH, CairoVersion::Cairo1 => ERC20_CAIRO1_CONTRACT_PATH, + #[cfg(feature = "cairo_native")] CairoVersion::Native => todo!("ERC20 cannot be tested with Native"), } .into() @@ -282,12 +287,14 @@ impl FeatureContract { match cairo_version { CairoVersion::Cairo0 => "0", CairoVersion::Cairo1 => "1", + #[cfg(feature = "cairo_native")] CairoVersion::Native => "_native", }, self.get_non_erc20_base_name(), match cairo_version { CairoVersion::Cairo0 => "_compiled", CairoVersion::Cairo1 => ".casm", + #[cfg(feature = "cairo_native")] CairoVersion::Native => ".sierra", } ) @@ -320,6 +327,7 @@ impl FeatureContract { let (tag_override, cargo_nightly_arg) = self.fixed_tag_and_rust_toolchain(); cairo1_compile(self.get_source_path(), tag_override, cargo_nightly_arg) } + #[cfg(feature = "cairo_native")] CairoVersion::Native => starknet_compile(self.get_source_path(), None, None), } } diff --git a/crates/blockifier/src/test_utils/struct_impls.rs b/crates/blockifier/src/test_utils/struct_impls.rs index 5906469d56..87d359a27d 100644 --- a/crates/blockifier/src/test_utils/struct_impls.rs +++ b/crates/blockifier/src/test_utils/struct_impls.rs @@ -1,5 +1,6 @@ use std::sync::Arc; +#[cfg(feature = "cairo_native")] use cairo_native::executor::AotNativeExecutor; use cairo_vm::vm::runners::cairo_runner::ExecutionResources; use serde_json::Value; @@ -16,12 +17,14 @@ use crate::bouncer::{BouncerConfig, BouncerWeights, BuiltinCount}; use crate::context::{BlockContext, ChainInfo, FeeTokenAddresses, TransactionContext}; use crate::execution::call_info::{CallExecution, CallInfo, Retdata}; use crate::execution::common_hints::ExecutionMode; -use crate::execution::contract_class::{ContractClassV0, ContractClassV1, NativeContractClassV1}; +use crate::execution::contract_class::{ContractClassV0, ContractClassV1}; use crate::execution::entry_point::{ CallEntryPoint, EntryPointExecutionContext, EntryPointExecutionResult, }; +#[cfg(feature = "cairo_native")] +use crate::execution::native::contract_class::NativeContractClassV1; use crate::state::state_api::State; use crate::test_utils::{ get_raw_contract_class, @@ -250,6 +253,7 @@ impl BouncerWeights { } } +#[cfg(feature = "cairo_native")] impl NativeContractClassV1 { /// Convenience function to construct a NativeContractClassV1 from a raw contract class. /// If control over the compilation is desired use [Self::new] instead. @@ -275,7 +279,10 @@ impl NativeContractClassV1 { let sierra_program = sierra_contract_class.extract_sierra_program()?; let executor = compile_and_load(&sierra_program)?; - Ok(Self::new(executor, sierra_contract_class)) + let casm_contract_class = cairo_lang_starknet_classes::casm_contract_class::CasmContractClass::from_contract_class(sierra_contract_class.clone(), false, usize::MAX)?; + let casm = ContractClassV1::try_from(casm_contract_class)?; + + Ok(Self::new(executor, sierra_contract_class, casm)) } pub fn from_file(contract_path: &str) -> Self { diff --git a/crates/blockifier/src/transaction/transactions_test.rs b/crates/blockifier/src/transaction/transactions_test.rs index 521fe88c6b..808405a493 100644 --- a/crates/blockifier/src/transaction/transactions_test.rs +++ b/crates/blockifier/src/transaction/transactions_test.rs @@ -194,14 +194,20 @@ fn expected_validate_call_info( ) -> Option { let retdata = match cairo_version { CairoVersion::Cairo0 => Retdata::default(), - CairoVersion::Cairo1 | CairoVersion::Native => retdata!(felt!(constants::VALIDATE_RETDATA)), + CairoVersion::Cairo1 => retdata!(felt!(constants::VALIDATE_RETDATA)), + #[cfg(feature = "cairo_native")] + CairoVersion::Native => retdata!(felt!(constants::VALIDATE_RETDATA)), }; // Extra range check in regular (invoke) validate call, due to passing the calldata as an array. let n_range_checks = match cairo_version { CairoVersion::Cairo0 => { usize::from(entry_point_selector_name == constants::VALIDATE_ENTRY_POINT_NAME) } - CairoVersion::Cairo1 | CairoVersion::Native => { + CairoVersion::Cairo1 => { + if entry_point_selector_name == constants::VALIDATE_ENTRY_POINT_NAME { 7 } else { 2 } + } + #[cfg(feature = "cairo_native")] + CairoVersion::Native => { if entry_point_selector_name == constants::VALIDATE_ENTRY_POINT_NAME { 7 } else { 2 } } }; diff --git a/crates/blockifier/tests/feature_contracts_compatibility_test.rs b/crates/blockifier/tests/feature_contracts_compatibility_test.rs index e4aa45b29d..a99f7bedbf 100644 --- a/crates/blockifier/tests/feature_contracts_compatibility_test.rs +++ b/crates/blockifier/tests/feature_contracts_compatibility_test.rs @@ -7,6 +7,7 @@ use rstest::rstest; const CAIRO0_FEATURE_CONTRACTS_DIR: &str = "feature_contracts/cairo0"; const CAIRO1_FEATURE_CONTRACTS_DIR: &str = "feature_contracts/cairo1"; +#[cfg(feature = "cairo_native")] const NATIVE_FEATURE_CONTRACTS_DIR: &str = "feature_contracts/cairo_native"; const COMPILED_CONTRACTS_SUBDIR: &str = "compiled"; const FIX_COMMAND: &str = "FIX_FEATURE_TEST=1 cargo test -p blockifier --test \ @@ -65,11 +66,13 @@ fn verify_and_get_files(cairo_version: CairoVersion) -> Vec<(String, String, Str let directory = match cairo_version { CairoVersion::Cairo0 => CAIRO0_FEATURE_CONTRACTS_DIR, CairoVersion::Cairo1 => CAIRO1_FEATURE_CONTRACTS_DIR, + #[cfg(feature = "cairo_native")] CairoVersion::Native => NATIVE_FEATURE_CONTRACTS_DIR, }; let compiled_extension = match cairo_version { CairoVersion::Cairo0 => "_compiled.json", CairoVersion::Cairo1 => ".casm.json", + #[cfg(feature = "cairo_native")] CairoVersion::Native => ".sierra.json", }; for file in fs::read_dir(directory).unwrap() { diff --git a/crates/tests-integration/Cargo.toml b/crates/tests-integration/Cargo.toml index 294c3470fb..cb09b5c0c0 100644 --- a/crates/tests-integration/Cargo.toml +++ b/crates/tests-integration/Cargo.toml @@ -8,6 +8,9 @@ license.workspace = true [lints] workspace = true +[features] +cairo_native = ["blockifier/cairo_native"] + [dependencies] anyhow.workspace = true assert_matches.workspace = true diff --git a/crates/tests-integration/src/state_reader.rs b/crates/tests-integration/src/state_reader.rs index b566245d0b..ac80b521e7 100644 --- a/crates/tests-integration/src/state_reader.rs +++ b/crates/tests-integration/src/state_reader.rs @@ -183,7 +183,10 @@ fn prepare_compiled_contract_classes( serde_json::from_str(&contract.raw_class()).unwrap(), )); } - CairoVersion::Native => todo!("look up what we need here"), + #[cfg(feature = "cairo_native")] + CairoVersion::Native => { + todo!("native integration doesn't support this yet") + } } } @@ -319,8 +322,9 @@ impl<'a> ThinStateDiffBuilder<'a> { CairoVersion::Cairo1 => { self.declared_classes.insert(contract.class_hash(), Default::default()); } + #[cfg(feature = "cairo_native")] CairoVersion::Native => { - todo!("look up what we need to do here") + todo!("native integration doesn't support this yet") } } }