// 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;
}