event_graph: go full millis (this is a breaking change)

This commit is contained in:
dasman
2024-10-01 21:02:50 +03:00
parent 40cbbfd325
commit 862abc537a
7 changed files with 26 additions and 85 deletions

1
Cargo.lock generated
View File

@@ -7029,7 +7029,6 @@ dependencies = [
"log",
"rand 0.8.5",
"ring 0.17.8",
"semver 1.0.23",
"serde",
"signal-hook",
"signal-hook-async-std",

View File

@@ -47,8 +47,6 @@ use super::{
const PENALTY_LIMIT: usize = 5;
const PROTOCOL_VERSION_SECS_TIMESTAMPS: semver::Version = semver::Version::new(0, 5, 0);
/// Reply types, we can either send server replies, or client replies.
pub enum ReplyType {
/// Server reply, we have to use numerics
@@ -192,29 +190,7 @@ impl Client {
}
// Otherwise, broadcast it
let connected_peers = self.server.darkirc.p2p.hosts().peers();
let mut peers_millis = vec![];
let mut peers_seconds = vec![];
for peer in connected_peers {
let peer_version = peer.version.lock().await.clone();
if let Some(ref peer_version) = peer_version {
if peer_version.version > PROTOCOL_VERSION_SECS_TIMESTAMPS{
peers_millis.push(peer)
} else {
peers_seconds.push(peer)
}
}
}
if !peers_millis.is_empty() {
self.server.darkirc.p2p.broadcast_to(&EventPut(event.clone()), &peers_millis).await;
}
if !peers_seconds.is_empty() {
let mut event = event;
event.timestamp /= 1000;
self.server.darkirc.p2p.broadcast_to(&EventPut(event), &peers_seconds).await;
}
// self.server.darkirc.p2p.broadcast(&EventPut(event)).await;
self.server.darkirc.p2p.broadcast(&EventPut(event)).await;
}
}
}

View File

@@ -37,7 +37,6 @@ ring = "0.17.8"
# Encoding and parsing
bs58 = "0.5.1"
toml = "0.8.19"
semver = "1.0.23"
# Misc
async-trait = "0.1.83"

View File

@@ -76,8 +76,6 @@ use crate::{
settings::{Args, CONFIG_FILE, CONFIG_FILE_CONTENTS},
};
const PROTOCOL_VERSION_SECS_TIMESTAMPS: semver::Version = semver::Version::new(0, 5, 0);
struct Workspace {
read_key: ChaChaBox,
write_key: Option<Ed25519KeyPair>,
@@ -320,29 +318,7 @@ async fn start_sync_loop(
error!(target: "taud", "Failed inserting new event to DAG: {}", e);
} else {
// Otherwise, broadcast it
let connected_peers = p2p.hosts().peers();
let mut peers_millis = vec![];
let mut peers_seconds = vec![];
for peer in connected_peers {
let peer_version = peer.version.lock().await.clone();
if let Some(ref peer_version) = peer_version {
if peer_version.version > PROTOCOL_VERSION_SECS_TIMESTAMPS {
peers_millis.push(peer)
} else {
peers_seconds.push(peer)
}
}
}
if !peers_millis.is_empty() {
p2p.broadcast_to(&EventPut(event.clone()), &peers_millis).await;
}
if !peers_seconds.is_empty() {
let mut event = event;
event.timestamp /= 1000;
p2p.broadcast_to(&EventPut(event), &peers_seconds).await;
}
// p2p.broadcast(&EventPut(event)).await;
p2p.broadcast(&EventPut(event)).await;
}
}
}

View File

@@ -66,9 +66,7 @@ impl Event {
/// Hash the [`Event`] to retrieve its ID
pub fn id(&self) -> blake3::Hash {
let mut hasher = blake3::Hasher::new();
let timestamp =
if self.timestamp > 1e10 as u64 { self.timestamp / 1000 } else { self.timestamp };
timestamp.encode(&mut hasher).unwrap();
self.timestamp.encode(&mut hasher).unwrap();
self.content.encode(&mut hasher).unwrap();
self.parents.encode(&mut hasher).unwrap();
self.layer.encode(&mut hasher).unwrap();
@@ -103,20 +101,16 @@ impl Event {
return Ok(false)
}
let timestamp =
if self.timestamp > 1e10 as u64 { self.timestamp / 1000 } else { self.timestamp };
// Check if the event timestamp is after genesis timestamp
if timestamp < genesis_timestamp - (EVENT_TIME_DRIFT / 1000) {
if self.timestamp < genesis_timestamp - EVENT_TIME_DRIFT {
return Ok(false)
}
// If a rotation has been set, check if the event timestamp
// is after the next genesis timestamp
if days_rotation > 0 {
let next_genesis_timestamp =
next_rotation_timestamp(INITIAL_GENESIS / 1000, days_rotation);
if timestamp > next_genesis_timestamp + (EVENT_TIME_DRIFT / 1000) {
let next_genesis_timestamp = next_rotation_timestamp(INITIAL_GENESIS, days_rotation);
if self.timestamp > next_genesis_timestamp + EVENT_TIME_DRIFT {
return Ok(false)
}
}
@@ -182,13 +176,10 @@ impl Event {
return false
}
let timestamp =
if self.timestamp > 1e10 as u64 { self.timestamp / 1000 } else { self.timestamp };
// Check if the event is too old or too new
let now = UNIX_EPOCH.elapsed().unwrap().as_secs();
let too_old = timestamp < (now - (EVENT_TIME_DRIFT / 1000));
let too_new = timestamp > (now + (EVENT_TIME_DRIFT / 1000));
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
}

View File

@@ -34,14 +34,14 @@ use smol::{
use tinyjson::JsonValue::{self};
use crate::{
event_graph::util::{replayer_log, seconds_until_next_rotation},
event_graph::util::replayer_log,
net::P2pPtr,
rpc::{
jsonrpc::{JsonResponse, JsonResult},
util::json_map,
},
system::{
sleep, timeout::timeout, Publisher, PublisherPtr, StoppableTask, StoppableTaskPtr,
msleep, timeout::timeout, Publisher, PublisherPtr, StoppableTask, StoppableTaskPtr,
Subscription,
},
Error, Result,
@@ -57,7 +57,7 @@ use proto::{EventRep, EventReq, TipRep, TipReq};
/// Utility functions
pub mod util;
use util::{generate_genesis, next_rotation_timestamp};
use util::{generate_genesis, millis_until_next_rotation, next_rotation_timestamp};
// Debugging event graph
pub mod deg;
@@ -512,7 +512,7 @@ impl EventGraph {
loop {
// Find the next rotation timestamp:
let next_rotation = next_rotation_timestamp(INITIAL_GENESIS / 1000, days_rotation);
let next_rotation = next_rotation_timestamp(INITIAL_GENESIS, days_rotation);
// Prepare the new genesis event
let current_genesis = Event {
@@ -523,10 +523,10 @@ impl EventGraph {
};
// Sleep until it's time to rotate.
let s = seconds_until_next_rotation(next_rotation);
let s = millis_until_next_rotation(next_rotation);
debug!(target: "event_graph::dag_prune_task()", "Sleeping {}s until next DAG prune", s);
sleep(s).await;
msleep(s).await;
debug!(target: "event_graph::dag_prune_task()", "Rotation period reached");
// Trigger DAG prune

View File

@@ -52,20 +52,20 @@ pub(super) fn midnight_timestamp(days: i64) -> u64 {
let cur_midnight = (now / DAY) * DAY;
// Adjust for days_from_now
((cur_midnight + (DAY * days)) / 1000) as u64
(cur_midnight + (DAY * days)) as 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
let elapsed_seconds = now - midnight_ts;
// Convert the elapsed seconds into days
elapsed_seconds / (DAY / 1000) as u64
elapsed_seconds / DAY as u64
}
/// Calculate the timestamp of the next DAG rotation.
@@ -99,11 +99,11 @@ pub fn next_rotation_timestamp(starting_timestamp: u64, rotation_period: u64) ->
/// Calculate the time in milliseconds until the next_rotation, given
/// as a timestamp.
/// `next_rotation` here represents a timestamp in UNIX epoch format.
pub fn seconds_until_next_rotation(next_rotation: u64) -> u64 {
pub fn millis_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");
}
@@ -117,7 +117,7 @@ pub fn generate_genesis(days_rotation: u64) -> Event {
INITIAL_GENESIS
} else {
// First check how many days passed since initial genesis.
let days_passed = days_since(INITIAL_GENESIS / 1000);
let days_passed = days_since(INITIAL_GENESIS);
// Calculate the number of days_rotation intervals since INITIAL_GENESIS
let rotations_since_genesis = days_passed / days_rotation;
@@ -126,7 +126,7 @@ pub fn generate_genesis(days_rotation: u64) -> Event {
INITIAL_GENESIS + (rotations_since_genesis * days_rotation * DAY as u64)
};
Event {
timestamp: timestamp / 1000, // to keep the genesis hash equal to old nodes.
timestamp,
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 + 86_400u64; // add a day
let midnight_tomorrow = midnight_today + 86_400_000u64; // add a day
assert_eq!(midnight_tomorrow, next_rotation_timestamp(midnight_today, 1));
}
@@ -242,12 +242,12 @@ mod tests {
}
#[test]
fn test_seconds_until_next_rotation_is_within_rotation_interval() {
fn test_millis_until_next_rotation_is_within_rotation_interval() {
let days_rotation = 1u64;
// The amount of time in seconds between rotations.
let rotation_interval = days_rotation * 86_400u64;
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);
let s = millis_until_next_rotation(next_rotation_timestamp);
assert!(s < rotation_interval);
}
}