#![doc(
html_logo_url = "https://raw.githubusercontent.com/maidsafe/QA/master/Images/maidsafe_logo.png",
html_favicon_url = "https://maidsafe.net/img/favicon.ico",
test(attr(forbid(warnings)))
)]
#![forbid(unsafe_code)]
#![warn(
missing_docs,
trivial_casts,
trivial_numeric_casts,
unused_extern_crates,
unused_import_braces,
unused_qualifications,
unused_results
)]
mod append_only_data;
mod coins;
mod errors;
mod identity;
mod immutable_data;
mod keys;
mod mutable_data;
mod request;
mod response;
mod transaction;
mod utils;
pub use append_only_data::{
Action as ADataAction, Address as ADataAddress, AppendOnlyData,
AppendOperation as ADataAppendOperation, Data as AData, Entries as ADataEntries,
Entry as ADataEntry, Index as ADataIndex, Indices as ADataIndices, Kind as ADataKind,
Owner as ADataOwner, Permissions as ADataPermissions,
PubPermissionSet as ADataPubPermissionSet, PubPermissions as ADataPubPermissions,
PubSeqAppendOnlyData, PubUnseqAppendOnlyData, SeqAppendOnly,
UnpubPermissionSet as ADataUnpubPermissionSet, UnpubPermissions as ADataUnpubPermissions,
UnpubSeqAppendOnlyData, UnpubUnseqAppendOnlyData, UnseqAppendOnly, User as ADataUser,
};
pub use coins::{Coins, MAX_COINS_VALUE};
pub use errors::{EntryError, Error, Result};
pub use identity::{
app::{FullId as AppFullId, PublicId as AppPublicId},
client::{FullId as ClientFullId, PublicId as ClientPublicId},
node::{FullId as NodeFullId, PublicId as NodePublicId},
PublicId,
};
pub use immutable_data::{
Address as IDataAddress, Data as IData, Kind as IDataKind, PubImmutableData,
UnpubImmutableData, MAX_IMMUTABLE_DATA_SIZE_IN_BYTES,
};
pub use keys::{BlsKeypair, BlsKeypairShare, Keypair, PublicKey, Signature};
pub use mutable_data::{
Action as MDataAction, Address as MDataAddress, Data as MData, Entries as MDataEntries,
EntryActions as MDataEntryActions, Kind as MDataKind, PermissionSet as MDataPermissionSet,
SeqEntries as MDataSeqEntries, SeqEntryAction as MDataSeqEntryAction,
SeqEntryActions as MDataSeqEntryActions, SeqMutableData, SeqValue as MDataSeqValue,
UnseqEntries as MDataUnseqEntries, UnseqEntryAction as MDataUnseqEntryAction,
UnseqEntryActions as MDataUnseqEntryActions, UnseqMutableData, Value as MDataValue,
Values as MDataValues,
};
pub use request::{LoginPacket, Request, RequestType, MAX_LOGIN_PACKET_BYTES};
pub use response::{Response, TryFromError};
pub use sha3::Sha3_512 as Ed25519Digest;
pub use transaction::{Transaction, TransactionId};
pub use utils::verify_signature;
use hex_fmt::HexFmt;
use multibase::Decodable;
use rand::{
distributions::{Distribution, Standard},
Rng,
};
use serde::{Deserialize, Serialize};
use std::{
fmt::{self, Debug, Display, Formatter},
net::SocketAddr,
};
#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize, Debug)]
pub enum Data {
Immutable(IData),
Mutable(MData),
AppendOnly(AData),
}
impl Data {
pub fn is_pub(&self) -> bool {
match *self {
Data::Immutable(ref idata) => idata.is_pub(),
Data::Mutable(_) => false,
Data::AppendOnly(ref adata) => adata.is_pub(),
}
}
pub fn is_unpub(&self) -> bool {
!self.is_pub()
}
}
impl From<IData> for Data {
fn from(data: IData) -> Self {
Data::Immutable(data)
}
}
impl From<MData> for Data {
fn from(data: MData) -> Self {
Data::Mutable(data)
}
}
impl From<AData> for Data {
fn from(data: AData) -> Self {
Data::AppendOnly(data)
}
}
#[derive(
Copy, Hash, Eq, PartialEq, PartialOrd, Ord, Clone, Serialize, Deserialize, Default, Debug,
)]
pub struct AppPermissions {
pub transfer_coins: bool,
pub perform_mutations: bool,
pub get_balance: bool,
}
pub const XOR_NAME_LEN: usize = 32;
#[derive(Clone, Copy, Default, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)]
pub struct XorName(pub [u8; XOR_NAME_LEN]);
impl XorName {
pub fn encode_to_zbase32(&self) -> String {
utils::encode(&self)
}
pub fn decode_from_zbase32<I: Decodable>(encoded: I) -> Result<Self> {
utils::decode(encoded)
}
}
impl Debug for XorName {
fn fmt(&self, formatter: &mut Formatter) -> fmt::Result {
write!(formatter, "{:<8}", HexFmt(&self.0))
}
}
impl Display for XorName {
fn fmt(&self, formatter: &mut Formatter) -> fmt::Result {
Debug::fmt(self, formatter)
}
}
impl Distribution<XorName> for Standard {
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> XorName {
XorName(rng.gen())
}
}
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq, Hash)]
pub struct ConnectionInfo {
pub peer_addr: SocketAddr,
pub peer_cert_der: Vec<u8>,
}
#[allow(clippy::large_enum_variant)]
#[derive(Hash, Eq, PartialEq, Clone, Serialize, Deserialize)]
pub enum Message {
Request {
request: Request,
message_id: MessageId,
signature: Option<Signature>,
},
Response {
response: Response,
message_id: MessageId,
},
Notification {
notification: Notification,
},
SectionInfo {
elders: Vec<(XorName, ConnectionInfo)>,
},
}
impl Message {
pub fn message_id(&self) -> Option<MessageId> {
match self {
Message::Request { message_id, .. } => Some(*message_id),
Message::Response { message_id, .. } => Some(*message_id),
Message::Notification { .. } => None,
Message::SectionInfo { .. } => None,
}
}
}
#[derive(Ord, PartialOrd, Debug, Clone, Copy, Eq, PartialEq, Serialize, Deserialize, Hash)]
pub struct MessageId(pub XorName);
impl MessageId {
pub fn new() -> MessageId {
MessageId(rand::random())
}
}
impl Default for MessageId {
fn default() -> Self {
Self::new()
}
}
#[allow(clippy::large_enum_variant)]
#[derive(Serialize, Deserialize)]
pub enum Challenge {
Request(PublicId, Vec<u8>),
Response {
client_id: PublicId,
signature: Signature,
request_section_info: bool,
},
}
#[derive(Hash, Eq, PartialEq, PartialOrd, Ord, Clone, Serialize, Deserialize, Debug)]
pub struct Notification(pub Transaction);
#[cfg(test)]
mod tests {
use crate::XorName;
use unwrap::unwrap;
#[test]
fn zbase32_encode_decode_xorname() {
let name = XorName(rand::random());
let encoded = name.encode_to_zbase32();
let decoded = unwrap!(XorName::decode_from_zbase32(&encoded));
assert_eq!(name, decoded);
}
}