Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/proof parser #63

Merged
merged 7 commits into from
Sep 18, 2024
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
97 changes: 97 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,7 @@ chrono = "0.4.38"
base64 = "0.22.1"
starknet-types-core = "~0.1.4"
futures = "0.3.30"
async-stream = "0.3.5"
async-stream = "0.3.5"
swiftness_proof_parser = { git = "https://github.com/cartridge-gg/swiftness", rev = "1d46e21"}
starknet-crypto = "0.7.0"
anyhow = "1.0.89"
32 changes: 11 additions & 21 deletions bin/cairo-prove/src/fetch.rs
Original file line number Diff line number Diff line change
@@ -1,34 +1,25 @@
use std::time::Duration;

use prover_sdk::sdk::ProverSDK;
use prover_sdk::{sdk::ProverSDK, JobResponse, ProverResult};
use serde_json::Value;
use tokio::time::sleep;
use tracing::info;

use crate::errors::ProveErrors;

pub async fn fetch_job_sse(sdk: ProverSDK, job: u64) -> Result<String, ProveErrors> {
pub async fn fetch_job_sse(sdk: ProverSDK, job: u64) -> Result<ProverResult, ProveErrors> {
info!("Job ID: {}", job);
sdk.sse(job).await?;
info!("Job completed");
let response = sdk.get_job(job).await?;
let response = response.text().await?;
let json_response: Value = serde_json::from_str(&response)?;
if let Some(status) = json_response.get("status").and_then(Value::as_str) {
if status == "Completed" {
return Ok(json_response
.get("result")
.and_then(Value::as_str)
.unwrap_or("No result found")
.to_string());
} else {
Err(ProveErrors::Custom(json_response.to_string()))
}
} else {
Err(ProveErrors::Custom(json_response.to_string()))
let json_response: JobResponse = serde_json::from_str(&response).unwrap();
if let JobResponse::Completed { result, .. } = json_response {
return Ok(result);
}
Err(ProveErrors::Custom("Job failed".to_string()))
}
pub async fn fetch_job_polling(sdk: ProverSDK, job: u64) -> Result<String, ProveErrors> {
pub async fn fetch_job_polling(sdk: ProverSDK, job: u64) -> Result<ProverResult, ProveErrors> {
info!("Fetching job: {}", job);
let mut counter = 0;
loop {
Expand All @@ -38,11 +29,10 @@ pub async fn fetch_job_polling(sdk: ProverSDK, job: u64) -> Result<String, Prove
if let Some(status) = json_response.get("status").and_then(Value::as_str) {
match status {
"Completed" => {
return Ok(json_response
.get("result")
.and_then(Value::as_str)
.unwrap_or("No result found")
.to_string());
let json_response: JobResponse = serde_json::from_str(&response).unwrap();
if let JobResponse::Completed { result, .. } = json_response {
return Ok(result);
}
}
"Pending" | "Running" => {
info!("Job is still in progress. Status: {}", status);
Expand Down
3 changes: 1 addition & 2 deletions bin/cairo-prove/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,7 @@ pub async fn main() -> Result<(), ProveErrors> {
fetch_job_polling(sdk, job).await?
};
let path: std::path::PathBuf = args.program_output;
std::fs::write(path, job)?;
std::fs::write(path, serde_json::to_string_pretty(&job)?)?;
}

Ok(())
}
26 changes: 25 additions & 1 deletion common/src/models.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use ed25519_dalek::VerifyingKey;
use serde::{Deserialize, Serialize};
use serde_with::{serde_as, DisplayFromStr};
use starknet_types_core::felt::Felt;

#[serde_as]
#[derive(Debug, Serialize, Deserialize)]
Expand All @@ -10,11 +11,34 @@ pub struct JWTResponse {
pub expiration: u64,
pub session_key: Option<VerifyingKey>,
}
#[derive(Serialize, Deserialize, Clone)]
#[derive(Serialize, Deserialize, Clone, Debug)]
pub enum JobStatus {
Pending,
Running,
Completed,
Failed,
Unknown,
}

#[derive(Clone, Serialize, Deserialize)]
pub struct ProverResult {
pub proof: String,
pub program_hash: Felt,
pub program_output: Vec<Felt>,
pub program_output_hash: Felt,
}
#[derive(Serialize, Deserialize)]
#[serde(untagged)]
pub enum JobResponse {
InProgress {
id: u64,
status: JobStatus,
},
Completed {
result: ProverResult,
status: JobStatus,
},
Failed {
error: String,
},
}
1 change: 1 addition & 0 deletions prover-sdk/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ pub mod errors;
pub mod sdk;
pub mod sdk_builder;

pub use common::models::{JobResponse, ProverResult};
pub use common::prover_input::*;
11 changes: 2 additions & 9 deletions prover-sdk/src/sdk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,22 +69,15 @@ impl ProverSDK {
let job = serde_json::from_str::<JobId>(&response_data)?;
Ok(job.job_id)
}
pub async fn verify(self, proof: String) -> Result<u64, SdkErrors> {
pub async fn verify(self, proof: String) -> Result<String, SdkErrors> {
let response = self
.client
.post(self.verify.clone())
.json(&proof)
.send()
.await?;
if !response.status().is_success() {
let response_data: String = response.text().await?;
tracing::error!("{}", response_data);
return Err(SdkErrors::VerifyResponseError(response_data));
}
let response_data = response.text().await?;

let job = serde_json::from_str::<JobId>(&response_data)?;
Ok(job.job_id)
Ok(response_data)
}
pub async fn get_job(&self, job_id: u64) -> Result<Response, SdkErrors> {
let url = format!("{}/{}", self.get_job.clone().as_str(), job_id);
Expand Down
16 changes: 8 additions & 8 deletions prover-sdk/tests/helpers/mod.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
use common::models::{JobResponse, ProverResult};
use prover_sdk::sdk::ProverSDK;
use serde_json::Value;

pub async fn fetch_job(sdk: ProverSDK, job: u64) -> String {
pub async fn fetch_job(sdk: ProverSDK, job: u64) -> Option<ProverResult> {
println!("Job ID: {}", job);
sdk.sse(job).await.unwrap();
let response = sdk.get_job(job).await.unwrap();
let response = response.text().await.unwrap();
let json_response: Value = serde_json::from_str(&response).unwrap();
return json_response
.get("result")
.and_then(Value::as_str)
.unwrap_or("No result found")
.to_string();
let json_response: JobResponse = serde_json::from_str(&response).unwrap();

if let JobResponse::Completed { result, .. } = json_response {
return Some(result);
}
None
}
22 changes: 11 additions & 11 deletions prover-sdk/tests/prove_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ use common::prover_input::*;
use helpers::fetch_job;
use prover_sdk::{access_key::ProverAccessKey, sdk::ProverSDK};
use serde_json::Value;

use starknet_types_core::felt::Felt;

use url::Url;
mod helpers;

Expand Down Expand Up @@ -31,9 +33,11 @@ async fn test_cairo_prove() {
};
let job = sdk.prove_cairo(data).await.unwrap();
let result = fetch_job(sdk.clone(), job).await;
let job = sdk.clone().verify(result).await.unwrap();
let result = fetch_job(sdk.clone(), job).await;
assert_eq!("true", result);
assert!(result.is_some());
let result = result.unwrap();
let result = sdk.clone().verify(result.proof).await;
assert!(result.is_ok(), "Failed to verify proof");
assert_eq!("true", result.unwrap());
}

#[tokio::test]
Expand All @@ -57,8 +61,7 @@ async fn test_cairo0_prove() {
};
let job = sdk.prove_cairo0(data).await.unwrap();
let result = fetch_job(sdk.clone(), job).await;
let job = sdk.clone().verify(result).await.unwrap();
let result = fetch_job(sdk.clone(), job).await;
let result = sdk.clone().verify(result.unwrap().proof).await.unwrap();
assert_eq!("true", result);
}
#[tokio::test]
Expand Down Expand Up @@ -88,15 +91,12 @@ async fn test_cairo_multi_prove() {
let job2 = sdk.prove_cairo(data.clone()).await.unwrap();
let job3 = sdk.prove_cairo(data.clone()).await.unwrap();
let result = fetch_job(sdk.clone(), job1).await;
let job = sdk.clone().verify(result).await.unwrap();
let result = fetch_job(sdk.clone(), job).await;
let result = sdk.clone().verify(result.unwrap().proof).await.unwrap();
assert_eq!("true", result);
let result = fetch_job(sdk.clone(), job2).await;
let job = sdk.clone().verify(result).await.unwrap();
let result = fetch_job(sdk.clone(), job).await;
let result = sdk.clone().verify(result.unwrap().proof).await.unwrap();
assert_eq!("true", result);
let result = fetch_job(sdk.clone(), job3).await;
let job = sdk.clone().verify(result).await.unwrap();
let result = fetch_job(sdk.clone(), job).await;
let result = sdk.clone().verify(result.unwrap().proof).await.unwrap();
assert_eq!("true", result);
}
Loading