Skip to main content

oris_evolution_network/
lib.rs

1//! Protocol contracts for the Oris Evolution Network (OEN).
2
3use chrono::Utc;
4use serde::{Deserialize, Serialize};
5use sha2::{Digest, Sha256};
6
7use oris_evolution::{Capsule, EvolutionEvent, Gene};
8
9#[derive(Clone, Debug, Serialize, Deserialize)]
10pub enum MessageType {
11    Publish,
12    Fetch,
13    Report,
14    Revoke,
15}
16
17#[derive(Clone, Debug, Serialize, Deserialize)]
18#[serde(tag = "kind", rename_all = "snake_case")]
19pub enum NetworkAsset {
20    Gene { gene: Gene },
21    Capsule { capsule: Capsule },
22    EvolutionEvent { event: EvolutionEvent },
23}
24
25#[derive(Clone, Debug, Serialize, Deserialize)]
26pub struct EvolutionEnvelope {
27    pub protocol: String,
28    pub protocol_version: String,
29    pub message_type: MessageType,
30    pub message_id: String,
31    pub sender_id: String,
32    pub timestamp: String,
33    pub assets: Vec<NetworkAsset>,
34    pub content_hash: String,
35}
36
37#[derive(Clone, Debug, Serialize, Deserialize)]
38pub struct PublishRequest {
39    pub sender_id: String,
40    pub assets: Vec<NetworkAsset>,
41}
42
43#[derive(Clone, Debug, Serialize, Deserialize)]
44pub struct FetchQuery {
45    pub sender_id: String,
46    pub signals: Vec<String>,
47}
48
49#[derive(Clone, Debug, Serialize, Deserialize)]
50pub struct FetchResponse {
51    pub sender_id: String,
52    pub assets: Vec<NetworkAsset>,
53}
54
55#[derive(Clone, Debug, Serialize, Deserialize)]
56pub struct RevokeNotice {
57    pub sender_id: String,
58    pub asset_ids: Vec<String>,
59    pub reason: String,
60}
61
62impl EvolutionEnvelope {
63    pub fn publish(sender_id: impl Into<String>, assets: Vec<NetworkAsset>) -> Self {
64        let sender_id = sender_id.into();
65        let mut envelope = Self {
66            protocol: "oen".into(),
67            protocol_version: "0.1".into(),
68            message_type: MessageType::Publish,
69            message_id: format!(
70                "msg-{:x}",
71                Utc::now().timestamp_nanos_opt().unwrap_or_default()
72            ),
73            sender_id,
74            timestamp: Utc::now().to_rfc3339(),
75            assets,
76            content_hash: String::new(),
77        };
78        envelope.content_hash = envelope.compute_content_hash();
79        envelope
80    }
81
82    pub fn compute_content_hash(&self) -> String {
83        let payload = (
84            &self.protocol,
85            &self.protocol_version,
86            &self.message_type,
87            &self.message_id,
88            &self.sender_id,
89            &self.timestamp,
90            &self.assets,
91        );
92        let json = serde_json::to_vec(&payload).unwrap_or_default();
93        let mut hasher = Sha256::new();
94        hasher.update(json);
95        hex::encode(hasher.finalize())
96    }
97
98    pub fn verify_content_hash(&self) -> bool {
99        self.compute_content_hash() == self.content_hash
100    }
101}