From 76821a3a817ff9bb14468c635ecadf70d25f5228 Mon Sep 17 00:00:00 2001 From: Rodrigo Date: Wed, 20 Nov 2024 12:26:43 +0000 Subject: [PATCH] fix(blockifier): add caching for native contracts (#2080) Co-Authored-By: Bohdan Ohorodnii --- Cargo.lock | 1 + crates/blockifier/src/test_utils/contracts.rs | 3 ++- .../blockifier/src/test_utils/struct_impls.rs | 22 +++++++++++++++++++ 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 2a46eb4ea4..8cac87e986 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1500,6 +1500,7 @@ dependencies = [ "indexmap 2.6.0", "itertools 0.12.1", "keccak", + "lazy_static", "log", "num-bigint 0.4.6", "num-integer", diff --git a/crates/blockifier/src/test_utils/contracts.rs b/crates/blockifier/src/test_utils/contracts.rs index dbbc6a5128..bf572839f0 100644 --- a/crates/blockifier/src/test_utils/contracts.rs +++ b/crates/blockifier/src/test_utils/contracts.rs @@ -188,7 +188,8 @@ impl FeatureContract { pub fn get_runnable_class(&self) -> RunnableContractClass { #[cfg(feature = "cairo_native")] if CairoVersion::Native == self.cairo_version() { - let native_contract_class = NativeContractClassV1::from_file(&self.get_compiled_path()); + let native_contract_class = + NativeContractClassV1::compile_or_get_cached(&self.get_compiled_path()).into(); return RunnableContractClass::V1Native(native_contract_class); } diff --git a/crates/blockifier/src/test_utils/struct_impls.rs b/crates/blockifier/src/test_utils/struct_impls.rs index 5e744b5c9d..2d21fa1564 100644 --- a/crates/blockifier/src/test_utils/struct_impls.rs +++ b/crates/blockifier/src/test_utils/struct_impls.rs @@ -1,4 +1,8 @@ +#[cfg(feature = "cairo_native")] +use std::collections::HashMap; use std::sync::Arc; +#[cfg(feature = "cairo_native")] +use std::sync::{LazyLock, RwLock}; use cairo_lang_starknet_classes::casm_contract_class::CasmContractClass; #[cfg(feature = "cairo_native")] @@ -238,6 +242,10 @@ impl BouncerWeights { } } +#[cfg(feature = "cairo_native")] +static COMPILED_NATIVE_CONTRACT_CACHE: LazyLock>> = + LazyLock::new(|| RwLock::new(HashMap::new())); + #[cfg(feature = "cairo_native")] impl NativeContractClassV1 { /// Convenience function to construct a NativeContractClassV1 from a raw contract class. @@ -271,4 +279,18 @@ impl NativeContractClassV1 { let raw_contract_class = get_raw_contract_class(contract_path); Self::try_from_json_string(&raw_contract_class) } + + /// Compile a contract from a file or get it from the cache. + pub fn compile_or_get_cached(path: &str) -> Self { + let cache = COMPILED_NATIVE_CONTRACT_CACHE.read().unwrap(); + if let Some(cached_class) = cache.get(path) { + return cached_class.clone(); + } + std::mem::drop(cache); + + let class = NativeContractClassV1::from_file(path); + let mut cache = COMPILED_NATIVE_CONTRACT_CACHE.write().unwrap(); + cache.insert(path.to_string(), class.clone()); + class + } }