Skip to content

Commit

Permalink
Implement bit length and is_valid_mmr_size test hints
Browse files Browse the repository at this point in the history
  • Loading branch information
fmkra committed Oct 16, 2024
1 parent 94f1df1 commit 1839982
Show file tree
Hide file tree
Showing 9 changed files with 246 additions and 11 deletions.
1 change: 1 addition & 0 deletions cairo_vm_hints/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion cairo_vm_hints/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ cairo-vm = { git = "https://github.com/lambdaclass/cairo-vm", rev = "3fb0344ce03
starknet-types-core = "0.1.7"
thiserror = "1.0.64"
clap = { version = "4.3.10", features = ["derive"] }
bincode = { version = "2.0.0-rc.3", default-features = false, features = ["serde"] }
bincode = { version = "2.0.0-rc.3", default-features = false, features = ["serde"] }
rand = "0.8"
30 changes: 28 additions & 2 deletions cairo_vm_hints/src/hint_processor.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,18 @@
use crate::hints::print_var::{print_var, PRINT_VAR};
use crate::hints::{
get_bit_length::{get_bit_length, GET_BIT_LENGTH},
test_is_valid_mmr_size_generate_random::{
test_is_valid_mmr_size_generate_random, TEST_IS_VALID_MMR_SIZE_GENERATE_RANDOM,
},
test_is_valid_mmr_size_generate_sequential::{
test_is_valid_mmr_size_generate_sequential, TEST_IS_VALID_MMR_SIZE_GENERATE_SEQUENTIAL,
},
test_is_valid_mmr_size_print_1::{
test_is_valid_mmr_size_print_1, TEST_IS_VALID_MMR_SIZE_PRINT_1,
},
test_is_valid_mmr_size_print_2::{
test_is_valid_mmr_size_print_2, TEST_IS_VALID_MMR_SIZE_PRINT_2,
},
};
use cairo_vm::{
hint_processor::{
builtin_hint_processor::builtin_hint_processor_definition::{
Expand Down Expand Up @@ -34,7 +48,19 @@ fn run_hint(
constants: &HashMap<String, Felt252>,
) -> Result<(), HintError> {
match hint_data.code.as_str() {
PRINT_VAR => print_var(vm, exec_scope, hint_data, constants),
TEST_IS_VALID_MMR_SIZE_PRINT_1 => {
test_is_valid_mmr_size_print_1(vm, exec_scope, hint_data, constants)
}
TEST_IS_VALID_MMR_SIZE_PRINT_2 => {
test_is_valid_mmr_size_print_2(vm, exec_scope, hint_data, constants)
}
TEST_IS_VALID_MMR_SIZE_GENERATE_SEQUENTIAL => {
test_is_valid_mmr_size_generate_sequential(vm, exec_scope, hint_data, constants)
}
TEST_IS_VALID_MMR_SIZE_GENERATE_RANDOM => {
test_is_valid_mmr_size_generate_random(vm, exec_scope, hint_data, constants)
}
GET_BIT_LENGTH => get_bit_length(vm, exec_scope, hint_data, constants),
_ => Err(HintError::UnknownHint(
hint_data.code.to_string().into_boxed_str(),
)),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,29 @@
use cairo_vm::hint_processor::builtin_hint_processor::builtin_hint_processor_definition::HintProcessorData;
use cairo_vm::hint_processor::builtin_hint_processor::hint_utils::get_integer_from_var_name;
use cairo_vm::hint_processor::builtin_hint_processor::hint_utils::{
get_integer_from_var_name, insert_value_from_var_name,
};
use cairo_vm::types::exec_scope::ExecutionScopes;
use cairo_vm::types::relocatable::MaybeRelocatable;
use cairo_vm::vm::{errors::hint_errors::HintError, vm_core::VirtualMachine};
use cairo_vm::Felt252;
use std::collections::HashMap;

pub const PRINT_VAR: &str = "print(ids.x)";
pub const GET_BIT_LENGTH: &str = "ids.bit_length = ids.x.bit_length()";

pub fn print_var(
pub fn get_bit_length(
vm: &mut VirtualMachine,
_exec_scope: &mut ExecutionScopes,
hint_data: &HintProcessorData,
_constants: &HashMap<String, Felt252>,
) -> Result<(), HintError> {
let ids_data = &hint_data.ids_data;
let ap_tracking = &hint_data.ap_tracking;
let a = get_integer_from_var_name("x", vm, ids_data, ap_tracking)?;
println!("printing {}", a);
let x = get_integer_from_var_name("x", vm, &hint_data.ids_data, &hint_data.ap_tracking)?;
insert_value_from_var_name(
"bit_length",
MaybeRelocatable::Int(x.bits().into()),
vm,
&hint_data.ids_data,
&hint_data.ap_tracking,
)?;

Ok(())
}
6 changes: 5 additions & 1 deletion cairo_vm_hints/src/hints/mod.rs
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
pub mod print_var;
pub mod get_bit_length;
pub mod test_is_valid_mmr_size_generate_random;
pub mod test_is_valid_mmr_size_generate_sequential;
pub mod test_is_valid_mmr_size_print_1;
pub mod test_is_valid_mmr_size_print_2;
84 changes: 84 additions & 0 deletions cairo_vm_hints/src/hints/test_is_valid_mmr_size_generate_random.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
use cairo_vm::hint_processor::builtin_hint_processor::builtin_hint_processor_definition::HintProcessorData;
use cairo_vm::hint_processor::builtin_hint_processor::hint_utils::{
get_integer_from_var_name, get_ptr_from_var_name,
};
use cairo_vm::types::exec_scope::ExecutionScopes;
use cairo_vm::types::relocatable::MaybeRelocatable;
use cairo_vm::vm::{errors::hint_errors::HintError, vm_core::VirtualMachine};
use cairo_vm::Felt252;
use rand::{thread_rng, Rng};
use starknet_types_core::felt::Felt;
use std::collections::HashMap;

fn is_valid_mmr_size(mut mmr_size: u64) -> bool {
if mmr_size == 0 {
return false;
}
let max_height = Felt::from(mmr_size).bits() as u32;
for height in (0..=max_height).rev() {
let node_count = 2u64.pow(height + 1) - 1;
if node_count <= mmr_size {
mmr_size -= node_count;
}
}
mmr_size == 0
}

pub const TEST_IS_VALID_MMR_SIZE_GENERATE_RANDOM: &str = "from tools.py.mmr import is_valid_mmr_size
import random
print(f\"Testing is_valid_mmr_size against python implementation with {ids.num_sizes} random sizes in [0, 20000000)...\")
sizes_to_test = random.sample(range(0, 20000000), ids.num_sizes)
expected_output = [is_valid_mmr_size(size) for size in sizes_to_test]
segments.write_arg(ids.expected_output, expected_output)
segments.write_arg(ids.input_array, sizes_to_test)";

pub fn test_is_valid_mmr_size_generate_random(
vm: &mut VirtualMachine,
_exec_scope: &mut ExecutionScopes,
hint_data: &HintProcessorData,
_constants: &HashMap<String, Felt252>,
) -> Result<(), HintError> {
// let ids_data = &hint_data.ids_data;
// let ap_tracking = &hint_data.ap_tracking;
// let a = get_integer_from_var_name("x", vm, ids_data, ap_tracking)?;
// vm.segments.write_arg(vm.seg, arg)
let num_sizes: u64 =
get_integer_from_var_name("num_sizes", vm, &hint_data.ids_data, &hint_data.ap_tracking)?
.try_into()
.unwrap();

println!(
"Testing is_valid_mmr_size against python implementation with {} random sizes in [0, 20000000)...",
num_sizes
);

let mut rng = thread_rng();
let mut input_array = vec![];
let mut expected_output = vec![];
for _ in 0..num_sizes {
let x = rng.gen_range(0..20000000);
input_array.push(MaybeRelocatable::Int(x.into()));
let y = is_valid_mmr_size(x);
expected_output.push(MaybeRelocatable::Int(y.into()));
}

let expected_output_ptr = get_ptr_from_var_name(
"expected_output",
vm,
&hint_data.ids_data,
&hint_data.ap_tracking,
)?;

let input_array_ptr = get_ptr_from_var_name(
"input_array",
vm,
&hint_data.ids_data,
&hint_data.ap_tracking,
)?;

vm.segments.load_data(input_array_ptr, &input_array)?;
vm.segments
.load_data(expected_output_ptr, &expected_output)?;

Ok(())
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
use cairo_vm::hint_processor::builtin_hint_processor::builtin_hint_processor_definition::HintProcessorData;
use cairo_vm::hint_processor::builtin_hint_processor::hint_utils::{
get_integer_from_var_name, get_ptr_from_var_name,
};
use cairo_vm::types::exec_scope::ExecutionScopes;
use cairo_vm::types::relocatable::MaybeRelocatable;
use cairo_vm::vm::{errors::hint_errors::HintError, vm_core::VirtualMachine};
use cairo_vm::Felt252;
use std::collections::{HashMap, HashSet};

pub const TEST_IS_VALID_MMR_SIZE_GENERATE_SEQUENTIAL: &str = "print(f\"Testing is_valid_mmr_size by creating the mmr for all sizes in [0, {ids.num_elems})...\")
from tools.py.mmr import MMR
mmr = MMR()
valid_mmr_sizes = set()
for i in range(ids.num_elems):
mmr.add(i)
valid_mmr_sizes.add(len(mmr.pos_hash))
expected_output = [size in valid_mmr_sizes for size in range(0, len(mmr.pos_hash) + 1)]
for out, inp in zip(expected_output, range(0, len(mmr.pos_hash) + 1)):
print(out, inp)
segments.write_arg(ids.expected_output, expected_output)
segments.write_arg(ids.input_array, list(range(0, len(mmr.pos_hash) + 1)))";

pub fn test_is_valid_mmr_size_generate_sequential(
vm: &mut VirtualMachine,
_exec_scope: &mut ExecutionScopes,
hint_data: &HintProcessorData,
_constants: &HashMap<String, Felt252>,
) -> Result<(), HintError> {
// let ids_data = &hint_data.ids_data;
// let ap_tracking = &hint_data.ap_tracking;
// let a = get_integer_from_var_name("x", vm, ids_data, ap_tracking)?;
// vm.segments.write_arg(vm.seg, arg)
let num_elems: u64 =
get_integer_from_var_name("num_elems", vm, &hint_data.ids_data, &hint_data.ap_tracking)?
.try_into()
.unwrap();

println!(
"Testing is_valid_mmr_size by creating the mmr for all sizes in [0, {})...",
num_elems
);

let mut valid_mmr_sizes = HashSet::new();
let mut mmr_size = 0;
for leaf_count in 1..=num_elems {
mmr_size = 2 * leaf_count - (leaf_count.count_ones() as u64);
valid_mmr_sizes.insert(mmr_size);
}
let expected_output = (0..=mmr_size)
.map(|i| MaybeRelocatable::Int(valid_mmr_sizes.contains(&i).into()))
.collect::<Vec<_>>();
let input_array = (0..=mmr_size)
.map(|x| MaybeRelocatable::Int(x.into()))
.collect::<Vec<_>>();

let expected_output_ptr = get_ptr_from_var_name(
"expected_output",
vm,
&hint_data.ids_data,
&hint_data.ap_tracking,
)?;

let input_array_ptr = get_ptr_from_var_name(
"input_array",
vm,
&hint_data.ids_data,
&hint_data.ap_tracking,
)?;

vm.segments.load_data(input_array_ptr, &input_array)?;
vm.segments
.load_data(expected_output_ptr, &expected_output)?;

Ok(())
}
17 changes: 17 additions & 0 deletions cairo_vm_hints/src/hints/test_is_valid_mmr_size_print_1.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
use cairo_vm::hint_processor::builtin_hint_processor::builtin_hint_processor_definition::HintProcessorData;
use cairo_vm::types::exec_scope::ExecutionScopes;
use cairo_vm::vm::{errors::hint_errors::HintError, vm_core::VirtualMachine};
use cairo_vm::Felt252;
use std::collections::HashMap;

pub const TEST_IS_VALID_MMR_SIZE_PRINT_1: &str = "print('\\n')";

pub fn test_is_valid_mmr_size_print_1(
_vm: &mut VirtualMachine,
_exec_scope: &mut ExecutionScopes,
_hint_data: &HintProcessorData,
_constants: &HashMap<String, Felt252>,
) -> Result<(), HintError> {
println!("\n");
Ok(())
}
17 changes: 17 additions & 0 deletions cairo_vm_hints/src/hints/test_is_valid_mmr_size_print_2.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
use cairo_vm::hint_processor::builtin_hint_processor::builtin_hint_processor_definition::HintProcessorData;
use cairo_vm::types::exec_scope::ExecutionScopes;
use cairo_vm::vm::{errors::hint_errors::HintError, vm_core::VirtualMachine};
use cairo_vm::Felt252;
use std::collections::HashMap;

pub const TEST_IS_VALID_MMR_SIZE_PRINT_2: &str = "print(f\"\\tPass!\\n\\n\")";

pub fn test_is_valid_mmr_size_print_2(
_vm: &mut VirtualMachine,
_exec_scope: &mut ExecutionScopes,
_hint_data: &HintProcessorData,
_constants: &HashMap<String, Felt252>,
) -> Result<(), HintError> {
println!("\tPass!\n\n");
Ok(())
}

0 comments on commit 1839982

Please sign in to comment.