Skip to content

Commit

Permalink
refactor(blockifier) split feature contracts to groups based on their…
Browse files Browse the repository at this point in the history
… tags
  • Loading branch information
meship-starkware committed Nov 24, 2024
1 parent 34323a1 commit 341c9dd
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 31 deletions.
14 changes: 11 additions & 3 deletions crates/blockifier/src/test_utils/cairo_compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -204,10 +204,9 @@ fn verify_cairo0_compiler_deps() {
);
}

fn prepare_cairo1_compiler_deps(git_tag_override: Option<String>) {
let cairo_repo_path = local_cairo1_compiler_repo_path();
fn get_tag_and_repo_file_path(git_tag_override: Option<String>) -> (String, PathBuf) {
let tag = git_tag_override.unwrap_or(cairo1_compiler_tag());

let cairo_repo_path = local_cairo1_compiler_repo_path();
// Check if the path is a directory.
assert!(
cairo_repo_path.is_dir(),
Expand All @@ -216,13 +215,22 @@ fn prepare_cairo1_compiler_deps(git_tag_override: Option<String>) {
cairo_repo_path.to_string_lossy(),
);

(tag, cairo_repo_path)
}

pub fn prepare_group_tag_compiler_deps(git_tag_override: Option<String>) {
let (tag, cairo_repo_path) = get_tag_and_repo_file_path(git_tag_override);
// Checkout the required version in the compiler repo.
run_and_verify_output(Command::new("git").args([
"-C",
cairo_repo_path.to_str().unwrap(),
"checkout",
&tag,
]));
}

fn prepare_cairo1_compiler_deps(git_tag_override: Option<String>) {
let (tag, cairo_repo_path) = get_tag_and_repo_file_path(git_tag_override);

// Verify that the checked out tag is as expected.
run_and_verify_output(Command::new("git").args([
Expand Down
51 changes: 39 additions & 12 deletions crates/blockifier/src/test_utils/contracts.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::collections::HashMap;

use cairo_lang_starknet_classes::casm_contract_class::CasmContractClass;
use starknet_api::abi::abi_utils::selector_from_name;
use starknet_api::abi::constants::CONSTRUCTOR_ENTRY_POINT_NAME;
Expand Down Expand Up @@ -86,6 +88,8 @@ 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 TagToContractsMapping = HashMap<(Option<String>, Option<String>), Vec<FeatureContract>>;

/// 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)]
Expand Down Expand Up @@ -189,7 +193,7 @@ impl FeatureContract {
#[cfg(feature = "cairo_native")]
if CairoVersion::Native == self.cairo_version() {
let native_contract_class =
NativeContractClassV1::compile_or_get_cached(&self.get_compiled_path()).into();
NativeContractClassV1::compile_or_get_cached(&self.get_compiled_path());
return RunnableContractClass::V1Native(native_contract_class);
}

Expand Down Expand Up @@ -317,7 +321,11 @@ impl FeatureContract {

/// 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) -> Vec<u8> {
pub fn compile(
&self,
tag_override: Option<String>,
cargo_nightly_arg: Option<String>,
) -> Vec<u8> {
if matches!(self, Self::ERC20(_)) {
panic!("ERC20 contract recompilation not supported.");
}
Expand All @@ -340,19 +348,15 @@ impl FeatureContract {
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)
}
#[cfg(feature = "cairo_native")]
CairoVersion::Native => {
let (tag_override, cargo_nightly_arg) = self.fixed_tag_and_rust_toolchain();
starknet_compile(
self.get_source_path(),
tag_override,
cargo_nightly_arg,
&mut vec![],
)
}
CairoVersion::Native => starknet_compile(
self.get_source_path(),
tag_override,
cargo_nightly_arg,
&mut vec![],
),
}
}

Expand Down Expand Up @@ -409,6 +413,29 @@ impl FeatureContract {
self.get_offset(selector, EntryPointType::Constructor)
}

pub fn feature_contracts_by_tag() -> TagToContractsMapping {
// EnumIter iterates over all variants with Default::default() as the cairo
// version.
let mut map = HashMap::new();
for contract in Self::iter() {
if matches!(contract, Self::ERC20(_)) {
continue;
}
let key = contract.fixed_tag_and_rust_toolchain();
let contracts_to_insert = if contract.has_two_versions() {
let mut other_contract = contract;
other_contract.set_cairo_version(contract.cairo_version().other());
map.entry((None, None)).or_insert_with(Vec::new).extend(vec![other_contract]);
vec![contract]
}else {
vec![contract]
};

map.entry(key).or_insert_with(Vec::new).extend(contracts_to_insert);
}
map
}

pub fn all_contracts() -> impl Iterator<Item = Self> {
// EnumIter iterates over all variants with Default::default() as the cairo
// version.
Expand Down
41 changes: 25 additions & 16 deletions crates/blockifier/tests/feature_contracts_compatibility_test.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::fs;

use blockifier::test_utils::cairo_compile::prepare_group_tag_compiler_deps;
use blockifier::test_utils::contracts::FeatureContract;
use blockifier::test_utils::CairoVersion;
use pretty_assertions::assert_eq;
Expand Down Expand Up @@ -36,25 +37,33 @@ const FIX_COMMAND: &str = "FIX_FEATURE_TEST=1 cargo test -p blockifier --test \
// `COMPILED_CONTRACTS_SUBDIR` which equals `starknet-compile-deprecated X.cairo --no_debug_info`.
fn verify_feature_contracts_compatibility(fix: bool, cairo_version: CairoVersion) {
// TODO(Dori, 1/10/2024): Parallelize this test.
for contract in FeatureContract::all_feature_contracts()
.filter(|contract| contract.cairo_version() == cairo_version)
for ((tag_override, cargo_nightly_arg), feature_contracts) in
FeatureContract::feature_contracts_by_tag()
{
// Compare output of cairo-file on file with existing compiled file.
let expected_compiled_output = contract.compile();
let existing_compiled_path = contract.get_compiled_path();
prepare_group_tag_compiler_deps(tag_override.clone());
for contract in feature_contracts
.into_iter()
.filter(|contract| contract.cairo_version() == cairo_version)
{
// Compare output of cairo-file on file with existing compiled file.
let expected_compiled_output =
contract.compile(tag_override.clone(), cargo_nightly_arg.clone());
let existing_compiled_path = contract.get_compiled_path();

if fix {
fs::write(&existing_compiled_path, &expected_compiled_output).unwrap();
}
let existing_compiled_contents = fs::read_to_string(&existing_compiled_path)
.unwrap_or_else(|_| panic!("Cannot read {existing_compiled_path}."));
if fix {
fs::write(&existing_compiled_path, &expected_compiled_output).unwrap();
}
let existing_compiled_contents = fs::read_to_string(&existing_compiled_path)
.unwrap_or_else(|_| panic!("Cannot read {existing_compiled_path}."));

if String::from_utf8(expected_compiled_output).unwrap() != existing_compiled_contents {
panic!(
"{} does not compile to {existing_compiled_path}.\nRun `{FIX_COMMAND}` to fix the \
existing file according to locally installed `starknet-compile-deprecated`.\n",
contract.get_source_path()
);
if String::from_utf8(expected_compiled_output).unwrap() != existing_compiled_contents {
panic!(
"{} does not compile to {existing_compiled_path}.\nRun `{FIX_COMMAND}` to fix \
the existing file according to locally installed \
`starknet-compile-deprecated`.\n",
contract.get_source_path()
);
}
}
}
}
Expand Down

0 comments on commit 341c9dd

Please sign in to comment.