diff --git a/src/event_graph2/event.rs b/src/event_graph2/event.rs
new file mode 100644
index 000000000..dcb436bdc
--- /dev/null
+++ b/src/event_graph2/event.rs
@@ -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 .
+ */
+
+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,
+ /// 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, 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()
+ }
+}
diff --git a/src/event_graph2/mod.rs b/src/event_graph2/mod.rs
index 249479a18..9d6e3c012 100644
--- a/src/event_graph2/mod.rs
+++ b/src/event_graph2/mod.rs
@@ -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,
- /// 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, 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()
- }
-}