-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #8 from iosis-tech/feat/compiler
- Loading branch information
Showing
25 changed files
with
445 additions
and
83 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
[package] | ||
name = "sharp-p2p-compiler" | ||
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] | ||
async-process.workspace = true | ||
cairo-proof-parser.workspace = true | ||
futures.workspace = true | ||
hex.workspace = true | ||
itertools.workspace = true | ||
libsecp256k1.workspace = true | ||
rand.workspace = true | ||
serde_json.workspace = true | ||
serde.workspace = true | ||
sharp-p2p-common.workspace = true | ||
strum.workspace = true | ||
tempfile.workspace = true | ||
thiserror.workspace = true | ||
tokio.workspace = true | ||
tracing.workspace = true | ||
zip-extensions.workspace = true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
use std::process::Command; | ||
|
||
fn main() { | ||
// Check if cairo-run command is present | ||
check_command("cairo-run"); | ||
|
||
// Check if cairo-compile command is present | ||
check_command("cairo-compile"); | ||
} | ||
|
||
fn check_command(cmd: &str) { | ||
match Command::new(cmd).arg("--version").output() { | ||
Ok(_) => println!("{} command found", cmd), | ||
Err(e) => panic!("Failed to execute {} command: {}", cmd, e), | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
use crate::{errors::CompilerControllerError, traits::CompilerController}; | ||
use async_process::Stdio; | ||
use futures::Future; | ||
use sharp_p2p_common::layout::Layout; | ||
use sharp_p2p_common::{job::Job, process::Process}; | ||
use std::path::PathBuf; | ||
use std::{io::Read, pin::Pin}; | ||
use tempfile::NamedTempFile; | ||
use tokio::{process::Command, select, sync::mpsc}; | ||
use tracing::debug; | ||
|
||
pub mod tests; | ||
|
||
pub struct CairoCompiler {} | ||
|
||
impl CairoCompiler { | ||
pub fn new() -> Self { | ||
Self {} | ||
} | ||
} | ||
|
||
impl Default for CairoCompiler { | ||
fn default() -> Self { | ||
Self::new() | ||
} | ||
} | ||
|
||
impl CompilerController for CairoCompiler { | ||
fn run( | ||
&self, | ||
program_path: PathBuf, | ||
program_input_path: PathBuf, | ||
) -> Result<Process<Result<Job, CompilerControllerError>>, CompilerControllerError> { | ||
let (terminate_tx, mut terminate_rx) = mpsc::channel::<()>(10); | ||
let future: Pin<Box<dyn Future<Output = Result<Job, CompilerControllerError>> + '_>> = | ||
Box::pin(async move { | ||
let layout: &str = Layout::RecursiveWithPoseidon.into(); | ||
|
||
let output = NamedTempFile::new()?; | ||
|
||
let mut task = Command::new("cairo-compile") | ||
.arg(program_path.as_path()) | ||
.arg("--output") | ||
.arg(output.path()) | ||
.arg("--proof_mode") | ||
.stdout(Stdio::null()) | ||
.spawn()?; | ||
|
||
debug!("program {:?} is compiling... ", program_path); | ||
|
||
loop { | ||
select! { | ||
output = task.wait() => { | ||
debug!("{:?}", output); | ||
if !output?.success() { | ||
return Err(CompilerControllerError::TaskTerminated); | ||
} | ||
let output = task.wait_with_output().await?; | ||
debug!("{:?}", output); | ||
break; | ||
} | ||
Some(()) = terminate_rx.recv() => { | ||
task.start_kill()?; | ||
} | ||
} | ||
} | ||
|
||
// output | ||
let mut cairo_pie = NamedTempFile::new()?; | ||
|
||
let mut task = Command::new("cairo-run") | ||
.arg("--program") | ||
.arg(output.path()) | ||
.arg("--layout") | ||
.arg(layout) | ||
.arg("--program_input") | ||
.arg(program_input_path.as_path()) | ||
.arg("--cairo_pie_output") | ||
.arg(cairo_pie.path()) | ||
.arg("--print_output") | ||
.stdout(Stdio::null()) | ||
.spawn()?; | ||
|
||
debug!("program {:?} is generating PIE... ", program_path); | ||
|
||
loop { | ||
select! { | ||
output = task.wait() => { | ||
debug!("{:?}", output); | ||
if !output?.success() { | ||
return Err(CompilerControllerError::TaskTerminated); | ||
} | ||
let output = task.wait_with_output().await?; | ||
debug!("{:?}", output); | ||
break; | ||
} | ||
Some(()) = terminate_rx.recv() => { | ||
task.start_kill()?; | ||
} | ||
} | ||
} | ||
|
||
// cairo run had finished | ||
let mut cairo_pie_bytes = Vec::new(); | ||
cairo_pie.read_to_end(&mut cairo_pie_bytes)?; | ||
|
||
// TODO: calculate details | ||
Ok(Job { cairo_pie_compressed: cairo_pie_bytes, ..Default::default() }) | ||
}); | ||
|
||
Ok(Process::new(future, terminate_tx)) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
pub mod models; | ||
|
||
#[cfg(all(test, feature = "full_test"))] | ||
pub mod multiple_job; | ||
#[cfg(test)] | ||
pub mod single_job; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
use std::{env, path::PathBuf}; | ||
|
||
pub struct TestFixture { | ||
pub program_input_path: PathBuf, | ||
pub program_path: PathBuf, | ||
} | ||
|
||
pub fn fixture() -> TestFixture { | ||
let ws_root = | ||
PathBuf::from(env::var("CARGO_MANIFEST_DIR").expect("CARGO_MANIFEST_DIR env not present")) | ||
.join("../../"); | ||
let program_path = ws_root.join("crates/tests/cairo/fibonacci.cairo"); | ||
let program_input_path = ws_root.join("crates/tests/cairo/fibonacci_input.json"); | ||
|
||
TestFixture { program_path, program_input_path } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
use crate::{ | ||
cairo_compiler::{tests::models::fixture, CairoCompiler}, | ||
traits::CompilerController, | ||
}; | ||
use futures::{stream::FuturesUnordered, StreamExt}; | ||
|
||
#[tokio::test] | ||
async fn run_multiple_jobs() { | ||
let fixture1 = fixture(); | ||
let fixture2 = fixture(); | ||
|
||
let compiler = CairoCompiler::new(); | ||
let mut futures = FuturesUnordered::new(); | ||
|
||
let job1 = compiler.run(fixture1.program_path, fixture1.program_input_path).unwrap(); | ||
let job2 = compiler.run(fixture2.program_path, fixture2.program_input_path).unwrap(); | ||
|
||
futures.push(job1); | ||
futures.push(job2); | ||
|
||
while let Some(job) = futures.next().await { | ||
job.unwrap(); | ||
} | ||
} | ||
|
||
#[tokio::test] | ||
async fn abort_multiple_jobs() { | ||
let fixture1 = fixture(); | ||
let fixture2 = fixture(); | ||
|
||
let runner = CairoCompiler::new(); | ||
let mut futures = FuturesUnordered::new(); | ||
|
||
let job1 = runner.run(fixture1.program_path, fixture1.program_input_path).unwrap(); | ||
let job2 = runner.run(fixture2.program_path, fixture2.program_input_path).unwrap(); | ||
|
||
job1.abort().await.unwrap(); | ||
job2.abort().await.unwrap(); | ||
|
||
futures.push(job1); | ||
futures.push(job2); | ||
|
||
while let Some(job_trace) = futures.next().await { | ||
job_trace.unwrap_err(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
use crate::{ | ||
cairo_compiler::{tests::models::fixture, CairoCompiler}, | ||
traits::CompilerController, | ||
}; | ||
|
||
#[tokio::test] | ||
async fn run_single_job() { | ||
let fixture = fixture(); | ||
|
||
let compiler = CairoCompiler::new(); | ||
compiler.run(fixture.program_path, fixture.program_input_path).unwrap().await.unwrap(); | ||
} | ||
|
||
#[tokio::test] | ||
async fn abort_single_jobs() { | ||
let fixture = fixture(); | ||
|
||
let runner = CairoCompiler::new(); | ||
let job = runner.run(fixture.program_path, fixture.program_input_path).unwrap(); | ||
job.abort().await.unwrap(); | ||
job.await.unwrap_err(); | ||
} |
Oops, something went wrong.