Skip to content

Commit

Permalink
wasm patch (#304)
Browse files Browse the repository at this point in the history
* wasm patch - no std support

* end_addr memory address bound

* prover input serialization
  • Loading branch information
Okm165 authored Jan 10, 2025
1 parent a27287c commit 07d3a9f
Show file tree
Hide file tree
Showing 10 changed files with 81 additions and 331 deletions.
337 changes: 48 additions & 289 deletions stwo_cairo_prover/Cargo.lock

Large diffs are not rendered by default.

9 changes: 4 additions & 5 deletions stwo_cairo_prover/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ edition = "2021"
bytemuck = { version = "1.20.0", features = ["derive"] }
cairo-lang-casm = "2.7.1"
# TODO(yuval): Use an official version, not a specific commit.
cairo-vm = { git = "https://github.com/lambdaclass/cairo-vm", rev = "3fb0344c", features = [
cairo-vm = { git = "https://github.com/lambdaclass/cairo-vm", rev = "83bfdcf", features = [
"mod_builtin",
] }
], default-features = false }
clap = { version = "4.3.10", features = ["derive"] }
env_logger = { version = "0.11.5", default-features = false }
hex = "0.4.3"
Expand All @@ -33,14 +33,13 @@ num-traits = "0.2.17"
rand = "0.8.5"
serde = "1.0.207"
serde_json = "1.0.1"
sonic-rs = "0.3.10"
stwo_cairo_prover = { path = "crates/prover", version = "~0.1.0" }
stwo_cairo_utils = { path = "crates/utils", version = "~0.1.0" }
# TODO(ShaharS): take stwo version from the source repository.
stwo-prover = { git = "https://github.com/starkware-libs/stwo", rev = "af5475cb", features = [
"parallel",
] }
thiserror = "1.0.63"
], default-features = false }
thiserror = { version = "2.0.10", default-features = false }
tracing = "0.1.40"
tracing-subscriber = "0.3.18"
paste = "1.0"
Expand Down
2 changes: 1 addition & 1 deletion stwo_cairo_prover/crates/prover/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ paste.workspace = true
prover_types = { path = "../prover_types" }
rayon = { version = "1.10.0" }
serde.workspace = true
sonic-rs.workspace = true
serde_json.workspace = true
starknet-ff.workspace = true
stwo_cairo_utils = { path = "../utils" }
stwo-cairo-serialize = { path = "../cairo-serialize" }
Expand Down
8 changes: 4 additions & 4 deletions stwo_cairo_prover/crates/prover/src/input/builtin_segments.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
use std::collections::HashMap;

use cairo_vm::air_public_input::MemorySegmentAddresses;
use cairo_vm::stdlib::collections::HashMap;
use cairo_vm::types::builtin_name::BuiltinName;
use serde::{Deserialize, Serialize};

/// This struct holds the builtins used in a Cairo program.
#[derive(Debug, Default)]
#[derive(Debug, Default, Serialize, Deserialize)]
pub struct BuiltinSegments {
pub add_mod: Option<MemorySegmentAddresses>,
pub bitwise: Option<MemorySegmentAddresses>,
Expand Down Expand Up @@ -80,7 +80,7 @@ mod test_builtin_segments {
let pub_data_string = std::fs::read_to_string(&path)
.unwrap_or_else(|_| panic!("Unable to read file: {}", path.display()));
let pub_data: PublicInput<'_> =
sonic_rs::from_str(&pub_data_string).expect("Unable to parse JSON");
serde_json::from_str(&pub_data_string).expect("Unable to parse JSON");

let builtin_segments = BuiltinSegments::from_memory_segments(&pub_data.memory_segments);
assert_eq!(builtin_segments.add_mod, None);
Expand Down
7 changes: 4 additions & 3 deletions stwo_cairo_prover/crates/prover/src/input/memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use std::collections::HashMap;
use std::ops::{Deref, DerefMut};

use itertools::Itertools;
use serde::{Deserialize, Serialize};

use super::vm_import::MemoryEntry;
use crate::components::memory::memory_id_to_big::component::N_M31_IN_SMALL_FELT252;
Expand Down Expand Up @@ -29,7 +30,7 @@ pub const P_MIN_2: [u32; 8] = [
0x0800_0000,
];

#[derive(Debug)]
#[derive(Debug, Serialize, Deserialize)]
pub struct MemoryConfig {
pub small_max: u128,
}
Expand All @@ -49,7 +50,7 @@ impl Default for MemoryConfig {

// TODO(spapini): Add U26 for addresses and U128 for range checks.
// TODO(spapini): Use some struct for Felt252 (that is still memory efficient).
#[derive(Debug)]
#[derive(Debug, Serialize, Deserialize)]
pub struct Memory {
pub config: MemoryConfig,
pub address_to_id: Vec<EncodedMemoryValueId>,
Expand Down Expand Up @@ -184,7 +185,7 @@ impl DerefMut for MemoryBuilder {
}

pub const LARGE_MEMORY_VALUE_ID_TAG: u32 = 0x4000_0000;
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
#[derive(Copy, Clone, PartialEq, Eq, Debug, Serialize, Deserialize)]
pub struct EncodedMemoryValueId(pub u32);
impl EncodedMemoryValueId {
pub fn encode(value: MemoryValueId) -> EncodedMemoryValueId {
Expand Down
3 changes: 2 additions & 1 deletion stwo_cairo_prover/crates/prover/src/input/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use std::collections::HashMap;
use builtin_segments::BuiltinSegments;
use memory::Memory;
use prover_types::cpu::M31;
use serde::{Deserialize, Serialize};
use state_transitions::StateTransitions;

pub mod builtin_segments;
Expand All @@ -16,7 +17,7 @@ pub mod vm_import;
pub const N_REGISTERS: usize = 3;

/// Externally provided inputs for the Stwo prover.
#[derive(Debug)]
#[derive(Debug, Serialize, Deserialize)]
pub struct ProverInput {
pub state_transitions: StateTransitions,
pub instruction_by_pc: HashMap<M31, u64>,
Expand Down
3 changes: 1 addition & 2 deletions stwo_cairo_prover/crates/prover/src/input/plain.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use std::collections::HashMap;

use cairo_vm::hint_processor::builtin_hint_processor::builtin_hint_processor_definition::BuiltinHintProcessor;
use cairo_vm::stdlib::collections::HashMap;
use cairo_vm::types::layout_name::LayoutName;
use cairo_vm::types::relocatable::MaybeRelocatable;
use cairo_vm::vm::runners::cairo_runner::CairoRunner;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use std::collections::HashMap;
use std::fmt::Display;

use prover_types::cpu::CasmState;
use serde::{Deserialize, Serialize};
use stwo_prover::core::fields::m31::M31;

use super::decode::Instruction;
Expand All @@ -19,7 +20,7 @@ const SMALL_MUL_MIN_VALUE: u64 = 0;
// TODO (Stav): Ensure it stays synced with that opcdode AIR's list.
/// This struct holds the components used to prove the opcodes in a Cairo program,
/// and should match the opcode's air used by `stwo-cairo-air`.
#[derive(Debug, Default, Clone)]
#[derive(Debug, Default, Clone, Serialize, Deserialize)]
pub struct CasmStatesByOpcode {
pub generic_opcode: Vec<CasmState>,
pub add_ap_opcode_is_imm_f_op_1_base_fp_f: Vec<CasmState>,
Expand Down Expand Up @@ -183,7 +184,7 @@ impl From<TraceEntry> for CasmState {

/// Holds the state transitions of a Cairo program, split according to the components responsible
/// for proving each transition.
#[derive(Debug, Default)]
#[derive(Debug, Default, Serialize, Deserialize)]
pub struct StateTransitions {
pub initial_state: CasmState,
pub final_state: CasmState,
Expand Down
11 changes: 6 additions & 5 deletions stwo_cairo_prover/crates/prover/src/input/vm_import/mod.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
mod json;

use std::collections::HashMap;
use std::io::Read;
use std::path::Path;

use bytemuck::{bytes_of_mut, Pod, Zeroable};
use cairo_vm::air_public_input::{MemorySegmentAddresses, PublicInput};
use cairo_vm::stdlib::collections::HashMap;
use cairo_vm::vm::trace::trace_entry::RelocatedTraceEntry;
use json::PrivateInput;
use thiserror::Error;
Expand All @@ -15,14 +15,15 @@ use super::builtin_segments::BuiltinSegments;
use super::memory::MemoryConfig;
use super::state_transitions::StateTransitions;
use super::ProverInput;
use crate::components::memory::MEMORY_ADDRESS_BOUND;
use crate::input::memory::MemoryBuilder;

#[derive(Debug, Error)]
pub enum VmImportError {
#[error("IO error: {0}")]
Io(#[from] std::io::Error),
#[error("JSON error: {0}")]
Json(#[from] sonic_rs::Error),
Json(#[from] serde_json::Error),
#[error("No memory segments")]
NoMemorySegments,
}
Expand All @@ -36,17 +37,17 @@ pub fn adapt_vm_output(
) -> Result<ProverInput, VmImportError> {
let _span = span!(Level::INFO, "adapt_vm_output").entered();
let public_input_string = std::fs::read_to_string(public_input_json)?;
let public_input: PublicInput<'_> = sonic_rs::from_str(&public_input_string)?;
let public_input: PublicInput<'_> = serde_json::from_str(&public_input_string)?;
let private_input: PrivateInput =
sonic_rs::from_str(&std::fs::read_to_string(private_input_json)?)?;
serde_json::from_str(&std::fs::read_to_string(private_input_json)?)?;

let end_addr = public_input
.memory_segments
.values()
.map(|v| v.stop_ptr)
.max()
.ok_or(VmImportError::NoMemorySegments)?;
assert!(end_addr < (1 << 32));
assert!(end_addr < MEMORY_ADDRESS_BOUND);

let memory_path = private_input_json
.parent()
Expand Down
27 changes: 8 additions & 19 deletions stwo_cairo_prover/crates/utils/src/vm_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@ use std::path::PathBuf;
use cairo_vm::cairo_run;
use cairo_vm::hint_processor::builtin_hint_processor::builtin_hint_processor_definition::BuiltinHintProcessor;
use cairo_vm::types::layout_name::LayoutName;
use cairo_vm::vm::errors::cairo_run_errors::CairoRunError;
use cairo_vm::vm::runners::cairo_pie::CairoPie;
use cairo_vm::vm::runners::cairo_runner::{CairoRunner, RunResources};
use cairo_vm::vm::runners::cairo_runner::CairoRunner;
use clap::{Parser, ValueHint};
use thiserror::Error;
use tracing::span;
Expand Down Expand Up @@ -57,8 +55,8 @@ pub struct VmArgs {
pub enum VmError {
#[error("Failed to interact with the file system")]
IO(#[from] std::io::Error),
#[error("The cairo program execution failed")]
Runner(#[from] CairoRunError),
#[error("Cairo program execution failed: {0}")]
Runner(String),
}

// This function's logic is copied-then-modified from cairo-vm-cli/src/main.rs:run in cairo-vm repo.
Expand All @@ -76,24 +74,15 @@ pub fn run_vm(args: &VmArgs) -> Result<CairoRunner, VmError> {
..Default::default()
};

let cairo_runner_result = if args.run_from_cairo_pie {
let pie = CairoPie::read_zip_file(&args.filename)?;
let mut hint_processor = BuiltinHintProcessor::new(
Default::default(),
RunResources::new(pie.execution_resources.n_steps),
);
cairo_run::cairo_run_pie(&pie, &cairo_run_config, &mut hint_processor)
} else {
let program_content = std::fs::read(args.filename.clone()).map_err(VmError::IO)?;
let mut hint_processor = BuiltinHintProcessor::new_empty();
cairo_run::cairo_run(&program_content, &cairo_run_config, &mut hint_processor)
};
let program_content = std::fs::read(args.filename.clone()).map_err(VmError::IO)?;
let mut hint_processor = BuiltinHintProcessor::new_empty();
let cairo_runner_result =
cairo_run::cairo_run(&program_content, &cairo_run_config, &mut hint_processor);

let cairo_runner = match cairo_runner_result {
Ok(runner) => runner,
Err(error) => {
eprintln!("{error}");
return Err(VmError::Runner(error));
return Err(VmError::Runner(error.to_string()));
}
};

Expand Down

0 comments on commit 07d3a9f

Please sign in to comment.