Skip to content

Commit adbaf96

Browse files
rodrigo-pinovarex83noaov1
authored
feat(blockifier): add support for native testing (#1301)
* feat: add native to testing suite * feat(blockifier): add cairo native feature test folder and contract * refactor: starknet compile function in casm compile * refactor: use unwrap_or_else instead of match * chore: add Native as a compilation feature * fix: compilation issues caused by previous refactor * feat(blockifier): add support for native testing Co-Authored-By: Bohdan Ohorodnii <[email protected]> Co-Authored-By: Noa Oved <[email protected]>
1 parent eba18d3 commit adbaf96

File tree

11 files changed

+9592
-28
lines changed

11 files changed

+9592
-28
lines changed

crates/blockifier/feature_contracts/cairo_native/compiled/test_contract.sierra.json

Lines changed: 8796 additions & 0 deletions
Large diffs are not rendered by default.

crates/blockifier/feature_contracts/cairo_native/test_contract.cairo

Lines changed: 608 additions & 0 deletions
Large diffs are not rendered by default.

crates/blockifier/src/execution/native/contract_class.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ use cairo_lang_starknet_classes::contract_class::{
66
ContractClass as SierraContractClass,
77
ContractEntryPoint as SierraContractEntryPoint,
88
};
9-
#[allow(unused_imports)]
109
use cairo_native::executor::AotNativeExecutor;
1110
use starknet_api::core::EntryPointSelector;
1211

crates/blockifier/src/execution/stack_trace_test.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,8 @@ Error in contract (contract address: {test_contract_address_2_felt:#064x}, class
245245
let expected_trace = match cairo_version {
246246
CairoVersion::Cairo0 => expected_trace_cairo0,
247247
CairoVersion::Cairo1 => expected_trace_cairo1,
248+
#[cfg(feature = "cairo_native")]
249+
CairoVersion::Native => panic!("Cairo Native is not yet supported"),
248250
};
249251

250252
assert_eq!(tx_execution_error.to_string(), expected_trace);
@@ -365,6 +367,10 @@ Error in contract (contract address: {contract_address_felt:#064x}, class hash:
365367
"
366368
)
367369
}
370+
#[cfg(feature = "cairo_native")]
371+
CairoVersion::Native => {
372+
todo!("Cairo Native is not yet supported here")
373+
}
368374
};
369375

370376
assert_eq!(tx_execution_error.to_string(), expected_trace);
@@ -520,6 +526,10 @@ Error in contract (contract address: {address_felt:#064x}, class hash: {test_con
520526
"
521527
)
522528
}
529+
#[cfg(feature = "cairo_native")]
530+
CairoVersion::Native => {
531+
todo!("Cairo Native not yet supported here.")
532+
}
523533
};
524534

525535
assert_eq!(tx_execution_error.to_string(), expected_trace);
@@ -620,6 +630,8 @@ Error in contract (contract address: {contract_address:#064x}, class hash: {:#06
620630
0x496e76616c6964207363656e6172696f ('Invalid scenario').",
621631
class_hash.0
622632
),
633+
#[cfg(feature = "cairo_native")]
634+
CairoVersion::Native => todo!("Cairo Native is not yet supported here."),
623635
};
624636

625637
// Clean pc locations from the trace.
@@ -692,6 +704,10 @@ Error in contract (contract address: {expected_address:#064x}, class hash: {:#06
692704
class_hash.0
693705
)
694706
.to_string(),
707+
#[cfg(feature = "cairo_native")]
708+
CairoVersion::Native => {
709+
todo!("Cairo Native not yet supported here.")
710+
}
695711
};
696712

697713
// Compare expected and actual error.
@@ -829,6 +845,10 @@ Error in contract (contract address: {expected_address:#064x}, class hash: {:#06
829845
ctor_selector.0
830846
)
831847
}
848+
#[cfg(feature = "cairo_native")]
849+
CairoVersion::Native => {
850+
todo!("Cairo Native not yet supported here.")
851+
}
832852
};
833853

834854
// Compare expected and actual error.

crates/blockifier/src/test_utils.rs

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@ pub const ERC20_CONTRACT_PATH: &str = "./ERC20/ERC20_Cairo0/ERC20_without_some_s
6565
pub enum CairoVersion {
6666
Cairo0,
6767
Cairo1,
68+
#[cfg(feature = "cairo_native")]
69+
Native,
6870
}
6971

7072
impl Default for CairoVersion {
@@ -91,6 +93,8 @@ impl CairoVersion {
9193
match self {
9294
Self::Cairo0 => Self::Cairo1,
9395
Self::Cairo1 => Self::Cairo0,
96+
#[cfg(feature = "cairo_native")]
97+
Self::Native => panic!("There is no other version for native"),
9498
}
9599
}
96100
}
@@ -117,6 +121,8 @@ impl CompilerBasedVersion {
117121
TrackedResource::CairoSteps
118122
}
119123
Self::CairoVersion(CairoVersion::Cairo1) => TrackedResource::SierraGas,
124+
#[cfg(feature = "cairo_native")]
125+
Self::CairoVersion(CairoVersion::Native) => TrackedResource::SierraGas,
120126
}
121127
}
122128
}
@@ -319,8 +325,6 @@ macro_rules! check_tx_execution_error_for_custom_hint {
319325
#[macro_export]
320326
macro_rules! check_tx_execution_error_for_invalid_scenario {
321327
($cairo_version:expr, $error:expr, $validate_constructor:expr $(,)?) => {
322-
use $crate::transaction::errors::TransactionExecutionError;
323-
324328
match $cairo_version {
325329
CairoVersion::Cairo0 => {
326330
$crate::check_tx_execution_error_inner!(
@@ -329,8 +333,22 @@ macro_rules! check_tx_execution_error_for_invalid_scenario {
329333
$validate_constructor,
330334
);
331335
}
332-
CairoVersion::Cairo1 => {
333-
if let TransactionExecutionError::ValidateTransactionError { error, .. } = $error {
336+
CairoVersion::Cairo1 => {
337+
if let $crate::transaction::errors::TransactionExecutionError::ValidateTransactionError {
338+
error, ..
339+
} = $error {
340+
assert_eq!(
341+
error.to_string(),
342+
"Execution failed. Failure reason: 0x496e76616c6964207363656e6172696f \
343+
('Invalid scenario')."
344+
)
345+
}
346+
}
347+
#[cfg(feature = "cairo_native")]
348+
CairoVersion::Native => {
349+
if let $crate::transaction::errors::TransactionExecutionError::ValidateTransactionError {
350+
error, ..
351+
} = $error {
334352
assert_eq!(
335353
error.to_string(),
336354
"Execution failed. Failure reason: 0x496e76616c6964207363656e6172696f \

crates/blockifier/src/test_utils/cairo_compile.rs

Lines changed: 34 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -71,10 +71,10 @@ fn local_cairo1_compiler_repo_path() -> PathBuf {
7171
// Location of blockifier's Cargo.toml.
7272
let manifest_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
7373

74-
Path::new(&manifest_dir).join(match std::env::var(CAIRO1_REPO_RELATIVE_PATH_OVERRIDE_ENV_VAR) {
75-
Ok(cairo1_repo_relative_path) => cairo1_repo_relative_path,
76-
Err(_) => DEFAULT_CAIRO1_REPO_RELATIVE_PATH.into(),
77-
})
74+
Path::new(&manifest_dir).join(
75+
env::var(CAIRO1_REPO_RELATIVE_PATH_OVERRIDE_ENV_VAR)
76+
.unwrap_or_else(|_| DEFAULT_CAIRO1_REPO_RELATIVE_PATH.into()),
77+
)
7878
}
7979

8080
/// Runs a command. If it has succeeded, it returns the command's output; otherwise, it panics with
@@ -110,16 +110,43 @@ pub fn cairo1_compile(
110110
path: String,
111111
git_tag_override: Option<String>,
112112
cargo_nightly_arg: Option<String>,
113+
) -> Vec<u8> {
114+
let mut base_compile_args = vec![];
115+
116+
let sierra_output =
117+
starknet_compile(path, git_tag_override, cargo_nightly_arg, &mut base_compile_args);
118+
119+
let mut temp_file = NamedTempFile::new().unwrap();
120+
temp_file.write_all(&sierra_output).unwrap();
121+
let temp_path_str = temp_file.into_temp_path();
122+
123+
// Sierra -> CASM.
124+
let mut sierra_compile_command = Command::new("cargo");
125+
sierra_compile_command.args(base_compile_args);
126+
sierra_compile_command.args(["starknet-sierra-compile", temp_path_str.to_str().unwrap()]);
127+
let casm_output = run_and_verify_output(&mut sierra_compile_command);
128+
129+
casm_output.stdout
130+
}
131+
132+
/// Compile Cairo1 Contract into their Sierra version using the compiler version set in the
133+
/// Cargo.toml
134+
pub fn starknet_compile(
135+
path: String,
136+
git_tag_override: Option<String>,
137+
cargo_nightly_arg: Option<String>,
138+
base_compile_args: &mut Vec<String>,
113139
) -> Vec<u8> {
114140
prepare_cairo1_compiler_deps(git_tag_override);
141+
115142
let cairo1_compiler_path = local_cairo1_compiler_repo_path();
116143

117144
// Command args common to both compilation phases.
118-
let mut base_compile_args = vec![
145+
base_compile_args.extend(vec![
119146
"run".into(),
120147
format!("--manifest-path={}/Cargo.toml", cairo1_compiler_path.to_string_lossy()),
121148
"--bin".into(),
122-
];
149+
]);
123150
// Add additional cargo arg if provided. Should be first arg (base command is `cargo`).
124151
if let Some(nightly_version) = cargo_nightly_arg {
125152
base_compile_args.insert(0, format!("+nightly-{nightly_version}"));
@@ -131,17 +158,7 @@ pub fn cairo1_compile(
131158
starknet_compile_commmand.args(["starknet-compile", "--", "--single-file", &path]);
132159
let sierra_output = run_and_verify_output(&mut starknet_compile_commmand);
133160

134-
let mut temp_file = NamedTempFile::new().unwrap();
135-
temp_file.write_all(&sierra_output.stdout).unwrap();
136-
let temp_path_str = temp_file.into_temp_path();
137-
138-
// Sierra -> CASM.
139-
let mut sierra_compile_command = Command::new("cargo");
140-
sierra_compile_command.args(base_compile_args);
141-
sierra_compile_command.args(["starknet-sierra-compile", temp_path_str.to_str().unwrap()]);
142-
let casm_output = run_and_verify_output(&mut sierra_compile_command);
143-
144-
casm_output.stdout
161+
sierra_output.stdout
145162
}
146163

147164
/// Verifies that the required dependencies are available before compiling; panics if unavailable.

crates/blockifier/src/test_utils/contracts.rs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ use crate::abi::abi_utils::selector_from_name;
1414
use crate::abi::constants::CONSTRUCTOR_ENTRY_POINT_NAME;
1515
use crate::execution::contract_class::RunnableContractClass;
1616
use crate::execution::entry_point::CallEntryPoint;
17+
#[cfg(feature = "cairo_native")]
18+
use crate::execution::native::contract_class::NativeContractClassV1;
19+
#[cfg(feature = "cairo_native")]
20+
use crate::test_utils::cairo_compile::starknet_compile;
1721
use crate::test_utils::cairo_compile::{cairo0_compile, cairo1_compile};
1822
use crate::test_utils::struct_impls::LoadContractFromFile;
1923
use crate::test_utils::{get_raw_contract_class, CairoVersion};
@@ -141,6 +145,8 @@ impl FeatureContract {
141145
match self.cairo_version() {
142146
CairoVersion::Cairo0 => CompiledClassHash(Felt::ZERO),
143147
CairoVersion::Cairo1 => CompiledClassHash(felt!(self.get_integer_base())),
148+
#[cfg(feature = "cairo_native")]
149+
CairoVersion::Native => CompiledClassHash(felt!(self.get_integer_base())),
144150
}
145151
}
146152

@@ -158,10 +164,20 @@ impl FeatureContract {
158164
CairoVersion::Cairo1 => {
159165
ContractClass::V1(CasmContractClass::from_file(&self.get_compiled_path()))
160166
}
167+
#[cfg(feature = "cairo_native")]
168+
CairoVersion::Native => {
169+
panic!("Native contracts are not supported by this function.")
170+
}
161171
}
162172
}
163173

164174
pub fn get_runnable_class(&self) -> RunnableContractClass {
175+
#[cfg(feature = "cairo_native")]
176+
if CairoVersion::Native == self.cairo_version() {
177+
let native_contract_class = NativeContractClassV1::from_file(&self.get_compiled_path());
178+
return RunnableContractClass::V1Native(native_contract_class);
179+
}
180+
165181
self.get_class().try_into().unwrap()
166182
}
167183

@@ -188,6 +204,8 @@ impl FeatureContract {
188204
match self.cairo_version() {
189205
CairoVersion::Cairo0 => 0,
190206
CairoVersion::Cairo1 => CAIRO1_BIT,
207+
#[cfg(feature = "cairo_native")]
208+
CairoVersion::Native => CAIRO1_BIT,
191209
}
192210
}
193211

@@ -244,6 +262,8 @@ impl FeatureContract {
244262
match cairo_version {
245263
CairoVersion::Cairo0 => ERC20_CAIRO0_CONTRACT_SOURCE_PATH,
246264
CairoVersion::Cairo1 => ERC20_CAIRO1_CONTRACT_SOURCE_PATH,
265+
#[cfg(feature = "cairo_native")]
266+
CairoVersion::Native => todo!("ERC20 contract is not supported by Native yet"),
247267
}
248268
.into()
249269
} else {
@@ -252,6 +272,8 @@ impl FeatureContract {
252272
match self.cairo_version() {
253273
CairoVersion::Cairo0 => "0",
254274
CairoVersion::Cairo1 => "1",
275+
#[cfg(feature = "cairo_native")]
276+
CairoVersion::Native => "_native",
255277
},
256278
self.get_non_erc20_base_name()
257279
)
@@ -264,6 +286,8 @@ impl FeatureContract {
264286
match cairo_version {
265287
CairoVersion::Cairo0 => ERC20_CAIRO0_CONTRACT_PATH,
266288
CairoVersion::Cairo1 => ERC20_CAIRO1_CONTRACT_PATH,
289+
#[cfg(feature = "cairo_native")]
290+
CairoVersion::Native => todo!("ERC20 cannot be tested with Native"),
267291
}
268292
.into()
269293
} else {
@@ -273,11 +297,15 @@ impl FeatureContract {
273297
match cairo_version {
274298
CairoVersion::Cairo0 => "0",
275299
CairoVersion::Cairo1 => "1",
300+
#[cfg(feature = "cairo_native")]
301+
CairoVersion::Native => "_native",
276302
},
277303
self.get_non_erc20_base_name(),
278304
match cairo_version {
279305
CairoVersion::Cairo0 => "_compiled",
280306
CairoVersion::Cairo1 => ".casm",
307+
#[cfg(feature = "cairo_native")]
308+
CairoVersion::Native => ".sierra",
281309
}
282310
)
283311
}
@@ -309,6 +337,16 @@ impl FeatureContract {
309337
let (tag_override, cargo_nightly_arg) = self.fixed_tag_and_rust_toolchain();
310338
cairo1_compile(self.get_source_path(), tag_override, cargo_nightly_arg)
311339
}
340+
#[cfg(feature = "cairo_native")]
341+
CairoVersion::Native => {
342+
let (tag_override, cargo_nightly_arg) = self.fixed_tag_and_rust_toolchain();
343+
starknet_compile(
344+
self.get_source_path(),
345+
tag_override,
346+
cargo_nightly_arg,
347+
&mut vec![],
348+
)
349+
}
312350
}
313351
}
314352

0 commit comments

Comments
 (0)