diff --git a/.dockerignore b/.dockerignore index c6eb944..c7ad19e 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,3 +1,45 @@ +# Generated by Cargo +# will have compiled files and executables +**/debug/ +**/target/ + +# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries +# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html +**/Cargo.lock + +# These are backup files generated by rustfmt +**/*.rs.bk + +# MSVC Windows builds of rustc generate these, which store debugging information +*.pdb + +# Scarb +**/Scarb.lock + +# vscode +**/.vscode/ + +# Git +**/.git + +# Docker +**/Dockerfile + +# Ignores +**/.gitignore +**/.dockerignore + +# Envs +**/*.cargo + +# Venvs +**/.venv + + +/resources +output.json +examples/Cairo/prover_input.json +examples/CairoZero/prover_input.json +/corelib + .idea/ -.git/ -target/ diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0776e22..d8744d0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -24,7 +24,7 @@ jobs: - name: Build run: cargo build --verbose test: - runs-on: ubuntu-latest + runs-on: ubuntu-latest-32-core steps: - uses: actions/checkout@v4 - uses: asdf-vm/actions/install@v3 @@ -37,9 +37,5 @@ jobs: ls -Rl examples/ - name: Build run: cargo build --verbose - - name: Run prover - run: | - cargo run -p prover -- --jwt-secret-key "asdf" --authorized-keys "0xd16b71c90dbf897e5964d2f267d04664b3c035036559d712994739ea6cf2fd9f" --message-expiration-time 60 --session-expiration-time 3600 & - sleep 5 - name: Run tests - run: cargo test --no-fail-fast --workspace --verbose + run: ./scripts/e2e_test.sh diff --git a/.gitignore b/.gitignore index 061f7c2..bf2ade7 100644 --- a/.gitignore +++ b/.gitignore @@ -19,9 +19,18 @@ # vscode **/.vscode/ +# Git +**/.git + +# Envs +**/*.cargo + +# Venvs +**/.venv + /resources -/.cargo -.venv output.json examples/Cairo/prover_input.json -examples/CairoZero/prover_input.json \ No newline at end of file +examples/CairoZero/prover_input.json +/corelib + diff --git a/Cargo.toml b/Cargo.toml index 82e8183..f690378 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,10 +5,10 @@ members = [ "bin/keygen", "bin/register", "crates/common", - "crates/podman", "crates/utils", "prover", "prover-sdk", + "cairo1-compile", ] [workspace.package] @@ -30,13 +30,12 @@ http = "1.1.0" hyper-util = "0.1.3" jsonwebtoken = "9.3.0" lazy_static = "1.4.0" -podman = { path = "crates/podman" } prefix-hex = "0.7.1" prover = { path = "prover" } +prover-sdk = { path = "prover-sdk" } rand = "0.8.5" reqwest = { version = "0.12.4", features = ["blocking", "json", "rustls-tls"], default-features = false } reqwest_cookie_store = "0.7.0" -prover-sdk = { path = "prover-sdk" } serde = { version = "1.0.197", features = ["derive"] } serde_json = "1.0.116" serde_with = "3.8.1" @@ -54,3 +53,6 @@ tracing = "0.1.40" tracing-subscriber = { version = "0.3.18", features = ["env-filter"] } url = { version = "2.5.0", features = ["serde"] } utils = { path = "crates/utils" } +config-generator = { git = "https://github.com/piotr-stec/genereate-config.git" } +cairo-lang-compiler = { git = "https://github.com/starkware-libs/cairo", tag = "v2.7.0-rc.3", default-features = false } +cairo-lang-sierra = { git = "https://github.com/starkware-libs/cairo", tag = "v2.7.0-rc.3", default-features = false } \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index a17ffd9..0505605 100644 --- a/Dockerfile +++ b/Dockerfile @@ -15,9 +15,38 @@ COPY --from=planner /app/recipe.json recipe.json RUN cargo chef cook --release --recipe-path recipe.json # Build application COPY . . +ENV PATH="/root/.cargo/bin:${PATH}" + RUN cargo build --release -p prover +RUN cargo install --git https://github.com/lambdaclass/cairo-vm --rev 37ea72977dccbc2b90b8b7534c1edabd2e2fef79 cairo1-run + + +FROM docker.io/piotr439/prover AS prover + + +FROM python:3.9.18-slim-bookworm AS final +WORKDIR / +RUN apt update && apt install -y build-essential libgmp-dev elfutils jq git +RUN pip install --upgrade pip + +COPY --from=builder /app/target/release/prover /usr/local/bin/prover +COPY --from=builder /usr/local/cargo/bin/cairo1-run /usr/local/bin/cairo1-run +COPY --from=prover /usr/bin/cpu_air_prover /usr/local/bin/cpu_air_prover +COPY --from=prover /usr/bin/cpu_air_verifier /usr/local/bin/cpu_air_verifier + +COPY --from=builder /app/config/cpu_air_prover_config.json /config/cpu_air_prover_config.json +RUN git clone --depth=1 -b v2.7.0-rc.3 https://github.com/starkware-libs/cairo.git +RUN mv cairo/corelib/ . + +RUN rm -rf cairo + +RUN pip install cairo-lang==0.13.1 +RUN pip install sympy==1.12.1 + +RUN mkdir resources/ +RUN mkdir resources/cairo/ +RUN mkdir resources/cairoZero/ + +EXPOSE 3000 -# We do not need the Rust toolchain to run the binary! -FROM alpine AS runtime -COPY --from=builder /app/target/release/prover /usr/local/bin ENTRYPOINT [ "prover" ] diff --git a/bin/cairo-prove/README.md b/bin/cairo-prove/README.md index 227182e..ad1accf 100644 --- a/bin/cairo-prove/README.md +++ b/bin/cairo-prove/README.md @@ -4,7 +4,8 @@ cargo run --bin cairo-prove -- --key --cairo-version <1/0> --url your_input.json > output.json ``` -By default cairo version is set to cairo 1 +By default cairo version is set to cairo 1 +test workflow ## Input format diff --git a/bin/cairo-prove/tests/common.rs b/bin/cairo-prove/tests/common.rs index 286387b..bd08669 100644 --- a/bin/cairo-prove/tests/common.rs +++ b/bin/cairo-prove/tests/common.rs @@ -1,45 +1,6 @@ use std::path::PathBuf; - -use prover::server::start; -use prover::Args; -use prover_sdk::ProverAccessKey; use tokio::fs::File; use tokio::io::AsyncReadExt; -use tokio::net::TcpListener; -use tokio::task::JoinHandle; -use url::Url; - -pub async fn spawn_prover() -> (JoinHandle<()>, ProverAccessKey, Url) { - use url::Url; - - let port = TcpListener::bind("127.0.0.1:0") - .await - .unwrap() - .local_addr() - .unwrap() - .port(); - - let key = ProverAccessKey::generate(); - let encoded_key = prefix_hex::encode(key.0.verifying_key().to_bytes()); - - let args = Args { - host: "0.0.0.0".to_string(), - port, - jwt_secret_key: "placeholder".to_string(), - message_expiration_time: 60, - session_expiration_time: 3600, - authorized_keys: Some(vec![encoded_key]), - authorized_keys_path: None, - }; - - let handle = tokio::spawn(async move { - start(args).await.unwrap(); - }); - - let url = Url::parse(&format!("http://localhost:{}", port)).unwrap(); - - (handle, key, url) -} pub async fn read_file(path: PathBuf) -> Result { let manifest_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR")); diff --git a/bin/cairo-prove/tests/prove.rs b/bin/cairo-prove/tests/prove.rs index fb576c0..49bd787 100644 --- a/bin/cairo-prove/tests/prove.rs +++ b/bin/cairo-prove/tests/prove.rs @@ -1,35 +1,37 @@ -use crate::common::{read_file, spawn_prover}; +use crate::common::read_file; use cairo_proof_parser::output::{extract_output, ExtractOutputResult}; use cairo_prove::{prove, CliInput}; use serde_json::Value; -use std::path::PathBuf; - +use std::{env, path::PathBuf}; +use url::Url; mod common; -// #[tokio::test] +#[tokio::test] async fn test_cairo1_fibonacci() -> Result<(), cairo_prove::ProveError> { - let (handle, key, url) = spawn_prover().await; - + let key = "0x5883b0e30b008e48af3d0bf5cfc138fb6093496da6f87d24b65def88470356d3"; + let port = env::var("PORT").unwrap(); + let prover_url = Url::parse(&format!("http://localhost:{}", port)).unwrap(); let args = CliInput { - key: key.signing_key_as_hex_string(), + key: key.to_string(), cairo_version: 1, - url, + url: prover_url, }; - let prover_input = read_file(PathBuf::from("examples/Cairo/prover_input.json")).await?; + let prover_input = + read_file(PathBuf::from("examples/Cairo/fibonacci_prover_input.json")).await?; let proof = prove(args, prover_input).await?; assert!(extract_output(&proof).is_ok()); - handle.abort(); Ok(()) } #[tokio::test] async fn test_cairo0_fibonacci() -> Result<(), cairo_prove::ProveError> { - let (handle, key, url) = spawn_prover().await; - + let key = "0x5883b0e30b008e48af3d0bf5cfc138fb6093496da6f87d24b65def88470356d3"; + let port = env::var("PORT").unwrap(); + let prover_url = Url::parse(&format!("http://localhost:{}", port)).unwrap(); let args = CliInput { - key: key.signing_key_as_hex_string(), + key: key.to_string(), cairo_version: 0, - url, + url: prover_url, }; let prover_input = read_file(PathBuf::from("examples/CairoZero/prover_input.json")).await?; let program_input: Value = serde_json::from_str(&prover_input)?; @@ -49,8 +51,5 @@ async fn test_cairo0_fibonacci() -> Result<(), cairo_prove::ProveError> { expected_input, fibonacci_claim_index, "Fibonacci index mismatch." ); - - handle.abort(); - Ok(()) } diff --git a/crates/podman/Cargo.toml b/cairo1-compile/Cargo.toml similarity index 50% rename from crates/podman/Cargo.toml rename to cairo1-compile/Cargo.toml index 826230c..a47b908 100644 --- a/crates/podman/Cargo.toml +++ b/cairo1-compile/Cargo.toml @@ -1,10 +1,13 @@ [package] -name = "podman" +name = "cairo1-compile" version.workspace = true edition.workspace = true # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -thiserror.workspace = true -tokio.workspace = true +cairo-lang-compiler.workspace = true +cairo-lang-sierra.workspace = true +clap.workspace = true +serde.workspace = true +serde_json.workspace = true diff --git a/cairo1-compile/README.md b/cairo1-compile/README.md new file mode 100644 index 0000000..842fdb0 --- /dev/null +++ b/cairo1-compile/README.md @@ -0,0 +1,26 @@ + +# Installation Guide + +Follow the steps below to install `cairo1-compile` and `cairo1-run`. + +## Install `cairo1-compile` + +To install `cairo1-compile`, run the following command: + +```sh +cargo install --path cairo1-compile +``` + +## Install `cairo1-run` + +To install `cairo1-run` from the repository, run the following command: + +```sh +cargo install --git https://github.com/lambdaclass/cairo-vm cairo1-run +``` + + +`cairo1-compile compile --output resources/fibonacci_compiled.sierra.json e2e_test/Cairo/fibonacci.cairo` +`cairo1-compile merge -o resources/fibonacci_prover_input.json resources/fibonacci_compiled.sierra.json e2e_test/Cairo/input.json` +`podman build -t stone5-cairo1:recursive -f Dockerfile .` +`podman run -i --rm stone5-cairo1:recursive < resources/fibonacci_prover_input.json > resources/proof.json` diff --git a/cairo1-compile/src/main.rs b/cairo1-compile/src/main.rs new file mode 100644 index 0000000..83999de --- /dev/null +++ b/cairo1-compile/src/main.rs @@ -0,0 +1,122 @@ +use std::{ + fmt, + fs::File, + io::{BufReader, Write}, + path::{Path, PathBuf}, +}; + +use cairo_lang_compiler::{ + compile_prepared_db, db::RootDatabase, project::setup_project, CompilerConfig, +}; +use cairo_lang_sierra::program::Program; +use clap::{Parser, ValueHint}; +use serde::Serialize; + +#[derive(Parser, Debug)] +struct CompileArgs { + #[clap(value_parser, value_hint=ValueHint::FilePath, value_name = "FILE")] + program: PathBuf, + #[clap(short, long, value_name = "FILE")] + output: Option, +} + +#[derive(Parser, Debug)] +struct MergeArgs { + #[clap(value_parser, value_hint=ValueHint::FilePath, value_name = "FILE")] + sierra: PathBuf, + #[clap(value_parser, value_hint=ValueHint::FilePath, value_name = "FILE")] + input: PathBuf, + #[clap(short, long, value_name = "FILE")] + output: Option, + #[clap(short, long, value_enum)] + layout: Option, +} + +#[derive(clap::ValueEnum, Clone, Debug, Default)] +enum Layout { + #[default] + Recursive, +} + +#[derive(Parser, Debug)] +#[clap(author, version, about, long_about = None)] +enum Args { + Compile(CompileArgs), + Merge(MergeArgs), +} + +fn main() { + match Args::parse() { + Args::Compile(args) => compile(args), + Args::Merge(args) => merge(args), + } +} + +#[derive(Debug, Clone, Serialize)] +struct ProgramWithArgs { + program: Program, + program_input: serde_json::Value, + layout: String, +} + +fn merge(args: MergeArgs) { + let sierra_program: Program = + serde_json::from_reader(BufReader::new(File::open(args.sierra).unwrap())).unwrap(); + let input: serde_json::Value = + serde_json::from_reader(BufReader::new(File::open(args.input).unwrap())).unwrap(); + + let layout = args.layout.unwrap_or(Layout::Recursive); + let merged = serde_json::to_string(&ProgramWithArgs { + program: sierra_program, + program_input: input, + layout: layout.to_string(), + }) + .unwrap(); + match args.output { + Some(output) => { + let mut file = std::fs::File::create(output).unwrap(); + file.write_all(merged.as_bytes()).unwrap(); + } + None => { + println!("{}", merged) + } + } +} + +fn compile(args: CompileArgs) { + let program = compile_sierra(&args.program); + let json_program = serde_json::to_string(&program).unwrap(); + match args.output { + Some(output) => { + let mut file = std::fs::File::create(output).unwrap(); + file.write_all(json_program.as_bytes()).unwrap(); + } + None => { + println!("{}", json_program) + } + } +} + +fn compile_sierra(filename: &Path) -> Program { + let compiler_config = CompilerConfig { + replace_ids: true, + ..CompilerConfig::default() + }; + let mut db = RootDatabase::builder() + .detect_corelib() + .skip_auto_withdraw_gas() + .build() + .unwrap(); + let main_crate_ids = setup_project(&mut db, filename).unwrap(); + compile_prepared_db(&mut db, main_crate_ids, compiler_config) + .unwrap() + .program +} + +impl fmt::Display for Layout { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Layout::Recursive => write!(f, "recursive"), + } + } +} diff --git a/config/cpu_air_prover_config.json b/config/cpu_air_prover_config.json new file mode 100644 index 0000000..423f1ed --- /dev/null +++ b/config/cpu_air_prover_config.json @@ -0,0 +1,9 @@ +{ + "cached_lde_config": { + "store_full_lde": false, + "use_fft_for_eval": false + }, + "constraint_polynomial_task_size": 256, + "n_out_of_memory_merkle_layers": 1, + "table_prover_n_tasks_per_segment": 32 +} diff --git a/crates/podman/src/lib.rs b/crates/podman/src/lib.rs deleted file mode 100644 index acf1556..0000000 --- a/crates/podman/src/lib.rs +++ /dev/null @@ -1,17 +0,0 @@ -pub mod process; -pub mod runner; - -pub fn add(left: usize, right: usize) -> usize { - left + right -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn it_works() { - let result = add(2, 2); - assert_eq!(result, 4); - } -} diff --git a/crates/podman/src/process.rs b/crates/podman/src/process.rs deleted file mode 100644 index d9ac16e..0000000 --- a/crates/podman/src/process.rs +++ /dev/null @@ -1,58 +0,0 @@ -use std::{process::Stdio, string::FromUtf8Error}; -use thiserror::Error; -use tokio::{ - io::{self, AsyncReadExt, AsyncWriteExt}, - process::Command, -}; - -#[derive(Error, Debug)] -pub enum ProcessError { - #[error("failed to spawn process: {0}")] - Spawn(#[from] io::Error), - - #[error("failed to open stdin")] - Stdin, - - #[error("failed to open stdout")] - Stdout, - - #[error("failed to parse stderr")] - StderrParse, - - #[error("podman error: {0}")] - Podman(String), - - #[error("UTF-8 parse error: {0}")] - FromUtf8(#[from] FromUtf8Error), -} - -pub async fn run(mut command: Command, input: Option) -> Result { - command - .stdout(Stdio::piped()) - .stderr(Stdio::piped()) - .stdin(Stdio::piped()); - - let mut child = command.spawn()?; - - if let Some(input) = input { - let mut stdin = child.stdin.take().ok_or(ProcessError::Stdin)?; - stdin.write_all(input.as_bytes()).await?; - stdin.flush().await?; - } - - let mut stdout = child.stdout.take().ok_or(ProcessError::Stdout)?; - let mut output_bytes = Vec::new(); - stdout.read_to_end(&mut output_bytes).await?; - let output = String::from_utf8(output_bytes)?; - - let status = child.wait().await?; - if !status.success() { - let mut stderr = child.stderr.take().ok_or(ProcessError::StderrParse)?; - let mut error_message = Vec::new(); - stderr.read_to_end(&mut error_message).await?; - let error_message = String::from_utf8(error_message)?; - Err(ProcessError::Podman(error_message)) - } else { - Ok(output) - } -} diff --git a/crates/podman/src/runner.rs b/crates/podman/src/runner.rs deleted file mode 100644 index 004f3fc..0000000 --- a/crates/podman/src/runner.rs +++ /dev/null @@ -1,27 +0,0 @@ -use tokio::process::Command; - -use crate::process::{self, ProcessError}; - -pub trait Runner { - fn run( - &self, - input: &str, - ) -> impl std::future::Future> + Send; -} - -pub struct PodmanRunner(String); - -impl PodmanRunner { - pub fn new(image_name: &str) -> Self { - PodmanRunner(image_name.to_string()) - } -} - -impl Runner for PodmanRunner { - async fn run(&self, input: &str) -> Result { - let mut command = Command::new("podman"); - command.arg("run").arg("-i").arg("--rm").arg(&self.0); - let result = process::run(command, Some(input.to_string())).await?; - Ok(result) - } -} diff --git a/examples/Cairo/fibonacci.cairo b/examples/Cairo/fibonacci.cairo index beb3b06..425c95c 100644 --- a/examples/Cairo/fibonacci.cairo +++ b/examples/Cairo/fibonacci.cairo @@ -1,13 +1,13 @@ -use core::felt252; - -fn main(n: felt252) -> Array { - let result = fib(1, 1, n); - array![result] +use core::array::ArrayTrait; +fn main(mut n: Array) -> Array { + let r = fib(n.pop_front().unwrap()); + array![r.into()] } -fn fib(a: felt252, b: felt252, n: felt252) -> felt252 { - match n { - 0 => a, - _ => fib(b, a + b, n - 1), +fn fib(n: felt252) -> felt252 { + if n == 1 || n == 0 { + return n; } + + fib(n - 1) + fib(n - 2) } \ No newline at end of file diff --git a/examples/Cairo/fibonacci_prover_input.json b/examples/Cairo/fibonacci_prover_input.json new file mode 100644 index 0000000..48d5084 --- /dev/null +++ b/examples/Cairo/fibonacci_prover_input.json @@ -0,0 +1,1198 @@ +{ + "program": { + "type_declarations": [ + { + "id": { "id": 1, "debug_name": "Array" }, + "long_id": { + "generic_id": "Array", + "generic_args": [{ "Type": { "id": 0, "debug_name": "felt252" } }] + }, + "declared_type_info": { + "storable": true, + "droppable": true, + "duplicatable": false, + "zero_sized": false + } + }, + { + "id": { "id": 12, "debug_name": "Const" }, + "long_id": { + "generic_id": "Const", + "generic_args": [ + { "Type": { "id": 0, "debug_name": "felt252" } }, + { "Value": [1, [2]] } + ] + }, + "declared_type_info": { + "storable": false, + "droppable": false, + "duplicatable": false, + "zero_sized": false + } + }, + { + "id": { "id": 0, "debug_name": "felt252" }, + "long_id": { "generic_id": "felt252", "generic_args": [] }, + "declared_type_info": { + "storable": true, + "droppable": true, + "duplicatable": true, + "zero_sized": false + } + }, + { + "id": { "id": 9, "debug_name": "NonZero" }, + "long_id": { + "generic_id": "NonZero", + "generic_args": [{ "Type": { "id": 0, "debug_name": "felt252" } }] + }, + "declared_type_info": { + "storable": true, + "droppable": true, + "duplicatable": true, + "zero_sized": false + } + }, + { + "id": { "id": 10, "debug_name": "Const" }, + "long_id": { + "generic_id": "Const", + "generic_args": [ + { "Type": { "id": 0, "debug_name": "felt252" } }, + { "Value": [1, [1]] } + ] + }, + "declared_type_info": { + "storable": false, + "droppable": false, + "duplicatable": false, + "zero_sized": false + } + }, + { + "id": { "id": 11, "debug_name": "Uninitialized" }, + "long_id": { + "generic_id": "Uninitialized", + "generic_args": [{ "Type": { "id": 0, "debug_name": "felt252" } }] + }, + "declared_type_info": { + "storable": false, + "droppable": true, + "duplicatable": false, + "zero_sized": false + } + }, + { + "id": { "id": 4, "debug_name": "core::panics::Panic" }, + "long_id": { + "generic_id": "Struct", + "generic_args": [ + { + "UserType": { + "id": [ + 2208749170, 1797821712, 129214108, 2539384922, 764199911, + 1378060934, 2080739472, 23743629 + ], + "debug_name": "core::panics::Panic" + } + } + ] + }, + "declared_type_info": { + "storable": true, + "droppable": true, + "duplicatable": true, + "zero_sized": true + } + }, + { + "id": { + "id": 5, + "debug_name": "Tuple>" + }, + "long_id": { + "generic_id": "Struct", + "generic_args": [ + { + "UserType": { + "id": [ + 1380714691, 777545161, 640624565, 3564344830, 2506258596, + 2515665124, 462026948, 49159723 + ], + "debug_name": "Tuple" + } + }, + { "Type": { "id": 4, "debug_name": "core::panics::Panic" } }, + { "Type": { "id": 1, "debug_name": "Array" } } + ] + }, + "declared_type_info": { + "storable": true, + "droppable": true, + "duplicatable": false, + "zero_sized": false + } + }, + { + "id": { + "id": 7, + "debug_name": "Const" + }, + "long_id": { + "generic_id": "Const", + "generic_args": [ + { "Type": { "id": 0, "debug_name": "felt252" } }, + { + "Value": [ + 1, + [ + 1818584110, 543580521, 2003984752, 976909678, 1953066862, + 20336 + ] + ] + } + ] + }, + "declared_type_info": { + "storable": false, + "droppable": false, + "duplicatable": false, + "zero_sized": false + } + }, + { + "id": { "id": 3, "debug_name": "Tuple>" }, + "long_id": { + "generic_id": "Struct", + "generic_args": [ + { + "UserType": { + "id": [ + 1380714691, 777545161, 640624565, 3564344830, 2506258596, + 2515665124, 462026948, 49159723 + ], + "debug_name": "Tuple" + } + }, + { "Type": { "id": 1, "debug_name": "Array" } } + ] + }, + "declared_type_info": { + "storable": true, + "droppable": true, + "duplicatable": false, + "zero_sized": false + } + }, + { + "id": { + "id": 6, + "debug_name": "core::panics::PanicResult::<(core::array::Array::,)>" + }, + "long_id": { + "generic_id": "Enum", + "generic_args": [ + { + "UserType": { + "id": [ + 704622403, 483171566, 1759595788, 2942942373, 3836427357, + 911959852, 2124004651, 45932020 + ], + "debug_name": "core::panics::PanicResult::<(core::array::Array::,)>" + } + }, + { "Type": { "id": 3, "debug_name": "Tuple>" } }, + { + "Type": { + "id": 5, + "debug_name": "Tuple>" + } + } + ] + }, + "declared_type_info": { + "storable": true, + "droppable": true, + "duplicatable": false, + "zero_sized": false + } + }, + { + "id": { "id": 2, "debug_name": "Box" }, + "long_id": { + "generic_id": "Box", + "generic_args": [{ "Type": { "id": 0, "debug_name": "felt252" } }] + }, + "declared_type_info": { + "storable": true, + "droppable": true, + "duplicatable": true, + "zero_sized": false + } + } + ], + "libfunc_declarations": [ + { + "id": { "id": 10, "debug_name": "disable_ap_tracking" }, + "long_id": { "generic_id": "disable_ap_tracking", "generic_args": [] } + }, + { + "id": { "id": 9, "debug_name": "array_pop_front" }, + "long_id": { + "generic_id": "array_pop_front", + "generic_args": [{ "Type": { "id": 0, "debug_name": "felt252" } }] + } + }, + { + "id": { "id": 11, "debug_name": "branch_align" }, + "long_id": { "generic_id": "branch_align", "generic_args": [] } + }, + { + "id": { "id": 12, "debug_name": "drop>" }, + "long_id": { + "generic_id": "drop", + "generic_args": [ + { "Type": { "id": 1, "debug_name": "Array" } } + ] + } + }, + { + "id": { "id": 8, "debug_name": "unbox" }, + "long_id": { + "generic_id": "unbox", + "generic_args": [{ "Type": { "id": 0, "debug_name": "felt252" } }] + } + }, + { + "id": { "id": 14, "debug_name": "store_temp" }, + "long_id": { + "generic_id": "store_temp", + "generic_args": [{ "Type": { "id": 0, "debug_name": "felt252" } }] + } + }, + { + "id": { + "id": 7, + "debug_name": "function_call" + }, + "long_id": { + "generic_id": "function_call", + "generic_args": [ + { + "UserFunc": { "id": 0, "debug_name": "fibonacci::fibonacci::fib" } + } + ] + } + }, + { + "id": { "id": 4, "debug_name": "array_new" }, + "long_id": { + "generic_id": "array_new", + "generic_args": [{ "Type": { "id": 0, "debug_name": "felt252" } }] + } + }, + { + "id": { "id": 3, "debug_name": "array_append" }, + "long_id": { + "generic_id": "array_append", + "generic_args": [{ "Type": { "id": 0, "debug_name": "felt252" } }] + } + }, + { + "id": { + "id": 6, + "debug_name": "struct_construct>>" + }, + "long_id": { + "generic_id": "struct_construct", + "generic_args": [ + { "Type": { "id": 3, "debug_name": "Tuple>" } } + ] + } + }, + { + "id": { + "id": 5, + "debug_name": "enum_init,)>, 0>" + }, + "long_id": { + "generic_id": "enum_init", + "generic_args": [ + { + "Type": { + "id": 6, + "debug_name": "core::panics::PanicResult::<(core::array::Array::,)>" + } + }, + { "Value": [0, []] } + ] + } + }, + { + "id": { + "id": 15, + "debug_name": "store_temp,)>>" + }, + "long_id": { + "generic_id": "store_temp", + "generic_args": [ + { + "Type": { + "id": 6, + "debug_name": "core::panics::PanicResult::<(core::array::Array::,)>" + } + } + ] + } + }, + { + "id": { + "id": 13, + "debug_name": "const_as_immediate>" + }, + "long_id": { + "generic_id": "const_as_immediate", + "generic_args": [ + { + "Type": { + "id": 7, + "debug_name": "Const" + } + } + ] + } + }, + { + "id": { + "id": 2, + "debug_name": "struct_construct" + }, + "long_id": { + "generic_id": "struct_construct", + "generic_args": [ + { "Type": { "id": 4, "debug_name": "core::panics::Panic" } } + ] + } + }, + { + "id": { + "id": 1, + "debug_name": "struct_construct>>" + }, + "long_id": { + "generic_id": "struct_construct", + "generic_args": [ + { + "Type": { + "id": 5, + "debug_name": "Tuple>" + } + } + ] + } + }, + { + "id": { + "id": 0, + "debug_name": "enum_init,)>, 1>" + }, + "long_id": { + "generic_id": "enum_init", + "generic_args": [ + { + "Type": { + "id": 6, + "debug_name": "core::panics::PanicResult::<(core::array::Array::,)>" + } + }, + { "Value": [1, [1]] } + ] + } + }, + { + "id": { "id": 19, "debug_name": "alloc_local" }, + "long_id": { + "generic_id": "alloc_local", + "generic_args": [{ "Type": { "id": 0, "debug_name": "felt252" } }] + } + }, + { + "id": { "id": 20, "debug_name": "finalize_locals" }, + "long_id": { "generic_id": "finalize_locals", "generic_args": [] } + }, + { + "id": { + "id": 21, + "debug_name": "const_as_immediate>" + }, + "long_id": { + "generic_id": "const_as_immediate", + "generic_args": [ + { "Type": { "id": 10, "debug_name": "Const" } } + ] + } + }, + { + "id": { "id": 22, "debug_name": "dup" }, + "long_id": { + "generic_id": "dup", + "generic_args": [{ "Type": { "id": 0, "debug_name": "felt252" } }] + } + }, + { + "id": { "id": 17, "debug_name": "felt252_sub" }, + "long_id": { "generic_id": "felt252_sub", "generic_args": [] } + }, + { + "id": { "id": 18, "debug_name": "felt252_is_zero" }, + "long_id": { "generic_id": "felt252_is_zero", "generic_args": [] } + }, + { + "id": { "id": 23, "debug_name": "drop>" }, + "long_id": { + "generic_id": "drop", + "generic_args": [ + { "Type": { "id": 11, "debug_name": "Uninitialized" } } + ] + } + }, + { + "id": { "id": 24, "debug_name": "jump" }, + "long_id": { "generic_id": "jump", "generic_args": [] } + }, + { + "id": { "id": 25, "debug_name": "drop>" }, + "long_id": { + "generic_id": "drop", + "generic_args": [ + { "Type": { "id": 9, "debug_name": "NonZero" } } + ] + } + }, + { + "id": { + "id": 26, + "debug_name": "const_as_immediate>" + }, + "long_id": { + "generic_id": "const_as_immediate", + "generic_args": [ + { "Type": { "id": 12, "debug_name": "Const" } } + ] + } + }, + { + "id": { "id": 27, "debug_name": "store_local" }, + "long_id": { + "generic_id": "store_local", + "generic_args": [{ "Type": { "id": 0, "debug_name": "felt252" } }] + } + }, + { + "id": { "id": 16, "debug_name": "felt252_add" }, + "long_id": { "generic_id": "felt252_add", "generic_args": [] } + } + ], + "statements": [ + { + "Invocation": { + "libfunc_id": { "id": 10, "debug_name": "disable_ap_tracking" }, + "args": [], + "branches": [{ "target": "Fallthrough", "results": [] }] + } + }, + { + "Invocation": { + "libfunc_id": { "id": 9, "debug_name": "array_pop_front" }, + "args": [{ "id": 0, "debug_name": null }], + "branches": [ + { + "target": "Fallthrough", + "results": [ + { "id": 1, "debug_name": null }, + { "id": 2, "debug_name": null } + ] + }, + { + "target": { "Statement": 13 }, + "results": [{ "id": 3, "debug_name": null }] + } + ] + } + }, + { + "Invocation": { + "libfunc_id": { "id": 11, "debug_name": "branch_align" }, + "args": [], + "branches": [{ "target": "Fallthrough", "results": [] }] + } + }, + { + "Invocation": { + "libfunc_id": { "id": 12, "debug_name": "drop>" }, + "args": [{ "id": 1, "debug_name": null }], + "branches": [{ "target": "Fallthrough", "results": [] }] + } + }, + { + "Invocation": { + "libfunc_id": { "id": 8, "debug_name": "unbox" }, + "args": [{ "id": 2, "debug_name": null }], + "branches": [ + { + "target": "Fallthrough", + "results": [{ "id": 4, "debug_name": null }] + } + ] + } + }, + { + "Invocation": { + "libfunc_id": { "id": 14, "debug_name": "store_temp" }, + "args": [{ "id": 4, "debug_name": null }], + "branches": [ + { + "target": "Fallthrough", + "results": [{ "id": 4, "debug_name": null }] + } + ] + } + }, + { + "Invocation": { + "libfunc_id": { + "id": 7, + "debug_name": "function_call" + }, + "args": [{ "id": 4, "debug_name": null }], + "branches": [ + { + "target": "Fallthrough", + "results": [{ "id": 5, "debug_name": null }] + } + ] + } + }, + { + "Invocation": { + "libfunc_id": { "id": 4, "debug_name": "array_new" }, + "args": [], + "branches": [ + { + "target": "Fallthrough", + "results": [{ "id": 6, "debug_name": null }] + } + ] + } + }, + { + "Invocation": { + "libfunc_id": { "id": 3, "debug_name": "array_append" }, + "args": [ + { "id": 6, "debug_name": null }, + { "id": 5, "debug_name": null } + ], + "branches": [ + { + "target": "Fallthrough", + "results": [{ "id": 7, "debug_name": null }] + } + ] + } + }, + { + "Invocation": { + "libfunc_id": { + "id": 6, + "debug_name": "struct_construct>>" + }, + "args": [{ "id": 7, "debug_name": null }], + "branches": [ + { + "target": "Fallthrough", + "results": [{ "id": 8, "debug_name": null }] + } + ] + } + }, + { + "Invocation": { + "libfunc_id": { + "id": 5, + "debug_name": "enum_init,)>, 0>" + }, + "args": [{ "id": 8, "debug_name": null }], + "branches": [ + { + "target": "Fallthrough", + "results": [{ "id": 9, "debug_name": null }] + } + ] + } + }, + { + "Invocation": { + "libfunc_id": { + "id": 15, + "debug_name": "store_temp,)>>" + }, + "args": [{ "id": 9, "debug_name": null }], + "branches": [ + { + "target": "Fallthrough", + "results": [{ "id": 9, "debug_name": null }] + } + ] + } + }, + { "Return": [{ "id": 9, "debug_name": null }] }, + { + "Invocation": { + "libfunc_id": { "id": 11, "debug_name": "branch_align" }, + "args": [], + "branches": [{ "target": "Fallthrough", "results": [] }] + } + }, + { + "Invocation": { + "libfunc_id": { "id": 12, "debug_name": "drop>" }, + "args": [{ "id": 3, "debug_name": null }], + "branches": [{ "target": "Fallthrough", "results": [] }] + } + }, + { + "Invocation": { + "libfunc_id": { "id": 4, "debug_name": "array_new" }, + "args": [], + "branches": [ + { + "target": "Fallthrough", + "results": [{ "id": 10, "debug_name": null }] + } + ] + } + }, + { + "Invocation": { + "libfunc_id": { + "id": 13, + "debug_name": "const_as_immediate>" + }, + "args": [], + "branches": [ + { + "target": "Fallthrough", + "results": [{ "id": 11, "debug_name": null }] + } + ] + } + }, + { + "Invocation": { + "libfunc_id": { "id": 14, "debug_name": "store_temp" }, + "args": [{ "id": 11, "debug_name": null }], + "branches": [ + { + "target": "Fallthrough", + "results": [{ "id": 11, "debug_name": null }] + } + ] + } + }, + { + "Invocation": { + "libfunc_id": { "id": 3, "debug_name": "array_append" }, + "args": [ + { "id": 10, "debug_name": null }, + { "id": 11, "debug_name": null } + ], + "branches": [ + { + "target": "Fallthrough", + "results": [{ "id": 12, "debug_name": null }] + } + ] + } + }, + { + "Invocation": { + "libfunc_id": { + "id": 2, + "debug_name": "struct_construct" + }, + "args": [], + "branches": [ + { + "target": "Fallthrough", + "results": [{ "id": 13, "debug_name": null }] + } + ] + } + }, + { + "Invocation": { + "libfunc_id": { + "id": 1, + "debug_name": "struct_construct>>" + }, + "args": [ + { "id": 13, "debug_name": null }, + { "id": 12, "debug_name": null } + ], + "branches": [ + { + "target": "Fallthrough", + "results": [{ "id": 14, "debug_name": null }] + } + ] + } + }, + { + "Invocation": { + "libfunc_id": { + "id": 0, + "debug_name": "enum_init,)>, 1>" + }, + "args": [{ "id": 14, "debug_name": null }], + "branches": [ + { + "target": "Fallthrough", + "results": [{ "id": 15, "debug_name": null }] + } + ] + } + }, + { + "Invocation": { + "libfunc_id": { + "id": 15, + "debug_name": "store_temp,)>>" + }, + "args": [{ "id": 15, "debug_name": null }], + "branches": [ + { + "target": "Fallthrough", + "results": [{ "id": 15, "debug_name": null }] + } + ] + } + }, + { "Return": [{ "id": 15, "debug_name": null }] }, + { + "Invocation": { + "libfunc_id": { "id": 19, "debug_name": "alloc_local" }, + "args": [], + "branches": [ + { + "target": "Fallthrough", + "results": [{ "id": 2, "debug_name": null }] + } + ] + } + }, + { + "Invocation": { + "libfunc_id": { "id": 20, "debug_name": "finalize_locals" }, + "args": [], + "branches": [{ "target": "Fallthrough", "results": [] }] + } + }, + { + "Invocation": { + "libfunc_id": { "id": 10, "debug_name": "disable_ap_tracking" }, + "args": [], + "branches": [{ "target": "Fallthrough", "results": [] }] + } + }, + { + "Invocation": { + "libfunc_id": { + "id": 21, + "debug_name": "const_as_immediate>" + }, + "args": [], + "branches": [ + { + "target": "Fallthrough", + "results": [{ "id": 3, "debug_name": null }] + } + ] + } + }, + { + "Invocation": { + "libfunc_id": { "id": 22, "debug_name": "dup" }, + "args": [{ "id": 0, "debug_name": null }], + "branches": [ + { + "target": "Fallthrough", + "results": [ + { "id": 0, "debug_name": null }, + { "id": 4, "debug_name": null } + ] + } + ] + } + }, + { + "Invocation": { + "libfunc_id": { "id": 17, "debug_name": "felt252_sub" }, + "args": [ + { "id": 4, "debug_name": null }, + { "id": 3, "debug_name": null } + ], + "branches": [ + { + "target": "Fallthrough", + "results": [{ "id": 5, "debug_name": null }] + } + ] + } + }, + { + "Invocation": { + "libfunc_id": { "id": 14, "debug_name": "store_temp" }, + "args": [{ "id": 5, "debug_name": null }], + "branches": [ + { + "target": "Fallthrough", + "results": [{ "id": 5, "debug_name": null }] + } + ] + } + }, + { + "Invocation": { + "libfunc_id": { "id": 18, "debug_name": "felt252_is_zero" }, + "args": [{ "id": 5, "debug_name": null }], + "branches": [ + { "target": "Fallthrough", "results": [] }, + { + "target": { "Statement": 35 }, + "results": [{ "id": 6, "debug_name": null }] + } + ] + } + }, + { + "Invocation": { + "libfunc_id": { "id": 11, "debug_name": "branch_align" }, + "args": [], + "branches": [{ "target": "Fallthrough", "results": [] }] + } + }, + { + "Invocation": { + "libfunc_id": { + "id": 23, + "debug_name": "drop>" + }, + "args": [{ "id": 2, "debug_name": null }], + "branches": [{ "target": "Fallthrough", "results": [] }] + } + }, + { + "Invocation": { + "libfunc_id": { "id": 24, "debug_name": "jump" }, + "args": [], + "branches": [{ "target": { "Statement": 41 }, "results": [] }] + } + }, + { + "Invocation": { + "libfunc_id": { "id": 11, "debug_name": "branch_align" }, + "args": [], + "branches": [{ "target": "Fallthrough", "results": [] }] + } + }, + { + "Invocation": { + "libfunc_id": { "id": 25, "debug_name": "drop>" }, + "args": [{ "id": 6, "debug_name": null }], + "branches": [{ "target": "Fallthrough", "results": [] }] + } + }, + { + "Invocation": { + "libfunc_id": { "id": 22, "debug_name": "dup" }, + "args": [{ "id": 0, "debug_name": null }], + "branches": [ + { + "target": "Fallthrough", + "results": [ + { "id": 0, "debug_name": null }, + { "id": 7, "debug_name": null } + ] + } + ] + } + }, + { + "Invocation": { + "libfunc_id": { "id": 18, "debug_name": "felt252_is_zero" }, + "args": [{ "id": 7, "debug_name": null }], + "branches": [ + { "target": "Fallthrough", "results": [] }, + { + "target": { "Statement": 43 }, + "results": [{ "id": 8, "debug_name": null }] + } + ] + } + }, + { + "Invocation": { + "libfunc_id": { "id": 11, "debug_name": "branch_align" }, + "args": [], + "branches": [{ "target": "Fallthrough", "results": [] }] + } + }, + { + "Invocation": { + "libfunc_id": { + "id": 23, + "debug_name": "drop>" + }, + "args": [{ "id": 2, "debug_name": null }], + "branches": [{ "target": "Fallthrough", "results": [] }] + } + }, + { + "Invocation": { + "libfunc_id": { "id": 14, "debug_name": "store_temp" }, + "args": [{ "id": 0, "debug_name": null }], + "branches": [ + { + "target": "Fallthrough", + "results": [{ "id": 0, "debug_name": null }] + } + ] + } + }, + { "Return": [{ "id": 0, "debug_name": null }] }, + { + "Invocation": { + "libfunc_id": { "id": 11, "debug_name": "branch_align" }, + "args": [], + "branches": [{ "target": "Fallthrough", "results": [] }] + } + }, + { + "Invocation": { + "libfunc_id": { "id": 25, "debug_name": "drop>" }, + "args": [{ "id": 8, "debug_name": null }], + "branches": [{ "target": "Fallthrough", "results": [] }] + } + }, + { + "Invocation": { + "libfunc_id": { + "id": 21, + "debug_name": "const_as_immediate>" + }, + "args": [], + "branches": [ + { + "target": "Fallthrough", + "results": [{ "id": 9, "debug_name": null }] + } + ] + } + }, + { + "Invocation": { + "libfunc_id": { "id": 22, "debug_name": "dup" }, + "args": [{ "id": 0, "debug_name": null }], + "branches": [ + { + "target": "Fallthrough", + "results": [ + { "id": 0, "debug_name": null }, + { "id": 10, "debug_name": null } + ] + } + ] + } + }, + { + "Invocation": { + "libfunc_id": { "id": 17, "debug_name": "felt252_sub" }, + "args": [ + { "id": 10, "debug_name": null }, + { "id": 9, "debug_name": null } + ], + "branches": [ + { + "target": "Fallthrough", + "results": [{ "id": 11, "debug_name": null }] + } + ] + } + }, + { + "Invocation": { + "libfunc_id": { "id": 14, "debug_name": "store_temp" }, + "args": [{ "id": 11, "debug_name": null }], + "branches": [ + { + "target": "Fallthrough", + "results": [{ "id": 11, "debug_name": null }] + } + ] + } + }, + { + "Invocation": { + "libfunc_id": { + "id": 7, + "debug_name": "function_call" + }, + "args": [{ "id": 11, "debug_name": null }], + "branches": [ + { + "target": "Fallthrough", + "results": [{ "id": 1, "debug_name": null }] + } + ] + } + }, + { + "Invocation": { + "libfunc_id": { + "id": 26, + "debug_name": "const_as_immediate>" + }, + "args": [], + "branches": [ + { + "target": "Fallthrough", + "results": [{ "id": 12, "debug_name": null }] + } + ] + } + }, + { + "Invocation": { + "libfunc_id": { "id": 17, "debug_name": "felt252_sub" }, + "args": [ + { "id": 0, "debug_name": null }, + { "id": 12, "debug_name": null } + ], + "branches": [ + { + "target": "Fallthrough", + "results": [{ "id": 13, "debug_name": null }] + } + ] + } + }, + { + "Invocation": { + "libfunc_id": { "id": 14, "debug_name": "store_temp" }, + "args": [{ "id": 13, "debug_name": null }], + "branches": [ + { + "target": "Fallthrough", + "results": [{ "id": 13, "debug_name": null }] + } + ] + } + }, + { + "Invocation": { + "libfunc_id": { "id": 27, "debug_name": "store_local" }, + "args": [ + { "id": 2, "debug_name": null }, + { "id": 1, "debug_name": null } + ], + "branches": [ + { + "target": "Fallthrough", + "results": [{ "id": 1, "debug_name": null }] + } + ] + } + }, + { + "Invocation": { + "libfunc_id": { + "id": 7, + "debug_name": "function_call" + }, + "args": [{ "id": 13, "debug_name": null }], + "branches": [ + { + "target": "Fallthrough", + "results": [{ "id": 14, "debug_name": null }] + } + ] + } + }, + { + "Invocation": { + "libfunc_id": { "id": 16, "debug_name": "felt252_add" }, + "args": [ + { "id": 1, "debug_name": null }, + { "id": 14, "debug_name": null } + ], + "branches": [ + { + "target": "Fallthrough", + "results": [{ "id": 15, "debug_name": null }] + } + ] + } + }, + { + "Invocation": { + "libfunc_id": { "id": 14, "debug_name": "store_temp" }, + "args": [{ "id": 15, "debug_name": null }], + "branches": [ + { + "target": "Fallthrough", + "results": [{ "id": 15, "debug_name": null }] + } + ] + } + }, + { "Return": [{ "id": 15, "debug_name": null }] } + ], + "funcs": [ + { + "id": { "id": 1, "debug_name": "fibonacci::fibonacci::main" }, + "signature": { + "param_types": [{ "id": 1, "debug_name": "Array" }], + "ret_types": [ + { + "id": 6, + "debug_name": "core::panics::PanicResult::<(core::array::Array::,)>" + } + ] + }, + "params": [ + { + "id": { "id": 0, "debug_name": null }, + "ty": { "id": 1, "debug_name": "Array" } + } + ], + "entry_point": 0 + }, + { + "id": { "id": 0, "debug_name": "fibonacci::fibonacci::fib" }, + "signature": { + "param_types": [{ "id": 0, "debug_name": "felt252" }], + "ret_types": [{ "id": 0, "debug_name": "felt252" }] + }, + "params": [ + { + "id": { "id": 0, "debug_name": null }, + "ty": { "id": 0, "debug_name": "felt252" } + } + ], + "entry_point": 24 + } + ] + }, + "program_input": ["[10]"], + "layout": "recursive" +} diff --git a/examples/Cairo/input.json b/examples/Cairo/input.json index 890dac6..ed14265 100644 --- a/examples/Cairo/input.json +++ b/examples/Cairo/input.json @@ -1 +1 @@ -["10"] \ No newline at end of file +["[10]"] \ No newline at end of file diff --git a/prover-sdk/src/lib.rs b/prover-sdk/src/lib.rs index 3f0abac..24731f9 100644 --- a/prover-sdk/src/lib.rs +++ b/prover-sdk/src/lib.rs @@ -1,156 +1,11 @@ -mod access_key; -mod errors; -mod load; +pub mod access_key; +pub mod errors; +pub mod load; pub mod prove_sdk_builder; -mod prover_sdk; +pub mod prover_sdk; pub use access_key::ProverAccessKey; pub use common::{Cairo0ProverInput, Cairo1CompiledProgram, Cairo1ProverInput, CompiledProgram}; pub use errors::ProverSdkErrors; pub use load::{load_cairo0, load_cairo1}; pub use prover_sdk::ProverSDK; - -#[cfg(test)] -mod tests { - use std::path::PathBuf; - - use crate::errors::ProverSdkErrors; - use crate::load::{load_cairo0, load_cairo1}; - use crate::prover_sdk::ProverSDK; - use crate::ProverAccessKey; - use prover::server::start; - use prover::Args; - use tokio::task::JoinHandle; - use url::Url; - - fn get_signing_key() -> ProverAccessKey { - ProverAccessKey::from_hex_string( - "0x1372ef5a200875fc0663f5e7819bb9ecc0ca99783306c19ab9123214c74ca251", - // Corresponding to 0xd16b71c90dbf897e5964d2f267d04664b3c035036559d712994739ea6cf2fd9f public key. - ) - .unwrap() - } - - async fn spawn_prover() -> (JoinHandle<()>, ProverAccessKey) { - let key = ProverAccessKey::generate(); - let encoded_key = prefix_hex::encode(key.0.verifying_key().to_bytes()); - - let args = Args { - host: "0.0.0.0".to_string(), - port: 3043, - jwt_secret_key: "placeholder".to_string(), - message_expiration_time: 60, - session_expiration_time: 3600, - authorized_keys: Some(vec![encoded_key]), - authorized_keys_path: None, - }; - - let handle = tokio::spawn(async move { - start(args).await.unwrap(); - }); - - (handle, key) - } - - // #[tokio::test] - async fn test_prover_cairo1_spawn_prover() -> Result<(), ProverSdkErrors> { - let (_handle, key) = spawn_prover().await; - - let prover_url = Url::parse("http://localhost:3043").unwrap(); - let sdk = ProverSDK::new(key, prover_url).await?; - - let data = load_cairo1(PathBuf::from("../examples/Cairo/prover_input.json")).await?; - let proof = sdk.prove_cairo1(data).await; - - // If authentication fails, print out the error message - assert!(proof.is_ok(), "Failed to prove with invalid url"); - // If authentication fails, print out the error message for debugging purposes - if let Err(err) = proof { - println!(" error: {}", err); - } - Ok(()) - } - - // #[tokio::test] - async fn test_prover_cairo0() -> Result<(), ProverSdkErrors> { - let prover_url = Url::parse("http://localhost:3000").unwrap(); // Provide an invalid URL - let sdk = ProverSDK::new(get_signing_key(), prover_url).await?; - - let data = load_cairo0(PathBuf::from("../examples/CairoZero/prover_input.json")).await?; - let proof = sdk.prove_cairo0(data).await; - // If authentication fails, print out the error message - assert!(proof.is_ok(), "Failed to prove with invalid url"); - // If authentication fails, print out the error message for debugging purposes - if let Err(err) = proof { - println!(" error: {}", err); - } - Ok(()) - } - - // #[tokio::test] - async fn test_prover_cairo1() -> Result<(), ProverSdkErrors> { - let prover_url = Url::parse("http://localhost:3000").unwrap(); - - // Act: Attempt to authenticate with the valid private key and invalid URL for authentication - let sdk = ProverSDK::new(get_signing_key(), prover_url).await?; - - let data = load_cairo1(PathBuf::from("../examples/Cairo/prover_input.json")).await?; - let proof = sdk.prove_cairo1(data).await; - // If authentication fails, print out the error message - assert!(proof.is_ok(), "Failed to prove with invalid url"); - // If authentication fails, print out the error message for debugging purposes - if let Err(err) = proof { - println!(" error: {}", err); - } - Ok(()) - } - - #[tokio::test] - async fn test_invalid_url_auth() -> Result<(), ProverSdkErrors> { - // Arrange: Set up any necessary data or dependencies - let prover_url = Url::parse("http://localhost:3345").unwrap(); // Provide an invalid URL for authentication - - // Act: Attempt to authenticate with the valid private key and invalid URL for authentication - let result = ProverSDK::new(get_signing_key(), prover_url).await; - // Assert: Check that authentication fails due to invalid URL - assert!( - result.is_err(), - "Expected authentication to fail with invalid URL for authentication" - ); - // If authentication fails, print out the error message - if let Err(err) = result { - println!("Error message: {}", err); - } - Ok(()) - } - - // #[tokio::test] - async fn test_invalid_prover() -> Result<(), ProverSdkErrors> { - // Arrange: Set up any necessary data or dependencies - let prover_url: Url = Url::parse("http://localhost:3000").unwrap(); - - // Act: Attempt to authenticate with the valid private key and invalid URL for authentication - let sdk = ProverSDK::new(get_signing_key(), prover_url).await?; - - let data = load_cairo1(PathBuf::from("../examples/Cairo/prover_input.json")).await?; - - let proof = sdk.prove_cairo0(data).await; - // If authentication fails, print out the error message - assert!(proof.is_err(), "Failed to prove with invalid url"); - - Ok(()) - } - - #[tokio::test] - async fn test_register() -> Result<(), ProverSdkErrors> { - let prover_url: Url = Url::parse("http://localhost:3000").unwrap(); - let new_key = ProverAccessKey::generate(); - - // Act: Attempt to authenticate with the valid private key - let mut sdk = ProverSDK::new(get_signing_key(), prover_url).await?; - sdk.register(new_key.0.verifying_key()).await?; - // If authentication fails, print out the error message - - Ok(()) - } -} diff --git a/prover-sdk/src/prove_sdk_builder.rs b/prover-sdk/src/prove_sdk_builder.rs index ed53313..0655ab9 100644 --- a/prover-sdk/src/prove_sdk_builder.rs +++ b/prover-sdk/src/prove_sdk_builder.rs @@ -255,7 +255,10 @@ impl ProverSDKBuilder { .base_url .join("/register") .map_err(ProverSdkErrors::UrlParseError)?, - + verify: self + .base_url + .join("/verify") + .map_err(ProverSdkErrors::UrlParseError)?, authority: signing_key, }) } diff --git a/prover-sdk/src/prover_sdk.rs b/prover-sdk/src/prover_sdk.rs index ec1983e..da693c1 100644 --- a/prover-sdk/src/prover_sdk.rs +++ b/prover-sdk/src/prover_sdk.rs @@ -15,6 +15,7 @@ pub struct ProverSDK { pub prover_cairo1: Url, pub register: Url, pub authority: ProverAccessKey, + pub verify: Url, } impl ProverSDK { @@ -159,4 +160,14 @@ impl ProverSDK { Ok(response_data) } + pub async fn verify(self, proof: String) -> Result { + let response = self + .client + .post(self.verify.clone()) + .json(&proof) + .send() + .await?; + let response_data = response.text().await?; + Ok(response_data) + } } diff --git a/prover-sdk/tests/sdk_test.rs b/prover-sdk/tests/sdk_test.rs new file mode 100644 index 0000000..9e3da29 --- /dev/null +++ b/prover-sdk/tests/sdk_test.rs @@ -0,0 +1,153 @@ +pub use access_key::ProverAccessKey; +pub use common::{Cairo0ProverInput, Cairo1CompiledProgram, Cairo1ProverInput, CompiledProgram}; +pub use errors::ProverSdkErrors; +pub use load::{load_cairo0, load_cairo1}; +pub use prover_sdk::ProverSDK; +use prover_sdk::{access_key, errors, load}; + +#[cfg(test)] +mod tests { + use std::env; + use std::path::PathBuf; + + use crate::load::{load_cairo0, load_cairo1}; + use crate::ProverAccessKey; + use prover_sdk::{ProverSDK, ProverSdkErrors}; + use url::Url; + + fn get_signing_key() -> ProverAccessKey { + ProverAccessKey::from_hex_string( + "0x5883b0e30b008e48af3d0bf5cfc138fb6093496da6f87d24b65def88470356d3", + ) + .unwrap() + } + #[tokio::test] + async fn test_prover_cairo0() -> Result<(), ProverSdkErrors> { + let port = env::var("PORT").unwrap(); + let prover_url = Url::parse(&format!("http://localhost:{}", port)).unwrap(); + + let sdk = ProverSDK::new(get_signing_key(), prover_url).await?; + + let data = load_cairo0(PathBuf::from("../examples/CairoZero/prover_input.json")).await?; + let proof = sdk.prove_cairo0(data).await; + + assert!(proof.is_ok(), "Failed to generate proof with Cairo 0"); + + // Verify the generated proof if successful + if let Err(err) = proof { + println!("Error during proof generation: {}", err); + } else { + let result: Result = sdk.verify(proof.unwrap()).await; + assert!(result.is_ok(), "Failed to verify proof"); + assert_eq!(result.unwrap(), "true", "Proof verification failed"); + } + + Ok(()) + } + + #[tokio::test] + async fn test_verify_invalid_proof() { + let port = env::var("PORT").unwrap(); + let prover_url = Url::parse(&format!("http://localhost:{}", port)).unwrap(); + + let sdk = ProverSDK::new(get_signing_key(), prover_url).await.unwrap(); + + // Attempt to verify an invalid proof + let result = sdk.verify("invalid_proof".to_string()).await; + + assert!( + result.is_ok(), + "Verification unexpectedly failed for an invalid proof" + ); + assert_eq!( + result.unwrap(), + "false", + "Invalid proof was incorrectly verified as valid" + ); + } + + #[tokio::test] + async fn test_prover_cairo1() -> Result<(), ProverSdkErrors> { + let port = env::var("PORT").unwrap(); + let prover_url = Url::parse(&format!("http://localhost:{}", port)).unwrap(); + + let sdk = ProverSDK::new(get_signing_key(), prover_url).await?; + + let data = load_cairo1(PathBuf::from( + "../examples/Cairo/fibonacci_prover_input.json", + )) + .await?; + let proof = sdk.prove_cairo1(data).await; + + assert!(proof.is_ok(), "Failed to generate proof with Cairo 1"); + + if let Err(err) = proof { + println!("Error during proof generation: {}", err); + } else { + let result: Result = sdk.verify(proof.unwrap()).await; + assert!(result.is_ok(), "Failed to verify proof"); + assert_eq!(result.unwrap(), "true", "Proof verification failed"); + } + + Ok(()) + } + + #[tokio::test] + async fn test_invalid_url_auth() -> Result<(), ProverSdkErrors> { + // Provide an invalid URL for SDK initialization + let prover_url = Url::parse("http://wrong:1234").unwrap(); + + let result = ProverSDK::new(get_signing_key(), prover_url).await; + + // Assert that SDK initialization fails due to the invalid URL + assert!( + result.is_err(), + "Expected SDK initialization to fail with an invalid URL" + ); + + if let Err(err) = result { + println!("Error during SDK initialization: {}", err); + } + + Ok(()) + } + + #[tokio::test] + async fn test_invalid_prover_data() -> Result<(), ProverSdkErrors> { + let port = env::var("PORT").unwrap(); + let prover_url = Url::parse(&format!("http://localhost:{}", port)).unwrap(); + + let sdk = ProverSDK::new(get_signing_key(), prover_url).await?; + + // Load Cairo 1 prover input data (intentional mismatch) + let data = load_cairo1(PathBuf::from( + "../examples/Cairo/fibonacci_prover_input.json", + )) + .await?; + + // Attempt to prove using Cairo 0 with incorrect input + let proof = sdk.prove_cairo0(data).await; + + // Assert that proof generation fails due to incorrect input + assert!( + proof.is_err(), + "Expected proof generation to fail with incorrect input" + ); + + Ok(()) + } + + #[tokio::test] + async fn test_register() -> Result<(), ProverSdkErrors> { + let port = env::var("PORT").unwrap(); + let prover_url = Url::parse(&format!("http://localhost:{}", port)).unwrap(); + + let new_key = ProverAccessKey::generate(); + + // Initialize the SDK and register the new key + let mut sdk = ProverSDK::new(get_signing_key(), prover_url).await?; + sdk.register(new_key.0.verifying_key()).await?; + + Ok(()) + } +} diff --git a/prover/Cargo.toml b/prover/Cargo.toml index 7de4f40..951cf7f 100644 --- a/prover/Cargo.toml +++ b/prover/Cargo.toml @@ -15,7 +15,6 @@ curve25519-dalek.workspace = true ed25519-dalek.workspace = true jsonwebtoken.workspace = true lazy_static.workspace = true -podman.workspace = true prefix-hex.workspace = true rand.workspace = true serde_json.workspace = true @@ -27,3 +26,4 @@ tower-http.workspace = true tracing-subscriber.workspace = true tracing.workspace = true utils.workspace = true +config-generator.workspace = true diff --git a/prover/src/auth/mod.rs b/prover/src/auth/mod.rs index 59ab1ae..7e1d11a 100644 --- a/prover/src/auth/mod.rs +++ b/prover/src/auth/mod.rs @@ -36,10 +36,10 @@ mod tests { use std::sync::Arc; use std::sync::Mutex; - // #[tokio::test] + #[tokio::test] async fn test_generate_nonce() -> Result<(), ProveError> { let private_key_hex: String = - r#"f91350db1ca372b54376b519be8bf73a7bbbbefc4ffe169797bc3f5ea2dec740"#.to_string(); + r#"0xf91350db1ca372b54376b519be8bf73a7bbbbefc4ffe169797bc3f5ea2dec740"#.to_string(); let private_key_bytes: Vec = prefix_hex::decode(&private_key_hex) .map_err(|err| ProveError::HexDecodeError(err.to_string()))?; let mut private_key_array = [0u8; 32]; diff --git a/prover/src/lib.rs b/prover/src/lib.rs index aeff97c..70c43a7 100644 --- a/prover/src/lib.rs +++ b/prover/src/lib.rs @@ -1,6 +1,7 @@ pub mod auth; pub mod prove; pub mod server; +pub mod verifier; use std::path::PathBuf; use clap::{arg, Parser, ValueHint}; diff --git a/prover/src/prove/cairo0.rs b/prover/src/prove/cairo0.rs index 7e43657..ea0da5f 100644 --- a/prover/src/prove/cairo0.rs +++ b/prover/src/prove/cairo0.rs @@ -2,17 +2,94 @@ use crate::auth::jwt::Claims; use crate::prove::errors::ProveError; use axum::Json; use common::Cairo0ProverInput; -use podman::runner::Runner; +use config_generator::generate_config; +use serde_json::Value; +use std::{ + path::{Path, PathBuf}, + process::Command, +}; +use tokio::fs; pub async fn root( _claims: Claims, Json(program_input): Json, ) -> Result { - let runner = - podman::runner::PodmanRunner::new("docker.io/neotheprogramist/stone-cairo0:latest"); - let v = serde_json::to_string(&program_input)?; - let result: String = runner.run(&v).await?; - let proof: serde_json::Value = serde_json::from_str(&result)?; + let program_input_path: PathBuf = Path::new("resources/cairoZero/input.json").to_path_buf(); + let program_path: PathBuf = Path::new("resources/cairoZero/program.json").to_path_buf(); + let proof_path: PathBuf = Path::new("program_proof_cairo0.json").to_path_buf(); + let trace_file = Path::new("resources/cairoZero/program_trace.trace").to_path_buf(); + let memory_file = Path::new("resources/cairoZero/program_memory.memory").to_path_buf(); + let public_input_file = + Path::new("resources/cairoZero/program_public_input.json").to_path_buf(); + let private_input_file = + Path::new("resources/cairoZero/program_private_input.json").to_path_buf(); + let params_file = Path::new("resources/cairoZero/cpu_air_params.json").to_path_buf(); + let config_file = Path::new("config/cpu_air_prover_config.json").to_path_buf(); + + let input = serde_json::to_string(&program_input.program_input)?; + let program = serde_json::to_string(&program_input.program)?; + let layout = program_input.layout; + + fs::write(&program_input_path, input.clone()).await?; + fs::write(&program_path, program.clone()).await?; + + //run cairo-run + let mut command = Command::new("cairo-run"); + command + .arg("--trace_file") + .arg(&trace_file) + .arg("--memory_file") + .arg(&memory_file) + .arg("--layout") + .arg(layout) + .arg("--proof_mode") + .arg("--air_public_input") + .arg(&public_input_file) + .arg("--air_private_input") + .arg(&private_input_file) + .arg("--program_input") + .arg(&program_input_path) + .arg("--program") + .arg(&program_path); + + let mut child = command.spawn()?; + let _status = child.wait()?; + + generate_config::generate( + "resources/cairoZero/program_public_input.json", + "resources/cairoZero/cpu_air_params.json", + ); + + //run cpu_air_prover + let mut command_proof = Command::new("cpu_air_prover"); + command_proof + .arg("--public_input_file") + .arg(&public_input_file) + .arg("--private_input_file") + .arg(&private_input_file) + .arg("--prover_config_file") + .arg(&config_file) + .arg("--parameter_file") + .arg(¶ms_file) + .arg("-generate_annotations") + .arg("--out_file") + .arg(&proof_path); + + let mut child_proof = command_proof.spawn()?; + let _status_proof = child_proof.wait()?; + + let result = fs::read_to_string(&proof_path).await?; + let proof: Value = serde_json::from_str(&result)?; let final_result = serde_json::to_string_pretty(&proof)?; + + fs::remove_file(&program_input_path).await?; + fs::remove_file(&program_path).await?; + fs::remove_file(&proof_path).await?; + fs::remove_file(&trace_file).await?; + fs::remove_file(&memory_file).await?; + fs::remove_file(&public_input_file).await?; + fs::remove_file(&private_input_file).await?; + fs::remove_file(¶ms_file).await?; + Ok(final_result) } diff --git a/prover/src/prove/cairo1.rs b/prover/src/prove/cairo1.rs index 50fb9de..21f9ce8 100644 --- a/prover/src/prove/cairo1.rs +++ b/prover/src/prove/cairo1.rs @@ -2,16 +2,104 @@ use crate::auth::jwt::Claims; use crate::prove::errors::ProveError; use axum::Json; use common::Cairo1ProverInput; -use podman::runner::Runner; +use config_generator::generate_config; +use serde_json::Value; +use tokio::fs; + +use std::path::{Path, PathBuf}; +use std::process::Command; pub async fn root( _claims: Claims, Json(program_input): Json, ) -> Result { - let runner = podman::runner::PodmanRunner::new("docker.io/neotheprogramist/stone-cairo:latest"); - let v = serde_json::to_string(&program_input)?; - let result: String = runner.run(&v).await?; - let proof: serde_json::Value = serde_json::from_str(&result)?; + let program_input_path: PathBuf = Path::new("resources/cairo/input.txt").to_path_buf(); + let program_path: PathBuf = Path::new("resources/cairo/program.json").to_path_buf(); + let proof_path: PathBuf = Path::new("program_proof_cairo1.json").to_path_buf(); + let trace_file = Path::new("resources/cairo/program_trace.trace").to_path_buf(); + let memory_file = Path::new("resources/cairo/program_memory.memory").to_path_buf(); + let public_input_file = Path::new("resources/cairo/program_public_input.json").to_path_buf(); + let private_input_file = Path::new("resources/cairo/program_private_input.json").to_path_buf(); + let params_file = Path::new("resources/cairo/cpu_air_params.json").to_path_buf(); + let config_file = Path::new("config/cpu_air_prover_config.json").to_path_buf(); + + let input = serde_json::to_string(&program_input.program_input)?; + let program = serde_json::to_string(&program_input.program)?; + let layout = program_input.layout; + + let json_value: Value = serde_json::from_str(&input)?; + + if let Value::Array(array) = json_value { + let output_str = array + .into_iter() + .filter_map(|v| v.as_str().map(|s| s.to_owned())) + .collect::>() + .join(" "); + + fs::write(program_input_path.clone(), output_str).await?; + } else { + eprintln!("Expected a JSON array"); + std::process::exit(1); + } + + fs::write(&program_path, &program).await?; + + //run cairo1-run + let mut command = Command::new("cairo1-run"); + command + .arg("--trace_file") + .arg(&trace_file) + .arg("--memory_file") + .arg(&memory_file) + .arg("--layout") + .arg(layout) + .arg("--proof_mode") + .arg("--air_public_input") + .arg(&public_input_file) + .arg("--air_private_input") + .arg(&private_input_file) + .arg("--args_file") + .arg(&program_input_path) + .arg(&program_path); + + let mut child = command.spawn()?; + let _status = child.wait()?; + + generate_config::generate( + "resources/cairo/program_public_input.json", + "resources/cairo/cpu_air_params.json", + ); + + //run cpu_air_prover + let mut command_proof = Command::new("cpu_air_prover"); + command_proof + .arg("--out_file") + .arg(&proof_path) + .arg("--private_input_file") + .arg(&private_input_file) + .arg("--public_input_file") + .arg(&public_input_file) + .arg("--prover_config_file") + .arg(&config_file) + .arg("--parameter_file") + .arg(¶ms_file) + .arg("-generate-annotations"); + + let mut child_proof = command_proof.spawn()?; + let _status_proof = child_proof.wait()?; + + let result = fs::read_to_string(&proof_path).await?; + let proof: Value = serde_json::from_str(&result)?; let final_result = serde_json::to_string_pretty(&proof)?; + + fs::remove_file(&program_input_path).await?; + fs::remove_file(&program_path).await?; + fs::remove_file(&proof_path).await?; + fs::remove_file(&trace_file).await?; + fs::remove_file(&memory_file).await?; + fs::remove_file(&public_input_file).await?; + fs::remove_file(&private_input_file).await?; + fs::remove_file(¶ms_file).await?; + Ok(final_result) } diff --git a/prover/src/prove/errors.rs b/prover/src/prove/errors.rs index 17ea978..125ddde 100644 --- a/prover/src/prove/errors.rs +++ b/prover/src/prove/errors.rs @@ -1,5 +1,4 @@ use axum::{http::StatusCode, response::IntoResponse, Json}; -use podman::process::ProcessError; use serde_json::json; use std::{env::VarError, net::AddrParseError}; use thiserror::Error; @@ -20,9 +19,6 @@ pub enum ServerError { #[derive(Error, Debug)] pub enum ProveError { - #[error("failed to prove state-diff-commitment")] - StateDiffCommitment(#[from] ProcessError), - #[error("Unauthorized public key request")] UnauthorizedPublicKey, @@ -63,9 +59,6 @@ pub enum ProveError { impl IntoResponse for ProveError { fn into_response(self) -> axum::response::Response { let (status, error_message) = match &self { - ProveError::StateDiffCommitment(_) => { - (StatusCode::INTERNAL_SERVER_ERROR, self.to_string()) - } ProveError::Parse(_) => (StatusCode::BAD_REQUEST, self.to_string()), ProveError::UnauthorizedPublicKey => (StatusCode::UNAUTHORIZED, self.to_string()), ProveError::Unauthorized(_) => (StatusCode::UNAUTHORIZED, self.to_string()), diff --git a/prover/src/prove/mod.rs b/prover/src/prove/mod.rs index a35db7e..e6c7612 100644 --- a/prover/src/prove/mod.rs +++ b/prover/src/prove/mod.rs @@ -11,47 +11,3 @@ pub fn router(app_state: &AppState) -> Router { .route("/cairo1", post(cairo1::root)) .with_state(app_state.clone()) } - -#[cfg(test)] -mod tests { - use super::*; - use crate::auth::jwt::Claims; - use axum::Json; - use cairo0::root; - use common::Cairo0ProverInput; - use errors::ProveError; - use tokio::fs::File; - use tokio::io::AsyncReadExt; - - #[tokio::test] - async fn test_root_with_input_json() { - // Read input data from resources/input.json - let input_json = read_json_file("../examples/CairoZero/prover_input.json") - .await - .expect("Failed to read input JSON"); - - // Call the root function with the input data and actual PodmanRunner - let result = root( - Claims { - sub: "jwt_token".to_string(), - exp: 3600, - }, - Json(input_json), - ) - .await; - - // Check if the result is as expected - assert!(result.is_ok()); - // Add assertions based on the expected behavior of root function - } - - async fn read_json_file(file_path: &str) -> Result { - let mut file = File::open(file_path).await?; - let mut json_string = String::new(); - file.read_to_string(&mut json_string).await?; - - let json_value: Cairo0ProverInput = serde_json::from_str(&json_string)?; - - Ok(json_value) - } -} diff --git a/prover/src/server.rs b/prover/src/server.rs index be087b3..1fda39e 100644 --- a/prover/src/server.rs +++ b/prover/src/server.rs @@ -3,9 +3,11 @@ use crate::{ self, authorizer::{Authorizer, FileAuthorizer}, }, - prove, Args, + prove, + verifier::verify_proof, + Args, }; -use axum::Router; +use axum::{routing::post, Router}; use prove::errors::ServerError; use std::{ collections::HashMap, @@ -69,6 +71,7 @@ pub async fn start(args: Args) -> Result<(), ServerError> { .nest("/", ok_router) .nest("/", auth::auth(&state)) .nest("/prove", prove::router(&state)) + .route("/verify", post(verify_proof)) .layer(( RequestBodyLimitLayer::new(100 * 1024 * 1024), TraceLayer::new_for_http(), diff --git a/prover/src/verifier.rs b/prover/src/verifier.rs new file mode 100644 index 0000000..91bf16d --- /dev/null +++ b/prover/src/verifier.rs @@ -0,0 +1,35 @@ +use std::{path::PathBuf, process::Command}; + +use axum::Json; + +pub async fn verify_proof(Json(proof): Json) -> Json { + // Define the path for the proof file + let file = PathBuf::from("proof"); + + // Write the proof string to the file + if let Err(e) = std::fs::write(&file, proof) { + eprintln!("Failed to write proof to file: {}", e); + return Json(false); + } + + // Create the command to run the verifier + let mut command = Command::new("cpu_air_verifier"); + command.arg("--in_file").arg(&file); + + // Execute the command and capture the status + let status = command.status(); + + // Remove the proof file + if let Err(e) = std::fs::remove_file(&file) { + eprintln!("Failed to remove proof file: {}", e); + } + + // Check if the command was successful + match status { + Ok(exit_status) => Json(exit_status.success()), + Err(e) => { + eprintln!("Failed to execute verifier: {}", e); + Json(false) + } + } +} diff --git a/scripts/0-venv.sh b/scripts/0-venv.sh old mode 100644 new mode 100755 diff --git a/scripts/corelib_install.sh b/scripts/corelib_install.sh new file mode 100755 index 0000000..aee0216 --- /dev/null +++ b/scripts/corelib_install.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +git clone --depth=1 -b v2.7.0-rc.3 https://github.com/starkware-libs/cairo.git \ + && mv cairo/corelib/ . \ + && rm -rf cairo/ \ No newline at end of file diff --git a/scripts/e2e_test.sh b/scripts/e2e_test.sh new file mode 100755 index 0000000..913a5c7 --- /dev/null +++ b/scripts/e2e_test.sh @@ -0,0 +1,31 @@ +#!/usr/bin/env bash + +IMAGE_NAME="http_prover_test" +CONTAINER_ENGINE="${CONTAINER_ENGINE:-podman}" +PORT="${PORT:-3040}" +# Check if the image already exists +if $CONTAINER_ENGINE images | grep -q "$IMAGE_NAME"; then + echo "Image $IMAGE_NAME already exists. Skipping build step." +else + echo "Image $IMAGE_NAME does not exist. Building the image..." + $CONTAINER_ENGINE build -t $IMAGE_NAME . + if [ $? -ne 0 ]; then + echo "Failed to build the image. Exiting." + exit 1 + fi +fi + +$CONTAINER_ENGINE run -d --replace --name http_prover_test \ + -p $PORT:3000 localhost/http_prover_test \ + --jwt-secret-key "jwt" \ + --message-expiration-time 3600 \ + --session-expiration-time 3600 \ + --authorized-keys 0xed126082726a1062ed6e886b2d7aba42e4f8964a13b4569988bd4c50b9a62076 +if [ $? -ne 0 ]; then + echo "Failed to run the image. Exiting." + exit 1 +fi + +cargo test --no-fail-fast --workspace --verbose -- --test-threads=1 + +$CONTAINER_ENGINE stop $IMAGE_NAME