mirror of
https://github.com/darkrenaissance/darkfi.git
synced 2026-01-09 22:57:59 -05:00
event_graph: go full millis (this is a breaking change)
This commit is contained in:
1
Cargo.lock
generated
1
Cargo.lock
generated
@@ -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",
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user