#![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 coins;
mod errors;
mod identity;
mod immutable_data;
mod keys;
mod mutable_data;
mod request;
mod response;
mod sequence;
mod utils;
pub use coins::Coins;
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, PubData as PubImmutableData,
UnpubData as 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,
SeqData as SeqMutableData, SeqEntries as MDataSeqEntries,
SeqEntryAction as MDataSeqEntryAction, SeqEntryActions as MDataSeqEntryActions,
SeqValue as MDataSeqValue, UnseqData as UnseqMutableData, UnseqEntries as MDataUnseqEntries,
UnseqEntryAction as MDataUnseqEntryAction, UnseqEntryActions as MDataUnseqEntryActions,
Value as MDataValue, Values as MDataValues,
};
pub use request::{
AuthorisationKind as RequestAuthKind, ClientRequest, CoinsRequest, IDataRequest, LoginPacket,
LoginPacketRequest, MDataRequest, Request, SDataRequest, Type as RequestType,
MAX_LOGIN_PACKET_BYTES,
};
pub use response::{Response, TryFromError};
pub use sequence::{
Action as SDataAction, Address as SDataAddress, Data as SData, Entries as SDataEntries,
Entry as SDataEntry, Index as SDataIndex, Indices as SDataIndices, Kind as SDataKind,
MutationOperation as SDataMutationOperation, Owner as SDataOwner,
Permissions as SDataPermissions, PrivPermissions as SDataPrivPermissions, PrivSeqData,
PrivUserPermissions as SDataPrivUserPermissions, PubPermissions as SDataPubPermissions,
PubSeqData, PubUserPermissions as SDataPubUserPermissions, User as SDataUser,
UserPermissions as SDataUserPermissions,
};
pub use sha3::Sha3_512 as Ed25519Digest;
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,
};
#[allow(clippy::large_enum_variant)]
#[derive(Clone, Eq, PartialEq, PartialOrd, Hash, Serialize, Deserialize, Debug)]
pub enum Data {
Immutable(IData),
Mutable(MData),
Sequence(SData),
}
impl Data {
pub fn is_pub(&self) -> bool {
match *self {
Self::Immutable(ref idata) => idata.is_pub(),
Self::Mutable(_) => false,
Self::Sequence(ref sdata) => sdata.is_pub(),
}
}
pub fn is_unpub(&self) -> bool {
!self.is_pub()
}
}
impl From<IData> for Data {
fn from(data: IData) -> Self {
Self::Immutable(data)
}
}
impl From<MData> for Data {
fn from(data: MData) -> Self {
Self::Mutable(data)
}
}
impl From<SData> for Data {
fn from(data: SData) -> Self {
Self::Sequence(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())
}
}
#[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,
},
}
impl Message {
pub fn message_id(&self) -> Option<MessageId> {
match self {
Self::Request { message_id, .. } | Self::Response { message_id, .. } => {
Some(*message_id)
}
Self::Notification { .. } => None,
}
}
}
#[derive(Ord, PartialOrd, Debug, Clone, Copy, Eq, PartialEq, Serialize, Deserialize, Hash)]
pub struct MessageId(pub XorName);
impl MessageId {
pub fn new() -> Self {
Self(rand::random())
}
}
impl Default for MessageId {
fn default() -> Self {
Self::new()
}
}
#[derive(Serialize, Deserialize)]
pub enum HandshakeRequest {
Bootstrap(PublicId),
Join(PublicId),
ChallengeResult(Signature),
}
#[allow(clippy::large_enum_variant)]
#[derive(Serialize, Deserialize)]
pub enum HandshakeResponse {
Rebootstrap(Vec<(XorName, SocketAddr)>),
Join(Vec<(XorName, SocketAddr)>),
Challenge(PublicId, Vec<u8>),
InvalidSection,
}
pub type TransactionId = u64;
#[derive(Copy, Clone, Hash, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize, Debug)]
pub struct Transaction {
pub id: TransactionId,
pub amount: Coins,
}
#[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);
}
}