Skip to content

Commit

Permalink
feat(starknet_class_manager): add storage trait and a cached implemen…
Browse files Browse the repository at this point in the history
  • Loading branch information
elintul authored Jan 19, 2025
1 parent bdd2b78 commit 68ccf63
Show file tree
Hide file tree
Showing 7 changed files with 167 additions and 3 deletions.
9 changes: 9 additions & 0 deletions Cargo.lock

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

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ members = [
"crates/starknet_api",
"crates/starknet_batcher",
"crates/starknet_batcher_types",
"crates/starknet_class_manager",
"crates/starknet_class_manager_types",
"crates/starknet_client",
"crates/starknet_committer",
Expand Down Expand Up @@ -222,6 +223,7 @@ starknet-types-core = "0.1.6"
starknet_api = { path = "crates/starknet_api", version = "0.0.0" }
starknet_batcher = { path = "crates/starknet_batcher", version = "0.0.0" }
starknet_batcher_types = { path = "crates/starknet_batcher_types", version = "0.0.0" }
starknet_class_manager = { path = "crates/starknet_class_manager", version = "0.0.0" }
starknet_class_manager_types = { path = "crates/starknet_class_manager_types", version = "0.0.0" }
starknet_client = { path = "crates/starknet_client", version = "0.0.0" }
starknet_committer = { path = "crates/starknet_committer", version = "0.0.0" }
Expand Down
1 change: 1 addition & 0 deletions commitlint.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ const Configuration = {
'starknet_client',
'starknet_committer',
'starknet_consensus_manager',
'starknet_class_manager',
'starknet_class_manager_types',
'starknet_gateway',
'starknet_gateway_types',
Expand Down
14 changes: 14 additions & 0 deletions crates/starknet_class_manager/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[package]
name = "starknet_class_manager"
edition.workspace = true
license.workspace = true
repository.workspace = true
version.workspace = true

[lints]
workspace = true

[dependencies]
starknet_api.workspace = true
starknet_class_manager_types.workspace = true
starknet_sierra_compile_types.workspace = true
131 changes: 131 additions & 0 deletions crates/starknet_class_manager/src/class_storage.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
use starknet_api::class_cache::GlobalContractCache;
use starknet_class_manager_types::{ClassId, ClassStorageError, ExecutableClassHash};
use starknet_sierra_compile_types::{RawClass, RawExecutableClass};

// TODO(Elin): restrict visibility once this code is used.

pub type ClassStorageResult<T> = Result<T, ClassStorageError>;

pub trait ClassStorage: Send + Sync {
fn set_class(
&mut self,
class_id: ClassId,
class: RawClass,
executable_class_hash: ExecutableClassHash,
executable_class: RawExecutableClass,
) -> ClassStorageResult<()>;

fn get_sierra(&self, class_id: ClassId) -> ClassStorageResult<RawClass>;

fn get_executable(&self, class_id: ClassId) -> ClassStorageResult<RawExecutableClass>;

fn set_deprecated_class(
&mut self,
class_id: ClassId,
class: RawExecutableClass,
) -> ClassStorageResult<()>;
}

#[derive(Clone, Copy, Debug)]
pub struct CachedClassStorageConfig {
class_cache_size: usize,
deprecated_class_cache_size: usize,
}

pub struct CachedClassStorage<S: ClassStorage> {
storage: S,

// Cache.
classes: GlobalContractCache<RawClass>,
executable_classes: GlobalContractCache<RawExecutableClass>,
executable_class_hashes: GlobalContractCache<ExecutableClassHash>,
deprecated_classes: GlobalContractCache<RawExecutableClass>,
}

impl<S: ClassStorage> CachedClassStorage<S> {
pub fn new(config: CachedClassStorageConfig, storage: S) -> Self {
Self {
storage,
classes: GlobalContractCache::new(config.class_cache_size),
executable_classes: GlobalContractCache::new(config.class_cache_size),
executable_class_hashes: GlobalContractCache::new(config.class_cache_size),
deprecated_classes: GlobalContractCache::new(config.deprecated_class_cache_size),
}
}

pub fn class_cached(&self, class_id: ClassId) -> bool {
self.executable_class_hashes.get(&class_id).is_some()
}

pub fn deprecated_class_cached(&self, class_id: ClassId) -> bool {
self.deprecated_classes.get(&class_id).is_some()
}
}

impl<S: ClassStorage> ClassStorage for CachedClassStorage<S> {
fn set_class(
&mut self,
class_id: ClassId,
class: RawClass,
executable_class_hash: ExecutableClassHash,
executable_class: RawExecutableClass,
) -> ClassStorageResult<()> {
if self.class_cached(class_id) {
return Ok(());
}

self.storage.set_class(
class_id,
class.clone(),
executable_class_hash,
executable_class.clone(),
)?;

// Cache the class.
// Done after successfully writing to storage as an optimization;
// does not require atomicity.
self.classes.set(class_id, class);
self.executable_classes.set(class_id, executable_class);
// Cache the executable class hash last; acts as an existence marker.
self.executable_class_hashes.set(class_id, executable_class_hash);

Ok(())
}

fn get_sierra(&self, class_id: ClassId) -> ClassStorageResult<RawClass> {
if let Some(class) = self.classes.get(&class_id) {
return Ok(class);
}

let class = self.storage.get_sierra(class_id)?;
self.classes.set(class_id, class.clone());

Ok(class)
}

fn get_executable(&self, class_id: ClassId) -> ClassStorageResult<RawExecutableClass> {
if let Some(class) = self.deprecated_classes.get(&class_id) {
return Ok(class);
}

let class = self.storage.get_executable(class_id)?;
self.deprecated_classes.set(class_id, class.clone());

Ok(class)
}

fn set_deprecated_class(
&mut self,
class_id: ClassId,
class: RawExecutableClass,
) -> ClassStorageResult<()> {
if self.deprecated_class_cached(class_id) {
return Ok(());
}

self.storage.set_deprecated_class(class_id, class.clone())?;
self.deprecated_classes.set(class_id, class);

Ok(())
}
}
1 change: 1 addition & 0 deletions crates/starknet_class_manager/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub mod class_storage;
12 changes: 9 additions & 3 deletions crates/starknet_class_manager_types/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,17 @@ pub trait ClassManagerClient: Send + Sync {
}

#[derive(Clone, Debug, Error, Eq, PartialEq, Serialize, Deserialize)]
pub enum ClassManagerError {
#[error("Compilation failed: {0}")]
CompilationUtilError(String),
pub enum ClassStorageError {
#[error("Class of hash: {class_id} not found")]
ClassNotFound { class_id: ClassId },
#[error("Storage error occurred: {0}")]
StorageError(String),
}

#[derive(Clone, Debug, Error, Eq, PartialEq, Serialize, Deserialize)]
pub enum ClassManagerError {
#[error(transparent)]
ClassStorageError(#[from] ClassStorageError),
}

#[derive(Clone, Debug, Error)]
Expand Down

0 comments on commit 68ccf63

Please sign in to comment.