blueprint_networking/blueprint_protocol/
mod.rs

1mod behaviour;
2mod handler;
3
4pub use behaviour::{BlueprintProtocolBehaviour, BlueprintProtocolEvent};
5use blueprint_crypto::KeyType;
6use libp2p::PeerId;
7
8use crate::discovery::peers::VerificationIdentifierKey;
9use serde::{Deserialize, Serialize};
10
11/// A message sent to a specific instance or broadcast to all instances
12#[derive(Debug, Clone, Serialize, Deserialize)]
13#[serde(bound = "K: KeyType")]
14pub enum InstanceMessageRequest<K: KeyType> {
15    /// Handshake request with authentication
16    Handshake {
17        /// Public key for authentication
18        verification_id_key: VerificationIdentifierKey<K>,
19        /// Signature for verification
20        signature: K::Signature,
21        /// Handshake message
22        msg: HandshakeMessage,
23    },
24    /// Protocol-specific message with custom payload
25    Protocol {
26        /// Protocol identifier (e.g., "consensus/1.0.0", "sync/1.0.0")
27        protocol: String,
28        /// Protocol-specific message payload
29        payload: Vec<u8>,
30        /// Optional metadata for the protocol handler
31        metadata: Option<Vec<u8>>,
32    },
33}
34
35/// Response to an instance message
36#[derive(Debug, Clone, Serialize, Deserialize)]
37#[serde(bound = "K: KeyType")]
38pub enum InstanceMessageResponse<K: KeyType> {
39    /// Handshake response with authentication
40    Handshake {
41        /// Public key for authentication
42        verification_id_key: VerificationIdentifierKey<K>,
43        /// Signature for verification
44        signature: K::Signature,
45        /// Handshake message
46        msg: HandshakeMessage,
47    },
48    /// Success response with optional data
49    Success {
50        /// Protocol identifier (e.g., "consensus/1.0.0", "sync/1.0.0")
51        protocol: String,
52        /// Response data specific to the protocol
53        data: Option<Vec<u8>>,
54    },
55    /// Error response with details
56    Error {
57        /// Error code
58        code: u16,
59        /// Error message
60        message: String,
61    },
62}
63
64#[derive(Debug, Clone, Serialize, Deserialize)]
65pub struct HandshakeMessage {
66    /// Sender [`PeerId`]
67    pub sender: PeerId,
68    /// A Unix timestamp in milliseconds
69    pub timestamp: u128,
70}
71
72impl HandshakeMessage {
73    /// Maximum age for a handshake message in milliseconds
74    pub const MAX_AGE: u128 = 30_000;
75
76    /// Creates a new handshake message
77    ///
78    /// # Panics
79    /// - If the system time is before the Unix epoch
80    #[must_use]
81    pub fn new(sender: PeerId) -> Self {
82        let timestamp = std::time::SystemTime::now()
83            .duration_since(std::time::UNIX_EPOCH)
84            .expect("time went backwards")
85            .as_millis();
86        Self { sender, timestamp }
87    }
88
89    /// Checks if the handshake message is expired
90    ///
91    /// # Arguments
92    /// - `max_age`: Maximum age in milliseconds
93    ///
94    /// # Returns
95    /// - `true` if the message is expired, `false` otherwise
96    ///
97    /// # Panics
98    /// - If the system time is before the Unix epoch
99    #[must_use]
100    pub fn is_expired(&self, max_age: u128) -> bool {
101        let now = std::time::SystemTime::now()
102            .duration_since(std::time::UNIX_EPOCH)
103            .expect("time went backwards")
104            .as_millis();
105        now.saturating_sub(self.timestamp) > max_age
106    }
107
108    /// Converts the handshake message to a byte array
109    #[must_use]
110    pub fn to_bytes(&self, other_peer_id: &PeerId) -> Vec<u8> {
111        let mut bytes = Vec::new();
112        bytes.extend(&self.sender.to_bytes());
113        bytes.extend(other_peer_id.to_bytes());
114        bytes.extend(&self.timestamp.to_be_bytes());
115        bytes
116    }
117}