mirror of
https://github.com/darkrenaissance/darkfi.git
synced 2026-01-09 14:48:08 -05:00
event-graph: Implement DAG pruning background task.
This commit is contained in:
@@ -20,10 +20,12 @@ use std::{
|
||||
cmp::Ordering,
|
||||
collections::{HashSet, VecDeque},
|
||||
sync::Arc,
|
||||
time::UNIX_EPOCH,
|
||||
};
|
||||
|
||||
use async_recursion::async_recursion;
|
||||
use darkfi_serial::{deserialize_async, serialize_async};
|
||||
use log::debug;
|
||||
use num_bigint::BigUint;
|
||||
use smol::{
|
||||
lock::{Mutex, RwLock},
|
||||
@@ -32,7 +34,7 @@ use smol::{
|
||||
|
||||
use crate::{
|
||||
net::P2pPtr,
|
||||
system::{StoppableTask, StoppableTaskPtr},
|
||||
system::{sleep, StoppableTask, StoppableTaskPtr},
|
||||
Error, Result,
|
||||
};
|
||||
|
||||
@@ -45,7 +47,7 @@ pub mod proto;
|
||||
|
||||
/// Utility functions
|
||||
mod util;
|
||||
use util::{days_since, DAY};
|
||||
use util::{days_since, next_rotation_timestamp, DAY};
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
@@ -183,7 +185,26 @@ impl EventGraph {
|
||||
// parameter. By pruning, we should deterministically replace the
|
||||
// genesis event (can use a deterministic timestamp) and drop everything
|
||||
// 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(¤t_genesis).await?;
|
||||
}
|
||||
}
|
||||
|
||||
/// Insert an event into the DAG.
|
||||
|
||||
@@ -46,3 +46,44 @@ pub(super) fn days_since(midnight_ts: u64) -> u64 {
|
||||
// Convert the elapsed seconds into days
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user