use serde::{Deserialize, Serialize};
use thiserror::Error;
#[derive(Debug, Error)]
pub enum VertexError {
#[error("Invalid parent reference")]
InvalidParent,
#[error("Parent not found")]
ParentNotFound,
#[error("Invalid payload format")]
InvalidPayload,
#[error("Invalid signature")]
InvalidSignature,
#[error("Vertex creation failed")]
CreationFailed,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct VertexId(Vec<u8>);
impl Default for VertexId {
fn default() -> Self {
Self::new()
}
}
impl VertexId {
pub fn new() -> Self {
use std::time::{SystemTime, UNIX_EPOCH};
let timestamp = SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.as_nanos() as u64;
Self(timestamp.to_be_bytes().to_vec())
}
pub fn from_bytes(bytes: Vec<u8>) -> Self {
Self(bytes)
}
pub fn as_bytes(&self) -> &[u8] {
&self.0
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Vertex {
pub id: VertexId,
pub parents: Vec<VertexId>,
pub payload: Vec<u8>,
pub timestamp: u64,
pub signature: Vec<u8>,
}
impl Vertex {
pub fn new(
id: VertexId,
payload: Vec<u8>,
parents: std::collections::HashSet<VertexId>,
) -> Self {
use std::time::{SystemTime, UNIX_EPOCH};
let timestamp = SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.as_secs();
Self {
id,
parents: parents.into_iter().collect(),
payload,
timestamp,
signature: Vec::new(), }
}
pub fn parents(&self) -> std::collections::HashSet<VertexId> {
self.parents.iter().cloned().collect()
}
}
pub trait VertexOps {
fn create(payload: Vec<u8>, parents: Vec<VertexId>) -> Result<Vertex, VertexError>;
fn validate(&self) -> Result<bool, VertexError>;
fn score(&self) -> f64;
fn is_tip(&self) -> bool;
}