1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
// 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. mod errors; use crate::{MessageId, MessageType, WireMsg}; use bytes::Bytes; pub use errors::Error; use serde::{Deserialize, Serialize}; use sn_data_types::{PublicKey, ReplicaPublicKeySet, Signature}; use std::{collections::BTreeMap, fmt, net::SocketAddr}; use xor_name::{Prefix, XorName}; /// Messages for exchanging network info, specifically on a target section for a msg. #[allow(clippy::large_enum_variant)] #[derive(Debug, Serialize, Deserialize, PartialEq)] pub enum Message { /// Message to request information about the section that matches the given name. GetSectionQuery(XorName), /// An EndUser that wants to interact with the network, /// would send this cmd to the elders received /// in the GetSectionResponse. RegisterEndUserCmd { /// The end user public key. end_user: PublicKey, /// A sig over the socketaddr from which /// this request is made, by the secret key /// corresponding to the end_user public key. socketaddr_sig: Signature, }, /// If the sig over the sender socketaddr /// cannot be verified by the provided public key. RegisterEndUserError(Error), /// Response to `GetSectionQuery`. GetSectionResponse(GetSectionResponse), /// Updated info related to section SectionInfoUpdate(ErrorResponse), } /// All the info a client needs about their section #[derive(Serialize, Deserialize, Hash, PartialEq, PartialOrd, Ord, Eq, Clone)] pub struct SectionInfo { /// Prefix of the section. pub prefix: Prefix, /// Public key set of the section. pub pk_set: ReplicaPublicKeySet, /// Section elders. pub elders: BTreeMap<XorName, SocketAddr>, /// Whether the section is allowed to taking new joining node. pub joins_allowed: bool, } impl fmt::Debug for SectionInfo { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!( f, "SectionInfo {{ prefix: {:?}, pk_set: PkSet {{ public_key: {:?} }}, elders: {:?}, joins_allowed: {:?}}}", self.prefix, self.pk_set.public_key(), self.elders, self.joins_allowed ) } } // Infrastructure error wrapper to add correltion info for triggering message #[derive(Debug, Serialize, Deserialize, Hash, PartialEq, PartialOrd, Ord, Eq, Clone)] pub struct ErrorResponse { /// Optional correlation id if this messge is in response to some non network info query/cmd pub correlation_id: MessageId, /// Section data error message pub error: Error, } /// Information about a section. #[derive(Debug, Serialize, Deserialize, PartialEq)] pub enum GetSectionResponse { /// Successful response to `GetSectionQuery`. Contains information about the requested /// section. Success(SectionInfo), /// Response to `GetSectionQuery` containing addresses of nodes that are closer to the /// requested name than the recipient. The request should be repeated to these addresses. Redirect(Vec<SocketAddr>), /// Request could not be fulfilled due to section constellation updates SectionInfoUpdate(Error), } impl Message { /// Convenience function to deserialize a 'Query' from bytes received over the wire. /// It returns an error if the bytes don't correspond to a network info query. pub fn from(bytes: Bytes) -> crate::Result<Self> { let deserialized = WireMsg::deserialize(bytes)?; if let MessageType::SectionInfo(query) = deserialized { Ok(query) } else { Err(crate::Error::FailedToParse( "bytes as a network info message".to_string(), )) } } /// serialize this Query into bytes ready to be sent over the wire. pub fn serialize(&self) -> crate::Result<Bytes> { WireMsg::serialize_sectioninfo_msg(self) } }