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

Bootloader enhancements #2

Open
wants to merge 12 commits into
base: main
Choose a base branch
from
Open
2 changes: 2 additions & 0 deletions .cargo/config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[env]
RUST_LOG = "debug"
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,6 @@ Cargo.lock

# MSVC Windows builds of rustc generate these, which store debugging information
*.pdb

# Pies
/*.zip
5 changes: 4 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,19 @@ version = "0.1.0"
edition = "2021"

[dependencies]
clap = { version = "4.3.10", features = ["derive"] }
cairo-vm = { git = "https://github.com/zksecurity/cairo-vm.git", features = [
"extensive_hints",
"clap",
], rev = "ac8b81b79f65f5017fe0929bf4025be4a0e9c73c" }
num-traits = "0.2.19"
serde = { version = "1.0.202", features = ["derive"] }
serde_json = "1.0.117"
starknet-crypto = "0.6.2"
starknet-types-core = "0.1.2"
thiserror = "1.0.61"
thiserror-no-std = "2.0.2"
tracing = "0.1"
tracing-subscriber = { version = "0.3", features = ["env-filter"] }

[dev-dependencies]
assert_matches = "1.5.0"
Expand Down
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ We currently support Cairo bootloader v0.13.0.

We provide two hint processors that can be used to execute bootloader hints.

``` sh
cargo run -- --cairo_pies pie.zip --secure_run true --ignore_fact_topologies --cairo_pie_output bootloader_pie.zip
```

### Standalone hint processor

The standalone hint processor (`BootloaderHintProcessor`) is the simplest way to execute the bootloader.
Expand Down
74 changes: 23 additions & 51 deletions examples/run_program.rs
Original file line number Diff line number Diff line change
@@ -1,54 +1,31 @@
use std::collections::HashMap;
use std::error::Error;
use std::path::Path;
use std::rc::Rc;
use std::{collections::HashMap, error::Error, path::Path, rc::Rc};

use cairo_vm::cairo_run::{cairo_run_program_with_initial_scope, CairoRunConfig};
use cairo_vm::hint_processor::builtin_hint_processor::builtin_hint_processor_definition::HintFunc;
use cairo_vm::hint_processor::builtin_hint_processor::hint_utils::insert_value_from_var_name;
use cairo_vm::types::exec_scope::ExecutionScopes;
use cairo_vm::types::layout_name::LayoutName;
use cairo_vm::types::program::Program;
use cairo_vm::vm::errors::cairo_run_errors::CairoRunError;
use cairo_vm::vm::runners::cairo_runner::CairoRunner;
use cairo_vm::Felt252;

use cairo_bootloader::bootloaders::load_bootloader;
use cairo_bootloader::tasks::make_bootloader_tasks;
use cairo_bootloader::{
insert_bootloader_input, BootloaderConfig, BootloaderHintProcessor, BootloaderInput,
PackedOutput, SimpleBootloaderInput, TaskSpec,
bootloaders::load_bootloader,
hints::{BootloaderConfig, BootloaderHintProcessor, BootloaderInput, PackedOutput, SimpleBootloaderInput, TaskSpec},
tasks::{insert_bootloader_input, make_bootloader_tasks},
};
use cairo_vm::{
cairo_run::{cairo_run_program_with_initial_scope, CairoRunConfig},
hint_processor::builtin_hint_processor::{builtin_hint_processor_definition::HintFunc, hint_utils::insert_value_from_var_name},
types::{exec_scope::ExecutionScopes, layout_name::LayoutName, program::Program},
vm::{errors::cairo_run_errors::CairoRunError, runners::cairo_runner::CairoRunner},
Felt252,
};

fn cairo_run_bootloader_in_proof_mode(
bootloader_program: &Program,
tasks: Vec<TaskSpec>,
) -> Result<CairoRunner, CairoRunError> {
fn cairo_run_bootloader_in_proof_mode(bootloader_program: &Program, tasks: Vec<TaskSpec>) -> Result<CairoRunner, CairoRunError> {
let mut hint_processor = BootloaderHintProcessor::new();
hint_processor.add_hint(
"ids.fibonacci_claim_index = program_input['fibonacci_claim_index']".to_string(),
Rc::new(HintFunc(Box::new(
|vm, exec_scopes, ids_data, ap_tracking, _constants| {
let program_input: HashMap<String, serde_json::Value> = exec_scopes
.get::<HashMap<String, serde_json::Value>>("program_input")
.unwrap()
.clone();
let fibonacci_claim_index: Felt252 = program_input
.get("fibonacci_claim_index")
.unwrap()
.as_u64()
.unwrap()
.into();
insert_value_from_var_name(
"fibonacci_claim_index",
fibonacci_claim_index,
vm,
ids_data,
ap_tracking,
)?;
Ok(())
},
))),
Rc::new(HintFunc(Box::new(|vm, exec_scopes, ids_data, ap_tracking, _constants| {
let program_input: HashMap<String, serde_json::Value> = exec_scopes
.get::<HashMap<String, serde_json::Value>>("program_input")
.unwrap()
.clone();
let fibonacci_claim_index: Felt252 = program_input.get("fibonacci_claim_index").unwrap().as_u64().unwrap().into();
insert_value_from_var_name("fibonacci_claim_index", fibonacci_claim_index, vm, ids_data, ap_tracking)?;
Ok(())
}))),
);

let cairo_run_config = CairoRunConfig {
Expand Down Expand Up @@ -85,12 +62,7 @@ fn cairo_run_bootloader_in_proof_mode(
insert_bootloader_input(&mut exec_scopes, bootloader_input);

// Run the bootloader
cairo_run_program_with_initial_scope(
&bootloader_program,
&cairo_run_config,
&mut hint_processor,
exec_scopes,
)
cairo_run_program_with_initial_scope(&bootloader_program, &cairo_run_config, &mut hint_processor, exec_scopes)
}

fn main() -> Result<(), Box<dyn Error>> {
Expand All @@ -99,7 +71,7 @@ fn main() -> Result<(), Box<dyn Error>> {
// let pie_paths = vec![Path::new(
// "./dependencies/test-programs/bootloader/pies/fibonacci/cairo_pie.zip",
// )];
let pie_paths = vec![Path::new("./examples/example.zip")];
let pie_paths = vec![Path::new("./examples/example.zip").to_path_buf()];
// let program_inputs_path = Path::new("./examples/fibonacci_input.json");
// let program_inputs_str = std::fs::read_to_string(program_inputs_path)?;
// let program_inputs =
Expand Down
2 changes: 2 additions & 0 deletions rust-toolchain.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[toolchain]
channel = "nightly-2025-01-02"
13 changes: 13 additions & 0 deletions rustfmt.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# See: https://rust-lang.github.io/rustfmt
max_width = 140
normalize_comments = true
use_field_init_shorthand = true

# Unstable
comment_width = 140
condense_wildcard_suffixes = true
format_code_in_doc_comments = true
group_imports = "StdExternalCrate"
imports_granularity = "Crate"
unstable_features = true
wrap_comments = true
7 changes: 3 additions & 4 deletions src/bootloaders.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
use cairo_vm::types::errors::program_errors::ProgramError;
use cairo_vm::types::program::Program;
use cairo_vm::types::{errors::program_errors::ProgramError, program::Program};

pub use crate::hints::*;

const BOOTLOADER_V0_13_0: &[u8] = include_bytes!("../resources/bootloader-0.13.0.json");
const BOOTLOADER_V0_13_1: &[u8] = include_bytes!("../resources/bootloader-0.13.1.json");
pub const BOOTLOADER_V0_13_0: &[u8] = include_bytes!("../resources/bootloader-0.13.0.json");
pub const BOOTLOADER_V0_13_1: &[u8] = include_bytes!("../resources/bootloader-0.13.1.json");

/// Loads the bootloader and returns it as a Cairo VM `Program` object.
pub fn load_bootloader() -> Result<Program, ProgramError> {
Expand Down
48 changes: 48 additions & 0 deletions src/error.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
use cairo_vm::{
air_public_input::PublicInputError,
cairo_run::EncodeTraceError,
types::errors::program_errors::ProgramError,
vm::errors::{cairo_run_errors::CairoRunError, memory_errors::MemoryError, trace_errors::TraceError, vm_errors::VirtualMachineError},
Felt252,
};
use thiserror_no_std::Error;

#[derive(Debug, Error)]
pub enum Error {
#[error("Invalid arguments")]
Cli(#[from] clap::Error),
#[error("Failed to interact with the file system")]
IO(#[from] std::io::Error),
#[error(transparent)]
EncodeTrace(#[from] EncodeTraceError),
#[error(transparent)]
VirtualMachine(#[from] VirtualMachineError),
#[error(transparent)]
Trace(#[from] TraceError),
#[error(transparent)]
PublicInput(#[from] PublicInputError),
#[error(transparent)]
CairoRunError(#[from] CairoRunError),
#[error("Failed to compile to cairo_pie:\n {0}")]
CairoPie(String),
#[error(transparent)]
Program(#[from] ProgramError),
#[error(transparent)]
Memory(#[from] MemoryError),
#[error("Program panicked with {0:?}")]
RunPanic(Vec<Felt252>),
#[error("Function signature has no return types")]
NoRetTypesInSignature,
#[error("Failed to extract return values from VM")]
FailedToExtractReturnValues,
#[error("Function expects arguments of size {expected} and received {actual} instead.")]
ArgumentsSizeMismatch { expected: i16, actual: i16 },
#[error("Function param {param_index} only partially contains argument {arg_index}.")]
ArgumentUnaligned { param_index: usize, arg_index: usize },
#[error("Only programs returning `Array<Felt252>` can be currently proven. Try serializing the final values before returning them")]
IlegalReturnValue,
#[error("Only programs with `Array<Felt252>` as an input can be currently proven. Try inputing the serialized version of the input and deserializing it on main")]
IlegalInputValue,
#[error(transparent)]
SerdeJson(#[from] serde_json::Error),
}
Loading