Skip to content

Commit

Permalink
invalid reason and sharp test
Browse files Browse the repository at this point in the history
  • Loading branch information
drspacemn committed Oct 25, 2023
1 parent 86a7011 commit a120bed
Show file tree
Hide file tree
Showing 6 changed files with 118 additions and 113 deletions.
79 changes: 39 additions & 40 deletions src/sharp/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ pub mod pie;
use std::path::PathBuf;

use cairo_vm::vm::runners::cairo_pie::CairoPie;
use serde::Deserialize;
use reqwest::blocking::Client;
use serde::{Deserialize, Serialize};
use serde_json::json;
use uuid::Uuid;

Expand All @@ -13,81 +14,79 @@ use crate::error::SnOsError;
pub const DEFUALT_SHARP_URL: &str = "https://testnet.provingservice.io";
pub const _LAMBDA_MAX_PIE_MB: u64 = 20_971_520;

#[derive(Debug)]
#[allow(dead_code)]
#[derive(Default, Clone, Debug, Deserialize, Serialize, PartialEq)]
#[allow(non_camel_case_types)]
pub enum CairoJobStatus {
Unknown,
NotCreated,
InProgress,
Processed,
Onchain,
Invalid,
Failed,
#[default]
UNKNOWN,
NOT_CREATED,
IN_PROGRESS,
PROCESSED,
ONCHAIN,
INVALID,
FAILED,
}

#[allow(dead_code)]
impl CairoJobStatus {
fn as_str(&self) -> &'static str {
match self {
CairoJobStatus::Unknown => "UNKNOWN",
CairoJobStatus::NotCreated => "NOT_CREATED",
CairoJobStatus::InProgress => "IN_PROGRESS",
CairoJobStatus::Processed => "PROCESSED",
CairoJobStatus::Onchain => "ONCHAIN",
CairoJobStatus::Invalid => "INVALID",
CairoJobStatus::Failed => "FAILED",
}
}
#[derive(Default, Clone, Debug, Deserialize, Serialize, PartialEq)]
#[allow(non_camel_case_types)]
pub enum InvalidReason {
#[default]
CAIRO_PIE_RUN_FAILURE,
FAILED_TO_GENERATE_FACT,
INCOMPATIBLE_PRIME,
NO_COMPATIBLE_LAYOUT,
INVALID_BUILTIN_ORDER_DECLERATION,
INVALID_BUILTIN_USAGE,
INVALID_CAIRO_PIE_FILE_FORMAT,
INVALID_CAIRO_PIE_STORAGE_KEY,
PAGE_SIZE_EXCEEDS_LIMIT,
SECURITY_CHECK_FAILURE,
}

#[derive(Default, Debug, Clone, PartialEq, Deserialize)]
#[serde(rename_all = "camelCase")]
#[derive(Clone, Default, Debug, PartialEq, Deserialize)]
pub struct CairoStatusResponse {
pub status: Option<String>,
#[serde(rename = "validation_done")]
pub status: CairoJobStatus,
pub version: u64,
pub validation_done: Option<bool>,
pub version: Option<u64>,
pub error_log: Option<String>,
pub invalid_reason: Option<InvalidReason>,
}

#[derive(Default, Debug, Clone, PartialEq, Deserialize)]
pub struct CairoJobResponse {
pub version: u64,
pub cairo_job_key: Option<Uuid>,
pub version: Option<u64>,
#[serde(rename = "errorMessage")]
pub error_message: Option<String>,
#[serde(rename = "errorType")]
pub error_type: Option<String>,
#[serde(rename = "stackTrace")]
pub stack_trace: Option<Vec<String>>,
}

pub struct SharpClient {
client: reqwest::blocking::Client,
client: Client,
sharp_addr: String,
pie_path: Option<PathBuf>,
}

pub enum SharPie {
pub enum SharpPie {
EncodedPie(String),
PieObject(CairoPie),
}

impl SharpClient {
pub fn new(sharp_addr: Option<String>, pie_path: Option<PathBuf>) -> Self {
Self { client: reqwest::blocking::Client::new(), sharp_addr: sharp_addr.unwrap_or_default(), pie_path }
Self { client: Client::new(), sharp_addr: sharp_addr.unwrap_or_default(), pie_path }
}

pub fn submit_pie(&self, pie: SharPie) -> Result<CairoJobResponse, SnOsError> {
pub fn submit_pie(&self, pie: SharpPie) -> Result<CairoJobResponse, SnOsError> {
let pie_enc = match pie {
SharPie::EncodedPie(encoded_pie) => encoded_pie,
SharPie::PieObject(pie_object) => match &self.pie_path {
SharpPie::EncodedPie(encoded_pie) => encoded_pie,
SharpPie::PieObject(pie_object) => match &self.pie_path {
Some(pp) => pie::encode_pie(pie_object, pp.as_path())?,
None => pie::encode_pie_mem(pie_object)?,
},
};

let data = json!({ "action": "add_job", "request": { "cairo_pie": pie_enc } });
println!("DATA: {:?}", data);

// CAREFUL NOT TO OVERWHELM SHARP DUE TO SHORT BLOCK TIMES
let resp = self
Expand Down Expand Up @@ -122,6 +121,6 @@ impl SharpClient {

impl Default for SharpClient {
fn default() -> Self {
Self { client: reqwest::blocking::Client::new(), sharp_addr: DEFUALT_SHARP_URL.to_string(), pie_path: None }
Self { client: Client::new(), sharp_addr: DEFUALT_SHARP_URL.to_string(), pie_path: None }
}
}
12 changes: 8 additions & 4 deletions src/sharp/pie.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::fs::File;
use std::io::{Cursor, Read, Seek, Write};
use std::path::Path;
use std::path::{Path, PathBuf};

use base64::engine::general_purpose;
use base64::Engine as _;
Expand Down Expand Up @@ -66,8 +66,12 @@ fn write_to_zip<W: Write + Seek>(pie: CairoPie, mut zip: ZipWriter<W>) -> Result
}

/// Convert the base64 encoding of the pie to an unzipped folder.
pub fn decode_base64_to_unzipped(encoded_pie: &str) -> Result<(), SnOsError> {
let buffer = general_purpose::STANDARD.decode(encoded_pie.as_bytes()).unwrap();
ZipArchive::new(Cursor::new(&buffer)).unwrap().extract(&Path::new("build/pie")).unwrap();
pub fn decode_base64_to_unzipped(pie_str: &str, dst: &str) -> Result<(), SnOsError> {
let buffer =
general_purpose::STANDARD.decode(pie_str.as_bytes()).map_err(|e| SnOsError::PieZipping(format!("{e}")))?;
ZipArchive::new(Cursor::new(&buffer))
.unwrap()
.extract(&PathBuf::from(dst))
.map_err(|e| SnOsError::PieZipping(format!("{e}")))?;
Ok(())
}
50 changes: 26 additions & 24 deletions tests/common/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ use cairo_vm::vm::runners::builtin_runner::{
use cairo_vm::vm::runners::cairo_pie::CairoPie;
use cairo_vm::vm::runners::cairo_runner::CairoRunner;
use cairo_vm::vm::vm_core::VirtualMachine;
use lazy_static::lazy_static;
use rstest::{fixture, rstest};
use snos::config::{StarknetGeneralConfig, DEFAULT_FEE_TOKEN_ADDR, DEFAULT_INPUT_PATH};
use snos::io::output::decode_output;
Expand All @@ -40,26 +41,26 @@ use starknet_api::{calldata, class_hash, contract_address, patricia_key, stark_f
pub const TESTING_FEE: u128 = 0x10000000000000000000000000;
pub const TESTING_TRANSFER_AMOUNT: u128 = 0x01000000000000000000000000000000;

// Contract Addresses - 0.12.2
pub const _TOKEN_FOR_TESTING_ADDRESS_0_12_2: &str = "572b6542feb4bf285b57a056b588d649e067b9cfab2a88c2b2df9ea6bae6049";
pub const DUMMY_ACCOUNT_ADDRESS_0_12_2: &str = "5ca2b81086d3fbb4f4af2f1deba4b7fd35e8f4b2caee4e056005c51c05c3dd0";
pub const _DUMMY_TOKEN_ADDRESS_0_12_2: &str = "3400a86fdc294a70fac1cf84f81a2127419359096b846be9814786d4fc056b8";
// -------------------------------Contract Addresses - 0.12.2-------------------------------
lazy_static! {
pub static ref DUMMY_ACCOUNT_ADDRESS_0_12_2: ContractAddress =
contract_address!("5ca2b81086d3fbb4f4af2f1deba4b7fd35e8f4b2caee4e056005c51c05c3dd0");
pub static ref TESTING_1_ADDREESS_0_12_2: ContractAddress =
contract_address!("46fd0893101585e0c7ebd3caf8097b179f774102d6373760c8f60b1a5ef8c92");
pub static ref TESTING_2_ADDREESS_0_12_2: ContractAddress =
contract_address!("4e9665675ca1ac12820b7aff2f44fec713e272efcd3f20aa0fd8ca277f25dc6");
pub static ref TESTING_3_ADDREESS_0_12_2: ContractAddress =
contract_address!("74cebec93a58b4400af9c082fb3c5adfa0800ff1489f8fc030076491ff86c48");
pub static ref TESTING_DELEGATE_ADDREESS_0_12_2: ContractAddress =
contract_address!("238e6b5dffc9f0eb2fe476855d0cd1e9e034e5625663c7eda2d871bd4b6eac0");
}

// Class Hashes - 0.12.2
// int - 1950604961159131904798252922088285101498625538306083185117403934352241550198
// -------------------------------Class Hashes - 0.12.2-------------------------------
pub const TOKEN_FOR_TESTING_HASH_0_12_2: &str = "45000d731e6d5ad0023e448dd15cab6f997b04a39120daf56a8816d9f436376";

// int - 646245114977324210659279014519951538684823368221946044944492064370769527799
pub const DUMMY_ACCOUNT_HASH_0_12_2: &str = "16dc3038da22dde8ad61a786ab9930699cc496c8bccb90d77cc8abee89803f7";

// int - 3531298130119845387864440863187980726515137569165069484670944625223023734186
pub const DUMMY_TOKEN_HASH_0_12_2: &str = "7cea4d7710723fa9e33472b6ceb71587a0ce4997ef486638dd0156bdb6c2daa";

// int - 3262122051170176624039908867798875903980511552421730070376672653403179864416
pub const TESTING_HASH_0_12_2: &str = "7364bafc3d2c56bc84404a6d8be799f533e518b8808bce86395a9442e1e5160";

pub const TESTING_HASH_2_0_12_2: &str = "49bcc976d628b1b238aefc20e77303a251a14ba6c99cd543a86708513414057";

pub const DELEGATE_PROXY_HASH_0_12_2: &str = "1880d2c303f26b658392a2c92a0677f3939f5fdfb960ecf5912afa06ad0b9d9";

#[allow(dead_code)]
Expand Down Expand Up @@ -182,7 +183,7 @@ pub fn initial_state(
*deploy_token_tx.contract_address.0.key(),
tranfer_selector.0,
stark_felt!(3_u8),
stark_felt!(DUMMY_ACCOUNT_ADDRESS_0_12_2),
*DUMMY_ACCOUNT_ADDRESS_0_12_2.0.key(),
stark_felt!(TESTING_TRANSFER_AMOUNT),
stark_felt!(0_u8)
],
Expand Down Expand Up @@ -216,11 +217,7 @@ fn shared_state(initial_state: SharedState<DictStateReader>) {
pub fn prepare_os_test(
mut initial_state: SharedState<DictStateReader>,
) -> (SharedState<DictStateReader>, Vec<TransactionExecutionInfo>) {
let contract_addresses = [
contract_address!("46fd0893101585e0c7ebd3caf8097b179f774102d6373760c8f60b1a5ef8c92"),
contract_address!("4e9665675ca1ac12820b7aff2f44fec713e272efcd3f20aa0fd8ca277f25dc6"),
contract_address!("74cebec93a58b4400af9c082fb3c5adfa0800ff1489f8fc030076491ff86c48"),
];
let contract_addresses = [*TESTING_1_ADDREESS_0_12_2, *TESTING_2_ADDREESS_0_12_2, *TESTING_3_ADDREESS_0_12_2];
let contract_calldata = [
vec![stark_felt!(321_u32), stark_felt!(543_u32)],
vec![stark_felt!(111_u32), stark_felt!(987_u32)],
Expand All @@ -229,7 +226,7 @@ pub fn prepare_os_test(
let contract_salts = [stark_felt!(17_u32), stark_felt!(42_u32), stark_felt!(53_u32)];

let mut nonce_manager = NonceManager::default();
let sender_addr = contract_address!(DUMMY_ACCOUNT_ADDRESS_0_12_2);
let sender_addr = *DUMMY_ACCOUNT_ADDRESS_0_12_2;
nonce_manager.next(sender_addr);

initial_state
Expand Down Expand Up @@ -334,7 +331,7 @@ pub fn prepare_os_test(
class_hash!(DELEGATE_PROXY_HASH_0_12_2),
);

assert_eq!(contract_address!("238e6b5dffc9f0eb2fe476855d0cd1e9e034e5625663c7eda2d871bd4b6eac0"), delegate_addr);
assert_eq!(*TESTING_DELEGATE_ADDREESS_0_12_2, delegate_addr);

txs.push(calldata![
*delegate_addr.0.key(),
Expand Down Expand Up @@ -362,7 +359,7 @@ pub fn prepare_os_test(
*delegate_addr.0.key(),
selector_from_name("test_get_caller_address").0,
stark_felt!(1_u32),
stark_felt!(DUMMY_ACCOUNT_ADDRESS_0_12_2)
*DUMMY_ACCOUNT_ADDRESS_0_12_2.0.key()
]);

txs.push(calldata![
Expand Down Expand Up @@ -402,7 +399,7 @@ pub fn prepare_os_test(
*delegate_addr.0.key(),
selector_from_name("test_get_tx_info").0,
stark_felt!(1_u8),
stark_felt!(DUMMY_ACCOUNT_ADDRESS_0_12_2)
*DUMMY_ACCOUNT_ADDRESS_0_12_2.0.key()
],
TransactionSignature(vec![stark_felt!(100_u32)]),
));
Expand Down Expand Up @@ -509,3 +506,8 @@ pub fn load_output() -> StarknetOsOutput {

decode_output(raw_output.0).unwrap()
}

#[fixture]
pub fn os_pie_string() -> String {
std::fs::read_to_string("tests/common/data/output_pie.b64").unwrap()
}
12 changes: 7 additions & 5 deletions tests/pie.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ use std::path::Path;
use cairo_vm::vm::runners::builtin_runner::OUTPUT_BUILTIN_NAME;
use cairo_vm::vm::runners::cairo_pie::{BuiltinAdditionalData, CairoPie, OutputBuiltinAdditionalData, SegmentInfo};
use cairo_vm::vm::runners::cairo_runner::ExecutionResources;
use common::setup_pie;
use common::{os_pie_string, setup_pie};
use rstest::rstest;
use serde_json::json;
use snos::sharp::pie::{decode_base64_to_unzipped, encode_pie, PIE_FILES};
use snos::sharp::pie::{decode_base64_to_unzipped, PIE_FILES};

#[rstest]
fn pie_metadata_ok(setup_pie: CairoPie) {
Expand Down Expand Up @@ -78,12 +78,14 @@ fn pie_memory_ok(setup_pie: CairoPie) {
}

#[rstest]
fn convert_b64_to_raw() {
decode_base64_to_unzipped(&std::fs::read_to_string("tests/common/data/output_pie.b64").unwrap()).unwrap();
fn convert_b64_to_raw(os_pie_string: String) {
let dst = "build/pie/";

decode_base64_to_unzipped(&os_pie_string, dst).unwrap();

for file in PIE_FILES {
assert!(
Path::new(&format!("build/pie/{file:}.{:}", if file != "memory" { "json" } else { "bin" })).exists(),
Path::new(&format!("{dst}{file:}.{:}", if file != "memory" { "json" } else { "bin" })).exists(),
"Missing file {file:}"
);
}
Expand Down
47 changes: 27 additions & 20 deletions tests/sharp.rs
Original file line number Diff line number Diff line change
@@ -1,33 +1,40 @@
mod common;

use rstest::*;
use snos::sharp::SharpClient;
use common::os_pie_string;
use rstest::rstest;
use snos::sharp::{CairoJobStatus, InvalidReason, SharpClient, SharpPie};

const _TEST_CAIRO_JOB_ID: &str = "3a24bbca-ad75-49d5-8ced-12796c6c0738";
const NEW_CAIRO_JOB: &str = "59b5138d-4c6e-49d3-9234-6495223acb43";
#[rstest]
fn sharp_submit_pie(os_pie_string: String) {
let sharp_client = SharpClient::default();
let submit_resp = sharp_client.submit_pie(SharpPie::EncodedPie(os_pie_string)).unwrap();
println!("{submit_resp:?}");

// #[rstest]
// fn sharp_client_submit(setup_pie: CairoPie) {
// // TODO: implement mocks here, so as to not overwhelm the SHARP
// let sharp_client = SharpClient::default();
// let submit_resp = sharp_client.submit_pie(setup_pie).unwrap();
// assert_eq!(submit_resp.cairo_job_key.unwrap().as_bytes().len(), 16);
// }
let job_id = submit_resp.cairo_job_key.unwrap().to_string();
let status_resp = sharp_client.get_status(&job_id).unwrap();
println!("RESP: {status_resp:?}");
}

#[rstest]
fn sharp_client_status() {
fn sharp_get_status() {
let good_cairo_job_id = "3a24bbca-ad75-49d5-8ced-12796c6c0738";

let sharp_client = SharpClient::default();
let submit_resp = sharp_client.get_status(NEW_CAIRO_JOB).unwrap();
println!("{submit_resp:?}");
let status_resp = sharp_client.get_status(good_cairo_job_id).unwrap();

assert_eq!(submit_resp.version.unwrap(), 1);
assert!(submit_resp.validation_done.unwrap());
assert_eq!(1, status_resp.version);
assert_eq!(CairoJobStatus::PROCESSED, status_resp.status);
}

#[rstest]
fn prove_os_run() {
fn sharp_get_status_err() {
let bad_cairo_job_id = "43454c8e-8f43-444f-aab2-edab05bef512";

let sharp_client = SharpClient::default();
let pie = std::fs::read_to_string("tests/common/data/output_pie.b64").unwrap();
let submit_resp = sharp_client.submit_pie(snos::sharp::SharPie::EncodedPie(pie)).unwrap();
println!("{submit_resp:?}");
let status_resp = sharp_client.get_status(bad_cairo_job_id).unwrap();
println!("STATUS: {:?}", status_resp);

assert_eq!(1, status_resp.version);
assert_eq!(CairoJobStatus::INVALID, status_resp.status);
assert_eq!(InvalidReason::SECURITY_CHECK_FAILURE, status_resp.invalid_reason.unwrap());
}
Loading

0 comments on commit a120bed

Please sign in to comment.