mirror of
https://github.com/darkrenaissance/darkfi.git
synced 2026-04-28 03:00:18 -04:00
event-graph: Move Event to a separate module
This commit is contained in:
108
src/event_graph2/event.rs
Normal file
108
src/event_graph2/event.rs
Normal file
@@ -0,0 +1,108 @@
|
||||
/* This file is part of DarkFi (https://dark.fi)
|
||||
*
|
||||
* Copyright (C) 2020-2023 Dyne.org foundation
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
use std::collections::HashSet;
|
||||
|
||||
use darkfi_serial::{async_trait, Encodable, SerialDecodable, SerialEncodable};
|
||||
|
||||
use super::{EventGraphPtr, EVENT_TIME_DRIFT, NULL_ID, N_EVENT_PARENTS};
|
||||
use crate::util::time::Timestamp;
|
||||
|
||||
/// Representation of an event in the Event Graph
|
||||
#[derive(Debug, Clone, SerialEncodable, SerialDecodable)]
|
||||
pub struct Event {
|
||||
/// Timestamp of the event
|
||||
pub(super) timestamp: Timestamp,
|
||||
/// Content of the event
|
||||
pub(super) content: Vec<u8>,
|
||||
/// Parent nodes in the event DAG
|
||||
pub(super) parents: [blake3::Hash; N_EVENT_PARENTS],
|
||||
}
|
||||
|
||||
impl Event {
|
||||
/// Create a new event with the given data and an [`EventGraph`] reference.
|
||||
/// The timestamp of the event will be the current time, and the parents
|
||||
/// will be `N_EVENT_PARENTS` from the current event graph unreferenced tips.
|
||||
/// The parents can also include NULL, but this should be handled by the rest
|
||||
/// of the codebase.
|
||||
pub async fn new(data: Vec<u8>, event_graph: EventGraphPtr) -> Self {
|
||||
Self {
|
||||
timestamp: Timestamp::current_time(),
|
||||
content: data,
|
||||
parents: event_graph.get_unreferenced_tips().await,
|
||||
}
|
||||
}
|
||||
|
||||
/// 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();
|
||||
self.content.encode(&mut hasher).unwrap();
|
||||
self.parents.encode(&mut hasher).unwrap();
|
||||
hasher.finalize()
|
||||
}
|
||||
|
||||
/*
|
||||
/// Check if an [`Event`] is considered too old.
|
||||
fn is_too_old(&self) -> bool {
|
||||
self.timestamp.0 < Timestamp::current_time().0 - ORPHAN_AGE_LIMIT
|
||||
}
|
||||
*/
|
||||
|
||||
/// Validate a new event for the correct layout and enforce relevant age,
|
||||
/// assuming some possibility for a time drift.
|
||||
pub fn validate(&self) -> 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 = Timestamp::current_time().0;
|
||||
let too_old = self.timestamp.0 < now - EVENT_TIME_DRIFT;
|
||||
let too_new = self.timestamp.0 > now + EVENT_TIME_DRIFT;
|
||||
|
||||
if too_old || too_new {
|
||||
return false
|
||||
}
|
||||
|
||||
// Validate the parents. We have to check that at least one parent
|
||||
// is not NULL, that the parent does not recursively reference the
|
||||
// event, and that no two parents are the same.
|
||||
let mut seen = HashSet::new();
|
||||
let self_id = self.id();
|
||||
|
||||
for parent_id in self.parents.iter() {
|
||||
if parent_id == &NULL_ID {
|
||||
continue
|
||||
}
|
||||
|
||||
if parent_id == &self_id {
|
||||
return false
|
||||
}
|
||||
|
||||
if seen.contains(parent_id) {
|
||||
return false
|
||||
}
|
||||
|
||||
seen.insert(parent_id);
|
||||
}
|
||||
|
||||
!seen.is_empty()
|
||||
}
|
||||
}
|
||||
@@ -22,12 +22,14 @@ use std::{
|
||||
};
|
||||
|
||||
use async_recursion::async_recursion;
|
||||
use darkfi_serial::{
|
||||
async_trait, deserialize_async, serialize_async, Encodable, SerialDecodable, SerialEncodable,
|
||||
};
|
||||
use darkfi_serial::{deserialize_async, serialize_async};
|
||||
use smol::lock::RwLock;
|
||||
|
||||
use crate::{net::P2pPtr, util::time::Timestamp, Result};
|
||||
use crate::{net::P2pPtr, Result};
|
||||
|
||||
/// An event graph event
|
||||
pub mod event;
|
||||
pub use event::Event;
|
||||
|
||||
/// P2P protocol implementation for the Event Graph
|
||||
pub mod proto;
|
||||
@@ -155,84 +157,3 @@ impl EventGraph {
|
||||
ordered_events.push_front(event_id);
|
||||
}
|
||||
}
|
||||
|
||||
/// Representation of an event in the Event Graph
|
||||
#[derive(Debug, Clone, SerialEncodable, SerialDecodable)]
|
||||
pub struct Event {
|
||||
/// Timestamp of the event
|
||||
timestamp: Timestamp,
|
||||
/// Content of the event
|
||||
content: Vec<u8>,
|
||||
/// Parent nodes in the event DAG
|
||||
parents: [blake3::Hash; N_EVENT_PARENTS],
|
||||
}
|
||||
|
||||
impl Event {
|
||||
/// Create a new event with the given data and an [`EventGraph`] reference.
|
||||
/// The timestamp of the event will be the current time, and the parents
|
||||
/// will be `N_EVENT_PARENTS` from the current event graph unreferenced tips.
|
||||
pub async fn new(data: Vec<u8>, event_graph: EventGraphPtr) -> Self {
|
||||
Self {
|
||||
timestamp: Timestamp::current_time(),
|
||||
content: data,
|
||||
parents: event_graph.get_unreferenced_tips().await,
|
||||
}
|
||||
}
|
||||
|
||||
/// 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();
|
||||
self.content.encode(&mut hasher).unwrap();
|
||||
self.parents.encode(&mut hasher).unwrap();
|
||||
hasher.finalize()
|
||||
}
|
||||
|
||||
/*
|
||||
/// Check if an [`Event`] is considered too old.
|
||||
fn is_too_old(&self) -> bool {
|
||||
self.timestamp.0 < Timestamp::current_time().0 - ORPHAN_AGE_LIMIT
|
||||
}
|
||||
*/
|
||||
|
||||
/// Validate a new event for the correct layout.
|
||||
pub fn validate(&self) -> 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 = Timestamp::current_time().0;
|
||||
let too_old = self.timestamp.0 < now - EVENT_TIME_DRIFT;
|
||||
let too_new = self.timestamp.0 > now + EVENT_TIME_DRIFT;
|
||||
|
||||
if too_old || too_new {
|
||||
return false
|
||||
}
|
||||
|
||||
// Validate the parents. We have to check that at least one parent
|
||||
// is not NULL, that the parent does not recursively reference the
|
||||
// event, and that no two parents are the same.
|
||||
let mut seen = HashSet::new();
|
||||
let self_id = self.id();
|
||||
|
||||
for parent_id in self.parents.iter() {
|
||||
if parent_id == &NULL_ID {
|
||||
continue
|
||||
}
|
||||
|
||||
if parent_id == &self_id {
|
||||
return false
|
||||
}
|
||||
|
||||
if seen.contains(parent_id) {
|
||||
return false
|
||||
}
|
||||
|
||||
seen.insert(parent_id)
|
||||
}
|
||||
|
||||
!seen.is_empty()
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user