Skip to content

Commit

Permalink
Feature: support output pages in public input memory
Browse files Browse the repository at this point in the history
Problem: output page IDs do not appear when exporting the builtin
memory, but default to page 0 instead.

Solution: add a `get_public_memory` to the output builtin to export page
IDs correctly.
  • Loading branch information
odesenfans committed Feb 22, 2024
1 parent 76622d8 commit d3a33c2
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 3 deletions.
33 changes: 33 additions & 0 deletions vm/src/vm/runners/builtin_runner/output.rs
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,21 @@ impl OutputBuiltinRunner {

Ok(())
}

pub fn get_public_memory(&self) -> Result<Vec<(usize, usize)>, RunnerError> {
let size = self
.stop_ptr
.ok_or(RunnerError::NoStopPointer(Box::new(OUTPUT_BUILTIN_NAME)))?;

let mut public_memory: Vec<(usize, usize)> = (0..size).map(|i| (i, 0)).collect();
for (page_id, page) in self.pages.iter() {
for index in 0..page.size {
public_memory[page.start + index].1 = page_id.clone();
}
}

Ok(public_memory)
}
}

impl Default for OutputBuiltinRunner {
Expand Down Expand Up @@ -551,4 +566,22 @@ mod tests {
matches!(result, Err(RunnerError::PageNotOnSegment(relocatable, base)) if relocatable == page_start && base == builtin.base())
)
}

#[test]
fn get_public_memory() {
let mut builtin = OutputBuiltinRunner::new(true);
let page_start = Relocatable {
segment_index: builtin.base() as isize,
offset: 2,
};
builtin
.add_page(1, page_start.clone(), 2)
.expect("Failed to add page");

// Mock the effects of `final_stack()`
builtin.stop_ptr = Some(4);

let public_memory = builtin.get_public_memory().unwrap();
assert_eq!(public_memory, vec![(0, 0), (1, 0), (2, 1), (3, 1)]);
}
}
6 changes: 3 additions & 3 deletions vm/src/vm/runners/cairo_runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ use num_traits::{ToPrimitive, Zero};
use serde::{Deserialize, Serialize};

use super::{
builtin_runner::{KeccakBuiltinRunner, PoseidonBuiltinRunner, OUTPUT_BUILTIN_NAME},
builtin_runner::{KeccakBuiltinRunner, PoseidonBuiltinRunner},
cairo_pie::{self, CairoPie, CairoPieMetadata, CairoPieVersion},
};

Expand Down Expand Up @@ -1091,8 +1091,8 @@ impl CairoRunner {
let (_, size) = builtin_runner
.get_used_cells_and_allocated_size(vm)
.map_err(RunnerError::FinalizeSegements)?;
if builtin_runner.name() == OUTPUT_BUILTIN_NAME {
let public_memory = (0..size).map(|i| (i, 0)).collect();
if let BuiltinRunner::Output(output_builtin) = builtin_runner {
let public_memory = output_builtin.get_public_memory()?;
vm.segments
.finalize(Some(size), builtin_runner.base(), Some(&public_memory))
} else {
Expand Down

0 comments on commit d3a33c2

Please sign in to comment.