Skip to content
This repository has been archived by the owner on Dec 6, 2024. It is now read-only.

Commit

Permalink
Merge pull request #24 from NethermindEth/feature/multiple-solc-versions
Browse files Browse the repository at this point in the history
  • Loading branch information
varex83 authored Nov 13, 2023
2 parents be13d76 + 449f9ae commit 6684b85
Show file tree
Hide file tree
Showing 20 changed files with 553 additions and 230 deletions.
14 changes: 10 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,11 @@ The easiest way to install Rust and Cargo is by using [rustup](https://rustup.rs
Then:

```bash
cd api;
cargo build;
cd api
cd hardhat_env
yarn
cd ..
cargo build
```

#### Plugin
Expand Down Expand Up @@ -78,8 +81,11 @@ pnpm run serve;
```

```bash
cd api;
cargo run;
cd api
cd hardhat_env
yarn
cd ..
VITE_URL=http://localhost:3000 cargo run
```

or alternatively, you can run the server in watch mode (with `cargo watch`):
Expand Down
14 changes: 11 additions & 3 deletions api/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,21 @@

- [Rust](https://www.rust-lang.org/tools/install)

## Prepare

```bash
cd api
cd hardhat_env
yarn
cd ..
```
## Run

```bash
cargo run
VITE_URL=http://localhost:3000 cargo run
```
## To run while watching files

```bash
cargo watch -x run
```
VITE_URL=http://localhost:3000 cargo watch -x run
```
4 changes: 4 additions & 0 deletions api/hardhat_env/hardhat.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ const config: HardhatUserConfig = {
solidity: {
version: "0.8.17",
},
// path to the directory with contracts
paths: {
sources: "./contracts",
},
};

export default config;
32 changes: 32 additions & 0 deletions api/hardhat_env/hardhat2.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// import { HardhatUserConfig } from "hardhat/config";
// import "@matterlabs/hardhat-zksync-deploy";
// import "@matterlabs/hardhat-zksync-solc";
// import "@matterlabs/hardhat-zksync-verify";
//
// const config: HardhatUserConfig = {
// zksolc: {
// version: "1.3.14",
// settings: {},
// },
// solidity: {
// version: "0.8.17",
// },
// paths: {
// sources: "./contracts/abc",
// }
// };
//
// export default config;

module.exports = {
zksolc: {
version: "1.3.12",
settings: {},
},
solidity: {
version: "0.8.17",
},
paths: {
sources: "./contracts/abc",
}
};
90 changes: 71 additions & 19 deletions api/src/handlers/compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ use crate::handlers::process::{do_process_command, fetch_process_result};
use crate::handlers::types::{ApiCommand, ApiCommandResult, CompileResponse, SolFile};
use crate::rate_limiter::RateLimited;
use crate::types::{ApiError, Result};
use crate::utils::hardhat_config::HardhatConfigBuilder;
use crate::utils::lib::{
check_file_ext, get_file_path, path_buf_to_string, status_code_to_message,
to_human_error_batch, ARTIFACTS_ROOT, SOL_ROOT,
to_human_error_batch, ALLOWED_VERSIONS, ARTIFACTS_ROOT, SOL_ROOT,
};
use crate::worker::WorkerEngine;
use rocket::serde::json;
Expand All @@ -18,30 +19,40 @@ use tracing::info;
use tracing::instrument;

#[instrument]
#[get("/compile/<remix_file_path..>")]
#[get("/compile/<version>/<remix_file_path..>")]
pub async fn compile(
version: String,
remix_file_path: PathBuf,
_rate_limited: RateLimited,
) -> Json<CompileResponse> {
info!("/compile/{:?}", remix_file_path);
do_compile(remix_file_path).await.unwrap_or_else(|e| {
Json(CompileResponse {
file_content: vec![],
message: e.to_string(),
status: "Error".to_string(),
info!("/compile/{:?}/{:?}", version, remix_file_path);
do_compile(version, remix_file_path)
.await
.unwrap_or_else(|e| {
Json(CompileResponse {
file_content: vec![],
message: e.to_string(),
status: "Error".to_string(),
})
})
})
}

#[instrument]
#[get("/compile-async/<remix_file_path..>")]
#[get("/compile-async/<version>/<remix_file_path..>")]
pub async fn compile_async(
version: String,
remix_file_path: PathBuf,
_rate_limited: RateLimited,
engine: &State<WorkerEngine>,
) -> String {
info!("/compile-async/{:?}", remix_file_path);
do_process_command(ApiCommand::Compile(remix_file_path), engine)
info!("/compile-async/{:?}/{:?}", version, remix_file_path);
do_process_command(
ApiCommand::Compile {
path: remix_file_path,
version,
},
engine,
)
}

#[instrument]
Expand All @@ -56,15 +67,44 @@ pub async fn get_compile_result(process_id: String, engine: &State<WorkerEngine>
})
}

pub async fn do_compile(remix_file_path: PathBuf) -> Result<Json<CompileResponse>> {
pub async fn do_compile(
version: String,
remix_file_path: PathBuf,
) -> Result<Json<CompileResponse>> {
if !ALLOWED_VERSIONS.contains(&version.as_str()) {
return Err(ApiError::VersionNotSupported(version));
}

let remix_file_path = path_buf_to_string(remix_file_path.clone())?;

check_file_ext(&remix_file_path, "sol")?;

let file_path = get_file_path(&remix_file_path);
let file_path = get_file_path(&version, &remix_file_path);

let sources_path = path_buf_to_string(Path::new(SOL_ROOT).join(&version))?;
let artifacts_path = ARTIFACTS_ROOT.to_string();

let hardhat_config = HardhatConfigBuilder::new()
.zksolc_version(&version)
.sources_path(&sources_path)
.artifacts_path(&artifacts_path)
.build();

// save temporary hardhat config to file
let hardhat_config_path = Path::new(SOL_ROOT).join(hardhat_config.name.clone());

fs::write(
hardhat_config_path.clone(),
hardhat_config.to_string_config(),
)
.await
.map_err(ApiError::FailedToWriteFile)?;

let compile_result = Command::new("yarn")
let compile_result = Command::new("npx")
.arg("hardhat")
.arg("compile")
.arg("--config")
.arg(hardhat_config_path.clone())
.current_dir(SOL_ROOT)
.stdout(Stdio::piped())
.stderr(Stdio::piped())
Expand All @@ -75,16 +115,28 @@ pub async fn do_compile(remix_file_path: PathBuf) -> Result<Json<CompileResponse
.wait_with_output()
.map_err(ApiError::FailedToReadOutput)?;

let sol_file_content = fs::read_to_string(&file_path)
.await
.map_err(ApiError::FailedToReadFile)?;
println!("output: {:?}", output);

let result_path_prefix = Path::new(ARTIFACTS_ROOT)
let result_path_prefix = Path::new(&artifacts_path)
.join(&version)
.join(remix_file_path.clone())
.to_str()
.ok_or(ApiError::FailedToParseString)?
.to_string();

println!("result_path_prefix: {}", result_path_prefix);
println!("sources_path: {}", sources_path);
println!("file_path: {}", path_buf_to_string(file_path.clone())?);

let sol_file_content = fs::read_to_string(&file_path)
.await
.map_err(ApiError::FailedToReadFile)?;

// delete the hardhat config file
fs::remove_file(hardhat_config_path)
.await
.map_err(ApiError::FailedToWriteFile)?;

let (ast, _) = solang_parser::parse(&sol_file_content, 0)
.map_err(|e| ApiError::FailedToParseSol(to_human_error_batch(e)))?;

Expand Down
31 changes: 10 additions & 21 deletions api/src/handlers/compiler_version.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
use crate::handlers::process::{do_process_command, fetch_process_result};
use crate::handlers::types::{ApiCommand, ApiCommandResult};
use crate::types::ApiError;
use crate::worker::WorkerEngine;
use rocket::State;
use crate::utils::lib::ALLOWED_VERSIONS;
use rocket::serde::json::serde_json;
use tracing::{info, instrument};

#[instrument]
Expand All @@ -13,27 +11,18 @@ pub async fn compiler_version() -> String {
}

#[instrument]
#[get("/compiler_version_async")]
pub async fn compiler_version_async(engine: &State<WorkerEngine>) -> String {
info!("/compiler_version_async");
do_process_command(ApiCommand::CompilerVersion, engine)
}

#[instrument]
#[get("/compiler_version_result/<process_id>")]
pub async fn get_compiler_version_result(
process_id: String,
engine: &State<WorkerEngine>,
) -> String {
info!("/compiler_version_result/{:?}", process_id);
fetch_process_result(process_id, engine, |result| match result {
ApiCommandResult::CompilerVersion(version) => version.to_string(),
_ => String::from("Result not available"),
})
#[get("/allowed_versions")]
pub async fn allowed_versions() -> String {
info!("/allowed_versions");
do_allowed_versions().unwrap_or_else(|e| format!("Error: {:?}", e))
}

/// Run ./zksolc --version to return compiler version string
///
pub fn do_compiler_version() -> Result<String, ApiError> {
Ok("zksolc-latest".to_string())
}

pub fn do_allowed_versions() -> Result<String, ApiError> {
Ok(serde_json::to_string(&ALLOWED_VERSIONS).unwrap())
}
5 changes: 4 additions & 1 deletion api/src/handlers/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,10 @@ pub async fn dispatch_command(command: ApiCommand) -> Result<ApiCommandResult, A
Ok(result) => Ok(ApiCommandResult::CompilerVersion(result)),
Err(e) => Err(e),
},
ApiCommand::Compile(remix_file_path) => match do_compile(remix_file_path).await {
ApiCommand::Compile {
path: remix_file_path,
version,
} => match do_compile(version, remix_file_path).await {
Ok(compile_response) => Ok(ApiCommandResult::Compile(compile_response.into_inner())),
Err(e) => Err(e),
},
Expand Down
22 changes: 16 additions & 6 deletions api/src/handlers/save_code.rs
Original file line number Diff line number Diff line change
@@ -1,24 +1,34 @@
use crate::types::{ApiError, Result};
use crate::utils::lib::{get_file_path, init_parent_directories, path_buf_to_string};
use crate::utils::lib::{
get_file_path, init_parent_directories, path_buf_to_string, ALLOWED_VERSIONS,
};
use rocket::data::ToByteUnit;
use rocket::Data;
use std::path::PathBuf;
use tracing::info;

#[post("/save_code/<remix_file_path..>", data = "<file>")]
pub async fn save_code(file: Data<'_>, remix_file_path: PathBuf) -> String {
#[post("/save_code/<version>/<remix_file_path..>", data = "<file>")]
pub async fn save_code(file: Data<'_>, version: String, remix_file_path: PathBuf) -> String {
info!("/save_code/{:?}", remix_file_path);
do_save_code(file, remix_file_path)
do_save_code(file, version, remix_file_path)
.await
.unwrap_or_else(|e| e.to_string())
}

/// Upload a data file
///
pub async fn do_save_code(file: Data<'_>, remix_file_path: PathBuf) -> Result<String> {
pub async fn do_save_code(
file: Data<'_>,
version: String,
remix_file_path: PathBuf,
) -> Result<String> {
if !ALLOWED_VERSIONS.contains(&version.as_str()) {
return Err(ApiError::VersionNotSupported(version));
}

let remix_file_path = path_buf_to_string(remix_file_path.clone())?;

let file_path = get_file_path(&remix_file_path);
let file_path = get_file_path(&version, &remix_file_path);

// create file directory from file path
init_parent_directories(file_path.clone()).await;
Expand Down
5 changes: 4 additions & 1 deletion api/src/handlers/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,10 @@ pub struct ScarbCompileResponse {
#[derive(Debug)]
pub enum ApiCommand {
CompilerVersion,
Compile(PathBuf),
Compile {
version: String,
path: PathBuf,
},
#[allow(dead_code)]
Shutdown,
}
Expand Down
7 changes: 2 additions & 5 deletions api/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,7 @@ use crate::rate_limiter::RateLimiter;
use crate::tracing_log::init_logger;
use crate::worker::WorkerEngine;
use handlers::compile::{compile, compile_async, get_compile_result};
use handlers::compiler_version::{
compiler_version, compiler_version_async, get_compiler_version_result,
};
use handlers::compiler_version::{allowed_versions, compiler_version};
use handlers::process::get_process_status;
use handlers::save_code::save_code;
use handlers::{health, who_is_this};
Expand Down Expand Up @@ -60,9 +58,8 @@ async fn rocket() -> _ {
get_compile_result,
save_code,
compiler_version,
compiler_version_async,
get_compiler_version_result,
get_process_status,
allowed_versions,
health,
who_is_this,
],
Expand Down
4 changes: 4 additions & 0 deletions api/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,8 @@ pub enum ApiError {
MutexUnlockError,
#[error("Error('s) raised while trying to parse sol file: \n{0}")]
FailedToParseSol(String),
#[error("Failed to write file: {0}")]
FailedToWriteFile(IoError),
#[error("Unsupported version: {0}")]
VersionNotSupported(String),
}
Loading

0 comments on commit 6684b85

Please sign in to comment.