From 7e8445ba0aadc9979092f0db26a2d0a912ad7884 Mon Sep 17 00:00:00 2001
From: Itay Tsabary <itayt@starkware.co>
Date: Tue, 30 Jul 2024 13:53:15 +0300
Subject: [PATCH] feat: add batcher_types communication

commit-id:aa33dbd8
---
 Cargo.lock                                |   8 ++
 crates/batcher_types/Cargo.toml           |  10 +-
 crates/batcher_types/src/batcher_types.rs |  21 +++++
 crates/batcher_types/src/communication.rs | 108 ++++++++++++++++++++++
 crates/batcher_types/src/errors.rs        |   9 ++
 crates/batcher_types/src/lib.rs           |   4 +-
 6 files changed, 157 insertions(+), 3 deletions(-)
 create mode 100644 crates/batcher_types/src/batcher_types.rs
 create mode 100644 crates/batcher_types/src/communication.rs
 create mode 100644 crates/batcher_types/src/errors.rs

diff --git a/Cargo.lock b/Cargo.lock
index dbd0885d29f..fff5c4e31d4 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -8918,6 +8918,14 @@ version = "0.0.0"
 [[package]]
 name = "starknet_batcher_types"
 version = "0.0.0"
+dependencies = [
+ "async-trait",
+ "mockall",
+ "papyrus_proc_macros",
+ "serde",
+ "starknet_mempool_infra",
+ "thiserror",
+]
 
 [[package]]
 name = "starknet_client"
diff --git a/crates/batcher_types/Cargo.toml b/crates/batcher_types/Cargo.toml
index b9b93d9d215..cee7f1e9d94 100644
--- a/crates/batcher_types/Cargo.toml
+++ b/crates/batcher_types/Cargo.toml
@@ -6,7 +6,13 @@ license.workspace = true
 repository.workspace = true
 
 
-[dependencies]
-
 [lints]
 workspace = true
+
+[dependencies]
+async-trait.workspace = true
+mockall.workspace = true
+papyrus_proc_macros = { path = "../papyrus_proc_macros" }
+serde = { workspace = true, feat = ["derive"] }
+starknet_mempool_infra = { path = "../mempool_infra" }
+thiserror.workspace = true
diff --git a/crates/batcher_types/src/batcher_types.rs b/crates/batcher_types/src/batcher_types.rs
new file mode 100644
index 00000000000..46ed01af10d
--- /dev/null
+++ b/crates/batcher_types/src/batcher_types.rs
@@ -0,0 +1,21 @@
+use serde::{Deserialize, Serialize};
+
+use crate::errors::BatcherError;
+
+// TODO(Tsabary/Yael/Dafna): Populate the data structure used to invoke the batcher.
+#[derive(Debug, Serialize, Deserialize)]
+pub struct BatcherFnOneInput {}
+
+// TODO(Tsabary/Yael/Dafna): Populate the data structure used to invoke the batcher.
+#[derive(Debug, Serialize, Deserialize)]
+pub struct BatcherFnTwoInput {}
+
+// TODO(Tsabary/Yael/Dafna): Replace with the actual return type of the batcher function.
+#[derive(Debug, Serialize, Deserialize)]
+pub struct BatcherFnOneReturnValue {}
+
+// TODO(Tsabary/Yael/Dafna): Replace with the actual return type of the batcher function.
+#[derive(Debug, Serialize, Deserialize)]
+pub struct BatcherFnTwoReturnValue {}
+
+pub type BatcherResult<T> = Result<T, BatcherError>;
diff --git a/crates/batcher_types/src/communication.rs b/crates/batcher_types/src/communication.rs
new file mode 100644
index 00000000000..b70ba698be2
--- /dev/null
+++ b/crates/batcher_types/src/communication.rs
@@ -0,0 +1,108 @@
+use std::sync::Arc;
+
+use async_trait::async_trait;
+use mockall::predicate::*;
+use mockall::*;
+use papyrus_proc_macros::handle_response_variants;
+use serde::{Deserialize, Serialize};
+use starknet_mempool_infra::component_client::{
+    ClientError,
+    LocalComponentClient,
+    RemoteComponentClient,
+};
+use starknet_mempool_infra::component_definitions::ComponentRequestAndResponseSender;
+use thiserror::Error;
+
+use crate::batcher_types::{
+    BatcherFnOneInput,
+    BatcherFnOneReturnValue,
+    BatcherFnTwoInput,
+    BatcherFnTwoReturnValue,
+    BatcherResult,
+};
+use crate::errors::BatcherError;
+
+pub type LocalBatcherClientImpl = LocalComponentClient<BatcherRequest, BatcherResponse>;
+pub type RemoteBatcherClientImpl = RemoteComponentClient<BatcherRequest, BatcherResponse>;
+pub type BatcherClientResult<T> = Result<T, BatcherClientError>;
+pub type BatcherRequestAndResponseSender =
+    ComponentRequestAndResponseSender<BatcherRequest, BatcherResponse>;
+pub type SharedBatcherClient = Arc<dyn BatcherClient>;
+
+/// Serves as the batcher's shared interface. Requires `Send + Sync` to allow transferring and
+/// sharing resources (inputs, futures) across threads.
+#[automock]
+#[async_trait]
+pub trait BatcherClient: Send + Sync {
+    async fn batcher_fn_one(
+        &self,
+        batcher_fn_one_input: BatcherFnOneInput,
+    ) -> BatcherClientResult<BatcherFnOneReturnValue>;
+
+    async fn batcher_fn_two(
+        &self,
+        batcher_fn_two_input: BatcherFnTwoInput,
+    ) -> BatcherClientResult<BatcherFnTwoReturnValue>;
+}
+
+#[derive(Debug, Serialize, Deserialize)]
+pub enum BatcherRequest {
+    BatcherFnOne(BatcherFnOneInput),
+    BatcherFnTwo(BatcherFnTwoInput),
+}
+
+#[derive(Debug, Serialize, Deserialize)]
+pub enum BatcherResponse {
+    BatcherFnOne(BatcherResult<BatcherFnOneReturnValue>),
+    BatcherFnTwo(BatcherResult<BatcherFnTwoReturnValue>),
+}
+
+#[derive(Clone, Debug, Error)]
+pub enum BatcherClientError {
+    #[error(transparent)]
+    ClientError(#[from] ClientError),
+    #[error(transparent)]
+    BatcherError(#[from] BatcherError),
+}
+
+#[async_trait]
+impl BatcherClient for LocalBatcherClientImpl {
+    async fn batcher_fn_one(
+        &self,
+        batcher_fn_one_input: BatcherFnOneInput,
+    ) -> BatcherClientResult<BatcherFnOneReturnValue> {
+        let request = BatcherRequest::BatcherFnOne(batcher_fn_one_input);
+        let response = self.send(request).await;
+        handle_response_variants!(BatcherResponse, BatcherFnOne, BatcherClientError, BatcherError)
+    }
+
+    async fn batcher_fn_two(
+        &self,
+        batcher_fn_two_input: BatcherFnTwoInput,
+    ) -> BatcherClientResult<BatcherFnTwoReturnValue> {
+        let request = BatcherRequest::BatcherFnTwo(batcher_fn_two_input);
+        let response = self.send(request).await;
+        handle_response_variants!(BatcherResponse, BatcherFnTwo, BatcherClientError, BatcherError)
+    }
+}
+
+#[async_trait]
+impl BatcherClient for RemoteBatcherClientImpl {
+    async fn batcher_fn_one(
+        &self,
+        batcher_fn_one_input: BatcherFnOneInput,
+    ) -> BatcherClientResult<BatcherFnOneReturnValue> {
+        let request = BatcherRequest::BatcherFnOne(batcher_fn_one_input);
+        let response = self.send(request).await?;
+        handle_response_variants!(BatcherResponse, BatcherFnOne, BatcherClientError, BatcherError)
+    }
+
+    async fn batcher_fn_two(
+        &self,
+        batcher_fn_two_input: BatcherFnTwoInput,
+    ) -> BatcherClientResult<BatcherFnTwoReturnValue> {
+        let request = BatcherRequest::BatcherFnTwo(batcher_fn_two_input);
+        let response = self.send(request).await?;
+        handle_response_variants!(BatcherResponse, BatcherFnTwo, BatcherClientError, BatcherError)
+    }
+}
diff --git a/crates/batcher_types/src/errors.rs b/crates/batcher_types/src/errors.rs
new file mode 100644
index 00000000000..1f8c7f2ae84
--- /dev/null
+++ b/crates/batcher_types/src/errors.rs
@@ -0,0 +1,9 @@
+use serde::{Deserialize, Serialize};
+use thiserror::Error;
+
+// TODO(Tsabary/Yael/Dafna): Populate with actual errors.
+#[derive(Clone, Debug, Error, PartialEq, Eq, Serialize, Deserialize)]
+pub enum BatcherError {
+    #[error("Placeholder error message")]
+    Placeholder,
+}
diff --git a/crates/batcher_types/src/lib.rs b/crates/batcher_types/src/lib.rs
index 8b137891791..22ac770efd4 100644
--- a/crates/batcher_types/src/lib.rs
+++ b/crates/batcher_types/src/lib.rs
@@ -1 +1,3 @@
-
+pub mod batcher_types;
+pub mod communication;
+pub mod errors;