diff --git a/easytier/src/proto/mod.rs b/easytier/src/proto/mod.rs index bffca9b0..cb455a89 100644 --- a/easytier/src/proto/mod.rs +++ b/easytier/src/proto/mod.rs @@ -12,6 +12,7 @@ pub mod web; #[cfg(test)] pub mod tests; +pub mod utils; const DESCRIPTOR_POOL_BYTES: &[u8] = include_bytes!(concat!(env!("OUT_DIR"), "/file_descriptor_set.bin")); diff --git a/easytier/src/proto/utils.rs b/easytier/src/proto/utils.rs new file mode 100644 index 00000000..c75e57c2 --- /dev/null +++ b/easytier/src/proto/utils.rs @@ -0,0 +1,20 @@ +use prost::Message; +use sha2::{Digest, Sha256}; + +/// Generates a stable digest strictly within the lifecycle of the current process. +/// +/// ⚠️ WARNING: +/// - This digest is ONLY guaranteed to be deterministic within a **single process and the exact same binary build**. +pub trait TransientDigest: Message { + fn digest(&self) -> [u8; 32] + where + Self: Sized, + { + let buf = self.encode_to_vec(); + let mut hasher = Sha256::new(); + hasher.update(buf); + hasher.finalize().into() + } +} + +impl TransientDigest for S {} diff --git a/easytier/src/utils.rs b/easytier/src/utils.rs index 9612be46..5d3fdd7d 100644 --- a/easytier/src/utils.rs +++ b/easytier/src/utils.rs @@ -1,5 +1,6 @@ use crate::common::log; use indoc::formatdoc; +use std::sync::Arc; use std::{fs::OpenOptions, str::FromStr}; pub type PeerRoutePair = crate::proto::api::instance::PeerRoutePair; @@ -136,7 +137,7 @@ pub fn find_free_tcp_port(mut range: std::ops::Range) -> Option { range.find(|&port| check_tcp_available(port)) } -pub fn weak_upgrade(weak: &std::sync::Weak) -> anyhow::Result> { +pub fn weak_upgrade(weak: &std::sync::Weak) -> anyhow::Result> { weak.upgrade() .ok_or_else(|| anyhow::anyhow!("{} not available", std::any::type_name::())) }