mirror of
https://github.com/darkrenaissance/darkfi.git
synced 2026-01-09 22:57:59 -05:00
event_graph: use millis for events timestamp, bump the versions of darkirc and taud and are changed slightly to accordigly interact with both old and new versions
This commit is contained in:
4
Cargo.lock
generated
4
Cargo.lock
generated
@@ -2208,7 +2208,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "darkirc"
|
||||
version = "0.5.0"
|
||||
version = "0.5.1"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"bcrypt",
|
||||
@@ -7091,7 +7091,7 @@ checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1"
|
||||
|
||||
[[package]]
|
||||
name = "taud"
|
||||
version = "0.4.1"
|
||||
version = "0.4.2"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"blake3 1.5.4",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
[package]
|
||||
name = "darkirc"
|
||||
description = "P2P IRC daemon"
|
||||
version = "0.5.0"
|
||||
version = "0.5.1"
|
||||
edition = "2021"
|
||||
authors = ["Dyne.org foundation <foundation@dyne.org>"]
|
||||
license = "AGPL-3.0-only"
|
||||
|
||||
@@ -190,7 +190,30 @@ impl Client {
|
||||
}
|
||||
|
||||
// Otherwise, broadcast it
|
||||
self.server.darkirc.p2p.broadcast(&EventPut(event)).await;
|
||||
let self_version = self.server.darkirc.p2p.settings().read().await.app_version.clone();
|
||||
let connected_peers = self.server.darkirc.p2p.hosts().peers();
|
||||
let mut peers_with_matched_version = vec![];
|
||||
let mut peers_with_different_version = vec![];
|
||||
for peer in connected_peers {
|
||||
let peer_version = peer.version.lock().await.clone();
|
||||
if let Some(ref peer_version) = peer_version {
|
||||
if self_version == peer_version.version {
|
||||
peers_with_matched_version.push(peer)
|
||||
} else {
|
||||
peers_with_different_version.push(peer)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !peers_with_matched_version.is_empty() {
|
||||
self.server.darkirc.p2p.broadcast_to(&EventPut(event.clone()), &peers_with_matched_version).await;
|
||||
}
|
||||
if !peers_with_different_version.is_empty() {
|
||||
let mut event = event;
|
||||
event.timestamp /= 1000;
|
||||
self.server.darkirc.p2p.broadcast_to(&EventPut(event), &peers_with_different_version).await;
|
||||
}
|
||||
// self.server.darkirc.p2p.broadcast(&EventPut(event)).await;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
[package]
|
||||
name = "taud"
|
||||
description = "Encrypted tasks management app using peer-to-peer network and Event Graph."
|
||||
version = "0.4.1"
|
||||
version = "0.4.2"
|
||||
edition = "2021"
|
||||
authors = ["Dyne.org foundation <foundation@dyne.org>"]
|
||||
license = "AGPL-3.0-only"
|
||||
|
||||
@@ -318,7 +318,30 @@ async fn start_sync_loop(
|
||||
error!(target: "taud", "Failed inserting new event to DAG: {}", e);
|
||||
} else {
|
||||
// Otherwise, broadcast it
|
||||
p2p.broadcast(&EventPut(event)).await;
|
||||
let self_version = p2p.settings().read().await.app_version.clone();
|
||||
let connected_peers = p2p.hosts().peers();
|
||||
let mut peers_with_matched_version = vec![];
|
||||
let mut peers_with_different_version = vec![];
|
||||
for peer in connected_peers {
|
||||
let peer_version = peer.version.lock().await.clone();
|
||||
if let Some(ref peer_version) = peer_version {
|
||||
if self_version == peer_version.version {
|
||||
peers_with_matched_version.push(peer)
|
||||
} else {
|
||||
peers_with_different_version.push(peer)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !peers_with_matched_version.is_empty() {
|
||||
p2p.broadcast_to(&EventPut(event.clone()), &peers_with_matched_version).await;
|
||||
}
|
||||
if !peers_with_different_version.is_empty() {
|
||||
let mut event = event;
|
||||
event.timestamp /= 1000;
|
||||
p2p.broadcast_to(&EventPut(event), &peers_with_different_version).await;
|
||||
}
|
||||
// p2p.broadcast(&EventPut(event)).await;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,13 +49,20 @@ impl Event {
|
||||
/// of the codebase.
|
||||
pub async fn new(data: Vec<u8>, event_graph: &EventGraph) -> Self {
|
||||
let (layer, parents) = event_graph.get_next_layer_with_parents().await;
|
||||
Self { timestamp: UNIX_EPOCH.elapsed().unwrap().as_secs(), content: data, parents, layer }
|
||||
Self {
|
||||
timestamp: UNIX_EPOCH.elapsed().unwrap().as_millis() as u64,
|
||||
content: data,
|
||||
parents,
|
||||
layer,
|
||||
}
|
||||
}
|
||||
|
||||
/// Hash the [`Event`] to retrieve its ID
|
||||
pub fn id(&self) -> blake3::Hash {
|
||||
let mut hasher = blake3::Hasher::new();
|
||||
self.timestamp.encode(&mut hasher).unwrap();
|
||||
let timestamp =
|
||||
if self.timestamp > 1e10 as u64 { self.timestamp / 1000 } else { self.timestamp };
|
||||
timestamp.encode(&mut hasher).unwrap();
|
||||
self.content.encode(&mut hasher).unwrap();
|
||||
self.parents.encode(&mut hasher).unwrap();
|
||||
self.layer.encode(&mut hasher).unwrap();
|
||||
@@ -91,7 +98,7 @@ impl Event {
|
||||
}
|
||||
|
||||
// Check if the event timestamp is after genesis timestamp
|
||||
if self.timestamp < genesis_timestamp - EVENT_TIME_DRIFT {
|
||||
if self.timestamp < genesis_timestamp - EVENT_TIME_DRIFT / 1000 {
|
||||
return Ok(false)
|
||||
}
|
||||
|
||||
@@ -99,7 +106,7 @@ impl Event {
|
||||
// is after the next genesis timestamp
|
||||
if days_rotation > 0 {
|
||||
let next_genesis_timestamp = next_rotation_timestamp(INITIAL_GENESIS, days_rotation);
|
||||
if self.timestamp > next_genesis_timestamp + EVENT_TIME_DRIFT {
|
||||
if self.timestamp > next_genesis_timestamp + EVENT_TIME_DRIFT / 1000 {
|
||||
return Ok(false)
|
||||
}
|
||||
}
|
||||
@@ -159,19 +166,28 @@ impl Event {
|
||||
/// assuming some possibility for a time drift.
|
||||
/// Note: This validation does *NOT* check for recursive references(circles),
|
||||
/// and should be used as a first quick check.
|
||||
pub fn validate_new(&self) -> bool {
|
||||
pub fn validate_new(&self, is_ver_match: bool) -> bool {
|
||||
// Let's not bother with empty events
|
||||
if self.content.is_empty() {
|
||||
return false
|
||||
}
|
||||
|
||||
// Check if the event is too old or too new
|
||||
let now = UNIX_EPOCH.elapsed().unwrap().as_secs();
|
||||
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
|
||||
if is_ver_match {
|
||||
// Check if the event is too old or too new
|
||||
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
|
||||
}
|
||||
} else {
|
||||
// Check if the event is too old or too new
|
||||
let now = UNIX_EPOCH.elapsed().unwrap().as_secs();
|
||||
let too_old = self.timestamp < (now - (EVENT_TIME_DRIFT / 1000));
|
||||
let too_new = self.timestamp > (now + (EVENT_TIME_DRIFT / 1000));
|
||||
if too_old || too_new {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// Validate the parents. We have to check that at least one parent
|
||||
|
||||
@@ -35,7 +35,7 @@ use tinyjson::JsonValue::{self};
|
||||
|
||||
use crate::{
|
||||
event_graph::util::{replayer_log, seconds_until_next_rotation},
|
||||
net::P2pPtr,
|
||||
net::{channel::Channel, P2pPtr},
|
||||
rpc::{
|
||||
jsonrpc::{JsonResponse, JsonResult},
|
||||
util::json_map,
|
||||
@@ -66,16 +66,16 @@ use deg::DegEvent;
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
/// Initial genesis timestamp (07 Sep 2023, 00:00:00 UTC)
|
||||
/// Initial genesis timestamp in millis (07 Sep 2023, 00:00:00 UTC)
|
||||
/// Must always be UTC midnight.
|
||||
const INITIAL_GENESIS: u64 = 1694044800;
|
||||
const INITIAL_GENESIS: u64 = 1_694_044_800_000;
|
||||
/// Genesis event contents
|
||||
const GENESIS_CONTENTS: &[u8] = &[0x47, 0x45, 0x4e, 0x45, 0x53, 0x49, 0x53];
|
||||
|
||||
/// The number of parents an event is supposed to have.
|
||||
const N_EVENT_PARENTS: usize = 5;
|
||||
/// Allowed timestamp drift in seconds
|
||||
const EVENT_TIME_DRIFT: u64 = 60;
|
||||
/// Allowed timestamp drift in milliseconds
|
||||
const EVENT_TIME_DRIFT: u64 = 60_000;
|
||||
/// Null event ID
|
||||
pub const NULL_ID: blake3::Hash = blake3::Hash::from_bytes([0x00; blake3::OUT_LEN]);
|
||||
|
||||
@@ -872,4 +872,18 @@ impl EventGraph {
|
||||
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
/// Check if the our version matches the connected peer's
|
||||
/// return true if they are, false otherwise
|
||||
async fn check_version_match(&self, channel: &Arc<Channel>) -> bool {
|
||||
let self_version = self.p2p.settings().read().await.app_version.clone();
|
||||
let peer_version = channel.version.lock().await.clone();
|
||||
if let Some(ref peer_version) = peer_version {
|
||||
if self_version == peer_version.version {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -203,7 +203,8 @@ impl ProtocolEventGraph {
|
||||
// Validate the new event first. If we do not consider it valid, we
|
||||
// will just drop it and stay quiet. If the malicious threshold
|
||||
// is reached, we will stop the connection.
|
||||
if !event.validate_new() {
|
||||
let is_ver_match = self.event_graph.check_version_match(&self.channel).await;
|
||||
if !event.validate_new(is_ver_match) {
|
||||
self.clone().increase_malicious_count().await?;
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -39,14 +39,14 @@ use crate::{
|
||||
Result,
|
||||
};
|
||||
|
||||
/// Seconds in a day
|
||||
pub(super) const DAY: i64 = 86400;
|
||||
/// MilliSeconds in a day
|
||||
pub(super) const DAY: i64 = 86_400_000;
|
||||
|
||||
/// Calculate the midnight timestamp given a number of days.
|
||||
/// If `days` is 0, calculate the midnight timestamp of today.
|
||||
pub(super) fn midnight_timestamp(days: i64) -> u64 {
|
||||
// Get current time
|
||||
let now = UNIX_EPOCH.elapsed().unwrap().as_secs() as i64;
|
||||
let now = UNIX_EPOCH.elapsed().unwrap().as_millis() as i64;
|
||||
|
||||
// Find the timestamp for the midnight of the current day
|
||||
let cur_midnight = (now / DAY) * DAY;
|
||||
@@ -58,7 +58,7 @@ pub(super) fn midnight_timestamp(days: i64) -> 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
|
||||
@@ -96,14 +96,14 @@ pub(super) fn next_rotation_timestamp(starting_timestamp: u64, rotation_period:
|
||||
midnight_timestamp(days_until_next_rotation)
|
||||
}
|
||||
|
||||
/// Calculate the time in seconds until the next_rotation, given
|
||||
/// Calculate the time in milliseconds until the next_rotation, given
|
||||
/// as a timestamp.
|
||||
/// `next_rotation` here represents a timestamp in UNIX epoch format.
|
||||
pub(super) fn seconds_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");
|
||||
}
|
||||
@@ -126,7 +126,7 @@ pub(super) fn generate_genesis(days_rotation: u64) -> Event {
|
||||
INITIAL_GENESIS + (rotations_since_genesis * days_rotation * DAY as u64)
|
||||
};
|
||||
Event {
|
||||
timestamp,
|
||||
timestamp: timestamp / 1000, // to keep the genesis hash equal to old nodes.
|
||||
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 + 86400u64; // add a day, in seconds
|
||||
let midnight_tomorrow = midnight_today + 86_400_000u64; // add a day, in milliseconds
|
||||
assert_eq!(midnight_tomorrow, next_rotation_timestamp(midnight_today, 1));
|
||||
}
|
||||
|
||||
@@ -245,7 +245,7 @@ mod tests {
|
||||
fn test_seconds_until_next_rotation_is_within_rotation_interval() {
|
||||
let days_rotation = 1u64;
|
||||
// The amount of time in seconds between rotations.
|
||||
let rotation_interval = days_rotation * 86400u64;
|
||||
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);
|
||||
assert!(s < rotation_interval);
|
||||
|
||||
@@ -93,7 +93,7 @@ pub struct Channel {
|
||||
/// The version message of the node we are connected to.
|
||||
/// Some if the version exchange has already occurred, None
|
||||
/// otherwise.
|
||||
version: Mutex<Option<Arc<VersionMessage>>>,
|
||||
pub version: Mutex<Option<Arc<VersionMessage>>>,
|
||||
/// Channel debug info
|
||||
pub info: ChannelInfo,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user