use alloc::vec::Vec; use crate::crypto::PublicKey; use serde::{Serialize, Deserialize}; use sha2::Digest; /// A tunnel that is used for communication #[derive(Serialize, Clone, Deserialize)] pub struct Tunnel { /// Tunnel's id. /// By the way, this id is `None` until the tunnel is validated in the backward movement pub id: Option, /// Ids, each of them is just for local storage on each node until a final global id is created pub local_ids: Vec, /// Ids of peers (in transport) by which we can send a message - one for backward direction, another for forward pub peer_ids: (u64, u64), /// Time at which this tunnel should be destroyed (UNIX epoch) pub ttd: u64, /// Public keys of nodes in the tunnel pub nodes_in_tunnel: Option>, /// Is this tunnel used for multicast? pub is_multicast: bool, /// If we created this tunnel, then this is the node that it's used to communicate with pub target_node: Option, } /// Tunnel, but only the fields that are ok to share #[derive(Serialize, Clone, Deserialize)] pub struct TunnelPublic { /// Tunnel's id id: Option, /// Ids, each of them is just for local storage on each node until a final global id is created local_ids: Vec, /// Time at which this tunnel should be destroyed (UNIX epoch) ttd: u64, /// Public keys of nodes in the tunnel nodes_in_tunnel: Option>, } impl TunnelPublic { pub fn hash(&self) -> Vec { sha2::Sha224::new() .chain(serde_cbor::to_vec(self).unwrap().as_slice()) .result().to_vec() } #[cfg(test)] pub fn new_for_test() -> Self { TunnelPublic { id: Some(56), local_ids: vec![5, 500, 120], ttd: 56, nodes_in_tunnel: Some(vec![crate::crypto::Keys::generate().get_public()]) } } } #[cfg(test)] use alloc::vec; #[test] fn test_tunnel_hashing() { let tun = TunnelPublic::new_for_test(); assert_eq!(tun.hash(), tun.hash()); assert_ne!(tun.hash(), TunnelPublic { id: Some(56), local_ids: vec![5, 500, 120], ttd: 56, nodes_in_tunnel: Some(vec![crate::crypto::Keys::generate().get_public()]) }.hash()); }