Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(blockifier): add caching for hot compilation of native contracts #2080

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions crates/blockifier/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ derive_more.workspace = true
indexmap.workspace = true
itertools.workspace = true
keccak.workspace = true
lazy_static.workspace = true
log.workspace = true
num-bigint.workspace = true
num-integer.workspace = true
Expand Down
1 change: 1 addition & 0 deletions crates/blockifier/src/execution/native/contract_class.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use crate::execution::contract_class::{ContractClassV1, EntryPointsByType, HasSe
use crate::execution::entry_point::CallEntryPoint;
use crate::execution::errors::PreExecutionError;
use crate::execution::native::utils::contract_entrypoint_to_entrypoint_selector;

#[derive(Clone, Debug, PartialEq, Eq)]
pub struct NativeContractClassV1(pub Arc<NativeContractClassV1Inner>);
impl Deref for NativeContractClassV1 {
Expand Down
5 changes: 4 additions & 1 deletion crates/blockifier/src/test_utils/contracts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,10 @@ 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();
// let native_contract_class =
// NativeContractClassV1::from_file(&self.get_compiled_path());
return RunnableContractClass::V1Native(native_contract_class);
}

Expand Down
29 changes: 29 additions & 0 deletions crates/blockifier/src/test_utils/struct_impls.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
#[cfg(feature = "cairo_native")]
use std::collections::HashMap;
use std::sync::Arc;
#[cfg(feature = "cairo_native")]
use std::sync::RwLock;

use cairo_lang_starknet_classes::casm_contract_class::CasmContractClass;
#[cfg(feature = "cairo_native")]
use cairo_lang_starknet_classes::contract_class::ContractClass as SierraContractClass;
#[cfg(feature = "cairo_native")]
use cairo_native::executor::AotContractExecutor;
use cairo_vm::vm::runners::cairo_runner::ExecutionResources;
#[cfg(feature = "cairo_native")]
use lazy_static::lazy_static;
use serde_json::Value;
use starknet_api::block::{BlockNumber, BlockTimestamp, NonzeroGasPrice};
use starknet_api::contract_address;
Expand Down Expand Up @@ -238,6 +244,12 @@ impl BouncerWeights {
}
}

#[cfg(feature = "cairo_native")]
lazy_static! {
/// A cache for compiled native contract classes.
static ref CACHED: RwLock<HashMap<String, NativeContractClassV1>> = RwLock::new(HashMap::new());
}

#[cfg(feature = "cairo_native")]
impl NativeContractClassV1 {
/// Convenience function to construct a NativeContractClassV1 from a raw contract class.
Expand Down Expand Up @@ -270,4 +282,21 @@ 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) -> NativeContractClassV1 {
{
let cache = CACHED.read().unwrap();
if let Some(cached_class) = cache.get(path) {
return cached_class.clone();
}
}

let class = NativeContractClassV1::from_file(path);

let mut cache = CACHED.write().unwrap();
cache.insert(path.to_string(), class.clone());

class
}
}
Loading