/// Because of the internal algorithms, it will be absolutely necessary that all clients possess a different CID.
/// If they do not, then a false search result may return, thus skewing the routing of the network and thus posing
/// a severe security risk.
pub fn generate_unused_cid(&self) -> u64 {
loop {
let rnd = rand::random::<u64>();
if !self.cid_table.contains(&rnd) {
return rnd;
}
}
}
I was thinking of maybe using a stream, and running while let None = ..., but I'm not sure what the cleanest and leanest way to make this async is. Upon each poll, a random value is generated, then compared to cid_table for any duplicates. The future completes once no duplicates are found, else, it ought to be re-polled again sometime in the future. It is very likely I don't need this subroutine async, but I'm considering "worst case scenario" and the entropy of rand drops, thus causing a loop which could hold back the entire event loop from continuing.
"Why not just use a counter to generate ID's"? I do not want this for security reasons
Depending on your requirements, you could pass a counter through an HMAC to have deterministic but non-predictable values.
What do you mean by the "entropy of rand dropping"? rand's thread-local RNG uses a cryptographically secure PRNG. It's not going to magically shrink its period down to something tiny at random.
Sometimes the shannon entropy becomes small (Thus producing duplicate consecutive values; I've seen this happen before when pseudo random generators are spam-called), but yeah it is unlikely to be an issue. If rand is indeed cryptographically secure, then what I have will suffice. But for educational purposes, how might this function get converted into async form without** having to write an entire impl Future on a custom struct? This will be useful for knowing how to make iterative functions as such async.
I am suspecting that a while let None stream will be "the" way to go about it?
wake_by_ref indicates that the task is runnable again. When it then returns Pending, the executor knows it can immediately poll it again (maybe after running some other tasks).