Skip to content
This repository has been archived by the owner on Jun 25, 2021. It is now read-only.

Commit

Permalink
Extract common state functionality into traits
Browse files Browse the repository at this point in the history
  • Loading branch information
madadam committed Apr 25, 2019
1 parent 2ea5476 commit 90511a8
Show file tree
Hide file tree
Showing 9 changed files with 249 additions and 156 deletions.
6 changes: 3 additions & 3 deletions src/states/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
// KIND, either express or implied. Please review the Licences for the specific language governing
// permissions and limitations relating to use of the SAFE Network Software.

use super::common::{unrelocated, Base, Bootstrapped, Unapproved, USER_MSG_CACHE_EXPIRY_DURATION};
use super::common::{proxied, Base, Bootstrapped, NotEstablished, USER_MSG_CACHE_EXPIRY_DURATION};
use crate::{
ack_manager::{Ack, AckManager, UnacknowledgedMessage},
error::{InterfaceError, RoutingError},
Expand Down Expand Up @@ -323,11 +323,11 @@ impl Bootstrapped for Client {
}
}

impl Unapproved for Client {
impl NotEstablished for Client {
const SEND_ACK: bool = false;

fn get_proxy_public_id(&self, proxy_name: &XorName) -> Result<&PublicId, RoutingError> {
unrelocated::get_proxy_public_id(self, &self.proxy_pub_id, proxy_name)
proxied::get_proxy_public_id(self, &self.proxy_pub_id, proxy_name)
}
}

Expand Down
8 changes: 5 additions & 3 deletions src/states/common/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,14 @@

mod base;
mod bootstrapped;
mod not_established;
pub mod proxied;
mod relocated;
mod unapproved;
pub mod unrelocated;
mod relocated_not_established;

pub use self::{
base::Base, bootstrapped::Bootstrapped, relocated::Relocated, unapproved::Unapproved,
base::Base, bootstrapped::Bootstrapped, not_established::NotEstablished, relocated::Relocated,
relocated_not_established::RelocatedNotEstablished,
};
use crate::time::Duration;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use crate::{
};
use std::collections::BTreeSet;

pub trait Unapproved: Bootstrapped {
pub trait NotEstablished: Bootstrapped {
// Whether acknowledge hop messages sent to us.
const SEND_ACK: bool;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,14 @@
// KIND, either express or implied. Please review the Licences for the specific language governing
// permissions and limitations relating to use of the SAFE Network Software.

use crate::{error::RoutingError, id::PublicId, xor_name::XorName};
//! Utilities for node states that are connected via proxy.

use crate::{
error::RoutingError,
id::PublicId,
peer_manager::{Peer, PeerManager},
xor_name::XorName,
};
use std::fmt::Display;

pub fn get_proxy_public_id<'a, T: Display>(
Expand All @@ -21,3 +28,24 @@ pub fn get_proxy_public_id<'a, T: Display>(
Err(RoutingError::ProxyConnectionNotFound)
}
}

pub fn find_proxy_public_id<'a, T: Display>(
label: &T,
peer_mgr: &'a PeerManager,
proxy_name: &XorName,
) -> Result<&'a PublicId, RoutingError> {
if let Some(pub_id) = peer_mgr.get_peer_by_name(proxy_name).map(Peer::pub_id) {
if peer_mgr.is_connected(pub_id) {
Ok(pub_id)
} else {
error!(
"{} - Unable to find connection to proxy in PeerManager.",
label
);
Err(RoutingError::ProxyConnectionNotFound)
}
} else {
error!("{} - Unable to find proxy in PeerManager.", label);
Err(RoutingError::ProxyConnectionNotFound)
}
}
35 changes: 26 additions & 9 deletions src/states/common/relocated.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

use super::bootstrapped::Bootstrapped;
use crate::{
ack_manager::Ack,
crust::CrustError,
error::RoutingError,
event::Event,
Expand All @@ -27,10 +28,12 @@ use std::collections::BTreeSet;

/// Common functionality for node states post-relocation.
pub trait Relocated: Bootstrapped {
fn peer_mgr(&mut self) -> &mut PeerManager;
fn peer_mgr(&self) -> &PeerManager;
fn peer_mgr_mut(&mut self) -> &mut PeerManager;
fn process_connection(&mut self, pub_id: PublicId, outbox: &mut EventBox);
fn is_peer_valid(&self, pub_id: &PublicId) -> bool;
fn add_to_notified_nodes(&mut self, pub_id: PublicId) -> bool;
fn remove_from_notified_nodes(&mut self, pub_id: &PublicId) -> bool;
fn add_to_routing_table_success(&mut self, pub_id: &PublicId);
fn add_to_routing_table_failure(&mut self, pub_id: &PublicId);

Expand All @@ -45,7 +48,10 @@ pub trait Relocated: Bootstrapped {
"{} Failed to prepare connection info: {:?}. Retrying.",
self, err
);
let new_token = match self.peer_mgr().get_new_connection_info_token(result_token) {
let new_token = match self
.peer_mgr_mut()
.get_new_connection_info_token(result_token)
{
Err(error) => {
debug!(
"{} Failed to prepare connection info, but no entry found in \
Expand All @@ -64,7 +70,7 @@ pub trait Relocated: Bootstrapped {

let our_pub_info = our_connection_info.to_pub_connection_info();
match self
.peer_mgr()
.peer_mgr_mut()
.connection_info_prepared(result_token, our_connection_info)
{
Err(error) => {
Expand Down Expand Up @@ -131,7 +137,7 @@ pub trait Relocated: Bootstrapped {
}

use crate::peer_manager::ConnectionInfoReceivedResult::*;
match self.peer_mgr().connection_info_received(
match self.peer_mgr_mut().connection_info_received(
src,
dst,
their_connection_info,
Expand Down Expand Up @@ -207,7 +213,7 @@ pub trait Relocated: Bootstrapped {
}

use crate::peer_manager::ConnectionInfoReceivedResult::*;
match self.peer_mgr().connection_info_received(
match self.peer_mgr_mut().connection_info_received(
Authority::ManagedNode(src),
dst,
their_connection_info,
Expand Down Expand Up @@ -256,13 +262,24 @@ pub trait Relocated: Bootstrapped {
return Transition::Stay;
}

self.peer_mgr().connected_to(&pub_id);
self.peer_mgr_mut().connected_to(&pub_id);
debug!("{} Received ConnectSuccess from {}.", self, pub_id);
self.process_connection(pub_id, outbox);

Transition::Stay
}

fn handle_ack_response(&mut self, ack: Ack) {
self.ack_mgr_mut().receive(ack)
}

fn log_connect_failure(&mut self, pub_id: &PublicId) {
if let Some(&PeerState::CrustConnecting) = self.peer_mgr().get_peer(pub_id).map(Peer::state)
{
debug!("{} Failed to connect to peer {:?}.", self, pub_id);
}
}

fn decrypt_connection_info(
&self,
encrypted_connection_info: &[u8],
Expand Down Expand Up @@ -309,7 +326,7 @@ pub trait Relocated: Bootstrapped {

// This will insert the peer if peer is not in peer_mgr and flag them to `valid`
if let Some(token) = self
.peer_mgr()
.peer_mgr_mut()
.get_connection_token(src, dst, their_public_id)
{
self.crust_service().prepare_connection_info(token);
Expand Down Expand Up @@ -404,7 +421,7 @@ pub trait Relocated: Bootstrapped {
self, pub_id
);
let _ = self.crust_service().disconnect(pub_id);
let _ = self.peer_mgr().remove_peer(pub_id);
let _ = self.peer_mgr_mut().remove_peer(pub_id);
}
}

Expand Down Expand Up @@ -434,7 +451,7 @@ pub trait Relocated: Bootstrapped {
}

fn add_to_routing_table(&mut self, pub_id: &PublicId, outbox: &mut EventBox) {
match self.peer_mgr().add_to_routing_table(pub_id) {
match self.peer_mgr_mut().add_to_routing_table(pub_id) {
Err(error) => {
debug!("{} Peer {:?} was not updated: {:?}", self, pub_id, error);
self.add_to_routing_table_failure(pub_id);
Expand Down
141 changes: 141 additions & 0 deletions src/states/common/relocated_not_established.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
// Copyright 2019 MaidSafe.net limited.
//
// This SAFE Network Software is licensed to you under The General Public License (GPL), version 3.
// Unless required by applicable law or agreed to in writing, the SAFE Network Software distributed
// under the GPL Licence is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. Please review the Licences for the specific language governing
// permissions and limitations relating to use of the SAFE Network Software.

use super::Relocated;
use crate::{
error::RoutingError,
id::PublicId,
messages::{DirectMessage, RoutingMessage},
outbox::EventBox,
peer_manager::{Peer, PeerState},
routing_table::Prefix,
state_machine::Transition,
xor_name::XorName,
};

pub trait RelocatedNotEstablished: Relocated {
fn our_prefix(&self) -> &Prefix<XorName>;
fn push_message_to_backlog(&mut self, msg: RoutingMessage);

fn check_direct_message_sender(
&self,
msg: &DirectMessage,
pub_id: &PublicId,
) -> Result<(), RoutingError> {
match self.peer_mgr().get_peer(pub_id).map(Peer::state) {
Some(&PeerState::Connected) | Some(&PeerState::Proxy) => Ok(()),
_ => {
debug!(
"{} Illegitimate direct message {:?} from {:?}.",
self, msg, pub_id
);
Err(RoutingError::InvalidStateForOperation)
}
}
}

fn handle_routing_message(
&mut self,
msg: RoutingMessage,
outbox: &mut EventBox,
) -> Result<(), RoutingError> {
use crate::{messages::MessageContent::*, routing_table::Authority::*};

let src_name = msg.src.name();

match msg {
RoutingMessage {
content:
ConnectionInfoRequest {
encrypted_conn_info,
pub_id,
msg_id,
},
src: ManagedNode(_),
dst: ManagedNode(_),
} => {
if self.our_prefix().matches(&src_name) {
self.handle_connection_info_request(
encrypted_conn_info,
pub_id,
msg_id,
msg.src,
msg.dst,
outbox,
)
} else {
self.add_message_to_backlog(RoutingMessage {
content: ConnectionInfoRequest {
encrypted_conn_info,
pub_id,
msg_id,
},
..msg
});
Ok(())
}
}
RoutingMessage {
content:
ConnectionInfoResponse {
encrypted_conn_info,
pub_id,
msg_id,
},
src: ManagedNode(src_name),
dst: Client { .. },
} => self.handle_connection_info_response(
encrypted_conn_info,
pub_id,
msg_id,
src_name,
msg.dst,
),
RoutingMessage {
content: Ack(ack, _),
..
} => {
self.handle_ack_response(ack);
Ok(())
}
_ => {
self.add_message_to_backlog(msg);
Ok(())
}
}
}

// Backlog the message to be processed once we are established.
fn add_message_to_backlog(&mut self, msg: RoutingMessage) {
trace!(
"{} Not established yet. Delaying message handling: {:?}",
self,
msg
);
self.push_message_to_backlog(msg);
}

fn handle_connect_failure(&mut self, pub_id: PublicId) -> Transition {
self.log_connect_failure(&pub_id);
let _ = self.dropped_peer(&pub_id);
Transition::Stay
}

fn dropped_peer(&mut self, pub_id: &PublicId) -> bool {
let was_proxy = self.peer_mgr().is_proxy(pub_id);
let _ = self.peer_mgr_mut().remove_peer(pub_id);
let _ = self.remove_from_notified_nodes(pub_id);

if was_proxy {
debug!("{} Lost connection to proxy {}.", self, pub_id);
false
} else {
true
}
}
}
20 changes: 13 additions & 7 deletions src/states/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1001,7 +1001,10 @@ impl Node {
Section(_),
) => self.handle_neighbour_confirm(digest, proofs, sec_infos_and_proofs),
(Merge(digest), PrefixSection(_), PrefixSection(_)) => self.handle_merge(digest),
(Ack(ack, _), _, _) => self.handle_ack_response(ack),
(Ack(ack, _), _, _) => {
self.handle_ack_response(ack);
Ok(())
}
(
UserMessagePart {
hash,
Expand Down Expand Up @@ -1741,11 +1744,6 @@ impl Node {
Ok(())
}

fn handle_ack_response(&mut self, ack: Ack) -> Result<(), RoutingError> {
self.ack_mgr.receive(ack);
Ok(())
}

fn send_parsec_gossip(&mut self, target: Option<(u64, PublicId)>) {
let (version, gossip_target) = match target {
Some((v, p)) => (v, p),
Expand Down Expand Up @@ -2683,7 +2681,11 @@ impl Bootstrapped for Node {
}

impl Relocated for Node {
fn peer_mgr(&mut self) -> &mut PeerManager {
fn peer_mgr(&self) -> &PeerManager {
&self.peer_mgr
}

fn peer_mgr_mut(&mut self) -> &mut PeerManager {
&mut self.peer_mgr
}

Expand Down Expand Up @@ -2711,6 +2713,10 @@ impl Relocated for Node {
fn add_to_notified_nodes(&mut self, pub_id: PublicId) -> bool {
self.notified_nodes.insert(pub_id)
}

fn remove_from_notified_nodes(&mut self, pub_id: &PublicId) -> bool {
self.notified_nodes.remove(pub_id)
}
}

impl Display for Node {
Expand Down
Loading

0 comments on commit 90511a8

Please sign in to comment.