use crate::messaging::system::{MembershipState, NodeState as NodeStateMsg, SectionAuth};
use crate::routing::{error::Error, Peer};
use std::net::SocketAddr;
use xor_name::XorName;
pub const MIN_AGE: u8 = 4;
pub const MIN_ADULT_AGE: u8 = MIN_AGE + 1;
pub const FIRST_SECTION_MIN_AGE: u8 = MIN_ADULT_AGE + 1;
pub const FIRST_SECTION_MAX_AGE: u8 = 100;
#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub(crate) struct NodeState {
peer: Peer,
state: MembershipState,
previous_name: Option<XorName>,
}
impl serde::Serialize for NodeState {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
self.to_msg().serialize(serializer)
}
}
impl NodeState {
pub(crate) fn joined(peer: Peer, previous_name: Option<XorName>) -> Self {
Self {
peer,
state: MembershipState::Joined,
previous_name,
}
}
#[cfg(test)]
pub(crate) fn left(peer: Peer, previous_name: Option<XorName>) -> Self {
Self {
peer,
state: MembershipState::Left,
previous_name,
}
}
pub(crate) fn peer(&self) -> &Peer {
&self.peer
}
pub(crate) fn name(&self) -> XorName {
self.peer.name()
}
pub(crate) fn addr(&self) -> SocketAddr {
self.peer.addr()
}
pub(crate) fn state(&self) -> MembershipState {
self.state
}
pub(crate) fn previous_name(&self) -> Option<XorName> {
self.previous_name
}
pub(crate) fn age(&self) -> u8 {
self.peer.age()
}
pub(crate) fn is_mature(&self) -> bool {
self.age() > MIN_AGE
}
pub(crate) fn leave(self) -> Result<Self, Error> {
if let MembershipState::Relocated(_) = self.state {
return Err(Error::InvalidState);
}
Ok(Self {
state: MembershipState::Left,
..self
})
}
pub(crate) fn relocate(self, dst: XorName) -> Self {
Self {
state: MembershipState::Relocated(dst),
..self
}
}
}
impl NodeState {
pub(crate) fn to_msg(&self) -> NodeStateMsg {
NodeStateMsg {
name: self.name(),
addr: self.addr(),
state: self.state,
previous_name: self.previous_name,
}
}
}
impl SectionAuth<NodeState> {
pub(crate) fn into_authed_msg(self) -> SectionAuth<NodeStateMsg> {
SectionAuth {
value: self.value.to_msg(),
sig: self.sig,
}
}
}
impl NodeStateMsg {
pub(crate) fn into_state(self) -> NodeState {
NodeState {
peer: Peer::new(self.name, self.addr),
state: self.state,
previous_name: self.previous_name,
}
}
}
impl SectionAuth<NodeStateMsg> {
pub(crate) fn into_authed_state(self) -> SectionAuth<NodeState> {
SectionAuth {
value: self.value.into_state(),
sig: self.sig,
}
}
}