diff --git a/crates/prover/Cargo.toml b/crates/prover/Cargo.toml new file mode 100644 index 0000000..cd0504d --- /dev/null +++ b/crates/prover/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "sharp-p2p-prover" +version.workspace = true +edition.workspace = true +repository.workspace = true +license-file.workspace = true + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +tokio.workspace = true +tracing.workspace = true +futures.workspace= true +thiserror.workspace = true +async-process.workspace = true +sharp-p2p-common.workspace = true \ No newline at end of file diff --git a/crates/prover/src/errors.rs b/crates/prover/src/errors.rs new file mode 100644 index 0000000..f739ec3 --- /dev/null +++ b/crates/prover/src/errors.rs @@ -0,0 +1,13 @@ +use thiserror::Error; + +#[derive(Error, Debug)] +pub enum ProverControllerError { + #[error("task not found")] + TaskNotFound, + + #[error("task not found")] + TaskTerminated, + + #[error("io")] + Io(#[from] std::io::Error), +} diff --git a/crates/prover/src/lib.rs b/crates/prover/src/lib.rs new file mode 100644 index 0000000..b92842a --- /dev/null +++ b/crates/prover/src/lib.rs @@ -0,0 +1,5 @@ +pub mod errors; +#[allow(async_fn_in_trait)] +pub mod traits; + +pub mod stone_prover; diff --git a/crates/prover/src/stone_prover/mod.rs b/crates/prover/src/stone_prover/mod.rs new file mode 100644 index 0000000..6be977b --- /dev/null +++ b/crates/prover/src/stone_prover/mod.rs @@ -0,0 +1,60 @@ +use std::collections::HashMap; + +use crate::{ + errors::ProverControllerError, + traits::{Prover, ProverController}, +}; +use sharp_p2p_common::{job::Job, job_witness::JobWitness}; +use tokio::process::{Child, Command}; +use tracing::{debug, trace}; + +pub struct StoneProver { + tasks: HashMap, +} + +impl Prover for StoneProver { + fn init() -> impl ProverController { + Self { tasks: HashMap::new() } + } +} + +impl ProverController for StoneProver { + async fn prove(&mut self, job: Job) -> Result { + let task = Command::new("sleep 20").spawn()?; + debug!("task {} spawned", job); + self.tasks.insert(job.to_owned(), task); + + let task_status = + self.tasks.get_mut(&job).ok_or(ProverControllerError::TaskNotFound)?.wait().await?; + + trace!("task {} woke up", job); + if !task_status.success() { + debug!("task terminated {}", job); + return Err(ProverControllerError::TaskTerminated); + } + + let task_output = self + .tasks + .remove(&job) + .ok_or(ProverControllerError::TaskNotFound)? + .wait_with_output() + .await?; + trace!("task {} output {:?}", job, task_output); + + todo!() + } + + async fn terminate(&mut self, job: &Job) -> Result<(), ProverControllerError> { + self.tasks.get_mut(job).ok_or(ProverControllerError::TaskNotFound)?.start_kill()?; + trace!("task scheduled for termination {}", job); + Ok(()) + } + + async fn drop(mut self) -> Result<(), ProverControllerError> { + let keys: Vec = self.tasks.keys().cloned().collect(); + for job in keys.iter() { + self.terminate(job).await?; + } + Ok(()) + } +} diff --git a/crates/prover/src/traits.rs b/crates/prover/src/traits.rs new file mode 100644 index 0000000..9d75910 --- /dev/null +++ b/crates/prover/src/traits.rs @@ -0,0 +1,13 @@ +use sharp_p2p_common::{job::Job, job_witness::JobWitness}; + +use crate::errors::ProverControllerError; + +pub trait Prover { + fn init() -> impl ProverController; +} + +pub trait ProverController { + async fn prove(&mut self, job: Job) -> Result; + async fn terminate(&mut self, job: &Job) -> Result<(), ProverControllerError>; + async fn drop(self) -> Result<(), ProverControllerError>; +}