diff --git a/Cargo.lock b/Cargo.lock index f7b39f1bab..4f8505e26b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10306,6 +10306,19 @@ dependencies = [ "thiserror", ] +[[package]] +name = "starknet_class_manager_types" +version = "0.0.0" +dependencies = [ + "async-trait", + "cairo-lang-starknet-classes", + "papyrus_proc_macros", + "serde", + "starknet_api", + "starknet_sequencer_infra", + "thiserror", +] + [[package]] name = "starknet_client" version = "0.0.0" diff --git a/Cargo.toml b/Cargo.toml index bfac7a76f6..650899940a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -32,6 +32,7 @@ members = [ "crates/starknet_api", "crates/starknet_batcher", "crates/starknet_batcher_types", + "crates/starknet_class_manager_types", "crates/starknet_client", "crates/starknet_committer", "crates/starknet_consensus_manager", @@ -217,6 +218,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_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" } starknet_consensus_manager = { path = "crates/starknet_consensus_manager", version = "0.0.0" } diff --git a/commitlint.config.js b/commitlint.config.js index f371cc6f69..e3fae9fd53 100644 --- a/commitlint.config.js +++ b/commitlint.config.js @@ -56,6 +56,7 @@ const Configuration = { 'starknet_client', 'starknet_committer', 'starknet_consensus_manager', + 'starknet_class_manager_types', 'starknet_gateway', 'starknet_gateway_types', 'starknet_http_server', diff --git a/crates/starknet_class_manager_types/Cargo.toml b/crates/starknet_class_manager_types/Cargo.toml new file mode 100644 index 0000000000..01a655bcd0 --- /dev/null +++ b/crates/starknet_class_manager_types/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "starknet_class_manager_types" +edition.workspace = true +license.workspace = true +repository.workspace = true +version.workspace = true + +[lints] +workspace = true + +[dependencies] +async-trait.workspace = true +cairo-lang-starknet-classes.workspace = true +papyrus_proc_macros.workspace = true +serde = { workspace = true, features = ["derive"] } +starknet_api.workspace = true +starknet_sequencer_infra.workspace = true +thiserror.workspace = true diff --git a/crates/starknet_class_manager_types/src/lib.rs b/crates/starknet_class_manager_types/src/lib.rs new file mode 100644 index 0000000000..52629a77b4 --- /dev/null +++ b/crates/starknet_class_manager_types/src/lib.rs @@ -0,0 +1,108 @@ +use async_trait::async_trait; +use cairo_lang_starknet_classes::casm_contract_class::CasmContractClass; +use papyrus_proc_macros::handle_response_variants; +use serde::{Deserialize, Serialize}; +use starknet_api::core::{ClassHash, CompiledClassHash}; +use starknet_api::state::SierraContractClass; +use starknet_sequencer_infra::component_client::ClientError; +use starknet_sequencer_infra::component_definitions::ComponentClient; +use thiserror::Error; + +pub type ClassManagerResult = Result; +pub type ClassManagerClientResult = Result; + +// TODO: export. +pub type ClassId = ClassHash; +pub type Class = SierraContractClass; +pub type ExecutableClass = CasmContractClass; +pub type ExecutableClassHash = CompiledClassHash; + +/// Serves as the class manager's shared interface. +/// Requires `Send + Sync` to allow transferring and sharing resources (inputs, futures) across +/// threads. +#[async_trait] +pub trait ClassManagerClient: Send + Sync { + // TODO(native): make generic in executable type. + async fn add_class( + &self, + class_id: ClassId, + class: Class, + ) -> ClassManagerClientResult; + + async fn get_executable(&self, class_id: ClassId) -> ClassManagerClientResult; + + async fn get_sierra(&self, class_id: ClassId) -> ClassManagerClientResult; +} + +#[derive(Clone, Debug, Error, Eq, PartialEq, Serialize, Deserialize)] +pub enum ClassManagerError { + #[error("Compilation failed: {0}")] + CompilationUtilError(String), + #[error("Class of hash: {class_id} not found")] + ClassNotFound { class_id: ClassId }, +} + +#[derive(Clone, Debug, Error)] +pub enum ClassManagerClientError { + #[error(transparent)] + ClientError(#[from] ClientError), + #[error(transparent)] + ClassManagerError(#[from] ClassManagerError), +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +pub enum ClassManagerRequest { + AddClass(ClassId, Class), + GetExecutable(ClassId), + GetSierra(ClassId), +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +pub enum ClassManagerResponse { + AddClass(ClassManagerResult), + GetExecutable(ClassManagerResult), + GetSierra(ClassManagerResult), +} + +#[async_trait] +impl ClassManagerClient for ComponentClientType +where + ComponentClientType: Send + Sync + ComponentClient, +{ + async fn add_class( + &self, + class_id: ClassId, + class: Class, + ) -> ClassManagerClientResult { + let request = ClassManagerRequest::AddClass(class_id, class); + let response = self.send(request).await; + handle_response_variants!( + ClassManagerResponse, + AddClass, + ClassManagerClientError, + ClassManagerError + ) + } + + async fn get_executable(&self, class_id: ClassId) -> ClassManagerClientResult { + let request = ClassManagerRequest::GetExecutable(class_id); + let response = self.send(request).await; + handle_response_variants!( + ClassManagerResponse, + GetExecutable, + ClassManagerClientError, + ClassManagerError + ) + } + + async fn get_sierra(&self, class_id: ClassId) -> ClassManagerClientResult { + let request = ClassManagerRequest::GetSierra(class_id); + let response = self.send(request).await; + handle_response_variants!( + ClassManagerResponse, + GetSierra, + ClassManagerClientError, + ClassManagerError + ) + } +} diff --git a/crates/starknet_sierra_compile/src/errors.rs b/crates/starknet_sierra_compile/src/errors.rs index d38760a5f7..0de236d66e 100644 --- a/crates/starknet_sierra_compile/src/errors.rs +++ b/crates/starknet_sierra_compile/src/errors.rs @@ -2,9 +2,10 @@ use cairo_lang_starknet_classes::allowed_libfuncs::AllowedLibfuncsError; use cairo_lang_starknet_classes::casm_contract_class::StarknetSierraCompilationError; #[cfg(feature = "cairo_native")] use cairo_native; +use serde::{Deserialize, Serialize}; use thiserror::Error; -#[derive(Debug, Error)] +#[derive(Clone, Debug, Error, PartialEq, Eq, Serialize, Deserialize)] pub enum CompilationUtilError { #[error("Starknet Sierra compilation error: {0}")] CompilationError(String),