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

Commit

Permalink
feat(node-cmds): add a couple of convenience functions to serialise/d…
Browse files Browse the repository at this point in the history
…eserialise NodeCmdMessages
  • Loading branch information
bochaco committed Apr 14, 2021
1 parent 629be8a commit dbcc3e9
Show file tree
Hide file tree
Showing 4 changed files with 123 additions and 24 deletions.
2 changes: 1 addition & 1 deletion src/lib.rs
Expand Up @@ -48,7 +48,7 @@ pub enum MessageType {
},
#[cfg(not(feature = "client-only"))]
NodeCmdMessage {
msg: node::NodeCmd,
msg: node::NodeCmdMessage,
dest_info: DestInfo,
src_section_pk: Option<PublicKey>,
},
Expand Down
21 changes: 12 additions & 9 deletions src/node/mod.rs
Expand Up @@ -9,13 +9,14 @@

mod node_cmd;

pub use self::node_cmd::{
NodeCmd, NodeCmdError, NodeDataError, NodeDataQueryResponse, NodeEvent, NodeQuery,
NodeQueryResponse, NodeRewardQuery, NodeSystemCmd, NodeSystemQuery, NodeSystemQueryResponse,
NodeTransferCmd, NodeTransferError, NodeTransferQuery, NodeTransferQueryResponse,
};
use crate::{Error, MessageType, Result, WireMsg};
use crate::{MessageType, WireMsg};
use bytes::Bytes;
pub use node_cmd::{
NodeCmd, NodeCmdError, NodeCmdMessage, NodeDataError, NodeDataQueryResponse, NodeEvent,
NodeQuery, NodeQueryResponse, NodeRewardQuery, NodeSystemCmd, NodeSystemQuery,
NodeSystemQueryResponse, NodeTransferCmd, NodeTransferError, NodeTransferQuery,
NodeTransferQueryResponse,
};
use serde::{Deserialize, Serialize};
use std::fmt::{self, Debug, Formatter};
use threshold_crypto::PublicKey as BlsPublicKey;
Expand All @@ -35,17 +36,19 @@ impl NodeMessage {

/// Convenience function to deserialize a 'NodeMessage' from bytes received over the wire.
/// It returns an error if the bytes don't correspond to a node message.
pub fn from(bytes: Bytes) -> Result<Self> {
pub fn from(bytes: Bytes) -> crate::Result<Self> {
let deserialized = WireMsg::deserialize(bytes)?;
if let MessageType::NodeMessage { msg, .. } = deserialized {
Ok(msg)
} else {
Err(Error::FailedToParse("bytes as a node message".to_string()))
Err(crate::Error::FailedToParse(
"bytes as a node message".to_string(),
))
}
}

/// serialize this NodeMessage into bytes ready to be sent over the wire.
pub fn serialize(&self, dest: XorName, dest_section_pk: BlsPublicKey) -> Result<Bytes> {
pub fn serialize(&self, dest: XorName, dest_section_pk: BlsPublicKey) -> crate::Result<Bytes> {
WireMsg::serialize_node_msg(self, dest, dest_section_pk)
}
}
Expand Down
99 changes: 94 additions & 5 deletions src/node/node_cmd.rs
Expand Up @@ -7,21 +7,110 @@
// specific language governing permissions and limitations relating to use of the SAFE Network
// Software.

// FIXME: change NodeCmd defnintions to return Result and
// Error defined for the crate::node instead of client Result/Error
use crate::client::{Error, Result};
use crate::{
client::{
BlobRead, BlobWrite, DataCmd as NodeDataCmd, DataQuery as NodeDataQuery, Error, Result,
},
EndUser,
client::{BlobRead, BlobWrite, DataCmd as NodeDataCmd, DataQuery as NodeDataQuery},
EndUser, MessageId, MessageType, WireMsg,
};
use bytes::Bytes;
use serde::{Deserialize, Serialize};
use sn_data_types::{
ActorHistory, Blob, BlobAddress, CreditAgreementProof, NodeAge, PublicKey, ReplicaEvent,
SectionElders, Signature,
};
use std::collections::BTreeMap;
use threshold_crypto::PublicKey as BlsPublicKey;
use xor_name::XorName;

// -------------- Node Cmds --------------
// -------------- Node Cmd Messages --------------
// TODO: this messages hierarchy needs to be merged into
// the NodeMessage hierarchy. It's temporarily here till
// all messages defined within sn_routing are migrated to
// this crate and within NodeMessage struct.

///
#[allow(clippy::large_enum_variant)]
#[derive(Debug, Eq, PartialEq, Clone, Serialize, Deserialize)]
pub enum NodeCmdMessage {
/// Cmds only sent internally in the network.
NodeCmd {
/// NodeCmd.
cmd: NodeCmd,
/// Message ID.
id: MessageId,
/// Target section's current PublicKey
target_section_pk: Option<PublicKey>,
},
/// An error of a NodeCmd.
NodeCmdError {
/// The error.
error: NodeCmdError,
/// Message ID.
id: MessageId,
/// ID of causing cmd.
correlation_id: MessageId,
/// Target section's current PublicKey
target_section_pk: Option<PublicKey>,
},
/// Events only sent internally in the network.
NodeEvent {
/// Request.
event: NodeEvent,
/// Message ID.
id: MessageId,
/// ID of causing cmd.
correlation_id: MessageId,
/// Target section's current PublicKey
target_section_pk: Option<PublicKey>,
},
/// Queries is a read-only operation.
NodeQuery {
/// Query.
query: NodeQuery,
/// Message ID.
id: MessageId,
/// Target section's current PublicKey
target_section_pk: Option<PublicKey>,
},
/// The response to a query, containing the query result.
NodeQueryResponse {
/// QueryResponse.
response: NodeQueryResponse,
/// Message ID.
id: MessageId,
/// ID of causing query.
correlation_id: MessageId,
/// Target section's current PublicKey
target_section_pk: Option<PublicKey>,
},
}

impl NodeCmdMessage {
/// Convenience function to deserialize a 'NodeCmdMessage' from bytes received over the wire.
/// It returns an error if the bytes don't correspond to a node command message.
pub fn from(bytes: Bytes) -> crate::Result<Self> {
let deserialized = WireMsg::deserialize(bytes)?;
if let MessageType::NodeCmdMessage { msg, .. } = deserialized {
Ok(msg)
} else {
Err(crate::Error::FailedToParse(
"bytes as a node command message".to_string(),
))
}
}

/// serialize this NodeCmd message into bytes ready to be sent over the wire.
pub fn serialize(
&self,
dest: XorName,
dest_section_pk: BlsPublicKey,
src_section_pk: Option<BlsPublicKey>,
) -> crate::Result<Bytes> {
WireMsg::serialize_node_cmd_msg(self, dest, dest_section_pk, src_section_pk)
}
}

///
#[allow(clippy::large_enum_variant)]
Expand Down
25 changes: 16 additions & 9 deletions src/serialisation/mod.rs
Expand Up @@ -100,7 +100,7 @@ impl WireMsg {
/// Creates a new instance keeping a (serialized) copy of the node 'Message' message provided.
#[cfg(not(feature = "client-only"))]
pub fn new_node_cmd_msg(
msg: &node::NodeCmd,
msg: &node::NodeCmdMessage,
dest: XorName,
dest_section_pk: PublicKey,
src_section_pk: Option<PublicKey>,
Expand Down Expand Up @@ -201,7 +201,7 @@ impl WireMsg {
}
#[cfg(not(feature = "client-only"))]
MessageKind::NodeCmdMessage => {
let node_cmd: node::NodeCmd =
let node_cmd: node::NodeCmdMessage =
rmp_serde::from_slice(&self.payload).map_err(|err| {
Error::FailedToParse(format!("NodeCmd message payload as Msgpack: {}", err))
})?;
Expand Down Expand Up @@ -276,7 +276,7 @@ impl WireMsg {
/// node::NodeCmdMessage, returning the serialized WireMsg.
#[cfg(not(feature = "client-only"))]
pub fn serialize_node_cmd_msg(
msg: &node::NodeCmd,
msg: &node::NodeCmdMessage,
dest: XorName,
dest_section_pk: PublicKey,
src_section_pk: Option<PublicKey>,
Expand All @@ -295,12 +295,13 @@ impl WireMsg {
mod tests {
use super::*;
use anyhow::Result;
use threshold_crypto::SecretKey;
use xor_name::XorName;

#[test]
fn serialisation_ping() -> Result<()> {
let dest = XorName::random();
let dest_section_pk = threshold_crypto::SecretKey::random().public_key();
let dest_section_pk = SecretKey::random().public_key();

let wire_msg = WireMsg::new_ping_msg(dest, dest_section_pk);
let serialized = wire_msg.serialize()?;
Expand All @@ -326,7 +327,7 @@ mod tests {
#[test]
fn serialisation_sectioninfo_msg() -> Result<()> {
let dest = XorName::random();
let dest_section_pk = threshold_crypto::SecretKey::random().public_key();
let dest_section_pk = SecretKey::random().public_key();

let query = section_info::Message::GetSectionQuery(dest_section_pk.into());
let wire_msg = WireMsg::new_sectioninfo_msg(&query, dest, dest_section_pk)?;
Expand Down Expand Up @@ -357,12 +358,18 @@ mod tests {
#[test]
#[cfg(not(feature = "client-only"))]
fn serialisation_node_cmd_msg() -> Result<()> {
use crate::MessageId;
use node::{NodeCmd, NodeCmdMessage, NodeSystemCmd};

let dest = XorName::random();
let src_section_pk = threshold_crypto::SecretKey::random().public_key();
let dest_section_pk = threshold_crypto::SecretKey::random().public_key();
let src_section_pk = SecretKey::random().public_key();
let dest_section_pk = SecretKey::random().public_key();

let node_cmd =
node::NodeCmd::System(node::NodeSystemCmd::RegisterWallet(dest_section_pk.into()));
let node_cmd = NodeCmdMessage::NodeCmd {
cmd: NodeCmd::System(NodeSystemCmd::RegisterWallet(dest_section_pk.into())),
id: MessageId::new(),
target_section_pk: None,
};

// first test without including a source section public key in the header
let wire_msg = WireMsg::new_node_cmd_msg(&node_cmd, dest, dest_section_pk, None)?;
Expand Down

0 comments on commit dbcc3e9

Please sign in to comment.