Pārlūkot izejas kodu

event_graph: use millis for events timestamp, bump the versions of darkirc and taud and are changed slightly to accordigly interact with both old and new versions

dasman 1 gadu atpakaļ
vecāks
revīzija
75b18d684e

+ 2 - 2
Cargo.lock

@@ -2208,7 +2208,7 @@ dependencies = [
 
 [[package]]
 name = "darkirc"
-version = "0.5.0"
+version = "0.5.1"
 dependencies = [
  "async-trait",
  "bcrypt",
@@ -7091,7 +7091,7 @@ checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1"
 
 [[package]]
 name = "taud"
-version = "0.4.1"
+version = "0.4.2"
 dependencies = [
  "async-trait",
  "blake3 1.5.4",

+ 1 - 1
bin/darkirc/Cargo.toml

@@ -1,7 +1,7 @@
 [package]
 name = "darkirc"
 description = "P2P IRC daemon"
-version = "0.5.0"
+version = "0.5.1"
 edition = "2021"
 authors = ["Dyne.org foundation <foundation@dyne.org>"]
 license = "AGPL-3.0-only"

+ 24 - 1
bin/darkirc/src/irc/client.rs

@@ -190,7 +190,30 @@ impl Client {
                                     }
 
                                     // Otherwise, broadcast it
-                                    self.server.darkirc.p2p.broadcast(&EventPut(event)).await;
+                                    let self_version = self.server.darkirc.p2p.settings().read().await.app_version.clone();
+                                    let connected_peers = self.server.darkirc.p2p.hosts().peers();
+                                    let mut peers_with_matched_version = vec![];
+                                    let mut peers_with_different_version = vec![];
+                                    for peer in connected_peers {
+                                        let peer_version = peer.version.lock().await.clone();
+                                        if let Some(ref peer_version) = peer_version {
+                                            if self_version == peer_version.version {
+                                                peers_with_matched_version.push(peer)
+                                            } else {
+                                                peers_with_different_version.push(peer)
+                                            }
+                                        }
+                                    }
+
+                                    if !peers_with_matched_version.is_empty() {
+                                        self.server.darkirc.p2p.broadcast_to(&EventPut(event.clone()), &peers_with_matched_version).await;
+                                    }
+                                    if !peers_with_different_version.is_empty() {
+                                        let mut event = event;
+                                        event.timestamp /= 1000;
+                                        self.server.darkirc.p2p.broadcast_to(&EventPut(event), &peers_with_different_version).await;
+                                    }
+                                    // self.server.darkirc.p2p.broadcast(&EventPut(event)).await;
                                 }
                             }
                         }

+ 1 - 1
bin/tau/taud/Cargo.toml

@@ -1,7 +1,7 @@
 [package]
 name = "taud"
 description = "Encrypted tasks management app using peer-to-peer network and Event Graph."
-version = "0.4.1"
+version = "0.4.2"
 edition = "2021"
 authors = ["Dyne.org foundation <foundation@dyne.org>"]
 license = "AGPL-3.0-only"

+ 24 - 1
bin/tau/taud/src/main.rs

@@ -318,7 +318,30 @@ async fn start_sync_loop(
                         error!(target: "taud", "Failed inserting new event to DAG: {}", e);
                     } else {
                         // Otherwise, broadcast it
-                        p2p.broadcast(&EventPut(event)).await;
+                        let self_version = p2p.settings().read().await.app_version.clone();
+                        let connected_peers = p2p.hosts().peers();
+                        let mut peers_with_matched_version = vec![];
+                        let mut peers_with_different_version = vec![];
+                        for peer in connected_peers {
+                            let peer_version = peer.version.lock().await.clone();
+                            if let Some(ref peer_version) = peer_version {
+                                if self_version == peer_version.version {
+                                    peers_with_matched_version.push(peer)
+                                } else {
+                                    peers_with_different_version.push(peer)
+                                }
+                            }
+                        }
+
+                        if !peers_with_matched_version.is_empty() {
+                            p2p.broadcast_to(&EventPut(event.clone()), &peers_with_matched_version).await;
+                        }
+                        if !peers_with_different_version.is_empty() {
+                            let mut event = event;
+                            event.timestamp /= 1000;
+                            p2p.broadcast_to(&EventPut(event), &peers_with_different_version).await;
+                        }
+                        // p2p.broadcast(&EventPut(event)).await;
                     }
                 }
             }

+ 28 - 12
src/event_graph/event.rs

@@ -49,13 +49,20 @@ impl Event {
     /// of the codebase.
     pub async fn new(data: Vec<u8>, event_graph: &EventGraph) -> Self {
         let (layer, parents) = event_graph.get_next_layer_with_parents().await;
-        Self { timestamp: UNIX_EPOCH.elapsed().unwrap().as_secs(), content: data, parents, layer }
+        Self {
+            timestamp: UNIX_EPOCH.elapsed().unwrap().as_millis() as u64,
+            content: data,
+            parents,
+            layer,
+        }
     }
 
     /// Hash the [`Event`] to retrieve its ID
     pub fn id(&self) -> blake3::Hash {
         let mut hasher = blake3::Hasher::new();
-        self.timestamp.encode(&mut hasher).unwrap();
+        let timestamp =
+            if self.timestamp > 1e10 as u64 { self.timestamp / 1000 } else { self.timestamp };
+        timestamp.encode(&mut hasher).unwrap();
         self.content.encode(&mut hasher).unwrap();
         self.parents.encode(&mut hasher).unwrap();
         self.layer.encode(&mut hasher).unwrap();
@@ -91,7 +98,7 @@ impl Event {
         }
 
         // Check if the event timestamp is after genesis timestamp
-        if self.timestamp < genesis_timestamp - EVENT_TIME_DRIFT {
+        if self.timestamp < genesis_timestamp - EVENT_TIME_DRIFT / 1000 {
             return Ok(false)
         }
 
@@ -99,7 +106,7 @@ impl Event {
         // is after the next genesis timestamp
         if days_rotation > 0 {
             let next_genesis_timestamp = next_rotation_timestamp(INITIAL_GENESIS, days_rotation);
-            if self.timestamp > next_genesis_timestamp + EVENT_TIME_DRIFT {
+            if self.timestamp > next_genesis_timestamp + EVENT_TIME_DRIFT / 1000 {
                 return Ok(false)
             }
         }
@@ -159,19 +166,28 @@ impl Event {
     /// assuming some possibility for a time drift.
     /// Note: This validation does *NOT* check for recursive references(circles),
     /// and should be used as a first quick check.
-    pub fn validate_new(&self) -> bool {
+    pub fn validate_new(&self, is_ver_match: bool) -> bool {
         // Let's not bother with empty events
         if self.content.is_empty() {
             return false
         }
 
-        // Check if the event is too old or too new
-        let now = UNIX_EPOCH.elapsed().unwrap().as_secs();
-        let too_old = self.timestamp < now - EVENT_TIME_DRIFT;
-        let too_new = self.timestamp > now + EVENT_TIME_DRIFT;
-
-        if too_old || too_new {
-            return false
+        if is_ver_match {
+            // Check if the event is too old or too new
+            let now = UNIX_EPOCH.elapsed().unwrap().as_millis() as u64;
+            let too_old = self.timestamp < now - EVENT_TIME_DRIFT;
+            let too_new = self.timestamp > now + EVENT_TIME_DRIFT;
+            if too_old || too_new {
+                return false
+            }
+        } else {
+            // Check if the event is too old or too new
+            let now = UNIX_EPOCH.elapsed().unwrap().as_secs();
+            let too_old = self.timestamp < (now - (EVENT_TIME_DRIFT / 1000));
+            let too_new = self.timestamp > (now + (EVENT_TIME_DRIFT / 1000));
+            if too_old || too_new {
+                return false
+            }
         }
 
         // Validate the parents. We have to check that at least one parent

+ 19 - 5
src/event_graph/mod.rs

@@ -35,7 +35,7 @@ use tinyjson::JsonValue::{self};
 
 use crate::{
     event_graph::util::{replayer_log, seconds_until_next_rotation},
-    net::P2pPtr,
+    net::{channel::Channel, P2pPtr},
     rpc::{
         jsonrpc::{JsonResponse, JsonResult},
         util::json_map,
@@ -66,16 +66,16 @@ use deg::DegEvent;
 #[cfg(test)]
 mod tests;
 
-/// Initial genesis timestamp (07 Sep 2023, 00:00:00 UTC)
+/// Initial genesis timestamp in millis (07 Sep 2023, 00:00:00 UTC)
 /// Must always be UTC midnight.
-const INITIAL_GENESIS: u64 = 1694044800;
+const INITIAL_GENESIS: u64 = 1_694_044_800_000;
 /// Genesis event contents
 const GENESIS_CONTENTS: &[u8] = &[0x47, 0x45, 0x4e, 0x45, 0x53, 0x49, 0x53];
 
 /// The number of parents an event is supposed to have.
 const N_EVENT_PARENTS: usize = 5;
-/// Allowed timestamp drift in seconds
-const EVENT_TIME_DRIFT: u64 = 60;
+/// Allowed timestamp drift in milliseconds
+const EVENT_TIME_DRIFT: u64 = 60_000;
 /// Null event ID
 pub const NULL_ID: blake3::Hash = blake3::Hash::from_bytes([0x00; blake3::OUT_LEN]);
 
@@ -872,4 +872,18 @@ impl EventGraph {
 
         Ok(result)
     }
+
+    /// Check if the our version matches the connected peer's
+    /// return true if they are, false otherwise
+    async fn check_version_match(&self, channel: &Arc<Channel>) -> bool {
+        let self_version = self.p2p.settings().read().await.app_version.clone();
+        let peer_version = channel.version.lock().await.clone();
+        if let Some(ref peer_version) = peer_version {
+            if self_version == peer_version.version {
+                return true
+            }
+        }
+
+        false
+    }
 }

+ 2 - 1
src/event_graph/proto.rs

@@ -203,7 +203,8 @@ impl ProtocolEventGraph {
             // Validate the new event first. If we do not consider it valid, we
             // will just drop it and stay quiet. If the malicious threshold
             // is reached, we will stop the connection.
-            if !event.validate_new() {
+            let is_ver_match = self.event_graph.check_version_match(&self.channel).await;
+            if !event.validate_new(is_ver_match) {
                 self.clone().increase_malicious_count().await?;
                 continue
             }

+ 9 - 9
src/event_graph/util.rs

@@ -39,14 +39,14 @@ use crate::{
     Result,
 };
 
-/// Seconds in a day
-pub(super) const DAY: i64 = 86400;
+/// MilliSeconds in a day
+pub(super) const DAY: i64 = 86_400_000;
 
 /// Calculate the midnight timestamp given a number of days.
 /// If `days` is 0, calculate the midnight timestamp of today.
 pub(super) fn midnight_timestamp(days: i64) -> u64 {
     // Get current time
-    let now = UNIX_EPOCH.elapsed().unwrap().as_secs() as i64;
+    let now = UNIX_EPOCH.elapsed().unwrap().as_millis() as i64;
 
     // Find the timestamp for the midnight of the current day
     let cur_midnight = (now / DAY) * DAY;
@@ -58,7 +58,7 @@ pub(super) fn midnight_timestamp(days: i64) -> u64 {
 /// Calculate the number of days since a given midnight timestamp.
 pub(super) fn days_since(midnight_ts: u64) -> u64 {
     // Get current time
-    let now = UNIX_EPOCH.elapsed().unwrap().as_secs();
+    let now = UNIX_EPOCH.elapsed().unwrap().as_millis() as u64;
 
     // Calculate the difference between the current timestamp
     // and the given midnight timestamp
@@ -96,14 +96,14 @@ pub(super) fn next_rotation_timestamp(starting_timestamp: u64, rotation_period:
     midnight_timestamp(days_until_next_rotation)
 }
 
-/// Calculate the time in seconds until the next_rotation, given
+/// Calculate the time in milliseconds until the next_rotation, given
 /// as a timestamp.
 /// `next_rotation` here represents a timestamp in UNIX epoch format.
 pub(super) fn seconds_until_next_rotation(next_rotation: u64) -> u64 {
     // Store `now` in a variable in order to avoid a TOCTOU error.
     // There may be a drift of one second between this panic check and
     // the return value if we get unlucky.
-    let now = UNIX_EPOCH.elapsed().unwrap().as_secs();
+    let now = UNIX_EPOCH.elapsed().unwrap().as_millis() as u64;
     if next_rotation < now {
         panic!("Next rotation timestamp is in the past");
     }
@@ -126,7 +126,7 @@ pub(super) fn generate_genesis(days_rotation: u64) -> Event {
         INITIAL_GENESIS + (rotations_since_genesis * days_rotation * DAY as u64)
     };
     Event {
-        timestamp,
+        timestamp: timestamp / 1000, // to keep the genesis hash equal to old nodes.
         content: GENESIS_CONTENTS.to_vec(),
         parents: [NULL_ID; N_EVENT_PARENTS],
         layer: 0,
@@ -225,7 +225,7 @@ mod tests {
         // we should get tomorrow's timestamp.
         // This is a special case.
         let midnight_today: u64 = midnight_timestamp(0);
-        let midnight_tomorrow = midnight_today + 86400u64; // add a day, in seconds
+        let midnight_tomorrow = midnight_today + 86_400_000u64; // add a day, in milliseconds
         assert_eq!(midnight_tomorrow, next_rotation_timestamp(midnight_today, 1));
     }
 
@@ -245,7 +245,7 @@ mod tests {
     fn test_seconds_until_next_rotation_is_within_rotation_interval() {
         let days_rotation = 1u64;
         // The amount of time in seconds between rotations.
-        let rotation_interval = days_rotation * 86400u64;
+        let rotation_interval = days_rotation * 86_400_000u64;
         let next_rotation_timestamp = next_rotation_timestamp(INITIAL_GENESIS, days_rotation);
         let s = seconds_until_next_rotation(next_rotation_timestamp);
         assert!(s < rotation_interval);

+ 1 - 1
src/net/channel.rs

@@ -93,7 +93,7 @@ pub struct Channel {
     /// The version message of the node we are connected to.
     /// Some if the version exchange has already occurred, None
     /// otherwise.
-    version: Mutex<Option<Arc<VersionMessage>>>,
+    pub version: Mutex<Option<Arc<VersionMessage>>>,
     /// Channel debug info
     pub info: ChannelInfo,
 }