// Copyright (C) 2017-2018 The Duniter Project Developers. // // 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 . //! Provide data structures to manage web of trusts. //! `LegacyWebOfTrust` is almost a translation of the legacy C++ coden while //! `RustyWebOfTrust` is a brand new implementation with a more "rusty" style. pub mod rusty; use serde::de::{self, Deserialize, DeserializeOwned, Deserializer, Visitor}; use serde::{Serialize, Serializer}; use std::fmt::{self, Debug}; /// Wrapper for a node id. #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] pub struct NodeId(pub usize); impl Serialize for NodeId { fn serialize(&self, serializer: S) -> Result where S: Serializer, { serializer.serialize_u32(self.0 as u32) } } struct NodeIdVisitor; impl<'de> Visitor<'de> for NodeIdVisitor { type Value = NodeId; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str("an integer between -2^31 and 2^31") } fn visit_u8(self, value: u8) -> Result where E: de::Error, { Ok(NodeId(value as usize)) } fn visit_u32(self, value: u32) -> Result where E: de::Error, { Ok(NodeId(value as usize)) } fn visit_u64(self, value: u64) -> Result where E: de::Error, { use std::usize; if value >= usize::MIN as u64 && value <= usize::MAX as u64 { Ok(NodeId(value as usize)) } else { Err(E::custom(format!("u32 out of range: {}", value))) } } } impl<'de> Deserialize<'de> for NodeId { fn deserialize(deserializer: D) -> Result where D: Deserializer<'de>, { deserializer.deserialize_u32(NodeIdVisitor) } } /// Results of a certification, with the current certification count /// of the destination as parameter. #[derive(Debug, Copy, Clone, PartialEq, Eq)] pub enum NewLinkResult { /// Certification worked. Ok(usize), /// This certification already exist. AlreadyCertified(usize), /// All available certifications has been used. AllCertificationsUsed(usize), /// Unknown source. UnknownSource(), /// Unknown target. UnknownTarget(), /// Self linking is forbidden. SelfLinkingForbidden(), } /// Results of a certification removal, with the current certification count /// of the destination as parameter. #[derive(Debug, Copy, Clone, PartialEq, Eq)] pub enum RemLinkResult { /// Certification has been removed. Removed(usize), /// Requested certification doesn't exist. UnknownCert(usize), /// Unknown source. UnknownSource(), /// Unknown target. UnknownTarget(), } /// Results of a certification test. #[derive(Debug, Copy, Clone, PartialEq, Eq)] pub enum HasLinkResult { /// Both nodes are known, here is the result. Link(bool), /// Unknown source. UnknownSource(), /// Unknown target. UnknownTarget(), } /// Trait for a Web Of Trust. /// Allow to provide other implementations of the `WoT` logic instead of the legacy C++ /// translated one. pub trait WebOfTrust: Clone + Debug + Default + DeserializeOwned + Send + Serialize + Sync { /// Create a new Web of Trust with the maximum of links a node can issue. fn new(max_links: usize) -> Self; /// Get the maximum number of links per user. fn get_max_link(&self) -> usize; /// Set the maximum number of links per user. fn set_max_link(&mut self, max_link: usize); /// Add a new node. fn add_node(&mut self) -> NodeId; /// Remove the last node. /// Returns `None` if the WoT was empty, otherwise new top node id. fn rem_node(&mut self) -> Option; /// Get the size of the WoT. fn size(&self) -> usize; /// Check if given node is enabled. /// Returns `None` if this node doesn't exist. fn is_enabled(&self, id: NodeId) -> Option; /// Set the enabled state of given node. /// Returns `Null` if this node doesn't exist, `enabled` otherwise. fn set_enabled(&mut self, id: NodeId, enabled: bool) -> Option; /// Get enabled node array. fn get_enabled(&self) -> Vec; /// Get disabled node array. fn get_disabled(&self) -> Vec; /// Try to add a link from the source to the target. fn add_link(&mut self, source: NodeId, target: NodeId) -> NewLinkResult; /// Try to remove a link from the source to the target. fn rem_link(&mut self, source: NodeId, target: NodeId) -> RemLinkResult; /// Test if there is a link from the source to the target. fn has_link(&self, source: NodeId, target: NodeId) -> HasLinkResult; /// Get the list of links source for this target. /// Returns `None` if this node doesn't exist. fn get_links_source(&self, target: NodeId) -> Option>; /// Get the number of issued links by a node. /// Returns `None` if this node doesn't exist. fn issued_count(&self, id: NodeId) -> Option; /// Test if a node is a sentry. fn is_sentry(&self, node: NodeId, sentry_requirement: usize) -> Option; /// Get sentries array. fn get_sentries(&self, sentry_requirement: usize) -> Vec; /// Get non sentries array. fn get_non_sentries(&self, sentry_requirement: usize) -> Vec; }