Просмотр исходного кода

event-graph: Implement DAG pruning background task.

parazyd 2 лет назад
Родитель
Сommit
cf0776caf0
2 измененных файлов с 65 добавлено и 3 удалено
  1. 24 3
      src/event_graph2/mod.rs
  2. 41 0
      src/event_graph2/util.rs

+ 24 - 3
src/event_graph2/mod.rs

@@ -20,10 +20,12 @@ use std::{
     cmp::Ordering,
     cmp::Ordering,
     collections::{HashSet, VecDeque},
     collections::{HashSet, VecDeque},
     sync::Arc,
     sync::Arc,
+    time::UNIX_EPOCH,
 };
 };
 
 
 use async_recursion::async_recursion;
 use async_recursion::async_recursion;
 use darkfi_serial::{deserialize_async, serialize_async};
 use darkfi_serial::{deserialize_async, serialize_async};
+use log::debug;
 use num_bigint::BigUint;
 use num_bigint::BigUint;
 use smol::{
 use smol::{
     lock::{Mutex, RwLock},
     lock::{Mutex, RwLock},
@@ -32,7 +34,7 @@ use smol::{
 
 
 use crate::{
 use crate::{
     net::P2pPtr,
     net::P2pPtr,
-    system::{StoppableTask, StoppableTaskPtr},
+    system::{sleep, StoppableTask, StoppableTaskPtr},
     Error, Result,
     Error, Result,
 };
 };
 
 
@@ -45,7 +47,7 @@ pub mod proto;
 
 
 /// Utility functions
 /// Utility functions
 mod util;
 mod util;
-use util::{days_since, DAY};
+use util::{days_since, next_rotation_timestamp, DAY};
 
 
 #[cfg(test)]
 #[cfg(test)]
 mod tests;
 mod tests;
@@ -183,7 +185,26 @@ impl EventGraph {
         // parameter. By pruning, we should deterministically replace the
         // parameter. By pruning, we should deterministically replace the
         // genesis event (can use a deterministic timestamp) and drop everything
         // genesis event (can use a deterministic timestamp) and drop everything
         // in the DAG, leaving just the new genesis event.
         // in the DAG, leaving just the new genesis event.
-        todo!()
+        loop {
+            // Find the next rotation timestamp:
+            let next_rotation = next_rotation_timestamp(INITIAL_GENESIS, days_rotation);
+
+            // Prepare the new genesis event
+            let current_genesis = Event {
+                timestamp: next_rotation,
+                content: vec![0x47, 0x45, 0x4e, 0x45, 0x53, 0x49, 0x53],
+                parents: [NULL_ID; N_EVENT_PARENTS],
+            };
+
+            // Sleep until it's time to rotate.
+            let s = UNIX_EPOCH.elapsed().unwrap().as_secs() - next_rotation;
+            debug!(target: "event_graph::dag_prune()", "Sleeping {}s until next DAG prune", s);
+            sleep(s).await;
+            debug!(target: "event_graph::dag_prune()", "Rotation period reached. Pruning DAG");
+
+            self.dag.clear()?;
+            self.dag_insert(&current_genesis).await?;
+        }
     }
     }
 
 
     /// Insert an event into the DAG.
     /// Insert an event into the DAG.

+ 41 - 0
src/event_graph2/util.rs

@@ -46,3 +46,44 @@ pub(super) fn days_since(midnight_ts: u64) -> u64 {
     // Convert the elapsed seconds into days
     // Convert the elapsed seconds into days
     elapsed_seconds / DAY as u64
     elapsed_seconds / DAY as u64
 }
 }
+
+/// Calculate the timestamp of the next DAG rotation.
+pub(super) fn next_rotation_timestamp(starting_timestamp: u64, rotation_period: u64) -> u64 {
+    // Calculate the number of days since the given starting point
+    let days_passed = days_since(starting_timestamp);
+
+    // Find out how many rotation periods have occurred since
+    // the starting point
+    let rotations_since_start = (days_passed + rotation_period - 1) / rotation_period;
+
+    // Find out the number of days until the next rotation
+    let days_until_next_rotation = rotations_since_start * rotation_period - days_passed;
+
+    // Get the timestamp for the next rotation
+    midnight_timestamp(days_until_next_rotation as i64)
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    #[test]
+    fn test_days_since() {
+        let five_days_ago = midnight_timestamp(-5);
+        assert_eq!(days_since(five_days_ago), 5);
+
+        let today = midnight_timestamp(0);
+        assert_eq!(days_since(today), 0);
+    }
+
+    #[test]
+    fn test_next_rotation_timestamp() {
+        let starting_point = midnight_timestamp(-10);
+        let rotation_period = 7;
+
+        // The first rotation since the starting point would be 3 days ago.
+        // So the next rotation should be 4 days from now.
+        let expected = midnight_timestamp(4);
+        assert_eq!(next_rotation_timestamp(starting_point, rotation_period), expected);
+    }
+}