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

Implement running from CairoPie #1720

Merged
merged 62 commits into from
Apr 25, 2024
Merged
Show file tree
Hide file tree
Changes from 61 commits
Commits
Show all changes
62 commits
Select commit Hold shift + click to select a range
a231575
Implement CairoPieMetadata validity checks
fmoletta Apr 16, 2024
3f99b46
Save progres
fmoletta Apr 17, 2024
b071346
Progress
fmoletta Apr 17, 2024
9ce9aea
Progress
fmoletta Apr 17, 2024
c79c02a
Clippy
fmoletta Apr 17, 2024
f8e8029
Impl generic serialization for suffixed ver
fmoletta Apr 17, 2024
e821c04
Implement custom generic deserialization
fmoletta Apr 18, 2024
3c4a417
Rename module
fmoletta Apr 18, 2024
cac3156
Complete API
fmoletta Apr 18, 2024
72c1a6b
Add docs & examples
fmoletta Apr 18, 2024
2652145
Fix docs
fmoletta Apr 18, 2024
4dd4e2b
Remove reference from method
fmoletta Apr 18, 2024
fc31dc6
Add clippy allow
fmoletta Apr 18, 2024
898bb0e
Add changelog entry
fmoletta Apr 18, 2024
7799173
Add no-std import
fmoletta Apr 18, 2024
922f963
Merge branch 'main' into use-builtin-name
fmoletta Apr 18, 2024
c49bb4b
Fix
fmoletta Apr 18, 2024
55d70b7
Merge branch 'use-builtin-name' of https://github.com/lambdaclass/cai…
fmoletta Apr 18, 2024
107a637
fmt
fmoletta Apr 18, 2024
f8d0082
Use a wrapper for CairoPie additional data
fmoletta Apr 18, 2024
92e69ee
Update changelog
fmoletta Apr 18, 2024
5b54cfa
Fix tests + fmt
fmoletta Apr 18, 2024
4730d7c
Merge branch 'main' of https://github.com/lambdaclass/cairo-vm into u…
fmoletta Apr 18, 2024
96141a6
Merge branch 'main' of https://github.com/lambdaclass/cairo-vm into r…
fmoletta Apr 18, 2024
60b3950
Merge with BuiltinName branch + add memory validity checks
fmoletta Apr 19, 2024
059e139
Add test for validity checks
fmoletta Apr 19, 2024
4f3e259
Start implementing cairo_run_pie
fmoletta Apr 19, 2024
0fd1c39
Implement extend_additional_data for hash
fmoletta Apr 19, 2024
c1a221d
Handle check
fmoletta Apr 19, 2024
4b36813
Simplify
fmoletta Apr 19, 2024
23821e9
Simplify
fmoletta Apr 19, 2024
f4b40de
Implement extend_additional_data for ecdsa
fmoletta Apr 19, 2024
11c7ed4
Add test
fmoletta Apr 19, 2024
301557d
Implement extend_additional_data for output
fmoletta Apr 19, 2024
1214c9f
Implement extend_additional_data for enum
fmoletta Apr 19, 2024
45392b1
Add changelog entry
fmoletta Apr 19, 2024
e993661
Merge branch 'main' into extend-additional-data
fmoletta Apr 19, 2024
34a1a96
Add doc comments to get_additional_data & extend_additional_data
fmoletta Apr 19, 2024
8e7936b
Merge branch 'extend-additional-data' of https://github.com/lambdacla…
fmoletta Apr 19, 2024
f679b06
Merge branch 'main' of https://github.com/lambdaclass/cairo-vm into r…
fmoletta Apr 19, 2024
7fc9be3
Check n_steps
fmoletta Apr 19, 2024
c683bac
Fail if proof mode
fmoletta Apr 19, 2024
39bfc1c
wip
fmoletta Apr 19, 2024
69155e1
Finalize segments by cairo pie
fmoletta Apr 19, 2024
d969fac
Add integration test for fibonacci
fmoletta Apr 22, 2024
ac73f53
Impl check_pie_compatibility
fmoletta Apr 22, 2024
1d80b79
Simplify code
fmoletta Apr 22, 2024
020aada
Merge branch 'extend-additional-data' into run-from-cairo-pie
fmoletta Apr 22, 2024
57cf7c1
Generalize test
fmoletta Apr 22, 2024
458c067
Extend additional data
fmoletta Apr 22, 2024
c1e1e5a
Improve test
fmoletta Apr 22, 2024
84ee280
Fix bug + add more test cases
fmoletta Apr 22, 2024
344db69
Add more test cases
fmoletta Apr 22, 2024
01f0bb4
Add doc
fmoletta Apr 22, 2024
4aae898
Add test
fmoletta Apr 22, 2024
7b5c02e
Add docs
fmoletta Apr 22, 2024
3fa430d
Add changelog entry
fmoletta Apr 22, 2024
cc96043
clippy
fmoletta Apr 22, 2024
1947cb6
changelog
fmoletta Apr 22, 2024
6ba7fec
fmt
fmoletta Apr 22, 2024
420347c
Merge branch 'main' into run-from-cairo-pie
fmoletta Apr 23, 2024
38b9ff8
Merge branch 'main' of https://github.com/lambdaclass/cairo-vm into r…
fmoletta Apr 25, 2024
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
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@

#### Upcoming Changes

* feat: Implement running from `CairoPie`[#1720](https://github.com/lambdaclass/cairo-vm/pull/1720)
* Add function `cairo_run_pie`
* Add `CairoPie` methods `run_validity_checks` & `check_pie_compatibility`
* Add `Program` method `from_stripped_program`

* feat: Implement `extend_additional_data` for `BuiltinRunner`[#1726](https://github.com/lambdaclass/cairo-vm/pull/1726)

* BREAKING: Set dynamic params as null by default on air public input [#1716](https://github.com/lambdaclass/cairo-vm/pull/1716)
Expand Down
135 changes: 131 additions & 4 deletions vm/src/cairo_run.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
use crate::{
hint_processor::hint_processor_definition::HintProcessor,
types::layout_name::LayoutName,
types::program::Program,
types::{builtin_name::BuiltinName, layout_name::LayoutName, program::Program},
vm::{
errors::{cairo_run_errors::CairoRunError, vm_exception::VmException},
runners::cairo_runner::CairoRunner,
errors::{
cairo_run_errors::CairoRunError, runner_errors::RunnerError, vm_exception::VmException,
},
runners::{cairo_pie::CairoPie, cairo_runner::CairoRunner},
security::verify_secure_runner,
vm_core::VirtualMachine,
},
Expand Down Expand Up @@ -105,6 +106,76 @@

cairo_run_program(&program, cairo_run_config, hint_executor)
}
/// Runs a Cairo PIE generated by a previous cairo execution
/// To generate a cairo pie use the runner's method `get_cairo_pie`
/// Note: Cairo PIEs cannot be ran in proof_mode
/// WARNING: As the RunResources are part of the HintProcessor trait, the caller should make sure that
/// the number of steps in the `RunResources` matches that of the `ExecutionResources` in the `CairoPie`.
/// An error will be returned if this doesn't hold.
pub fn cairo_run_pie(
pie: &CairoPie,
cairo_run_config: &CairoRunConfig,
hint_processor: &mut dyn HintProcessor,
) -> Result<(CairoRunner, VirtualMachine), CairoRunError> {
if cairo_run_config.proof_mode {
return Err(RunnerError::CairoPieProofMode.into());

Check warning on line 121 in vm/src/cairo_run.rs

View check run for this annotation

Codecov / codecov/patch

vm/src/cairo_run.rs#L121

Added line #L121 was not covered by tests
}
if !hint_processor
.get_n_steps()
.is_some_and(|steps| steps == pie.execution_resources.n_steps)
{
return Err(RunnerError::PieNStepsVsRunResourcesNStepsMismatch.into());
}
pie.run_validity_checks()?;
let secure_run = cairo_run_config.secure_run.unwrap_or(true);

let allow_missing_builtins = cairo_run_config.allow_missing_builtins.unwrap_or_default();

let program = Program::from_stripped_program(&pie.metadata.program);
let mut cairo_runner = CairoRunner::new(&program, cairo_run_config.layout, false)?;

let mut vm = VirtualMachine::new(cairo_run_config.trace_enabled);
let end = cairo_runner.initialize(&mut vm, allow_missing_builtins)?;
vm.finalize_segments_by_cairo_pie(pie);
// Load builtin additional data
for (name, data) in pie.additional_data.0.iter() {
// Data is not trusted in secure_run, therefore we skip extending the hash builtin's data
if matches!(name, BuiltinName::pedersen) && secure_run {
continue;
}
if let Some(builtin) = vm.builtin_runners.iter_mut().find(|b| b.name() == *name) {
builtin.extend_additional_data(data)?;
}

Check warning on line 148 in vm/src/cairo_run.rs

View check run for this annotation

Codecov / codecov/patch

vm/src/cairo_run.rs#L148

Added line #L148 was not covered by tests
}
// Load previous execution memory
let n_extra_segments = pie.metadata.extra_segments.len();
vm.segments.load_pie_memory(&pie.memory, n_extra_segments)?;

cairo_runner
.run_until_pc(end, &mut vm, hint_processor)
.map_err(|err| VmException::from_vm_error(&cairo_runner, &vm, err))?;

cairo_runner.end_run(
cairo_run_config.disable_trace_padding,
false,
&mut vm,
hint_processor,
)?;

vm.verify_auto_deductions()?;
cairo_runner.read_return_values(&mut vm, allow_missing_builtins)?;

if secure_run {
verify_secure_runner(&cairo_runner, true, None, &mut vm)?;
// Check that the Cairo PIE produced by this run is compatible with the Cairo PIE received
cairo_runner
.get_cairo_pie(&vm)?
.check_pie_compatibility(pie)?;
}

Check warning on line 174 in vm/src/cairo_run.rs

View check run for this annotation

Codecov / codecov/patch

vm/src/cairo_run.rs#L174

Added line #L174 was not covered by tests
cairo_runner.relocate(&mut vm, cairo_run_config.relocate_mem)?;

Ok((cairo_runner, vm))
}

#[cfg(feature = "arbitrary")]
pub fn cairo_run_fuzzed_program(
Expand Down Expand Up @@ -207,6 +278,7 @@
mod tests {
use super::*;
use crate::stdlib::prelude::*;
use crate::vm::runners::cairo_runner::RunResources;
use crate::Felt252;
use crate::{
hint_processor::{
Expand All @@ -217,6 +289,7 @@
};
use bincode::enc::write::SliceWriter;

use rstest::rstest;
#[cfg(target_arch = "wasm32")]
use wasm_bindgen_test::*;

Expand Down Expand Up @@ -377,4 +450,58 @@
assert!(cairo_runner.relocate(&mut vm, false).is_ok());
assert!(cairo_runner.relocated_trace.is_none());
}

#[rstest]
#[case(include_bytes!("../../cairo_programs/fibonacci.json"))]
#[case(include_bytes!("../../cairo_programs/integration.json"))]
#[case(include_bytes!("../../cairo_programs/common_signature.json"))]
#[case(include_bytes!("../../cairo_programs/relocate_segments.json"))]
#[case(include_bytes!("../../cairo_programs/ec_op.json"))]
#[case(include_bytes!("../../cairo_programs/bitwise_output.json"))]
fn get_and_run_cairo_pie(#[case] program_content: &[u8]) {
let cairo_run_config = CairoRunConfig {
layout: LayoutName::starknet_with_keccak,
..Default::default()
};
// First run program to get Cairo PIE
let cairo_pie = {
let (runner, vm) = cairo_run(
program_content,
&cairo_run_config,
&mut BuiltinHintProcessor::new_empty(),
)
.unwrap();
runner.get_cairo_pie(&vm).unwrap()
};
let mut hint_processor = BuiltinHintProcessor::new(
Default::default(),
RunResources::new(cairo_pie.execution_resources.n_steps),
);
// Default config runs with secure_run, which checks that the Cairo PIE produced by this run is compatible with the one received
assert!(cairo_run_pie(&cairo_pie, &cairo_run_config, &mut hint_processor).is_ok());
}

#[test]
fn cairo_run_pie_n_steps_not_set() {
// First run program to get Cairo PIE
let cairo_pie = {
let (runner, vm) = cairo_run(
include_bytes!("../../cairo_programs/fibonacci.json"),
&CairoRunConfig::default(),
&mut BuiltinHintProcessor::new_empty(),
)
.unwrap();
runner.get_cairo_pie(&vm).unwrap()
};
// Run Cairo PIE
let res = cairo_run_pie(
&cairo_pie,
&CairoRunConfig::default(),
&mut BuiltinHintProcessor::new_empty(),
);
assert!(res.is_err_and(|err| matches!(
err,
CairoRunError::Runner(RunnerError::PieNStepsVsRunResourcesNStepsMismatch)
)));
}
}
20 changes: 20 additions & 0 deletions vm/src/tests/cairo_pie_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -274,3 +274,23 @@ fn serialize_cairo_pie() {
.unwrap(),
);
}

#[test]
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
fn run_pie_validity_checks_integration() {
// Run the program
let program_content = include_bytes!("../../../cairo_programs/integration.json");
let mut hint_processor = BuiltinHintProcessor::new_empty();
let (runner, vm) = cairo_run(
program_content,
&CairoRunConfig {
layout: LayoutName::all_cairo,
..Default::default()
},
&mut hint_processor,
)
.expect("cairo_run failure");
// Obtain the pie
let cairo_pie = runner.get_cairo_pie(&vm).expect("Failed to get pie");
assert!(cairo_pie.run_validity_checks().is_ok())
}
12 changes: 12 additions & 0 deletions vm/src/types/program.rs
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,18 @@ impl Program {
})
}

pub fn from_stripped_program(stripped: &StrippedProgram) -> Program {
Program {
shared_program_data: Arc::new(SharedProgramData {
data: stripped.data.clone(),
main: Some(stripped.main),
..Default::default()
}),
constants: Default::default(),
builtins: stripped.builtins.clone(),
}
}

pub fn serialize(&self) -> Result<Vec<u8>, ProgramError> {
let program_serializer: ProgramSerializer = ProgramSerializer::from(self);
let bytes: Vec<u8> = serde_json::to_vec(&program_serializer)?;
Expand Down
41 changes: 41 additions & 0 deletions vm/src/vm/errors/cairo_pie_errors.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
use thiserror_no_std::Error;

use crate::types::builtin_name::BuiltinName;

#[derive(Eq, Hash, PartialEq, Debug, Error)]
pub enum CairoPieValidationError {
#[error("Invalid main() address.")]
InvalidMainAddress,
#[error("Program length does not match the program segment size.")]
ProgramLenVsSegmentSizeMismatch,
#[error("Builtin list mismatch in builtin_segments.")]
BuiltinListVsSegmentsMismatch,
#[error("Invalid segment size for ret_fp. Must be 0.")]
InvalidRetFpSegmentSize,
#[error("Invalid segment size for ret_pc. Must be 0.")]
InvalidRetPcSegmentSize,
#[error("Invalid segment index for program_segment.")]
InvalidProgramSegmentIndex,
#[error("Invalid segment index for execution_segment.")]
InvalidExecutionSegmentIndex,
#[error("Invalid segment index for {0}.")]
InvalidBuiltinSegmentIndex(BuiltinName),
#[error("Invalid segment index for ret_fp_segment.")]
InvalidRetFpSegmentIndex,
#[error("Invalid segment index for ret_pc_segment.")]
InvalidRetPcSegmentIndex,
#[error("Invalid segment indices for extra_segments.")]
InvalidExtraSegmentIndex,
#[error("Invalid address")]
InvalidAddress,
#[error("Cairo PIE diff: metadata mismatch")]
DiffMetadata,
#[error("Cairo PIE diff: memory mismatch")]
DiffMemory,
#[error("Cairo PIE diff: execution_resources mismatch")]
DiffExecutionResources,
#[error("Cairo PIE diff: additional_data mismatch")]
DiffAdditionalData,
#[error("Cairo PIE diff: additional_data[{0}] mismatch")]
DiffAdditionalDataForBuiltin(BuiltinName),
}
3 changes: 3 additions & 0 deletions vm/src/vm/errors/cairo_run_errors.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use thiserror_no_std::Error;

use super::cairo_pie_errors::CairoPieValidationError;
use super::memory_errors::MemoryError;
use super::vm_exception::VmException;
use crate::types::errors::program_errors::ProgramError;
Expand All @@ -21,4 +22,6 @@ pub enum CairoRunError {
MemoryError(#[from] MemoryError),
#[error(transparent)]
VmException(#[from] VmException),
#[error("Cairo Pie validation failed: {0}")]
CairoPieValidation(#[from] CairoPieValidationError),
}
1 change: 1 addition & 0 deletions vm/src/vm/errors/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
pub mod cairo_pie_errors;
pub mod cairo_run_errors;
pub mod exec_scope_errors;
pub mod hint_errors;
Expand Down
4 changes: 4 additions & 0 deletions vm/src/vm/errors/runner_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,10 @@ pub enum RunnerError {
MissingBuiltin(BuiltinName),
#[error("The stop pointer of the missing builtin {0} must be 0")]
MissingBuiltinStopPtrNotZero(BuiltinName),
#[error("The number of steps in the Cairo PIE's execution resources does not match the number of steps in the RunResources")]
PieNStepsVsRunResourcesNStepsMismatch,
#[error("A Cairo PIE can not be ran in proof_mode")]
CairoPieProofMode,
#[error("{0}: Invalid additional data")]
InvalidAdditionalData(BuiltinName),
}
Expand Down
Loading
Loading