oris_evolution_network/
lib.rs1use 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}