event-graph: Implement DAG pruning background task.

This commit is contained in:
parazyd
2023-09-07 14:52:27 +02:00
parent c041aea075
commit cf0776caf0
2 changed files with 65 additions and 3 deletions

View File

@@ -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(&current_genesis).await?;
}
}
/// Insert an event into the DAG.

View File

@@ -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);
}
}