use crate::{crypto, peer::Peer, MIN_AGE};
use ed25519_dalek::Keypair;
use std::{
fmt::{self, Debug, Display, Formatter},
net::SocketAddr,
sync::Arc,
};
use xor_name::XorName;
#[derive(Clone)]
pub(crate) struct Node {
pub keypair: Arc<Keypair>,
pub addr: SocketAddr,
pub age: u8,
}
impl Node {
pub fn new(keypair: Keypair, addr: SocketAddr) -> Self {
Self {
keypair: Arc::new(keypair),
addr,
age: MIN_AGE,
}
}
pub fn with_age(self, age: u8) -> Self {
Self { age, ..self }
}
pub fn peer(&self) -> Peer {
Peer::new(self.name(), self.addr, self.age)
}
pub fn name(&self) -> XorName {
crypto::name(&self.keypair.public)
}
}
impl Display for Node {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
write!(f, "{}", self.name())
}
}
impl Debug for Node {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
f.debug_struct("Node")
.field("name", &self.name())
.field("addr", &self.addr)
.field("age", &self.age)
.finish()
}
}
#[cfg(test)]
pub(crate) mod test_utils {
use super::*;
use itertools::Itertools;
use proptest::{collection::SizeRange, prelude::*};
pub(crate) fn arbitrary_node(age: impl Strategy<Value = u8>) -> impl Strategy<Value = Node> {
(
crypto::test_utils::arbitrary_keypair(),
any::<SocketAddr>(),
age,
)
.prop_map(|(keypair, addr, age)| Node::new(keypair, addr).with_age(age))
}
pub(crate) fn arbitrary_unique_nodes(
count: impl Into<SizeRange>,
age: impl Strategy<Value = u8>,
) -> impl Strategy<Value = Vec<Node>> {
proptest::collection::vec(arbitrary_node(age), count).prop_filter(
"non-unique keys",
|nodes| {
nodes
.iter()
.unique_by(|node| node.keypair.secret.as_bytes())
.count()
== nodes.len()
},
)
}
}