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: PIE example + run bootloader helper #5

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all 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
4 changes: 4 additions & 0 deletions .github/workflows/check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ jobs:
- name: Run Rust tests
run: |
RUSTFLAGS="-D warnings" cargo test
- name: Run examples
run: |
RUSTFLAGS="-D warnings" cargo run --example run_cairo_pie
RUSTFLAGS="-D warnings" cargo run --example run_program

udeps:
runs-on: ubuntu-latest
Expand Down
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
cairo-vm = { git = "https://github.com/lambdaclass/cairo-vm", rev = "05352b1c67859a4d8cd128575c1e68ca7e300341", features = ["extensive_hints"] }
cairo-vm = { git = "https://github.com/lambdaclass/cairo-vm", rev = "fdf3fee0eab32db0e55aeaba63ee581a55c16c58", features = ["extensive_hints"] }
num-traits = "0.2.19"
serde = { version = "1.0.202", features = ["derive"] }
serde_json = "1.0.117"
Expand Down
20 changes: 20 additions & 0 deletions examples/run_cairo_pie.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
use std::error::Error;

use cairo_bootloader::cairo_run_bootloader_in_proof_mode;
use cairo_bootloader::tasks::make_bootloader_tasks;

fn main() -> Result<(), Box<dyn Error>> {
let fibonacci_pie = include_bytes!(
"../dependencies/test-programs/bootloader/pies/fibonacci-stone-e2e/cairo_pie.zip"
);

let tasks = make_bootloader_tasks(&[], &[fibonacci_pie])?;

let mut runner = cairo_run_bootloader_in_proof_mode(tasks, None, None, None)?;

let mut output_buffer = "Bootloader output:\n".to_string();
runner.vm.write_output(&mut output_buffer)?;
print!("{output_buffer}");

Ok(())
}
65 changes: 3 additions & 62 deletions examples/run_program.rs
Original file line number Diff line number Diff line change
@@ -1,75 +1,16 @@
use std::error::Error;

use cairo_vm::cairo_run::{cairo_run_program_with_initial_scope, CairoRunConfig};
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::cairo_run_bootloader_in_proof_mode;
use cairo_bootloader::tasks::make_bootloader_tasks;
use cairo_bootloader::{
insert_bootloader_input, BootloaderConfig, BootloaderHintProcessor, BootloaderInput,
PackedOutput, SimpleBootloaderInput, TaskSpec,
};

fn cairo_run_bootloader_in_proof_mode(
bootloader_program: &Program,
tasks: Vec<TaskSpec>,
) -> Result<CairoRunner, CairoRunError> {
let mut hint_processor = BootloaderHintProcessor::new();

let cairo_run_config = CairoRunConfig {
entrypoint: "main",
trace_enabled: false,
relocate_mem: false,
layout: LayoutName::starknet_with_keccak,
proof_mode: true,
secure_run: None,
disable_trace_padding: false,
allow_missing_builtins: None,
};

// Build the bootloader input
let n_tasks = tasks.len();
let bootloader_input = BootloaderInput {
simple_bootloader_input: SimpleBootloaderInput {
fact_topologies_path: None,
single_page: false,
tasks,
},
bootloader_config: BootloaderConfig {
simple_bootloader_program_hash: Felt252::from(0),
supported_cairo_verifier_program_hashes: vec![],
},
packed_outputs: vec![PackedOutput::Plain(vec![]); n_tasks],
};

// Note: the method used to set the bootloader input depends on
// https://github.com/lambdaclass/cairo-vm/pull/1772 and may change depending on review.
let mut exec_scopes = ExecutionScopes::new();
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,
)
}

fn main() -> Result<(), Box<dyn Error>> {
let bootloader_program = load_bootloader()?;
let fibonacci_program = include_bytes!("fibonacci.json");

let tasks = make_bootloader_tasks(&[fibonacci_program], &[])?;

let mut runner = cairo_run_bootloader_in_proof_mode(&bootloader_program, tasks)?;
let mut runner = cairo_run_bootloader_in_proof_mode(tasks, None, None, None)?;

let mut output_buffer = "Program Output:\n".to_string();
let mut output_buffer = "Bootloader output:\n".to_string();
runner.vm.write_output(&mut output_buffer)?;
print!("{output_buffer}");

Expand Down
4 changes: 2 additions & 2 deletions src/hints/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ mod program_hash;
mod program_loader;
mod select_builtins;
mod simple_bootloader_hints;
mod types;
pub(crate) mod types;
mod vars;

pub use hint_processors::{BootloaderHintProcessor, MinimalBootloaderHintProcessor};
pub use types::{
BootloaderConfig, BootloaderInput, PackedOutput, SimpleBootloaderInput, Task, TaskSpec,
};

pub use vars::BOOTLOADER_INPUT;
pub use vars::{BOOTLOADER_INPUT, BOOTLOADER_PROGRAM_IDENTIFIERS};
18 changes: 18 additions & 0 deletions src/hints/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,3 +78,21 @@ pub struct BootloaderInput {
pub bootloader_config: BootloaderConfig,
pub packed_outputs: Vec<PackedOutput>,
}

impl BootloaderInput {
pub fn new(tasks: Vec<TaskSpec>, fact_topologies_path: Option<PathBuf>) -> Self {
let n_tasks = tasks.len();
Self {
simple_bootloader_input: SimpleBootloaderInput {
fact_topologies_path,
single_page: false,
tasks,
},
bootloader_config: BootloaderConfig {
simple_bootloader_program_hash: Felt252::from(0),
supported_cairo_verifier_program_hashes: vec![],
},
packed_outputs: vec![PackedOutput::Plain(vec![]); n_tasks],
}
}
}
62 changes: 60 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,75 @@
use std::path::PathBuf;

use cairo_vm::cairo_run::{cairo_run_program_with_initial_scope, CairoRunConfig};
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;

pub use hints::*;

use crate::bootloaders::load_bootloader;
use crate::hints::types::ProgramIdentifiers;

pub mod bootloaders;
mod hints;
pub mod tasks;

#[cfg(test)]
pub mod macros;

/// Inserts the bootloader input in the execution scopes.
pub fn insert_bootloader_input(
/// Inserts the bootloader input and program identifiers in the execution scopes.
pub fn prepare_bootloader_exec_scopes(
exec_scopes: &mut ExecutionScopes,
bootloader_input: BootloaderInput,
bootloader_program: &Program,
) {
exec_scopes.insert_value(BOOTLOADER_INPUT, bootloader_input);
let identifiers: ProgramIdentifiers = bootloader_program
.iter_identifiers()
.map(|(k, v)| (k.to_string(), v.clone()))
.collect();
exec_scopes.insert_value(BOOTLOADER_PROGRAM_IDENTIFIERS, identifiers);
}

/// A helper function to run the bootloader in proof mode.
///
/// Reimplement your own version of this function if you wish to modify the Cairo run config
/// or other parameters.
pub fn cairo_run_bootloader_in_proof_mode(
tasks: Vec<TaskSpec>,
layout: Option<LayoutName>,
allow_missing_builtins: Option<bool>,
fact_topologies_path: Option<PathBuf>,
) -> Result<CairoRunner, CairoRunError> {
let mut hint_processor = BootloaderHintProcessor::new();

let bootloader_program = load_bootloader()?;

let cairo_run_config = CairoRunConfig {
entrypoint: "main",
trace_enabled: true,
relocate_mem: true,
layout: layout.unwrap_or(LayoutName::starknet_with_keccak),
proof_mode: true,
secure_run: None,
disable_trace_padding: false,
allow_missing_builtins,
};

// Build the bootloader input
let bootloader_input = BootloaderInput::new(tasks, fact_topologies_path);

// Load initial variables in the exec scopes
let mut exec_scopes = ExecutionScopes::new();
prepare_bootloader_exec_scopes(&mut exec_scopes, bootloader_input, &bootloader_program);

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