From bed092e6ac4ee80c51b76b46fa863d20fd35056d Mon Sep 17 00:00:00 2001 From: Bartosz Nowak Date: Wed, 23 Oct 2024 12:00:08 +0200 Subject: [PATCH] mpt hints implemented 7 minor fixes --- cairo_vm_hints/src/hints/lib/mpt/mod.rs | 203 ++++++++++++++++++ .../src/hints/tests/construct_mmr.rs | 14 +- cairo_vm_hints/src/mmr.rs | 10 +- 3 files changed, 217 insertions(+), 10 deletions(-) diff --git a/cairo_vm_hints/src/hints/lib/mpt/mod.rs b/cairo_vm_hints/src/hints/lib/mpt/mod.rs index 8b13789..4b31673 100644 --- a/cairo_vm_hints/src/hints/lib/mpt/mod.rs +++ b/cairo_vm_hints/src/hints/lib/mpt/mod.rs @@ -1 +1,204 @@ +const FELT_0: Felt252 = Felt252::ZERO; +const FELT_127: Felt252 = Felt252::from_hex_unchecked("0x7f"); +const FELT_128: Felt252 = Felt252::from_hex_unchecked("0x80"); +const FELT_183: Felt252 = Felt252::from_hex_unchecked("0xB7"); +const FELT_184: Felt252 = Felt252::from_hex_unchecked("0xB8"); +const FELT_191: Felt252 = Felt252::from_hex_unchecked("0xBF"); +const FELT_192: Felt252 = Felt252::from_hex_unchecked("0xC0"); +const FELT_247: Felt252 = Felt252::from_hex_unchecked("0xF7"); +const FELT_248: Felt252 = Felt252::from_hex_unchecked("0xF8"); +const FELT_255: Felt252 = Felt252::from_hex_unchecked("0xFF"); +/// Check if the value indicates a single byte (0x00 to 0x7f). +fn is_single_byte(value: Felt252) -> bool { + FELT_0 <= value && value <= FELT_127 +} + +/// Check if the value indicates a short string (0x80 to 0xb7). +fn is_short_string(value: Felt252) -> bool { + FELT_128 <= value && value <= FELT_183 +} + +/// Check if the value indicates a long string (0xb8 to 0xbf). +fn is_long_string(value: Felt252) -> bool { + FELT_184 <= value && value <= FELT_191 +} + +/// Check if the value indicates a short list (0xc0 to 0xf7). +fn is_short_list(value: Felt252) -> bool { + FELT_192 <= value && value <= FELT_247 +} + +/// Check if the value indicates a long list (0xf8 to 0xff). +fn is_long_list(value: Felt252) -> bool { + FELT_248 <= value && value <= FELT_255 +} + +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, 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 HINT_LONG_SHORT_LIST: &str = "from tools.py.hints import is_short_list, is_long_list\nif is_short_list(ids.list_prefix):\n ids.long_short_list = 0\nelif is_long_list(ids.list_prefix):\n ids.long_short_list = 1\nelse:\n raise ValueError(f\"Invalid list prefix: {hex(ids.list_prefix)}. Not a recognized list type.\")"; + +pub fn hint_long_short_list( + vm: &mut VirtualMachine, + _exec_scope: &mut ExecutionScopes, + hint_data: &HintProcessorData, + _constants: &HashMap, +) -> Result<(), HintError> { + let list_prefix = get_integer_from_var_name( + "list_prefix", + vm, + &hint_data.ids_data, + &hint_data.ap_tracking, + )?; + + match list_prefix { + value if is_short_list(value) => insert_value_from_var_name( + "long_short_list", + MaybeRelocatable::Int(Felt252::ZERO), + vm, + &hint_data.ids_data, + &hint_data.ap_tracking, + ), + value if is_long_list(value) => insert_value_from_var_name( + "long_short_list", + MaybeRelocatable::Int(Felt252::ONE), + vm, + &hint_data.ids_data, + &hint_data.ap_tracking, + ), + value => Err(HintError::InvalidValue(Box::new(( + "Invalid list prefix. Not a recognized list type.", + value, + Felt252::ZERO, + )))), + } +} + +pub const HINT_FIRST_ITEM_TYPE: &str = "from tools.py.hints import is_single_byte, is_short_string\nif is_single_byte(ids.first_item_prefix):\n ids.first_item_type = 0\nelif is_short_string(ids.first_item_prefix):\n ids.first_item_type = 1\nelse:\n raise ValueError(f\"Unsupported first item prefix: {hex(ids.first_item_prefix)}.\")"; + +pub fn hint_first_item_type( + vm: &mut VirtualMachine, + _exec_scope: &mut ExecutionScopes, + hint_data: &HintProcessorData, + _constants: &HashMap, +) -> Result<(), HintError> { + let first_item_prefix = get_integer_from_var_name( + "first_item_prefix", + vm, + &hint_data.ids_data, + &hint_data.ap_tracking, + )?; + + match first_item_prefix { + value if is_single_byte(value) => insert_value_from_var_name( + "first_item_type", + MaybeRelocatable::Int(Felt252::ZERO), + vm, + &hint_data.ids_data, + &hint_data.ap_tracking, + ), + value if is_short_string(value) => insert_value_from_var_name( + "first_item_type", + MaybeRelocatable::Int(Felt252::ONE), + vm, + &hint_data.ids_data, + &hint_data.ap_tracking, + ), + value => Err(HintError::InvalidValue(Box::new(( + "Unsupported first item prefix", + value, + Felt252::ZERO, + )))), + } +} + +pub const HINT_SECOND_ITEM_TYPE: &str = "from tools.py.hints import is_single_byte, is_short_string, is_long_string\nif is_single_byte(ids.second_item_prefix):\n ids.second_item_type = 0\nelif is_short_string(ids.second_item_prefix):\n ids.second_item_type = 1\nelif is_long_string(ids.second_item_prefix):\n ids.second_item_type = 2\nelse:\n raise ValueError(f\"Unsupported second item prefix: {hex(ids.second_item_prefix)}.\")"; + +pub fn hint_second_item_type( + vm: &mut VirtualMachine, + _exec_scope: &mut ExecutionScopes, + hint_data: &HintProcessorData, + _constants: &HashMap, +) -> Result<(), HintError> { + let second_item_prefix = get_integer_from_var_name( + "second_item_prefix", + vm, + &hint_data.ids_data, + &hint_data.ap_tracking, + )?; + + match second_item_prefix { + value if is_single_byte(value) => insert_value_from_var_name( + "second_item_type", + MaybeRelocatable::Int(Felt252::ZERO), + vm, + &hint_data.ids_data, + &hint_data.ap_tracking, + ), + value if is_short_string(value) => insert_value_from_var_name( + "second_item_type", + MaybeRelocatable::Int(Felt252::ONE), + vm, + &hint_data.ids_data, + &hint_data.ap_tracking, + ), + value if is_long_string(value) => insert_value_from_var_name( + "second_item_type", + MaybeRelocatable::Int(Felt252::TWO), + vm, + &hint_data.ids_data, + &hint_data.ap_tracking, + ), + value => Err(HintError::InvalidValue(Box::new(( + "Unsupported second item prefix", + value, + Felt252::ZERO, + )))), + } +} + +pub const HINT_ITEM_TYPE: &str = "from tools.py.hints import is_single_byte, is_short_string\nif is_single_byte(ids.item_prefix):\n ids.item_type = 0\nelif is_short_string(ids.item_prefix):\n ids.item_type = 1\nelse:\n raise ValueError(f\"Unsupported item prefix: {hex(ids.item_prefix)} for a branch node. Should be single byte or short string only.\")"; + +pub fn hint_item_type( + vm: &mut VirtualMachine, + _exec_scope: &mut ExecutionScopes, + hint_data: &HintProcessorData, + _constants: &HashMap, +) -> Result<(), HintError> { + let item_prefix = get_integer_from_var_name( + "item_prefix", + vm, + &hint_data.ids_data, + &hint_data.ap_tracking, + )?; + + match item_prefix { + value if is_single_byte(value) => insert_value_from_var_name( + "item_type", + MaybeRelocatable::Int(Felt252::ZERO), + vm, + &hint_data.ids_data, + &hint_data.ap_tracking, + ), + value if is_short_string(value) => insert_value_from_var_name( + "item_type", + MaybeRelocatable::Int(Felt252::ONE), + vm, + &hint_data.ids_data, + &hint_data.ap_tracking, + ), + value => Err(HintError::InvalidValue(Box::new(( + "Unsupported item prefix for a branch node. Should be single byte or short string only.", + value, + Felt252::ZERO, + )))), + } +} diff --git a/cairo_vm_hints/src/hints/tests/construct_mmr.rs b/cairo_vm_hints/src/hints/tests/construct_mmr.rs index 21d0895..227e1c0 100644 --- a/cairo_vm_hints/src/hints/tests/construct_mmr.rs +++ b/cairo_vm_hints/src/hints/tests/construct_mmr.rs @@ -142,8 +142,7 @@ pub fn test_construct_mmr( )?, &keccak_hash_array .iter() - .map(|x| split_u256(x)) - .flatten() + .flat_map(split_u256) .map(|x| MaybeRelocatable::Int(x.into())) .collect::>(), )?; @@ -192,15 +191,14 @@ pub fn test_construct_mmr( )?, &previous_peaks_keccak .iter() - .map(|x| split_u256(&x)) - .flatten() + .flat_map(split_u256) .map(|x| MaybeRelocatable::Int(x.into())) .collect::>(), )?; insert_value_from_var_name( "mmr_last_root_poseidon", - MaybeRelocatable::Int(mmr_poseidon.get_root().try_into().unwrap()), + MaybeRelocatable::Int(mmr_poseidon.get_root().into()), vm, &hint_data.ids_data, &hint_data.ap_tracking, @@ -214,7 +212,7 @@ pub fn test_construct_mmr( )?, &split_u256(&mmr_keccak.get_root()) .iter() - .map(|x| MaybeRelocatable::Int(x.try_into().unwrap())) + .map(|x| MaybeRelocatable::Int(x.into())) .collect::>(), )?; @@ -227,7 +225,7 @@ pub fn test_construct_mmr( insert_value_from_var_name( "expected_new_root_poseidon", - MaybeRelocatable::Int(mmr_poseidon.get_root().try_into().unwrap()), + MaybeRelocatable::Int(mmr_poseidon.get_root().into()), vm, &hint_data.ids_data, &hint_data.ap_tracking, @@ -241,7 +239,7 @@ pub fn test_construct_mmr( )?, &split_u256(&mmr_keccak.get_root()) .iter() - .map(|x| MaybeRelocatable::Int(x.try_into().unwrap())) + .map(|x| MaybeRelocatable::Int(x.into())) .collect::>(), )?; insert_value_from_var_name( diff --git a/cairo_vm_hints/src/mmr.rs b/cairo_vm_hints/src/mmr.rs index 37477cf..06ae142 100644 --- a/cairo_vm_hints/src/mmr.rs +++ b/cairo_vm_hints/src/mmr.rs @@ -41,7 +41,7 @@ impl Hasher for Poseidon { } fn hash(&self, x: &BigUint, y: &BigUint) -> BigUint { - poseidon_hash(x.try_into().unwrap(), y.try_into().unwrap()).to_biguint() + poseidon_hash(x.into(), y.into()).to_biguint() } } @@ -52,6 +52,12 @@ pub struct Mmr { leaf_count: usize, } +impl Default for Mmr { + fn default() -> Self { + Self::new() + } +} + impl Mmr { pub fn new() -> Mmr { Mmr { @@ -102,7 +108,7 @@ impl Mmr { self.nodes.push(element.clone()); let mut last_node = element; for peak in peaks.iter().rev().take(no_merged_peaks as usize) { - last_node = self.hasher.hash(&peak, &last_node); + last_node = self.hasher.hash(peak, &last_node); self.nodes.push(last_node.clone()); } }