use std::collections::HashSet; use std::sync::{Mutex, OnceLock}; static PEER_URLS: OnceLock>> = OnceLock::new(); static BOOTSTRAP_URL: OnceLock> = OnceLock::new(); static SELF_URL: OnceLock = OnceLock::new(); static FAUCET_DONE: OnceLock>> = OnceLock::new(); pub fn init(self_url: String, bootstrap_url: Option) { let _ = PEER_URLS.set(Mutex::new(HashSet::new())); let _ = BOOTSTRAP_URL.set(bootstrap_url); let _ = SELF_URL.set(self_url); let _ = FAUCET_DONE.set(Mutex::new(HashSet::new())); } pub fn add_peer(url: &str) { if url.is_empty() { return; } if let Some(self_url) = SELF_URL.get() { if url == self_url { return; } } if let Some(Some(bs)) = BOOTSTRAP_URL.get().map(|o| o.as_ref()) { if url == bs { return; } } if let Some(lock) = PEER_URLS.get() { if let Ok(mut set) = lock.lock() { set.insert(url.to_string()); } } } pub fn get_peers() -> Vec { if let Some(lock) = PEER_URLS.get() { if let Ok(set) = lock.lock() { return set.iter().cloned().collect(); } } vec![] } pub fn get_self_url() -> Option { SELF_URL.get().cloned() } pub fn faucet_already_done(url: &str) -> bool { if let Some(lock) = FAUCET_DONE.get() { if let Ok(set) = lock.lock() { return set.contains(url); } } false } pub fn mark_faucet_done(url: &str) { if let Some(lock) = FAUCET_DONE.get() { if let Ok(mut set) = lock.lock() { set.insert(url.to_string()); } } }