const PEER_ID_MASK: u64 = (1u64 << 63) - 1;
pub fn mint_peer_id() -> u64 {
let uuid = nodedb_types::id_gen::uuid_v7();
let mut hash = 0xcbf2_9ce4_8422_2325u64;
for byte in uuid.as_bytes() {
hash ^= *byte as u64;
hash = hash.wrapping_mul(0x1000_0000_01b3);
}
match hash & PEER_ID_MASK {
0 => 1,
id => id,
}
}
pub fn is_valid_peer_id(peer_id: u64) -> bool {
peer_id != 0 && peer_id & !PEER_ID_MASK == 0
}
#[cfg(test)]
mod tests {
use super::*;
use std::collections::HashSet;
#[test]
fn minted_ids_are_valid() {
for _ in 0..1_000 {
assert!(is_valid_peer_id(mint_peer_id()));
}
}
#[test]
fn minted_ids_do_not_repeat() {
let ids: HashSet<u64> = (0..10_000).map(|_| mint_peer_id()).collect();
assert_eq!(
ids.len(),
10_000,
"a repeat within one process means two replicas can collide too"
);
}
#[test]
fn zero_and_reserved_bit_are_rejected() {
assert!(!is_valid_peer_id(0));
assert!(!is_valid_peer_id(1u64 << 63));
assert!(!is_valid_peer_id(u64::MAX));
assert!(is_valid_peer_id(1));
assert!(is_valid_peer_id(PEER_ID_MASK));
}
}