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

Commit

Permalink
feat: add Envelope and InfrastructureQuery
Browse files Browse the repository at this point in the history
  • Loading branch information
madadam authored and joshuef committed Feb 4, 2021
1 parent 19e0e92 commit e0b999f
Show file tree
Hide file tree
Showing 13 changed files with 426 additions and 189 deletions.
4 changes: 2 additions & 2 deletions src/consensus/dkg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -577,7 +577,7 @@ impl DkgCommand {
let variant = Variant::DKGMessage { dkg_key, message };
let message = Message::single_src(node, DstLocation::Direct, variant, None, None)?;

Ok(Command::send_message_to_targets(
Ok(Command::send_message_to_nodes(
&recipients,
recipients.len(),
message.to_bytes(),
Expand All @@ -601,7 +601,7 @@ impl DkgCommand {
let variant = Variant::DKGFailureObservation { dkg_key, proof };
let message = Message::single_src(node, DstLocation::Direct, variant, None, None)?;

Ok(Command::send_message_to_targets(
Ok(Command::send_message_to_nodes(
&recipients,
recipients.len(),
message.to_bytes(),
Expand Down
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ pub use self::{
error::{Error, Result},
event::{Event, NodeElderChange, SendStream},
location::{DstLocation, SrcLocation},
messages::{InfrastructureQuery, MessageKind},
routing::{Config, EventStream, Routing},
section::{SectionProofChain, MIN_AGE},
};
Expand Down
100 changes: 100 additions & 0 deletions src/messages/envelope.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
// Copyright 2021 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 std::convert::TryFrom;

use super::{InfrastructureQuery, Message};
use bytes::Bytes;
use thiserror::Error;

/// Single byte that identifies the message type.
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
#[repr(u8)]
pub enum MessageKind {
/// Ping message used to probe whether nodes/client are online. Does not need to be handled.
Ping = 0,
/// Node-to-node message.
Node = 1,
/// Node-to-client or client-to-node message.
Client = 2,
/// Message to query the network infrastructure or a response to such query.
Infrastructure = 3,
}

impl TryFrom<u8> for MessageKind {
type Error = UnknownMessageKind;

fn try_from(input: u8) -> Result<Self, Self::Error> {
match input {
0 => Ok(Self::Ping),
1 => Ok(Self::Node),
2 => Ok(Self::Client),
3 => Ok(Self::Infrastructure),
_ => Err(UnknownMessageKind),
}
}
}

#[derive(Debug, Error, PartialEq, Eq)]
#[error("unknown message kind")]
pub struct UnknownMessageKind;

#[allow(clippy::large_enum_variant)]
#[derive(Debug)]
pub(crate) enum Envelope {
Ping,
Node(Message),
Client(Bytes),
Infrastructure(InfrastructureQuery),
}

impl Envelope {
pub fn from_bytes(bytes: &Bytes) -> Result<Self, FromBytesError> {
match MessageKind::try_from(bytes[0]) {
Ok(MessageKind::Ping) => Ok(Self::Ping),
Ok(MessageKind::Node) => Ok(Self::Node(Message::from_bytes(&bytes.slice(1..))?)),
Ok(MessageKind::Client) => Ok(Self::Client(bytes.slice(1..))),
Ok(MessageKind::Infrastructure) => Ok(Self::Infrastructure(
bincode::deserialize(&bytes[1..]).map_err(FromBytesError::Infrastructure)?,
)),
Err(_) => Err(FromBytesError::UnknownMessageKind),
}
}
}

#[derive(Debug, Error)]
pub(crate) enum FromBytesError {
#[error("failed to parse node message: {}", .0)]
Node(#[from] super::CreateError),
#[error("failed to parse infrastructure query: {}", .0)]
Infrastructure(#[source] bincode::Error),
#[error("unknown message kind")]
UnknownMessageKind,
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn message_kind_from_u8() {
for &(kind, byte) in &[
(MessageKind::Ping, 0),
(MessageKind::Node, 1),
(MessageKind::Client, 2),
(MessageKind::Infrastructure, 3),
] {
assert_eq!(kind as u8, byte);
assert_eq!(MessageKind::try_from(byte), Ok(kind))
}

for byte in 4..u8::MAX {
assert!(MessageKind::try_from(byte).is_err())
}
}
}
31 changes: 31 additions & 0 deletions src/messages/infrastructure_query.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Copyright 2021 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 serde::{Deserialize, Serialize};
use std::{collections::BTreeMap, net::SocketAddr};
use xor_name::{Prefix, XorName};

/// Message to query the network infrastructure.
#[derive(Debug, Serialize, Deserialize)]
pub enum InfrastructureQuery {
/// Message to request information about the section that matches the given name.
GetSectionRequest(XorName),
/// Successful response to `GetSectionRequest`. Contains information about the requested
/// section.
GetSectionSuccess {
/// Prefix of the section.
prefix: Prefix,
/// Public key of the section.
key: bls::PublicKey,
/// Section elders.
elders: BTreeMap<XorName, SocketAddr>,
},
/// Response to `GetSectionRequest` containing addresses of nodes that are closer to the
/// requested name than the recipient. The request should be repeated to these addresses.
GetSectionRedirect(Vec<SocketAddr>),
}
12 changes: 7 additions & 5 deletions src/messages/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,22 @@
// 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.

mod envelope;
mod hash;
mod infrastructure_query;
mod plain_message;
mod src_authority;
mod variant;

pub use self::{hash::MessageHash, src_authority::SrcAuthority};
pub(crate) use self::{
envelope::Envelope,
plain_message::PlainMessage,
variant::{BootstrapResponse, JoinRequest, ResourceProofResponse, Variant},
};
pub use self::{
envelope::MessageKind, hash::MessageHash, infrastructure_query::InfrastructureQuery,
src_authority::SrcAuthority,
};
use crate::{
crypto::{self, name, Verifier},
error::{Error, Result},
Expand All @@ -30,10 +36,6 @@ use std::fmt::{self, Debug, Formatter};
use thiserror::Error;
use xor_name::Prefix;

// Message used to probe a peer connection.
// NOTE: ideally this would be empty, but that is currently treated as error by qp2p.
pub(crate) const PING: &[u8] = &[0];

/// Message sent over the network.
#[derive(Clone, Eq, Serialize, Deserialize)]
pub(crate) struct Message {
Expand Down
4 changes: 2 additions & 2 deletions src/relocation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
use crate::{
crypto::{self, Keypair, Signature, Verifier},
error::Error,
messages::{Message, Variant},
messages::{Envelope, Message, Variant},
network::Network,
peer::Peer,
section::{MemberInfo, Section},
Expand Down Expand Up @@ -208,7 +208,7 @@ pub(crate) enum RelocateState {
// will exchange it for an actual `Relocate` message.
Delayed(Bytes),
// Relocation in progress. The sender is used to pass messages to the bootstrap task.
InProgress(mpsc::Sender<(Message, SocketAddr)>),
InProgress(mpsc::Sender<(Envelope, SocketAddr)>),
}

/// Action to relocate a node.
Expand Down

0 comments on commit e0b999f

Please sign in to comment.