Skip to content

Commit 8c8d07b

Browse files
committed
committer: generate random state diff test util.
1 parent 49e11a0 commit 8c8d07b

File tree

4 files changed

+97
-7
lines changed

4 files changed

+97
-7
lines changed

crates/starknet_committer/src/block_committer.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@ pub mod commit;
22
pub mod errors;
33
pub mod input;
44
pub mod random_structs;
5+
pub mod state_diff_generator;

crates/starknet_committer/src/block_committer/random_structs.rs

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,13 @@ use rand::prelude::IteratorRandom;
66
use rand::Rng;
77
use rand_distr::num_traits::ToPrimitive;
88
use rand_distr::{Distribution, Geometric};
9-
use starknet_api::core::{ClassHash, ContractAddress, Nonce, PATRICIA_KEY_UPPER_BOUND};
9+
use starknet_api::core::{
10+
ClassHash,
11+
ContractAddress,
12+
Nonce,
13+
PatriciaKey,
14+
PATRICIA_KEY_UPPER_BOUND,
15+
};
1016
use starknet_patricia::felt::u256_from_felt;
1117
use starknet_patricia::hash::hash_trait::HashOutput;
1218
use starknet_patricia::patricia_merkle_tree::external_test_utils::{
@@ -181,14 +187,20 @@ random_filled_node!(StarknetStorageValue);
181187
random_filled_node!(CompiledClassHash);
182188
random_filled_node!(ContractState);
183189

184-
impl RandomValue for ContractAddress {
190+
impl RandomValue for PatriciaKey {
185191
fn random<R: Rng>(rng: &mut R, max: Option<U256>) -> Self {
186-
let address_max = u256_from_felt(&Felt::from_hex_unchecked(PATRICIA_KEY_UPPER_BOUND));
187-
let max = match max {
188-
None => address_max,
189-
Some(caller_max) => min(address_max, caller_max),
192+
let upper_bound = u256_from_felt(&Felt::from_hex_unchecked(PATRICIA_KEY_UPPER_BOUND));
193+
let max_patricia_key = match max {
194+
None => upper_bound,
195+
Some(caller_max) => min(upper_bound, caller_max),
190196
};
191-
ContractAddress::try_from(Felt::random(rng, Some(max))).unwrap()
197+
PatriciaKey::try_from(Felt::random(rng, Some(max_patricia_key))).unwrap()
198+
}
199+
}
200+
201+
impl RandomValue for ContractAddress {
202+
fn random<R: Rng>(rng: &mut R, max: Option<U256>) -> Self {
203+
ContractAddress(PatriciaKey::random(rng, max))
192204
}
193205
}
194206

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
use std::collections::HashMap;
2+
3+
use rand::rngs::StdRng;
4+
use starknet_api::core::{ContractAddress, PatriciaKey};
5+
use starknet_api::state::StorageKey;
6+
7+
use crate::block_committer::input::{StarknetStorageKey, StarknetStorageValue, StateDiff};
8+
use crate::block_committer::random_structs::RandomValue;
9+
10+
#[cfg(test)]
11+
#[path = "state_diff_generator_test.rs"]
12+
pub mod state_diff_generator_test;
13+
14+
pub(crate) const CONTRACT_ADDRESS: u32 = 500_u32;
15+
pub(crate) const N_STORAGE_UPDATES: usize = 1000_usize;
16+
17+
pub fn generate_random_state_diff(rng: &mut StdRng) -> StateDiff {
18+
let mut storage_updates = HashMap::new();
19+
let mut contract_updates = HashMap::with_capacity(N_STORAGE_UPDATES);
20+
for _ in 0..N_STORAGE_UPDATES {
21+
let storage_entry = generate_random_storage_entry(rng);
22+
contract_updates.insert(storage_entry.0, storage_entry.1);
23+
}
24+
25+
storage_updates.insert(ContractAddress::from(CONTRACT_ADDRESS), contract_updates);
26+
StateDiff {
27+
address_to_class_hash: Default::default(),
28+
address_to_nonce: Default::default(),
29+
class_hash_to_compiled_class_hash: HashMap::new(),
30+
storage_updates,
31+
}
32+
}
33+
34+
pub(crate) fn generate_random_storage_entry(
35+
rng: &mut StdRng,
36+
) -> (StarknetStorageKey, StarknetStorageValue) {
37+
let key = StarknetStorageKey(StorageKey(PatriciaKey::random(rng, None)));
38+
let value = StarknetStorageValue::random(rng, None);
39+
(key, value)
40+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
use std::collections::HashMap;
2+
3+
use rand::rngs::StdRng;
4+
use rand::SeedableRng;
5+
use rstest::rstest;
6+
use starknet_api::core::ContractAddress;
7+
8+
use crate::block_committer::state_diff_generator::{
9+
generate_random_state_diff,
10+
generate_random_storage_entry,
11+
CONTRACT_ADDRESS,
12+
N_STORAGE_UPDATES,
13+
};
14+
15+
#[rstest]
16+
fn generate_random_state_diff_test() {
17+
let seed = 42_u64; // Constant seed for reproducibility
18+
let mut rng = StdRng::seed_from_u64(seed);
19+
let state_diff = generate_random_state_diff(&mut rng);
20+
let contract =
21+
state_diff.storage_updates.get(&ContractAddress::from(CONTRACT_ADDRESS)).unwrap();
22+
assert_eq!(contract.len(), N_STORAGE_UPDATES);
23+
}
24+
25+
#[rstest]
26+
fn key_distribution_test() {
27+
let seed = 42_u64; // Constant seed for reproducibility
28+
let mut rng = StdRng::seed_from_u64(seed);
29+
30+
let n_iterations = N_STORAGE_UPDATES * 100;
31+
let mut storage_updates = HashMap::with_capacity(n_iterations);
32+
for _ in 0..n_iterations {
33+
let (key, value) = generate_random_storage_entry(&mut rng);
34+
storage_updates.insert(key, value);
35+
}
36+
assert!(storage_updates.len() >= (n_iterations * 99 / 100), "Key distribution is limited");
37+
}

0 commit comments

Comments
 (0)