Skip to content

Commit

Permalink
Merge pull request #150 from NethermindEth/feature/multiple-cairo-ver…
Browse files Browse the repository at this point in the history
…sions

[WIP] add support of multiple cairo versions
  • Loading branch information
stranger80 authored Oct 18, 2023
2 parents f068f6e + c7f378b commit 921aa2d
Show file tree
Hide file tree
Showing 19 changed files with 529 additions and 318 deletions.
4 changes: 2 additions & 2 deletions DockerfileRocket
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ RUN cargo build --release
RUN chmod +x ./docker_run.sh

# Build the cairo compiler
WORKDIR /opt/app/api/cairo
RUN cargo build --release --workspace
WORKDIR /opt/app/api/cairo_compilers
RUN chmod +x ./build.sh; ./build.sh

EXPOSE 8000

Expand Down
10 changes: 8 additions & 2 deletions api/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,16 @@ RUN rustup install stable

# Create and activate a Python virtual environment
RUN python -m venv ~/cairo_venv
RUN source ~/cairo_venv/bin/activate
RUN . ~/cairo_venv/bin/activate
ENV PATH="/root/cairo_venv/bin:${PATH}"

# Install cairo-lang
RUN pip install cairo-lang

# install Scarb
RUN curl --proto '=https' --tlsv1.2 -sSf https://docs.swmansion.com/scarb/install.sh | bash
ENV PATH="/root/.local/bin:${PATH}"

# Set the working directory
WORKDIR /app

Expand All @@ -38,7 +42,9 @@ COPY . .
# RUN cd cairo; git checkout v1.0.0-alpha.6
# Or if you chose to copy the whole repo
# RUN git submodule update --init
RUN cd cairo; cargo build --bin starknet-compile; cargo build --bin starknet-sierra-compile

#RUN cd cairo; cargo build --bin starknet-compile; cargo build --bin starknet-sierra-compile
RUN cd cairo_compilers; chmod +x build.sh; ./build.sh
RUN cargo build --release

EXPOSE 8000:80
Expand Down
24 changes: 24 additions & 0 deletions api/cairo_compilers/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#!/bin/bash

echo "Building cairo compilers"

directories=$(ls -d */)

for dir in $directories
do
echo "Building $dir"

if [[ ! -f "$dir/Cargo.toml" ]] || [[ ! "$dir" =~ ^v[0-9]+\.[0-9]+\.[0-9]+/$ ]]; then
echo "Invalid cairo version provided $dir"
exit 1
fi

cd "$dir" || exit 1

cargo build --bin starknet-compile --release
cargo build --bin starknet-sierra-compile --release

cd ..

echo "Done building $dir"
done
8 changes: 5 additions & 3 deletions api/src/handlers/cairo_version.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::handlers::process::{do_process_command, fetch_process_result};
use crate::handlers::types::{ApiCommand, ApiCommandResult};
use crate::utils::lib::CAIRO_DIR;
use crate::utils::lib::DEFAULT_CAIRO_DIR;
use crate::worker::WorkerEngine;
use rocket::State;
use std::process::{Command, Stdio};
Expand Down Expand Up @@ -34,9 +34,11 @@ pub async fn get_cairo_version_result(process_id: String, engine: &State<WorkerE

/// Run Cairo --version to return Cairo version string
///
/// ## Note
/// (default Cairo version will be used)
pub fn do_cairo_version() -> Result<String, String> {
let mut version_caller = Command::new("cargo");
version_caller.current_dir(CAIRO_DIR);
version_caller.current_dir(DEFAULT_CAIRO_DIR);
match String::from_utf8(
version_caller
.arg("run")
Expand All @@ -48,7 +50,7 @@ pub fn do_cairo_version() -> Result<String, String> {
.arg("--version")
.stdout(Stdio::piped())
.spawn()
.expect("Failed to execute cairo-compile")
.map_err(|e| format!("Failed to get cairo version: {:?}", e))?
.wait_with_output()
.map_err(|e| format!("Failed to get cairo version: {:?}", e))?
.stdout,
Expand Down
29 changes: 29 additions & 0 deletions api/src/handlers/cairo_versions.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
use crate::utils::lib::CAIRO_COMPILERS_DIR;
use rocket::tokio::fs::read_dir;
use std::path::Path;
use tracing::instrument;

#[instrument]
#[get("/cairo_versions")]
pub async fn cairo_versions() -> String {
do_cairo_versions().await.unwrap_or_else(|e| e)
}

/// Get cairo versions
pub async fn do_cairo_versions() -> Result<String, String> {
let path = Path::new(CAIRO_COMPILERS_DIR);

let mut dir = read_dir(path).await.unwrap();
let mut result = vec![];

while let Ok(Some(entry)) = dir.next_entry().await {
let entry = entry;
let path = entry.path();
if path.is_dir() {
println!("{:?}", entry.file_name());
result.push(entry.file_name().to_string_lossy().to_string());
}
}

Ok(format!("{:?}", result))
}
103 changes: 81 additions & 22 deletions api/src/handlers/compile_casm.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::handlers::process::{do_process_command, fetch_process_result};
use crate::handlers::types::{ApiCommand, ApiCommandResult, CompileResponse};
use crate::utils::lib::{get_file_ext, get_file_path, CAIRO_DIR, CASM_ROOT};
use crate::utils::lib::{get_file_ext, get_file_path, CAIRO_COMPILERS_DIR, CASM_ROOT};
use crate::worker::WorkerEngine;
use rocket::fs::NamedFile;
use rocket::serde::json;
Expand All @@ -12,44 +12,65 @@ use std::process::{Command, Stdio};
use tracing::info;
use tracing::instrument;

#[instrument]
#[get("/compile-to-casm/<remix_file_path..>")]
pub async fn compile_to_casm(remix_file_path: PathBuf) -> Json<CompileResponse> {
#[get("/compile-to-casm/<version>/<remix_file_path..>")]
pub async fn compile_to_casm(version: String, remix_file_path: PathBuf) -> Json<CompileResponse> {
info!("/compile-to-casm/{:?}", remix_file_path);
do_compile_to_casm(remix_file_path).await
do_compile_to_casm(version.clone(), remix_file_path)
.await
.unwrap_or_else(|e| {
Json(CompileResponse {
file_content: "".to_string(),
message: e,
status: "CompilationFailed".to_string(),
cairo_version: version,
})
})
}

#[instrument]
#[get("/compile-to-casm-async/<remix_file_path..>")]
#[get("/compile-to-casm-async/<version>/<remix_file_path..>")]
pub async fn compile_to_casm_async(
version: String,
remix_file_path: PathBuf,
engine: &State<WorkerEngine>,
) -> String {
info!("/compile-to-casm-async/{:?}", remix_file_path);
do_process_command(ApiCommand::CasmCompile(remix_file_path), engine)
do_process_command(
ApiCommand::CasmCompile {
remix_file_path,
version,
},
engine,
)
}

#[instrument]
#[get("/compile-to-casm-result/<process_id>")]
pub async fn compile_to_casm_result(process_id: String, engine: &State<WorkerEngine>) -> String {
info!("/compile-to-casm-result/{:?}", process_id);
fetch_process_result(process_id, engine, |result| match result {
ApiCommandResult::CasmCompile(casm_result) => json::to_string(&casm_result).unwrap(),
ApiCommandResult::CasmCompile(casm_result) => {
json::to_string(&casm_result).unwrap_or("Failed to fetch result".to_string())
}
_ => String::from("Result not available"),
})
}

/// Compile source file to CASM
///
pub async fn do_compile_to_casm(remix_file_path: PathBuf) -> Json<CompileResponse> {
pub async fn do_compile_to_casm(
version: String,
remix_file_path: PathBuf,
) -> Result<Json<CompileResponse>, String> {
let remix_file_path = match remix_file_path.to_str() {
Some(path) => path.to_string(),
None => {
return Json(CompileResponse {
return Ok(Json(CompileResponse {
file_content: "".to_string(),
message: "File path not found".to_string(),
status: "FileNotFound".to_string(),
});
cairo_version: version,
}));
}
};

Expand All @@ -60,11 +81,12 @@ pub async fn do_compile_to_casm(remix_file_path: PathBuf) -> Json<CompileRespons
}
_ => {
debug!("LOG: File extension not supported");
return Json(CompileResponse {
return Ok(Json(CompileResponse {
file_content: "".to_string(),
message: "File extension not supported".to_string(),
status: "FileExtensionNotSupported".to_string(),
});
cairo_version: version,
}));
}
}

Expand All @@ -73,7 +95,19 @@ pub async fn do_compile_to_casm(remix_file_path: PathBuf) -> Json<CompileRespons
let casm_remix_path = remix_file_path.replace(&get_file_ext(&remix_file_path), "casm");

let mut compile = Command::new("cargo");
compile.current_dir(CAIRO_DIR);

let path_to_cairo_compiler = Path::new(CAIRO_COMPILERS_DIR).join(&version);

if path_to_cairo_compiler.exists() {
compile.current_dir(path_to_cairo_compiler);
} else {
return Ok(Json(CompileResponse {
file_content: "".to_string(),
message: "Cairo compiler not found".to_string(),
status: "CairoCompilerNotFound".to_string(),
cairo_version: version,
}));
}

let casm_path = Path::new(CASM_ROOT).join(&casm_remix_path);

Expand Down Expand Up @@ -104,20 +138,32 @@ pub async fn do_compile_to_casm(remix_file_path: PathBuf) -> Json<CompileRespons
.spawn();

if result.is_err() {
return Json(CompileResponse {
return Ok(Json(CompileResponse {
file_content: "".to_string(),
message: "Failed to execute starknet-sierra-compile".to_string(),
status: "SierraCompilationFailed".to_string(),
});
cairo_version: version,
}));
}

let result = result.unwrap();

debug!("LOG: ran command:{:?}", compile);

let output = result.wait_with_output().expect("Failed to wait on child");
let output = result.wait_with_output();

Json(CompileResponse {
if output.is_err() {
return Ok(Json(CompileResponse {
file_content: "".to_string(),
message: "Failed to wait on child".to_string(),
status: "SierraCompilationFailed".to_string(),
cairo_version: version,
}));
}

let output = output.unwrap();

Ok(Json(CompileResponse {
file_content: match NamedFile::open(&casm_path).await.ok() {
Some(file) => match file.path().to_str() {
Some(path) => match fs::read_to_string(path.to_string()).await {
Expand All @@ -129,13 +175,26 @@ pub async fn do_compile_to_casm(remix_file_path: PathBuf) -> Json<CompileRespons
None => "".to_string(),
},
message: String::from_utf8(output.stderr)
.unwrap()
.replace(&file_path.to_str().unwrap().to_string(), &remix_file_path)
.replace(&casm_path.to_str().unwrap().to_string(), &casm_remix_path),
.map_err(|e| format!("Failed to read stderr: {:?}", e))?
.replace(
&file_path
.to_str()
.ok_or("Failed to parse string".to_string())?
.to_string(),
&remix_file_path,
)
.replace(
&casm_path
.to_str()
.ok_or("Failed to parse string".to_string())?
.to_string(),
&casm_remix_path,
),
status: match output.status.code() {
Some(0) => "Success".to_string(),
Some(_) => "SierraCompilationFailed".to_string(),
None => "UnknownError".to_string(),
},
})
cairo_version: version,
}))
}
Loading

0 comments on commit 921aa2d

Please sign in to comment.