From fa2492f1648001adbdf85791cb58573bfb0c5f81 Mon Sep 17 00:00:00 2001 From: Filip Krawczyk Date: Fri, 25 Oct 2024 19:54:22 +0200 Subject: [PATCH] Clean up hint processing --- Cargo.lock | 21 +++++++++ Cargo.toml | 3 +- cairo_vm_hints/Cargo.toml | 1 + cairo_vm_hints/src/hint_processor.rs | 2 +- cairo_vm_hints/src/hints/lib/bit_length.rs | 17 ++----- .../src/hints/lib/block_header/mod.rs | 17 ++----- .../src/hints/lib/mmr/bit_length.rs | 9 +++- .../src/hints/lib/mmr/left_child.rs | 9 +++- cairo_vm_hints/src/hints/lib/mmr/mod.rs | 27 ----------- cairo_vm_hints/src/hints/lib/mod.rs | 34 -------------- cairo_vm_hints/src/hints/lib/mpt/mod.rs | 28 +++++------ .../src/hints/lib/rlp_little/assert.rs | 17 +++++-- .../src/hints/lib/rlp_little/divmod.rs | 9 +++- .../src/hints/lib/rlp_little/leading_zeros.rs | 17 +++++-- .../src/hints/lib/rlp_little/mod.rs | 46 ------------------ .../src/hints/lib/rlp_little/nibbles.rs | 38 +++++++++++---- cairo_vm_hints/src/hints/lib/utils/assert.rs | 16 +++++-- cairo_vm_hints/src/hints/lib/utils/carry.rs | 9 +++- cairo_vm_hints/src/hints/lib/utils/divmod.rs | 23 ++++++--- cairo_vm_hints/src/hints/lib/utils/mod.rs | 41 ---------------- .../src/hints/lib/utils/trailing_zeroes.rs | 9 +++- cairo_vm_hints/src/hints/lib/utils/write.rs | 44 ++++++++++++----- cairo_vm_hints/src/hints/mod.rs | 27 +++++++---- .../src/hints/tests/construct_mmr.rs | 9 +++- cairo_vm_hints/src/hints/tests/dw_hack.rs | 34 ++++++++++---- .../src/hints/tests/encode_packed_256.rs | 9 +++- .../src/hints/tests/mmr_size_generate.rs | 16 +++++-- cairo_vm_hints/src/hints/tests/mod.rs | 47 ------------------- cairo_vm_hints/src/hints/tests/print.rs | 16 +++++-- 29 files changed, 277 insertions(+), 318 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a572f60..3fc5cb5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -239,6 +239,7 @@ dependencies = [ "cairo-vm", "clap", "hex", + "linkme", "num-bigint", "num-traits", "rand", @@ -550,6 +551,26 @@ version = "0.2.161" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e9489c2807c139ffd9c1794f4af0ebe86a828db53ecdc7fea2111d0fed085d1" +[[package]] +name = "linkme" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70fe496a7af8c406f877635cbf3cd6a9fac9d6f443f58691cd8afe6ce0971af4" +dependencies = [ + "linkme-impl", +] + +[[package]] +name = "linkme-impl" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b01f197a15988fb5b2ec0a5a9800c97e70771499c456ad757d63b3c5e9b96e75" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.82", +] + [[package]] name = "log" version = "0.4.22" diff --git a/Cargo.toml b/Cargo.toml index 31c4c6f..25e0c1e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,4 +16,5 @@ num-bigint = "0.4.6" num-traits = "0.2.19" tiny-keccak = { version = "2.0.2", features = ["keccak"] } hex = "0.4.3" -starknet-crypto = "0.7.2" \ No newline at end of file +starknet-crypto = "0.7.2" +linkme = "0.3.29" \ No newline at end of file diff --git a/cairo_vm_hints/Cargo.toml b/cairo_vm_hints/Cargo.toml index bafdd2b..e6a0af7 100644 --- a/cairo_vm_hints/Cargo.toml +++ b/cairo_vm_hints/Cargo.toml @@ -16,3 +16,4 @@ num-traits.workspace = true tiny-keccak.workspace = true hex.workspace = true starknet-crypto.workspace = true +linkme.workspace = true diff --git a/cairo_vm_hints/src/hint_processor.rs b/cairo_vm_hints/src/hint_processor.rs index 9051fbf..c0550d2 100644 --- a/cairo_vm_hints/src/hint_processor.rs +++ b/cairo_vm_hints/src/hint_processor.rs @@ -1,4 +1,4 @@ -use crate::run_hint; +use crate::hints::run_hint; use cairo_vm::{ hint_processor::{ builtin_hint_processor::builtin_hint_processor_definition::{ diff --git a/cairo_vm_hints/src/hints/lib/bit_length.rs b/cairo_vm_hints/src/hints/lib/bit_length.rs index 5a76ebb..8d06fe7 100644 --- a/cairo_vm_hints/src/hints/lib/bit_length.rs +++ b/cairo_vm_hints/src/hints/lib/bit_length.rs @@ -1,3 +1,4 @@ +use crate::hints::{Hint, HINTS}; 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, @@ -6,6 +7,7 @@ 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 linkme::distributed_slice; use std::collections::HashMap; const HINT_BIT_LENGTH: &str = "ids.bit_length = ids.x.bit_length()"; @@ -28,16 +30,5 @@ fn hint_bit_length( Ok(()) } -pub fn run_hint( - vm: &mut VirtualMachine, - exec_scope: &mut ExecutionScopes, - hint_data: &HintProcessorData, - constants: &HashMap, -) -> Result<(), HintError> { - match hint_data.code.as_str() { - HINT_BIT_LENGTH => hint_bit_length(vm, exec_scope, hint_data, constants), - _ => Err(HintError::UnknownHint( - hint_data.code.to_string().into_boxed_str(), - )), - } -} +#[distributed_slice(HINTS)] +static _HINT_BIT_LENGTH: Hint = (HINT_BIT_LENGTH, hint_bit_length); diff --git a/cairo_vm_hints/src/hints/lib/block_header/mod.rs b/cairo_vm_hints/src/hints/lib/block_header/mod.rs index 5636111..5419c36 100644 --- a/cairo_vm_hints/src/hints/lib/block_header/mod.rs +++ b/cairo_vm_hints/src/hints/lib/block_header/mod.rs @@ -1,3 +1,4 @@ +use crate::hints::{Hint, HINTS}; 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_into_ap, @@ -6,6 +7,7 @@ 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 linkme::distributed_slice; use std::cmp::Ordering; use std::collections::HashMap; @@ -31,16 +33,5 @@ fn hint_rlp_bigint_size( Ok(()) } -pub fn run_hint( - vm: &mut VirtualMachine, - exec_scope: &mut ExecutionScopes, - hint_data: &HintProcessorData, - constants: &HashMap, -) -> Result<(), HintError> { - match hint_data.code.as_str() { - HINT_RLP_BIGINT_SIZE => hint_rlp_bigint_size(vm, exec_scope, hint_data, constants), - _ => Err(HintError::UnknownHint( - hint_data.code.to_string().into_boxed_str(), - )), - } -} +#[distributed_slice(HINTS)] +static _HINT_RLP_BIGINT_SIZE: Hint = (HINT_RLP_BIGINT_SIZE, hint_rlp_bigint_size); diff --git a/cairo_vm_hints/src/hints/lib/mmr/bit_length.rs b/cairo_vm_hints/src/hints/lib/mmr/bit_length.rs index 567dbd0..9b61cdf 100644 --- a/cairo_vm_hints/src/hints/lib/mmr/bit_length.rs +++ b/cairo_vm_hints/src/hints/lib/mmr/bit_length.rs @@ -1,3 +1,4 @@ +use crate::hints::{Hint, HINTS}; 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, @@ -6,11 +7,12 @@ 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 linkme::distributed_slice; use std::collections::HashMap; -pub const MMR_BIT_LENGTH: &str = "ids.bit_length = ids.mmr_len.bit_length()"; +const MMR_LEFT_CHILD: &str = "ids.bit_length = ids.mmr_len.bit_length()"; -pub fn mmr_bit_length( +fn mmr_left_child( vm: &mut VirtualMachine, _exec_scope: &mut ExecutionScopes, hint_data: &HintProcessorData, @@ -27,3 +29,6 @@ pub fn mmr_bit_length( Ok(()) } + +#[distributed_slice(HINTS)] +static _MMR_LEFT_CHILD: Hint = (MMR_LEFT_CHILD, mmr_left_child); diff --git a/cairo_vm_hints/src/hints/lib/mmr/left_child.rs b/cairo_vm_hints/src/hints/lib/mmr/left_child.rs index 673058c..940b81f 100644 --- a/cairo_vm_hints/src/hints/lib/mmr/left_child.rs +++ b/cairo_vm_hints/src/hints/lib/mmr/left_child.rs @@ -1,3 +1,4 @@ +use crate::hints::{Hint, HINTS}; 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, @@ -6,12 +7,13 @@ 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 linkme::distributed_slice; use starknet_types_core::felt::Felt; use std::collections::HashMap; -pub const MMR_LEFT_CHILD: &str = "ids.in_mmr = 1 if ids.left_child<=ids.mmr_len else 0"; +const MMR_LEFT_CHILD: &str = "ids.in_mmr = 1 if ids.left_child<=ids.mmr_len else 0"; -pub fn mmr_left_child( +fn mmr_left_child( vm: &mut VirtualMachine, _exec_scope: &mut ExecutionScopes, hint_data: &HintProcessorData, @@ -41,3 +43,6 @@ pub fn mmr_left_child( Ok(()) } + +#[distributed_slice(HINTS)] +static _MMR_LEFT_CHILD: Hint = (MMR_LEFT_CHILD, mmr_left_child); diff --git a/cairo_vm_hints/src/hints/lib/mmr/mod.rs b/cairo_vm_hints/src/hints/lib/mmr/mod.rs index 142a591..25f605e 100644 --- a/cairo_vm_hints/src/hints/lib/mmr/mod.rs +++ b/cairo_vm_hints/src/hints/lib/mmr/mod.rs @@ -1,29 +1,2 @@ -use cairo_vm::{ - hint_processor::builtin_hint_processor::builtin_hint_processor_definition::HintProcessorData, - types::exec_scope::ExecutionScopes, - vm::{errors::hint_errors::HintError, vm_core::VirtualMachine}, - Felt252, -}; -use std::collections::HashMap; - mod bit_length; mod left_child; - -pub fn run_hint( - vm: &mut VirtualMachine, - exec_scope: &mut ExecutionScopes, - hint_data: &HintProcessorData, - constants: &HashMap, -) -> Result<(), HintError> { - match hint_data.code.as_str() { - bit_length::MMR_BIT_LENGTH => { - bit_length::mmr_bit_length(vm, exec_scope, hint_data, constants) - } - left_child::MMR_LEFT_CHILD => { - left_child::mmr_left_child(vm, exec_scope, hint_data, constants) - } - _ => Err(HintError::UnknownHint( - hint_data.code.to_string().into_boxed_str(), - )), - } -} diff --git a/cairo_vm_hints/src/hints/lib/mod.rs b/cairo_vm_hints/src/hints/lib/mod.rs index 786e25e..7f2e53b 100644 --- a/cairo_vm_hints/src/hints/lib/mod.rs +++ b/cairo_vm_hints/src/hints/lib/mod.rs @@ -1,40 +1,6 @@ -use cairo_vm::{ - hint_processor::builtin_hint_processor::builtin_hint_processor_definition::HintProcessorData, - types::exec_scope::ExecutionScopes, - vm::{errors::hint_errors::HintError, vm_core::VirtualMachine}, - Felt252, -}; -use std::collections::HashMap; - mod bit_length; mod block_header; mod mmr; mod mpt; mod rlp_little; mod utils; - -pub fn run_hint( - vm: &mut VirtualMachine, - exec_scope: &mut ExecutionScopes, - hint_data: &HintProcessorData, - constants: &HashMap, -) -> Result<(), HintError> { - let hints = [ - bit_length::run_hint, - block_header::run_hint, - mmr::run_hint, - mpt::run_hint, - rlp_little::run_hint, - utils::run_hint, - ]; - - for hint in hints.iter() { - let res = hint(vm, exec_scope, hint_data, constants); - if !matches!(res, Err(HintError::UnknownHint(_))) { - return res; - } - } - Err(HintError::UnknownHint( - hint_data.code.to_string().into_boxed_str(), - )) -} diff --git a/cairo_vm_hints/src/hints/lib/mpt/mod.rs b/cairo_vm_hints/src/hints/lib/mpt/mod.rs index 19693dc..0d9c247 100644 --- a/cairo_vm_hints/src/hints/lib/mpt/mod.rs +++ b/cairo_vm_hints/src/hints/lib/mpt/mod.rs @@ -34,6 +34,7 @@ fn is_long_list(value: Felt252) -> bool { FELT_248 <= value && value <= FELT_255 } +use crate::hints::{Hint, HINTS}; 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, @@ -42,6 +43,7 @@ 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 linkme::distributed_slice; use std::collections::HashMap; 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.\")"; @@ -81,6 +83,8 @@ fn hint_long_short_list( )))), } } +#[distributed_slice(HINTS)] +static _HIT_LONG_SHORT_LIST: Hint = (HINT_LONG_SHORT_LIST, hint_long_short_list); 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)}.\")"; @@ -120,6 +124,9 @@ fn hint_first_item_type( } } +#[distributed_slice(HINTS)] +static _HINT_FIRST_ITEM_TYPE: Hint = (HINT_FIRST_ITEM_TYPE, hint_first_item_type); + 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)}.\")"; fn hint_second_item_type( @@ -165,6 +172,9 @@ fn hint_second_item_type( } } +#[distributed_slice(HINTS)] +static _HINT_SECOND_ITEM_TYPE: Hint = (HINT_SECOND_ITEM_TYPE, hint_second_item_type); + 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.\")"; fn hint_item_type( @@ -203,19 +213,5 @@ fn hint_item_type( } } -pub fn run_hint( - vm: &mut VirtualMachine, - exec_scope: &mut ExecutionScopes, - hint_data: &HintProcessorData, - constants: &HashMap, -) -> Result<(), HintError> { - match hint_data.code.as_str() { - HINT_LONG_SHORT_LIST => hint_long_short_list(vm, exec_scope, hint_data, constants), - HINT_FIRST_ITEM_TYPE => hint_first_item_type(vm, exec_scope, hint_data, constants), - HINT_SECOND_ITEM_TYPE => hint_second_item_type(vm, exec_scope, hint_data, constants), - HINT_ITEM_TYPE => hint_item_type(vm, exec_scope, hint_data, constants), - _ => Err(HintError::UnknownHint( - hint_data.code.to_string().into_boxed_str(), - )), - } -} +#[distributed_slice(HINTS)] +static _HINT_ITEM_TYPE: Hint = (HINT_ITEM_TYPE, hint_item_type); diff --git a/cairo_vm_hints/src/hints/lib/rlp_little/assert.rs b/cairo_vm_hints/src/hints/lib/rlp_little/assert.rs index 18ad553..032ae08 100644 --- a/cairo_vm_hints/src/hints/lib/rlp_little/assert.rs +++ b/cairo_vm_hints/src/hints/lib/rlp_little/assert.rs @@ -1,14 +1,16 @@ +use crate::hints::{Hint, HINTS}; use crate::utils; use cairo_vm::hint_processor::builtin_hint_processor::builtin_hint_processor_definition::HintProcessorData; 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 linkme::distributed_slice; use std::collections::HashMap; -pub const HINT_EXPECTED_LEADING_ZEROES: &str = "assert ids.res == expected_leading_zeroes, f\"Expected {expected_leading_zeroes} but got {ids.res}\""; +const HINT_EXPECTED_LEADING_ZEROES: &str = "assert ids.res == expected_leading_zeroes, f\"Expected {expected_leading_zeroes} but got {ids.res}\""; -pub fn hint_expected_leading_zeroes( +fn hint_expected_leading_zeroes( vm: &mut VirtualMachine, exec_scope: &mut ExecutionScopes, hint_data: &HintProcessorData, @@ -27,9 +29,13 @@ pub fn hint_expected_leading_zeroes( } } -pub const HINT_EXPECTED_NIBBLE: &str = "assert ids.extracted_nibble_at_pos == expected_nibble, f\"extracted_nibble_at_pos={ids.extracted_nibble_at_pos} expected_nibble={expected_nibble}\""; +#[distributed_slice(HINTS)] +static _HINT_EXPECTED_LEADING_ZEROS: Hint = + (HINT_EXPECTED_LEADING_ZEROES, hint_expected_leading_zeroes); -pub fn hint_expected_nibble( +const HINT_EXPECTED_NIBBLE: &str = "assert ids.extracted_nibble_at_pos == expected_nibble, f\"extracted_nibble_at_pos={ids.extracted_nibble_at_pos} expected_nibble={expected_nibble}\""; + +fn hint_expected_nibble( vm: &mut VirtualMachine, exec_scope: &mut ExecutionScopes, hint_data: &HintProcessorData, @@ -48,3 +54,6 @@ pub fn hint_expected_nibble( Ok(()) } } + +#[distributed_slice(HINTS)] +static _HINT_EXPECTED_NIBBLE: Hint = (HINT_EXPECTED_NIBBLE, hint_expected_nibble); diff --git a/cairo_vm_hints/src/hints/lib/rlp_little/divmod.rs b/cairo_vm_hints/src/hints/lib/rlp_little/divmod.rs index 55e076b..189c38b 100644 --- a/cairo_vm_hints/src/hints/lib/rlp_little/divmod.rs +++ b/cairo_vm_hints/src/hints/lib/rlp_little/divmod.rs @@ -1,16 +1,18 @@ +use crate::hints::{Hint, HINTS}; use crate::utils; use cairo_vm::hint_processor::builtin_hint_processor::builtin_hint_processor_definition::HintProcessorData; use cairo_vm::types::exec_scope::ExecutionScopes; use cairo_vm::types::relocatable::Relocatable; use cairo_vm::vm::{errors::hint_errors::HintError, vm_core::VirtualMachine}; use cairo_vm::Felt252; +use linkme::distributed_slice; use starknet_types_core::felt::NonZeroFelt; use std::collections::HashMap; -pub const HINT_POW_CUT: &str = +const HINT_POW_CUT: &str = "ids.q, ids.r = divmod(memory[ids.array + ids.start_word + ids.i], ids.pow_cut)"; -pub fn hint_pow_cut( +fn hint_pow_cut( vm: &mut VirtualMachine, _exec_scope: &mut ExecutionScopes, hint_data: &HintProcessorData, @@ -34,3 +36,6 @@ pub fn hint_pow_cut( utils::write_value("q", q, vm, hint_data)?; utils::write_value("r", r, vm, hint_data) } + +#[distributed_slice(HINTS)] +static _HINT_POW_CUT: Hint = (HINT_POW_CUT, hint_pow_cut); diff --git a/cairo_vm_hints/src/hints/lib/rlp_little/leading_zeros.rs b/cairo_vm_hints/src/hints/lib/rlp_little/leading_zeros.rs index 99c4a21..e884021 100644 --- a/cairo_vm_hints/src/hints/lib/rlp_little/leading_zeros.rs +++ b/cairo_vm_hints/src/hints/lib/rlp_little/leading_zeros.rs @@ -1,13 +1,15 @@ +use crate::hints::{Hint, HINTS}; use crate::utils; 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 linkme::distributed_slice; use std::collections::HashMap; -pub const HINT_EXPECTED_LEADING_ZEROES: &str = "from tools.py.utils import parse_int_to_bytes, count_leading_zero_nibbles_from_hex\nreversed_hex = parse_int_to_bytes(ids.x.low + (2 ** 128) * ids.x.high)[::-1].hex()\nexpected_leading_zeroes = count_leading_zero_nibbles_from_hex(reversed_hex[1:] if ids.cut_nibble == 1 else reversed_hex)"; +const HINT_EXPECTED_LEADING_ZEROES: &str = "from tools.py.utils import parse_int_to_bytes, count_leading_zero_nibbles_from_hex\nreversed_hex = parse_int_to_bytes(ids.x.low + (2 ** 128) * ids.x.high)[::-1].hex()\nexpected_leading_zeroes = count_leading_zero_nibbles_from_hex(reversed_hex[1:] if ids.cut_nibble == 1 else reversed_hex)"; -pub fn hint_expected_leading_zeroes( +fn hint_expected_leading_zeroes( vm: &mut VirtualMachine, exec_scope: &mut ExecutionScopes, hint_data: &HintProcessorData, @@ -42,9 +44,13 @@ pub fn hint_expected_leading_zeroes( Ok(()) } -pub const HINT_EXPECTED_NIBBLE: &str = "key_hex = ids.key_leading_zeroes_nibbles * '0' + hex(ids.key.low + (2 ** 128) * ids.key.high)[2:]\nexpected_nibble = int(key_hex[ids.nibble_index + ids.key_leading_zeroes_nibbles], 16)"; +#[distributed_slice(HINTS)] +static _HINT_EXPECTED_LEADING_ZEROES: Hint = + (HINT_EXPECTED_LEADING_ZEROES, hint_expected_leading_zeroes); -pub fn hint_expected_nibble( +const HINT_EXPECTED_NIBBLE: &str = "key_hex = ids.key_leading_zeroes_nibbles * '0' + hex(ids.key.low + (2 ** 128) * ids.key.high)[2:]\nexpected_nibble = int(key_hex[ids.nibble_index + ids.key_leading_zeroes_nibbles], 16)"; + +fn hint_expected_nibble( vm: &mut VirtualMachine, exec_scope: &mut ExecutionScopes, hint_data: &HintProcessorData, @@ -73,3 +79,6 @@ pub fn hint_expected_nibble( Ok(()) } + +#[distributed_slice(HINTS)] +static _HINT_EXPECTED_NIBBLE: Hint = (HINT_EXPECTED_NIBBLE, hint_expected_nibble); diff --git a/cairo_vm_hints/src/hints/lib/rlp_little/mod.rs b/cairo_vm_hints/src/hints/lib/rlp_little/mod.rs index 7ad2be4..5f0cdb9 100644 --- a/cairo_vm_hints/src/hints/lib/rlp_little/mod.rs +++ b/cairo_vm_hints/src/hints/lib/rlp_little/mod.rs @@ -1,50 +1,4 @@ -use std::collections::HashMap; - -use cairo_vm::{ - hint_processor::builtin_hint_processor::builtin_hint_processor_definition::HintProcessorData, - types::exec_scope::ExecutionScopes, - vm::{errors::hint_errors::HintError, vm_core::VirtualMachine}, - Felt252, -}; - mod assert; mod divmod; mod leading_zeros; mod nibbles; - -pub fn run_hint( - vm: &mut VirtualMachine, - exec_scope: &mut ExecutionScopes, - hint_data: &HintProcessorData, - constants: &HashMap, -) -> Result<(), HintError> { - match hint_data.code.as_str() { - assert::HINT_EXPECTED_LEADING_ZEROES => { - assert::hint_expected_leading_zeroes(vm, exec_scope, hint_data, constants) - } - assert::HINT_EXPECTED_NIBBLE => { - assert::hint_expected_nibble(vm, exec_scope, hint_data, constants) - } - divmod::HINT_POW_CUT => divmod::hint_pow_cut(vm, exec_scope, hint_data, constants), - leading_zeros::HINT_EXPECTED_LEADING_ZEROES => { - leading_zeros::hint_expected_leading_zeroes(vm, exec_scope, hint_data, constants) - } - leading_zeros::HINT_EXPECTED_NIBBLE => { - leading_zeros::hint_expected_nibble(vm, exec_scope, hint_data, constants) - } - nibbles::HINT_IS_ZERO => nibbles::hint_is_zero(vm, exec_scope, hint_data, constants), - nibbles::HINT_NIBBLE_FROM_LOW => { - nibbles::hint_nibble_from_low(vm, exec_scope, hint_data, constants) - } - nibbles::HINT_NEEDS_NEXT_WORD => { - nibbles::hint_needs_next_word(vm, exec_scope, hint_data, constants) - } - nibbles::HINT_NEEDS_NEXT_WORD_ENDING => { - nibbles::hint_needs_next_word_ending(vm, exec_scope, hint_data, constants) - } - nibbles::HINT_WORDS_LOOP => nibbles::hint_words_loop(vm, exec_scope, hint_data, constants), - _ => Err(HintError::UnknownHint( - hint_data.code.to_string().into_boxed_str(), - )), - } -} diff --git a/cairo_vm_hints/src/hints/lib/rlp_little/nibbles.rs b/cairo_vm_hints/src/hints/lib/rlp_little/nibbles.rs index dbcb08e..af5c7d1 100644 --- a/cairo_vm_hints/src/hints/lib/rlp_little/nibbles.rs +++ b/cairo_vm_hints/src/hints/lib/rlp_little/nibbles.rs @@ -1,9 +1,11 @@ +use crate::hints::{Hint, HINTS}; use crate::utils; use cairo_vm::hint_processor::builtin_hint_processor::builtin_hint_processor_definition::HintProcessorData; use cairo_vm::hint_processor::builtin_hint_processor::hint_utils::insert_value_into_ap; use cairo_vm::types::exec_scope::ExecutionScopes; use cairo_vm::vm::{errors::hint_errors::HintError, vm_core::VirtualMachine}; use cairo_vm::Felt252; +use linkme::distributed_slice; use std::cmp::Ordering; use std::collections::HashMap; @@ -11,10 +13,10 @@ const FELT_31: Felt252 = Felt252::from_hex_unchecked("0x1F"); const FELT_32: Felt252 = Felt252::from_hex_unchecked("0x20"); const FELT_63: Felt252 = Felt252::from_hex_unchecked("0x3F"); -pub const HINT_IS_ZERO: &str = +const HINT_IS_ZERO: &str = "ids.is_zero = 1 if ids.nibble_index <= (ids.key_leading_zeroes_nibbles - 1) else 0"; -pub fn hint_is_zero( +fn hint_is_zero( vm: &mut VirtualMachine, _exec_scope: &mut ExecutionScopes, hint_data: &HintProcessorData, @@ -35,10 +37,13 @@ pub fn hint_is_zero( ) } -pub const HINT_NIBBLE_FROM_LOW: &str = +#[distributed_slice(HINTS)] +static _HINT_IS_ZERO: Hint = (HINT_IS_ZERO, hint_is_zero); + +const HINT_NIBBLE_FROM_LOW: &str = "ids.get_nibble_from_low = 1 if (0 <= ids.nibble_index <= 31 and ids.key_nibbles <= 32) or (32 <= ids.nibble_index <= 63 and ids.key_nibbles > 32) else 0"; -pub fn hint_nibble_from_low( +fn hint_nibble_from_low( vm: &mut VirtualMachine, _exec_scope: &mut ExecutionScopes, hint_data: &HintProcessorData, @@ -59,10 +64,13 @@ pub fn hint_nibble_from_low( utils::write_value("get_nibble_from_low", get_nibble_from_low, vm, hint_data) } -pub const HINT_NEEDS_NEXT_WORD: &str = +#[distributed_slice(HINTS)] +static _HINT_NIBBLE_FROM_LOW: Hint = (HINT_NIBBLE_FROM_LOW, hint_nibble_from_low); + +const HINT_NEEDS_NEXT_WORD: &str = "ids.needs_next_word = 1 if ids.n_bytes > ids.avl_bytes_in_word else 0"; -pub fn hint_needs_next_word( +fn hint_needs_next_word( vm: &mut VirtualMachine, _exec_scope: &mut ExecutionScopes, hint_data: &HintProcessorData, @@ -80,10 +88,13 @@ pub fn hint_needs_next_word( utils::write_value("needs_next_word", needs_next_word, vm, hint_data) } -pub const HINT_NEEDS_NEXT_WORD_ENDING: &str = +#[distributed_slice(HINTS)] +static _HINT_NEEDS_NEXT_WORD: Hint = (HINT_NEEDS_NEXT_WORD, hint_needs_next_word); + +const HINT_NEEDS_NEXT_WORD_ENDING: &str = "ids.needs_next_word = 1 if ids.n_ending_bytes > ids.avl_bytes_in_word else 0"; -pub fn hint_needs_next_word_ending( +fn hint_needs_next_word_ending( vm: &mut VirtualMachine, _exec_scope: &mut ExecutionScopes, hint_data: &HintProcessorData, @@ -101,10 +112,14 @@ pub fn hint_needs_next_word_ending( utils::write_value("needs_next_word", needs_next_word, vm, hint_data) } -pub const HINT_WORDS_LOOP: &str = +#[distributed_slice(HINTS)] +static _HINT_NEEDS_NEXT_WORD_ENDING: Hint = + (HINT_NEEDS_NEXT_WORD_ENDING, hint_needs_next_word_ending); + +const HINT_WORDS_LOOP: &str = "memory[ap] = 1 if (ids.n_words_to_handle_in_loop - ids.n_words_handled) == 0 else 0"; -pub fn hint_words_loop( +fn hint_words_loop( vm: &mut VirtualMachine, _exec_scope: &mut ExecutionScopes, hint_data: &HintProcessorData, @@ -123,3 +138,6 @@ pub fn hint_words_loop( }, ) } + +#[distributed_slice(HINTS)] +static _HINT_WORDS_LOOP: Hint = (HINT_WORDS_LOOP, hint_words_loop); diff --git a/cairo_vm_hints/src/hints/lib/utils/assert.rs b/cairo_vm_hints/src/hints/lib/utils/assert.rs index b0ee599..b0d9abb 100644 --- a/cairo_vm_hints/src/hints/lib/utils/assert.rs +++ b/cairo_vm_hints/src/hints/lib/utils/assert.rs @@ -1,14 +1,16 @@ +use crate::hints::{Hint, HINTS}; use crate::utils; use cairo_vm::hint_processor::builtin_hint_processor::builtin_hint_processor_definition::HintProcessorData; use cairo_vm::hint_processor::builtin_hint_processor::hint_utils::get_constant_from_var_name; use cairo_vm::types::exec_scope::ExecutionScopes; use cairo_vm::vm::{errors::hint_errors::HintError, vm_core::VirtualMachine}; use cairo_vm::Felt252; +use linkme::distributed_slice; use std::collections::HashMap; -pub const HINT_ASSERT_INTEGER_DIV32: &str = "from starkware.cairo.common.math_utils import assert_integer\nassert_integer(ids.DIV_32)\nif not (0 < ids.DIV_32 <= PRIME):\n raise ValueError(f'div={hex(ids.DIV_32)} is out of the valid range.')"; +const HINT_ASSERT_INTEGER_DIV32: &str = "from starkware.cairo.common.math_utils import assert_integer\nassert_integer(ids.DIV_32)\nif not (0 < ids.DIV_32 <= PRIME):\n raise ValueError(f'div={hex(ids.DIV_32)} is out of the valid range.')"; -pub fn hint_assert_integer_div32( +fn hint_assert_integer_div32( vm: &mut VirtualMachine, _exec_scope: &mut ExecutionScopes, hint_data: &HintProcessorData, @@ -24,9 +26,12 @@ pub fn hint_assert_integer_div32( } } -pub const HINT_ASSERT_INTEGER_DIV: &str = "from starkware.cairo.common.math_utils import assert_integer\nassert_integer(ids.div)\nif not (0 < ids.div <= PRIME):\n raise ValueError(f'div={hex(ids.div)} is out of the valid range.')"; +#[distributed_slice(HINTS)] +static _HINT_ASSERT_INTEGER_DIV32: Hint = (HINT_ASSERT_INTEGER_DIV32, hint_assert_integer_div32); -pub fn hint_assert_integer_div( +const HINT_ASSERT_INTEGER_DIV: &str = "from starkware.cairo.common.math_utils import assert_integer\nassert_integer(ids.div)\nif not (0 < ids.div <= PRIME):\n raise ValueError(f'div={hex(ids.div)} is out of the valid range.')"; + +fn hint_assert_integer_div( vm: &mut VirtualMachine, _exec_scope: &mut ExecutionScopes, hint_data: &HintProcessorData, @@ -41,3 +46,6 @@ pub fn hint_assert_integer_div( Ok(()) } } + +#[distributed_slice(HINTS)] +static _HINT_ASSERT_INTEGER_DIV: Hint = (HINT_ASSERT_INTEGER_DIV, hint_assert_integer_div); diff --git a/cairo_vm_hints/src/hints/lib/utils/carry.rs b/cairo_vm_hints/src/hints/lib/utils/carry.rs index 74355d3..b92135d 100644 --- a/cairo_vm_hints/src/hints/lib/utils/carry.rs +++ b/cairo_vm_hints/src/hints/lib/utils/carry.rs @@ -1,14 +1,16 @@ +use crate::hints::{Hint, HINTS}; use crate::utils; 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 linkme::distributed_slice; use num_bigint::BigUint; use std::collections::HashMap; -pub const HINT_CARRY: &str = "sum_low = ids.a.low + ids.b.low\nids.carry_low = 1 if sum_low >= ids.SHIFT else 0\nsum_high = ids.a.high + ids.b.high + ids.carry_low\nids.carry_high = 1 if sum_high >= ids.SHIFT else 0"; +const HINT_CARRY: &str = "sum_low = ids.a.low + ids.b.low\nids.carry_low = 1 if sum_low >= ids.SHIFT else 0\nsum_high = ids.a.high + ids.b.high + ids.carry_low\nids.carry_high = 1 if sum_high >= ids.SHIFT else 0"; -pub fn hint_carry( +fn hint_carry( vm: &mut VirtualMachine, _exec_scope: &mut ExecutionScopes, hint_data: &HintProcessorData, @@ -44,3 +46,6 @@ pub fn hint_carry( Ok(()) } + +#[distributed_slice(HINTS)] +static _HINT_CARRY: Hint = (HINT_CARRY, hint_carry); diff --git a/cairo_vm_hints/src/hints/lib/utils/divmod.rs b/cairo_vm_hints/src/hints/lib/utils/divmod.rs index ebda9d7..dec8418 100644 --- a/cairo_vm_hints/src/hints/lib/utils/divmod.rs +++ b/cairo_vm_hints/src/hints/lib/utils/divmod.rs @@ -1,16 +1,18 @@ +use crate::hints::{Hint, HINTS}; use crate::utils; 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 linkme::distributed_slice; use starknet_types_core::felt::NonZeroFelt; use std::collections::HashMap; const FELT_8: Felt252 = Felt252::from_hex_unchecked("0x08"); -pub const HINT_VALUE_DIV32: &str = "ids.q, ids.r = divmod(ids.value, ids.DIV_32)"; +const HINT_VALUE_DIV32: &str = "ids.q, ids.r = divmod(ids.value, ids.DIV_32)"; -pub fn hint_value_div32( +fn hint_value_div32( vm: &mut VirtualMachine, _exec_scope: &mut ExecutionScopes, hint_data: &HintProcessorData, @@ -24,9 +26,12 @@ pub fn hint_value_div32( utils::write_value("r", r, vm, hint_data) } -pub const HINT_VALUE_8: &str = "ids.q, ids.r = divmod(ids.value, 8)"; +#[distributed_slice(HINTS)] +static _HINT_VALUE_DIV32: Hint = (HINT_VALUE_DIV32, hint_value_div32); -pub fn hint_value_8( +const HINT_VALUE_8: &str = "ids.q, ids.r = divmod(ids.value, 8)"; + +fn hint_value_8( vm: &mut VirtualMachine, _exec_scope: &mut ExecutionScopes, hint_data: &HintProcessorData, @@ -39,9 +44,12 @@ pub fn hint_value_8( utils::write_value("r", r, vm, hint_data) } -pub const HINT_VALUE_DIV: &str = "ids.q, ids.r = divmod(ids.value, ids.div)"; +#[distributed_slice(HINTS)] +static _HINT_VALUE_8: Hint = (HINT_VALUE_8, hint_value_8); + +const HINT_VALUE_DIV: &str = "ids.q, ids.r = divmod(ids.value, ids.div)"; -pub fn hint_value_div( +fn hint_value_div( vm: &mut VirtualMachine, _exec_scope: &mut ExecutionScopes, hint_data: &HintProcessorData, @@ -54,3 +62,6 @@ pub fn hint_value_div( utils::write_value("q", q, vm, hint_data)?; utils::write_value("r", r, vm, hint_data) } + +#[distributed_slice(HINTS)] +static _HINT_VALUE_DIV: Hint = (HINT_VALUE_DIV, hint_value_div); diff --git a/cairo_vm_hints/src/hints/lib/utils/mod.rs b/cairo_vm_hints/src/hints/lib/utils/mod.rs index 7750c47..fe867e3 100644 --- a/cairo_vm_hints/src/hints/lib/utils/mod.rs +++ b/cairo_vm_hints/src/hints/lib/utils/mod.rs @@ -1,46 +1,5 @@ -use std::collections::HashMap; - -use cairo_vm::{ - hint_processor::builtin_hint_processor::builtin_hint_processor_definition::HintProcessorData, - types::exec_scope::ExecutionScopes, - vm::{errors::hint_errors::HintError, vm_core::VirtualMachine}, - Felt252, -}; - mod assert; mod carry; mod divmod; mod trailing_zeroes; mod write; - -pub fn run_hint( - vm: &mut VirtualMachine, - exec_scope: &mut ExecutionScopes, - hint_data: &HintProcessorData, - constants: &HashMap, -) -> Result<(), HintError> { - match hint_data.code.as_str() { - assert::HINT_ASSERT_INTEGER_DIV32 => { - assert::hint_assert_integer_div32(vm, exec_scope, hint_data, constants) - } - assert::HINT_ASSERT_INTEGER_DIV => { - assert::hint_assert_integer_div(vm, exec_scope, hint_data, constants) - } - carry::HINT_CARRY => carry::hint_carry(vm, exec_scope, hint_data, constants), - divmod::HINT_VALUE_DIV32 => divmod::hint_value_div32(vm, exec_scope, hint_data, constants), - divmod::HINT_VALUE_8 => divmod::hint_value_8(vm, exec_scope, hint_data, constants), - divmod::HINT_VALUE_DIV => divmod::hint_value_div(vm, exec_scope, hint_data, constants), - trailing_zeroes::HINT_TRAILING_ZEROES_BYTES => { - trailing_zeroes::hint_trailing_zeroes_bytes(vm, exec_scope, hint_data, constants) - } - write::HINT_WRITE_2 => write::hint_write_2(vm, exec_scope, hint_data, constants), - write::HINT_WRITE_3 => write::hint_write_3(vm, exec_scope, hint_data, constants), - write::HINT_WRITE_4 => write::hint_write_4(vm, exec_scope, hint_data, constants), - write::HINT_WRITE_5 => write::hint_write_5(vm, exec_scope, hint_data, constants), - write::HINT_WRITE_6 => write::hint_write_6(vm, exec_scope, hint_data, constants), - write::HINT_WRITE_7 => write::hint_write_7(vm, exec_scope, hint_data, constants), - _ => Err(HintError::UnknownHint( - hint_data.code.to_string().into_boxed_str(), - )), - } -} diff --git a/cairo_vm_hints/src/hints/lib/utils/trailing_zeroes.rs b/cairo_vm_hints/src/hints/lib/utils/trailing_zeroes.rs index 2f5f501..94c53b6 100644 --- a/cairo_vm_hints/src/hints/lib/utils/trailing_zeroes.rs +++ b/cairo_vm_hints/src/hints/lib/utils/trailing_zeroes.rs @@ -1,13 +1,15 @@ +use crate::hints::{Hint, HINTS}; use crate::utils; 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 linkme::distributed_slice; use std::collections::HashMap; -pub const HINT_TRAILING_ZEROES_BYTES: &str = "from tools.py.utils import count_trailing_zero_bytes_from_int\nids.trailing_zeroes_bytes = count_trailing_zero_bytes_from_int(ids.x)"; +const HINT_TRAILING_ZEROES_BYTES: &str = "from tools.py.utils import count_trailing_zero_bytes_from_int\nids.trailing_zeroes_bytes = count_trailing_zero_bytes_from_int(ids.x)"; -pub fn hint_trailing_zeroes_bytes( +fn hint_trailing_zeroes_bytes( vm: &mut VirtualMachine, exec_scope: &mut ExecutionScopes, hint_data: &HintProcessorData, @@ -25,3 +27,6 @@ pub fn hint_trailing_zeroes_bytes( Ok(()) } + +#[distributed_slice(HINTS)] +static _HINT_TRAILING_ZEROES_BYTES: Hint = (HINT_TRAILING_ZEROES_BYTES, hint_trailing_zeroes_bytes); diff --git a/cairo_vm_hints/src/hints/lib/utils/write.rs b/cairo_vm_hints/src/hints/lib/utils/write.rs index 2d4ab38..22935c4 100644 --- a/cairo_vm_hints/src/hints/lib/utils/write.rs +++ b/cairo_vm_hints/src/hints/lib/utils/write.rs @@ -1,14 +1,16 @@ +use crate::hints::{Hint, HINTS}; use crate::utils; use cairo_vm::hint_processor::builtin_hint_processor::builtin_hint_processor_definition::HintProcessorData; 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 linkme::distributed_slice; use std::collections::HashMap; -pub const HINT_WRITE_2: &str = "from tools.py.hints import write_word_to_memory\nwrite_word_to_memory(ids.word, 2, memory, ap)"; +const HINT_WRITE_2: &str = "from tools.py.hints import write_word_to_memory\nwrite_word_to_memory(ids.word, 2, memory, ap)"; -pub fn hint_write_2( +fn hint_write_2( vm: &mut VirtualMachine, _exec_scope: &mut ExecutionScopes, hint_data: &HintProcessorData, @@ -24,9 +26,12 @@ pub fn hint_write_2( Ok(()) } -pub const HINT_WRITE_3: &str = "from tools.py.hints import write_word_to_memory\nwrite_word_to_memory(ids.word, 3, memory, ap)"; +#[distributed_slice(HINTS)] +static _HINT_WRITE_2: Hint = (HINT_WRITE_2, hint_write_2); -pub fn hint_write_3( +const HINT_WRITE_3: &str = "from tools.py.hints import write_word_to_memory\nwrite_word_to_memory(ids.word, 3, memory, ap)"; + +fn hint_write_3( vm: &mut VirtualMachine, _exec_scope: &mut ExecutionScopes, hint_data: &HintProcessorData, @@ -42,9 +47,12 @@ pub fn hint_write_3( Ok(()) } -pub const HINT_WRITE_4: &str = "from tools.py.hints import write_word_to_memory\nwrite_word_to_memory(ids.word, 4, memory, ap)"; +#[distributed_slice(HINTS)] +static _HINT_WRITE_3: Hint = (HINT_WRITE_3, hint_write_3); + +const HINT_WRITE_4: &str = "from tools.py.hints import write_word_to_memory\nwrite_word_to_memory(ids.word, 4, memory, ap)"; -pub fn hint_write_4( +fn hint_write_4( vm: &mut VirtualMachine, _exec_scope: &mut ExecutionScopes, hint_data: &HintProcessorData, @@ -60,9 +68,12 @@ pub fn hint_write_4( Ok(()) } -pub const HINT_WRITE_5: &str = "from tools.py.hints import write_word_to_memory\nwrite_word_to_memory(ids.word, 5, memory, ap)"; +#[distributed_slice(HINTS)] +static _HINT_WRITE_4: Hint = (HINT_WRITE_4, hint_write_4); + +const HINT_WRITE_5: &str = "from tools.py.hints import write_word_to_memory\nwrite_word_to_memory(ids.word, 5, memory, ap)"; -pub fn hint_write_5( +fn hint_write_5( vm: &mut VirtualMachine, _exec_scope: &mut ExecutionScopes, hint_data: &HintProcessorData, @@ -78,9 +89,12 @@ pub fn hint_write_5( Ok(()) } -pub const HINT_WRITE_6: &str = "from tools.py.hints import write_word_to_memory\nwrite_word_to_memory(ids.word, 6, memory, ap)"; +#[distributed_slice(HINTS)] +static _HINT_WRITE_5: Hint = (HINT_WRITE_5, hint_write_5); -pub fn hint_write_6( +const HINT_WRITE_6: &str = "from tools.py.hints import write_word_to_memory\nwrite_word_to_memory(ids.word, 6, memory, ap)"; + +fn hint_write_6( vm: &mut VirtualMachine, _exec_scope: &mut ExecutionScopes, hint_data: &HintProcessorData, @@ -96,9 +110,12 @@ pub fn hint_write_6( Ok(()) } -pub const HINT_WRITE_7: &str = "from tools.py.hints import write_word_to_memory\nwrite_word_to_memory(ids.word, 7, memory, ap)"; +#[distributed_slice(HINTS)] +static _HINT_WRITE_6: Hint = (HINT_WRITE_6, hint_write_6); + +const HINT_WRITE_7: &str = "from tools.py.hints import write_word_to_memory\nwrite_word_to_memory(ids.word, 7, memory, ap)"; -pub fn hint_write_7( +fn hint_write_7( vm: &mut VirtualMachine, _exec_scope: &mut ExecutionScopes, hint_data: &HintProcessorData, @@ -113,3 +130,6 @@ pub fn hint_write_7( Ok(()) } + +#[distributed_slice(HINTS)] +static _HINT_WRITE_7: Hint = (HINT_WRITE_7, hint_write_7); diff --git a/cairo_vm_hints/src/hints/mod.rs b/cairo_vm_hints/src/hints/mod.rs index 1d0d075..0ca284a 100644 --- a/cairo_vm_hints/src/hints/mod.rs +++ b/cairo_vm_hints/src/hints/mod.rs @@ -4,26 +4,35 @@ use cairo_vm::{ vm::{errors::hint_errors::HintError, vm_core::VirtualMachine}, Felt252, }; +use linkme::distributed_slice; use std::collections::HashMap; mod lib; mod tests; +type Hint = ( + &'static str, + fn( + vm: &mut VirtualMachine, + exec_scope: &mut ExecutionScopes, + hint_data: &HintProcessorData, + constants: &HashMap, + ) -> Result<(), HintError>, +); + +#[distributed_slice] +pub static HINTS: [Hint]; + pub fn run_hint( vm: &mut VirtualMachine, exec_scope: &mut ExecutionScopes, hint_data: &HintProcessorData, constants: &HashMap, ) -> Result<(), HintError> { - let hints = [lib::run_hint, tests::run_hint]; - - for hint in hints.iter() { - let res = hint(vm, exec_scope, hint_data, constants); - if !matches!(res, Err(HintError::UnknownHint(_))) { - return res; + for (hint_str, hint_func) in HINTS { + if hint_data.code == hint_str.to_string() { + return hint_func(vm, exec_scope, hint_data, constants); } } - Err(HintError::UnknownHint( - hint_data.code.to_string().into_boxed_str(), - )) + Err(HintError::UnknownHint(hint_data.code.as_str().into())) } diff --git a/cairo_vm_hints/src/hints/tests/construct_mmr.rs b/cairo_vm_hints/src/hints/tests/construct_mmr.rs index db24852..bb37511 100644 --- a/cairo_vm_hints/src/hints/tests/construct_mmr.rs +++ b/cairo_vm_hints/src/hints/tests/construct_mmr.rs @@ -1,3 +1,4 @@ +use crate::hints::{Hint, HINTS}; use crate::mmr::{Keccak, Mmr, Poseidon}; use crate::utils::{split_u256, write_struct, write_value, write_vector}; use cairo_vm::hint_processor::builtin_hint_processor::builtin_hint_processor_definition::HintProcessorData; @@ -5,12 +6,13 @@ 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 linkme::distributed_slice; use num_bigint::{BigUint, RandBigInt}; use num_traits::{Num, One}; use rand::{thread_rng, Rng}; use std::collections::HashMap; -pub const TEST_CONSTRUCT_MMR: &str = "import random +const TEST_CONSTRUCT_MMR: &str = "import random from tools.py.mmr import get_peaks, MMR, PoseidonHasher, KeccakHasher STARK_PRIME = 3618502788666131213697322783095070105623107215331596699973092056135872020481 @@ -76,7 +78,7 @@ ids.expected_new_root_poseidon = mmr_poseidon.get_root() ids.expected_new_root_keccak.low, ids.expected_new_root_keccak.high = split_128(mmr_keccak.get_root()) ids.expected_new_len = len(mmr_poseidon.pos_hash)"; -pub fn test_construct_mmr( +fn test_construct_mmr( vm: &mut VirtualMachine, _exec_scope: &mut ExecutionScopes, hint_data: &HintProcessorData, @@ -203,3 +205,6 @@ pub fn test_construct_mmr( Ok(()) } + +#[distributed_slice(HINTS)] +static _TEST_CONSTRUCT_MMR: Hint = (TEST_CONSTRUCT_MMR, test_construct_mmr); diff --git a/cairo_vm_hints/src/hints/tests/dw_hack.rs b/cairo_vm_hints/src/hints/tests/dw_hack.rs index e3813c2..6bfea04 100644 --- a/cairo_vm_hints/src/hints/tests/dw_hack.rs +++ b/cairo_vm_hints/src/hints/tests/dw_hack.rs @@ -1,14 +1,16 @@ +use crate::hints::{Hint, HINTS}; use crate::utils::{get_value, write_value}; use cairo_vm::hint_processor::builtin_hint_processor::builtin_hint_processor_definition::HintProcessorData; 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 linkme::distributed_slice; use std::collections::HashMap; -pub const HINT_BIT_LENGTH_ASSIGN_140: &str = "ids.bit_length = 140"; +const HINT_BIT_LENGTH_ASSIGN_140: &str = "ids.bit_length = 140"; -pub fn hint_bit_length_assign_140( +fn hint_bit_length_assign_140( vm: &mut VirtualMachine, _exec_scope: &mut ExecutionScopes, hint_data: &HintProcessorData, @@ -24,9 +26,12 @@ pub fn hint_bit_length_assign_140( Ok(()) } -pub const HINT_BIT_LENGTH_ASSIGN_NEGATIVE_ONE: &str = "ids.bit_length = -1"; +#[distributed_slice(HINTS)] +static _HINT_BIT_LENGTH_ASSIGN_140: Hint = (HINT_BIT_LENGTH_ASSIGN_140, hint_bit_length_assign_140); -pub fn hint_bit_length_assign_negative_one( +const HINT_BIT_LENGTH_ASSIGN_NEGATIVE_ONE: &str = "ids.bit_length = -1"; + +fn hint_bit_length_assign_negative_one( vm: &mut VirtualMachine, _exec_scope: &mut ExecutionScopes, hint_data: &HintProcessorData, @@ -42,9 +47,15 @@ pub fn hint_bit_length_assign_negative_one( Ok(()) } -pub const HINT_BIT_LENGTH_ASSIGN_2500: &str = "ids.bit_length = 2500"; +#[distributed_slice(HINTS)] +static _HINT_BIT_LENGTH_ASSIGN_NEGATIVE_ONE: Hint = ( + HINT_BIT_LENGTH_ASSIGN_NEGATIVE_ONE, + hint_bit_length_assign_negative_one, +); + +const HINT_BIT_LENGTH_ASSIGN_2500: &str = "ids.bit_length = 2500"; -pub fn hint_bit_length_assign_2500( +fn hint_bit_length_assign_2500( vm: &mut VirtualMachine, _exec_scope: &mut ExecutionScopes, hint_data: &HintProcessorData, @@ -60,9 +71,13 @@ pub fn hint_bit_length_assign_2500( Ok(()) } -pub const HINT_PRINT_NS: &str = "print(\"N\", ids.N, \"n\", ids.n)"; +#[distributed_slice(HINTS)] +static _HINT_BIT_LENGTH_ASSIGN_2500: Hint = + (HINT_BIT_LENGTH_ASSIGN_2500, hint_bit_length_assign_2500); -pub fn hint_print_ns( +const HINT_PRINT_NS: &str = "print(\"N\", ids.N, \"n\", ids.n)"; + +fn hint_print_ns( vm: &mut VirtualMachine, _exec_scope: &mut ExecutionScopes, hint_data: &HintProcessorData, @@ -75,3 +90,6 @@ pub fn hint_print_ns( ); Ok(()) } + +#[distributed_slice(HINTS)] +static _HINT_PRINT_NS: Hint = (HINT_PRINT_NS, hint_print_ns); diff --git a/cairo_vm_hints/src/hints/tests/encode_packed_256.rs b/cairo_vm_hints/src/hints/tests/encode_packed_256.rs index 8ae2c5b..4fa4221 100644 --- a/cairo_vm_hints/src/hints/tests/encode_packed_256.rs +++ b/cairo_vm_hints/src/hints/tests/encode_packed_256.rs @@ -1,8 +1,10 @@ +use crate::hints::{Hint, HINTS}; use cairo_vm::hint_processor::builtin_hint_processor::builtin_hint_processor_definition::HintProcessorData; 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 linkme::distributed_slice; use rand::Rng; use sha3::Digest; use sha3::Keccak256; @@ -34,9 +36,9 @@ fn keccak(x: &[u8; 32], y: &[u8; 32]) -> [u8; 32] { hasher.finalize().into() } -pub const HINT_GENERATE_TEST_VECTOR: &str = "import sha3\nimport random\nfrom web3 import Web3\ndef split_128(a):\n \"\"\"Takes in value, returns uint256-ish tuple.\"\"\"\n return [a & ((1 << 128) - 1), a >> 128]\ndef write_uint256_array(ptr, array):\n counter = 0\n for uint in array:\n memory[ptr._reference_value+counter] = uint[0]\n memory[ptr._reference_value+counter+1] = uint[1]\n counter += 2\ndef generate_n_bit_random(n):\n return random.randint(2**(n-1), 2**n - 1)\n\n# Implementation of solitidy keccak256(encodedPacked(x, y)) in python.\ndef encode_packed_256_256(x_y):\n return int(Web3.solidityKeccak([\"uint256\", \"uint256\"], [x_y[0], x_y[1]]).hex(), 16)\n# Another implementation that uses sha3 directly and should be equal. \ndef keccak_256_256(x_y):\n k=sha3.keccak_256()\n k.update(x_y[0].to_bytes(32, 'big'))\n k.update(x_y[1].to_bytes(32, 'big'))\n return int.from_bytes(k.digest(), 'big')\n\n# Build Test vector [[x_1, y_1], [x_2, y_2], ..., [x_len, y_len]].\n\n# 256 random pairs of numbers, each pair having two random numbers of 1-256 bits.\nx_y_list = [[generate_n_bit_random(random.randint(1, 256)), generate_n_bit_random(random.randint(1, 256))] for _ in range(256)]\n# Adds 256 more pairs of equal bit length to the test vector.\nx_y_list += [[generate_n_bit_random(i), generate_n_bit_random(i)] for i in range(1,257)]\n\nkeccak_output_list = [encode_packed_256_256(x_y) for x_y in x_y_list]\nkeccak_result_list = [keccak_256_256(x_y) for x_y in x_y_list]\n\n# Sanity check on keccak implementations.\nassert all([keccak_output_list[i] == keccak_result_list[i] for i in range(len(keccak_output_list))])\n\n\n# Prepare x_array and y_array :\nx_array_split = [split_128(x_y[0]) for x_y in x_y_list]\ny_array_split = [split_128(x_y[1]) for x_y in x_y_list]\n# Write x_array : \nwrite_uint256_array(ids.x_array, x_array_split)\n# Write y_array :\nwrite_uint256_array(ids.y_array, y_array_split)\n\n# Prepare keccak_result_array :\nkeccak_result_list_split = [split_128(keccak_result) for keccak_result in keccak_result_list]\n# Write keccak_result_array :\nwrite_uint256_array(ids.keccak_result_array, keccak_result_list_split)\n\n# Write len :\nids.len = len(keccak_result_list)"; +const HINT_GENERATE_TEST_VECTOR: &str = "import sha3\nimport random\nfrom web3 import Web3\ndef split_128(a):\n \"\"\"Takes in value, returns uint256-ish tuple.\"\"\"\n return [a & ((1 << 128) - 1), a >> 128]\ndef write_uint256_array(ptr, array):\n counter = 0\n for uint in array:\n memory[ptr._reference_value+counter] = uint[0]\n memory[ptr._reference_value+counter+1] = uint[1]\n counter += 2\ndef generate_n_bit_random(n):\n return random.randint(2**(n-1), 2**n - 1)\n\n# Implementation of solitidy keccak256(encodedPacked(x, y)) in python.\ndef encode_packed_256_256(x_y):\n return int(Web3.solidityKeccak([\"uint256\", \"uint256\"], [x_y[0], x_y[1]]).hex(), 16)\n# Another implementation that uses sha3 directly and should be equal. \ndef keccak_256_256(x_y):\n k=sha3.keccak_256()\n k.update(x_y[0].to_bytes(32, 'big'))\n k.update(x_y[1].to_bytes(32, 'big'))\n return int.from_bytes(k.digest(), 'big')\n\n# Build Test vector [[x_1, y_1], [x_2, y_2], ..., [x_len, y_len]].\n\n# 256 random pairs of numbers, each pair having two random numbers of 1-256 bits.\nx_y_list = [[generate_n_bit_random(random.randint(1, 256)), generate_n_bit_random(random.randint(1, 256))] for _ in range(256)]\n# Adds 256 more pairs of equal bit length to the test vector.\nx_y_list += [[generate_n_bit_random(i), generate_n_bit_random(i)] for i in range(1,257)]\n\nkeccak_output_list = [encode_packed_256_256(x_y) for x_y in x_y_list]\nkeccak_result_list = [keccak_256_256(x_y) for x_y in x_y_list]\n\n# Sanity check on keccak implementations.\nassert all([keccak_output_list[i] == keccak_result_list[i] for i in range(len(keccak_output_list))])\n\n\n# Prepare x_array and y_array :\nx_array_split = [split_128(x_y[0]) for x_y in x_y_list]\ny_array_split = [split_128(x_y[1]) for x_y in x_y_list]\n# Write x_array : \nwrite_uint256_array(ids.x_array, x_array_split)\n# Write y_array :\nwrite_uint256_array(ids.y_array, y_array_split)\n\n# Prepare keccak_result_array :\nkeccak_result_list_split = [split_128(keccak_result) for keccak_result in keccak_result_list]\n# Write keccak_result_array :\nwrite_uint256_array(ids.keccak_result_array, keccak_result_list_split)\n\n# Write len :\nids.len = len(keccak_result_list)"; -pub fn hint_generate_test_vector( +fn hint_generate_test_vector( vm: &mut VirtualMachine, _exec_scope: &mut ExecutionScopes, hint_data: &HintProcessorData, @@ -96,3 +98,6 @@ pub fn hint_generate_test_vector( Ok(()) } + +#[distributed_slice(HINTS)] +static _HINT_GENERATE_TEST_VECTOR: Hint = (HINT_GENERATE_TEST_VECTOR, hint_generate_test_vector); diff --git a/cairo_vm_hints/src/hints/tests/mmr_size_generate.rs b/cairo_vm_hints/src/hints/tests/mmr_size_generate.rs index d25d6ea..610ade5 100644 --- a/cairo_vm_hints/src/hints/tests/mmr_size_generate.rs +++ b/cairo_vm_hints/src/hints/tests/mmr_size_generate.rs @@ -1,8 +1,10 @@ +use crate::hints::{Hint, HINTS}; use cairo_vm::hint_processor::builtin_hint_processor::builtin_hint_processor_definition::HintProcessorData; 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 linkme::distributed_slice; use rand::{thread_rng, Rng}; use starknet_types_core::felt::Felt; use std::collections::{HashMap, HashSet}; @@ -23,9 +25,9 @@ fn is_valid_mmr_size(mut mmr_size: u64) -> bool { mmr_size == 0 } -pub const HINT_GENERATE_RANDOM: &str = "from tools.py.mmr import is_valid_mmr_size\nimport random\nprint(f\"Testing is_valid_mmr_size against python implementation with {ids.num_sizes} random sizes in [0, 20000000)...\")\nsizes_to_test = random.sample(range(0, 20000000), ids.num_sizes)\nexpected_output = [is_valid_mmr_size(size) for size in sizes_to_test]\nsegments.write_arg(ids.expected_output, expected_output)\nsegments.write_arg(ids.input_array, sizes_to_test)"; +const HINT_GENERATE_RANDOM: &str = "from tools.py.mmr import is_valid_mmr_size\nimport random\nprint(f\"Testing is_valid_mmr_size against python implementation with {ids.num_sizes} random sizes in [0, 20000000)...\")\nsizes_to_test = random.sample(range(0, 20000000), ids.num_sizes)\nexpected_output = [is_valid_mmr_size(size) for size in sizes_to_test]\nsegments.write_arg(ids.expected_output, expected_output)\nsegments.write_arg(ids.input_array, sizes_to_test)"; -pub fn hint_generate_random( +fn hint_generate_random( vm: &mut VirtualMachine, _exec_scope: &mut ExecutionScopes, hint_data: &HintProcessorData, @@ -58,9 +60,12 @@ pub fn hint_generate_random( Ok(()) } -pub const HINT_GENERATE_SEQUENTIAL: &str = "print(f\"Testing is_valid_mmr_size by creating the mmr for all sizes in [0, {ids.num_elems})...\")\nfrom tools.py.mmr import MMR\nmmr = MMR()\nvalid_mmr_sizes =set()\nfor i in range(ids.num_elems):\n mmr.add(i)\n valid_mmr_sizes.add(len(mmr.pos_hash))\n\nexpected_output = [size in valid_mmr_sizes for size in range(0, len(mmr.pos_hash) + 1)]\nsegments.write_arg(ids.expected_output, expected_output)\nsegments.write_arg(ids.input_array, list(range(0, len(mmr.pos_hash) + 1)))"; +#[distributed_slice(HINTS)] +static _HINT_GENERATE_RANDOM: Hint = (HINT_GENERATE_RANDOM, hint_generate_random); -pub fn hint_generate_sequential( +const HINT_GENERATE_SEQUENTIAL: &str = "print(f\"Testing is_valid_mmr_size by creating the mmr for all sizes in [0, {ids.num_elems})...\")\nfrom tools.py.mmr import MMR\nmmr = MMR()\nvalid_mmr_sizes =set()\nfor i in range(ids.num_elems):\n mmr.add(i)\n valid_mmr_sizes.add(len(mmr.pos_hash))\n\nexpected_output = [size in valid_mmr_sizes for size in range(0, len(mmr.pos_hash) + 1)]\nsegments.write_arg(ids.expected_output, expected_output)\nsegments.write_arg(ids.input_array, list(range(0, len(mmr.pos_hash) + 1)))"; + +fn hint_generate_sequential( vm: &mut VirtualMachine, _exec_scope: &mut ExecutionScopes, hint_data: &HintProcessorData, @@ -95,3 +100,6 @@ pub fn hint_generate_sequential( Ok(()) } + +#[distributed_slice(HINTS)] +static _HINT_GENERATE_SEQUENTIAL: Hint = (HINT_GENERATE_SEQUENTIAL, hint_generate_sequential); diff --git a/cairo_vm_hints/src/hints/tests/mod.rs b/cairo_vm_hints/src/hints/tests/mod.rs index 528f77d..02e63ff 100644 --- a/cairo_vm_hints/src/hints/tests/mod.rs +++ b/cairo_vm_hints/src/hints/tests/mod.rs @@ -1,52 +1,5 @@ -use cairo_vm::{ - hint_processor::builtin_hint_processor::builtin_hint_processor_definition::HintProcessorData, - types::exec_scope::ExecutionScopes, - vm::{errors::hint_errors::HintError, vm_core::VirtualMachine}, - Felt252, -}; -use std::collections::HashMap; - mod construct_mmr; mod dw_hack; mod encode_packed_256; mod mmr_size_generate; mod print; - -pub fn run_hint( - vm: &mut VirtualMachine, - exec_scope: &mut ExecutionScopes, - hint_data: &HintProcessorData, - constants: &HashMap, -) -> Result<(), HintError> { - match hint_data.code.as_str() { - construct_mmr::TEST_CONSTRUCT_MMR => { - construct_mmr::test_construct_mmr(vm, exec_scope, hint_data, constants) - } - dw_hack::HINT_BIT_LENGTH_ASSIGN_140 => { - dw_hack::hint_bit_length_assign_140(vm, exec_scope, hint_data, constants) - } - dw_hack::HINT_BIT_LENGTH_ASSIGN_NEGATIVE_ONE => { - dw_hack::hint_bit_length_assign_negative_one(vm, exec_scope, hint_data, constants) - } - dw_hack::HINT_BIT_LENGTH_ASSIGN_2500 => { - dw_hack::hint_bit_length_assign_2500(vm, exec_scope, hint_data, constants) - } - dw_hack::HINT_PRINT_NS => dw_hack::hint_print_ns(vm, exec_scope, hint_data, constants), - encode_packed_256::HINT_GENERATE_TEST_VECTOR => { - encode_packed_256::hint_generate_test_vector(vm, exec_scope, hint_data, constants) - } - mmr_size_generate::HINT_GENERATE_RANDOM => { - mmr_size_generate::hint_generate_random(vm, exec_scope, hint_data, constants) - } - mmr_size_generate::HINT_GENERATE_SEQUENTIAL => { - mmr_size_generate::hint_generate_sequential(vm, exec_scope, hint_data, constants) - } - print::HINT_PRINT_BREAKLINE => { - print::hint_print_breakline(vm, exec_scope, hint_data, constants) - } - print::HINT_PRINT_PASS => print::hint_print_pass(vm, exec_scope, hint_data, constants), - _ => Err(HintError::UnknownHint( - hint_data.code.to_string().into_boxed_str(), - )), - } -} diff --git a/cairo_vm_hints/src/hints/tests/print.rs b/cairo_vm_hints/src/hints/tests/print.rs index ac437b2..59c150f 100644 --- a/cairo_vm_hints/src/hints/tests/print.rs +++ b/cairo_vm_hints/src/hints/tests/print.rs @@ -1,12 +1,14 @@ +use crate::hints::{Hint, HINTS}; 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 linkme::distributed_slice; use std::collections::HashMap; -pub const HINT_PRINT_BREAKLINE: &str = "print('\\n')"; +const HINT_PRINT_BREAKLINE: &str = "print('\\n')"; -pub fn hint_print_breakline( +fn hint_print_breakline( _vm: &mut VirtualMachine, _exec_scope: &mut ExecutionScopes, _hint_data: &HintProcessorData, @@ -16,9 +18,12 @@ pub fn hint_print_breakline( Ok(()) } -pub const HINT_PRINT_PASS: &str = "print(f\"\\tPass!\\n\\n\")"; +#[distributed_slice(HINTS)] +static _HINT_PRINT_BREAKLINE: Hint = (HINT_PRINT_BREAKLINE, hint_print_breakline); -pub fn hint_print_pass( +const HINT_PRINT_PASS: &str = "print(f\"\\tPass!\\n\\n\")"; + +fn hint_print_pass( _vm: &mut VirtualMachine, _exec_scope: &mut ExecutionScopes, _hint_data: &HintProcessorData, @@ -27,3 +32,6 @@ pub fn hint_print_pass( println!("\tPass!\n\n"); Ok(()) } + +#[distributed_slice(HINTS)] +static _HINT_PRINT_PASS: Hint = (HINT_PRINT_PASS, hint_print_pass);