diff --git a/crates/committer/Cargo.toml b/crates/committer/Cargo.toml index 4457da33..0019d10f 100644 --- a/crates/committer/Cargo.toml +++ b/crates/committer/Cargo.toml @@ -31,3 +31,6 @@ strum.workspace = true strum_macros.workspace = true thiserror.workspace = true tokio.workspace = true + +[target.'cfg(test)'.features] +default = ["testing"] diff --git a/crates/committer/src/patricia_merkle_tree.rs b/crates/committer/src/patricia_merkle_tree.rs index add87dc6..75126515 100644 --- a/crates/committer/src/patricia_merkle_tree.rs +++ b/crates/committer/src/patricia_merkle_tree.rs @@ -5,5 +5,8 @@ pub mod original_skeleton_tree; pub mod types; pub mod updated_skeleton_tree; -#[cfg(any(feature = "testing", test))] +#[cfg(test)] pub mod test_utils; + +#[cfg(feature = "testing")] +pub mod testing_utils; diff --git a/crates/committer/src/patricia_merkle_tree/original_skeleton_tree/utils_test.rs b/crates/committer/src/patricia_merkle_tree/original_skeleton_tree/utils_test.rs index 2b3d552c..289ac680 100644 --- a/crates/committer/src/patricia_merkle_tree/original_skeleton_tree/utils_test.rs +++ b/crates/committer/src/patricia_merkle_tree/original_skeleton_tree/utils_test.rs @@ -1,8 +1,8 @@ use super::split_leaves; use crate::patricia_merkle_tree::test_utils::as_fully_indexed; -use crate::patricia_merkle_tree::test_utils::get_random_u256; use crate::patricia_merkle_tree::test_utils::random; use crate::patricia_merkle_tree::test_utils::small_tree_index_to_full; +use crate::patricia_merkle_tree::testing_utils::get_random_u256; use crate::patricia_merkle_tree::types::{NodeIndex, SubTreeHeight}; use ethnum::{uint, U256}; use rand::rngs::ThreadRng; diff --git a/crates/committer/src/patricia_merkle_tree/test_utils.rs b/crates/committer/src/patricia_merkle_tree/test_utils.rs index bf6259cd..6be22239 100644 --- a/crates/committer/src/patricia_merkle_tree/test_utils.rs +++ b/crates/committer/src/patricia_merkle_tree/test_utils.rs @@ -1,26 +1,11 @@ use crate::felt::Felt; -use crate::patricia_merkle_tree::errors::TypesError; use crate::patricia_merkle_tree::node_data::inner_node::{EdgePathLength, PathToBottom}; use crate::patricia_merkle_tree::node_data::leaf::SkeletonLeaf; +use crate::patricia_merkle_tree::testing_utils::get_random_u256; use ethnum::U256; use rand::rngs::ThreadRng; -use rand::Rng; use rstest::{fixture, rstest}; -impl TryFrom<&U256> for Felt { - type Error = TypesError; - fn try_from(value: &U256) -> Result { - if *value > U256::from(&Felt::MAX) { - return Err(TypesError::ConversionError { - from: *value, - to: "Felt", - reason: "value is bigger than felt::max", - }); - } - Ok(Self::from_bytes_be(&value.to_be_bytes())) - } -} - impl From for SkeletonLeaf { fn from(value: u8) -> Self { Self::from(Felt::from(value)) @@ -49,10 +34,8 @@ pub(crate) fn random() -> ThreadRng { rand::thread_rng() } -#[cfg(test)] use crate::patricia_merkle_tree::types::{NodeIndex, SubTreeHeight}; -#[cfg(test)] impl NodeIndex { /// Assumes self represents an index in a smaller tree height. Returns a node index represents /// the same index in the starknet state tree as if the smaller tree was 'planted' at the lowest @@ -64,44 +47,9 @@ impl NodeIndex { } } -#[cfg(test)] pub(crate) fn small_tree_index_to_full(index: U256, height: SubTreeHeight) -> NodeIndex { NodeIndex::from_subtree_index(NodeIndex::new(index), height) } -/// Generates a random U256 number between low and high (exclusive). -/// Panics if low > high. -#[cfg(any(feature = "testing", test))] -pub fn get_random_u256(rng: &mut R, low: U256, high: U256) -> U256 { - assert!(low < high); - let high_of_low = low.high(); - let high_of_high = high.high(); - - let delta = high - low; - if delta <= u128::MAX { - let delta = u128::try_from(delta).expect("Failed to convert delta to u128"); - return low + rng.gen_range(0..delta); - } - - // Randomize the high 128 bits in the extracted range, and the low 128 bits in their entire - // domain until the result is in range. - // As high-low>u128::MAX, the expected number of samples until the loops breaks is bound from - // above by 3 (as either: - // 1. high_of_high > high_of_low + 1, and there is a 1/3 chance to get a valid result for high - // bits in (high_of_low, high_of_high). - // 2. high_of_high == high_of_low + 1, and every possible low 128 bits value is valid either - // when the high bits equal high_of_high, or when they equal high_of_low). - let mut randomize = || { - U256::from_words( - rng.gen_range(*high_of_low..=*high_of_high), - rng.gen_range(0..=u128::MAX), - ) - }; - let mut result = randomize(); - while result < low || result >= high { - result = randomize(); - } - result -} #[rstest] #[should_panic] @@ -115,7 +63,6 @@ fn test_get_random_u256(mut random: ThreadRng, #[case] low: U256, #[case] high: assert!(low <= r && r < high); } -#[cfg(test)] pub(crate) fn as_fully_indexed( subtree_height: u8, indices: impl Iterator, diff --git a/crates/committer/src/patricia_merkle_tree/testing_utils.rs b/crates/committer/src/patricia_merkle_tree/testing_utils.rs new file mode 100644 index 00000000..14233a51 --- /dev/null +++ b/crates/committer/src/patricia_merkle_tree/testing_utils.rs @@ -0,0 +1,53 @@ +use ethnum::U256; + +use crate::felt::Felt; +use crate::patricia_merkle_tree::errors::TypesError; +use rand::Rng; + +impl TryFrom<&U256> for Felt { + type Error = TypesError; + fn try_from(value: &U256) -> Result { + if *value > U256::from(&Felt::MAX) { + return Err(TypesError::ConversionError { + from: *value, + to: "Felt", + reason: "value is bigger than felt::max", + }); + } + Ok(Self::from_bytes_be(&value.to_be_bytes())) + } +} + +/// Generates a random U256 number between low and high (exclusive). +/// Panics if low > high +pub fn get_random_u256(rng: &mut R, low: U256, high: U256) -> U256 { + assert!(low < high); + let high_of_low = low.high(); + let high_of_high = high.high(); + + let delta = high - low; + if delta <= u128::MAX { + let delta = u128::try_from(delta).expect("Failed to convert delta to u128"); + return low + rng.gen_range(0..delta); + } + + // Randomize the high 128 bits in the extracted range, and the low 128 bits in their entire + // domain until the result is in range. + // As high-low>u128::MAX, the expected number of samples until the loops breaks is bound from + // above by 3 (as either: + // 1. high_of_high > high_of_low + 1, and there is a 1/3 chance to get a valid result for high + // bits in (high_of_low, high_of_high). + // 2. high_of_high == high_of_low + 1, and every possible low 128 bits value is valid either + // when the high bits equal high_of_high, or when they equal high_of_low). + let mut randomize = || { + U256::from_words( + rng.gen_range(*high_of_low..=*high_of_high), + rng.gen_range(0..=u128::MAX), + ) + }; + let mut result = randomize(); + while result < low || result >= high { + result = randomize(); + } + result +} diff --git a/crates/committer/src/patricia_merkle_tree/types_test.rs b/crates/committer/src/patricia_merkle_tree/types_test.rs index 98ce688a..6ff00eb0 100644 --- a/crates/committer/src/patricia_merkle_tree/types_test.rs +++ b/crates/committer/src/patricia_merkle_tree/types_test.rs @@ -1,12 +1,12 @@ use crate::block_committer::input::{ContractAddress, StarknetStorageKey}; use crate::felt::Felt; use crate::patricia_merkle_tree::node_data::inner_node::{EdgePathLength, PathToBottom}; -use crate::patricia_merkle_tree::test_utils::{get_random_u256, random}; +use crate::patricia_merkle_tree::test_utils::random; +use crate::patricia_merkle_tree::testing_utils::get_random_u256; use crate::patricia_merkle_tree::types::NodeIndex; -use rand::rngs::ThreadRng; - use ethnum::{uint, U256}; +use rand::rngs::ThreadRng; use rand::Rng; use rstest::rstest; diff --git a/crates/committer_cli/src/tests/utils/random_structs.rs b/crates/committer_cli/src/tests/utils/random_structs.rs index 02d1c3d7..089fc5ba 100644 --- a/crates/committer_cli/src/tests/utils/random_structs.rs +++ b/crates/committer_cli/src/tests/utils/random_structs.rs @@ -16,7 +16,7 @@ use committer::patricia_merkle_tree::node_data::inner_node::{ use committer::patricia_merkle_tree::node_data::leaf::ContractState; use committer::patricia_merkle_tree::node_data::leaf::LeafDataImpl; use committer::patricia_merkle_tree::node_data::leaf::LeafDataImplDiscriminants as LeafDataVariants; -use committer::patricia_merkle_tree::test_utils::get_random_u256; +use committer::patricia_merkle_tree::testing_utils::get_random_u256; use committer::patricia_merkle_tree::types::NodeIndex; use ethnum::U256; use rand::prelude::IteratorRandom;