bity_ic_utils/
rand.rs

1use ic_cdk::management_canister::raw_rand;
2use std::time::Duration;
3
4// Provides random number generation utilities for Internet Computer canisters.
5
6/// Generates a random 64-bit nonce.
7///
8/// # Returns
9///
10/// Returns a Result containing a u64 random number, or an error message if generation fails.
11pub async fn generate_rand_nonce() -> Result<u64, String> {
12    generate_rand_byte_array().await.map(u64::from_be_bytes)
13}
14
15/// Generates a random 8-byte array.
16///
17/// # Returns
18///
19/// Returns a Result containing an 8-byte array, or an error message if generation fails.
20pub async fn generate_rand_byte_array() -> Result<[u8; 8], String> {
21    match raw_rand().await {
22        Ok(random_bytes) => {
23            let bytes_array: Result<[u8; 8], _> = random_bytes[0..8].try_into();
24
25            match bytes_array {
26                Ok(bytes) => Ok(bytes),
27                Err(err) => Err(format!("Initialising slicing byte array: {}", err)),
28            }
29        }
30        Err(err) => Err(format!("Random bytes generation error: {:?}", err)),
31    }
32}
33
34/// Generates a random delay duration up to the specified maximum interval.
35///
36/// # Arguments
37///
38/// * `max_interval` - The maximum duration for the random delay
39///
40/// # Returns
41///
42/// Returns a Result containing the random Duration, or an error message if generation fails.
43pub async fn generate_random_delay(max_interval: Duration) -> Result<Duration, String> {
44    let random_nonce = generate_rand_nonce().await?;
45
46    let random_delay_nanos = random_nonce % (max_interval.as_nanos() as u64);
47
48    Ok(Duration::from_nanos(random_delay_nanos))
49}