diff --git a/Cargo.lock b/Cargo.lock index f7b39f1babd..c010e5815ee 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10376,6 +10376,19 @@ dependencies = [ "validator", ] +[[package]] +name = "starknet_contract_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_gateway" version = "0.0.0" diff --git a/Cargo.toml b/Cargo.toml index bfac7a76f69..5ae9c85ebdd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -35,6 +35,7 @@ members = [ "crates/starknet_client", "crates/starknet_committer", "crates/starknet_consensus_manager", + "crates/starknet_contract_manager_types", "crates/starknet_gateway", "crates/starknet_gateway_types", "crates/starknet_http_server", @@ -220,6 +221,7 @@ starknet_batcher_types = { path = "crates/starknet_batcher_types", version = "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" } +starknet_contract_manager_types = { path = "crates/starknet_contract_manager_types", version = "0.0.0" } starknet_gateway = { path = "crates/starknet_gateway", version = "0.0.0" } starknet_gateway_types = { path = "crates/starknet_gateway_types", version = "0.0.0" } starknet_http_server = { path = "crates/starknet_http_server", version = "0.0.0" } diff --git a/commitlint.config.js b/commitlint.config.js index f371cc6f693..a4ceeab8727 100644 --- a/commitlint.config.js +++ b/commitlint.config.js @@ -56,6 +56,7 @@ const Configuration = { 'starknet_client', 'starknet_committer', 'starknet_consensus_manager', + 'starknet_contract_manager_types', 'starknet_gateway', 'starknet_gateway_types', 'starknet_http_server', diff --git a/crates/starknet_contract_manager_types/Cargo.toml b/crates/starknet_contract_manager_types/Cargo.toml new file mode 100644 index 00000000000..afe2ae63867 --- /dev/null +++ b/crates/starknet_contract_manager_types/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "starknet_contract_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_contract_manager_types/src/lib.rs b/crates/starknet_contract_manager_types/src/lib.rs new file mode 100644 index 00000000000..3c42decf0d9 --- /dev/null +++ b/crates/starknet_contract_manager_types/src/lib.rs @@ -0,0 +1,120 @@ +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 ContractManagerResult = Result; +pub type ContractManagerClientResult = Result; + +// TODO: export. +type ContractId = ClassHash; +type ExecutableClass = CasmContractClass; +type ExecutableClassHash = CompiledClassHash; + +/// Serves as the contract manager's shared interface. +/// Requires `Send + Sync` to allow transferring and sharing resources (inputs, futures) across +/// threads. +#[async_trait] +pub trait ContractManagerClient: Send + Sync { + // TODO(native): make generic in executable type. + async fn add_contract( + &self, + contract_id: ContractId, + contract: SierraContractClass, + ) -> ContractManagerClientResult; + + async fn get_executable( + &self, + contract_id: ContractId, + ) -> ContractManagerClientResult; + + async fn get_sierra( + &self, + contract_id: ContractId, + ) -> ContractManagerClientResult; +} + +#[derive(Clone, Debug, Error, Eq, PartialEq, Serialize, Deserialize)] +pub enum ContractManagerError { + #[error("Compilation failed: {0}")] + CompilationUtilError(String), + #[error("Contract of hash: {contract_id} not found")] + ContractNotFound { contract_id: ContractId }, +} + +#[derive(Clone, Debug, Error)] +pub enum ContractManagerClientError { + #[error(transparent)] + ClientError(#[from] ClientError), + #[error(transparent)] + ContractManagerError(#[from] ContractManagerError), +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +pub enum ContractManagerRequest { + AddContract(ContractId, SierraContractClass), + GetExecutable(ContractId), + GetSierra(ContractId), +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +pub enum ContractManagerResponse { + AddContract(ContractManagerResult), + GetExecutable(ContractManagerResult), + GetSierra(ContractManagerResult), +} + +#[async_trait] +impl ContractManagerClient for ComponentClientType +where + ComponentClientType: + Send + Sync + ComponentClient, +{ + async fn add_contract( + &self, + contract_id: ContractId, + contract: SierraContractClass, + ) -> ContractManagerClientResult { + let request = ContractManagerRequest::AddContract(contract_id, contract); + let response = self.send(request).await; + handle_response_variants!( + ContractManagerResponse, + AddContract, + ContractManagerClientError, + ContractManagerError + ) + } + + async fn get_executable( + &self, + contract_id: ContractId, + ) -> ContractManagerClientResult { + let request = ContractManagerRequest::GetExecutable(contract_id); + let response = self.send(request).await; + handle_response_variants!( + ContractManagerResponse, + GetExecutable, + ContractManagerClientError, + ContractManagerError + ) + } + + async fn get_sierra( + &self, + contract_id: ContractId, + ) -> ContractManagerClientResult { + let request = ContractManagerRequest::GetSierra(contract_id); + let response = self.send(request).await; + handle_response_variants!( + ContractManagerResponse, + GetSierra, + ContractManagerClientError, + ContractManagerError + ) + } +} diff --git a/crates/starknet_sierra_compile/src/errors.rs b/crates/starknet_sierra_compile/src/errors.rs index d38760a5f76..0de236d66e7 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),