use crate::types::{Post, PostId}; /// Compute the content ID (BLAKE3 hash) of a post. /// This is deterministic: same post data always produces the same ID. pub fn compute_post_id(post: &Post) -> PostId { let bytes = serde_json::to_vec(post).expect("post serialization should not fail"); *blake3::hash(&bytes).as_bytes() } /// Verify that a post's content matches the claimed ID pub fn verify_post_id(id: &PostId, post: &Post) -> bool { &compute_post_id(post) == id } #[cfg(test)] mod tests { use super::*; #[test] fn test_deterministic_hashing() { let post = Post { author: [1u8; 32], content: "hello world".to_string(), attachments: vec![], timestamp_ms: 1000, }; let id1 = compute_post_id(&post); let id2 = compute_post_id(&post); assert_eq!(id1, id2); } #[test] fn test_different_content_different_id() { let post1 = Post { author: [1u8; 32], content: "hello".to_string(), attachments: vec![], timestamp_ms: 1000, }; let post2 = Post { author: [1u8; 32], content: "world".to_string(), attachments: vec![], timestamp_ms: 1000, }; assert_ne!(compute_post_id(&post1), compute_post_id(&post2)); } #[test] fn test_verify() { let post = Post { author: [1u8; 32], content: "test".to_string(), attachments: vec![], timestamp_ms: 1000, }; let id = compute_post_id(&post); assert!(verify_post_id(&id, &post)); assert!(!verify_post_id(&[0u8; 32], &post)); } }