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

Commit

Permalink
Merge 3a065b6 into 2c97090
Browse files Browse the repository at this point in the history
  • Loading branch information
bochaco committed May 28, 2021
2 parents 2c97090 + 3a065b6 commit c7d8d7b
Show file tree
Hide file tree
Showing 14 changed files with 1,208 additions and 20 deletions.
4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,18 @@ version = "26.0.0"

[dependencies]
bincode = "1.2.1"
bls_dkg = "~0.3.1"
bls_signature_aggregator = "~0.2.0"
bytes = "1.0.1"
cookie-factory = "0.3.1"
crdts = "6.3.2"
hex_fmt = "~0.3.0"
itertools = "~0.9.0"
multibase = "~0.8.0"
rand = "~0.7.3"
rand_core = "~0.5.1"
rmp-serde = "~0.15.1"
secured_linked_list = "0.1.1"
serde_bytes = "0.11.5"
signature = "1.1.0"
sn_data_types = "~0.18.3"
Expand Down
114 changes: 114 additions & 0 deletions src/node/agreement.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
// Copyright 2020 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 super::{
plain_message::PlainMessage,
section::{MemberInfo, SectionAuthorityProvider},
};
use bls_signature_aggregator::Proof;
use ed25519_dalek::{PublicKey, Signature};
use hex_fmt::HexFmt;
use secured_linked_list::SecuredLinkedList;
use serde::{Deserialize, Serialize};
use std::{
borrow::Borrow,
collections::BTreeSet,
fmt::{self, Debug, Formatter},
};
use threshold_crypto::PublicKey as BlsPublicKey;
use xor_name::{Prefix, XorName};

/// SHA3-256 hash digest.
pub type Digest256 = [u8; 32];

/// Unique identified of a DKG session.
#[derive(Copy, Clone, Eq, PartialEq, Hash, Serialize, Deserialize)]
pub struct DkgKey {
pub hash: Digest256,
pub generation: u64,
}

impl Debug for DkgKey {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
write!(f, "DkgKey({:10}/{})", HexFmt(&self.hash), self.generation)
}
}

#[derive(Copy, Clone, Eq, PartialEq, Debug, Serialize, Deserialize)]
pub struct DkgFailureProof {
pub public_key: PublicKey,
pub signature: Signature,
}

#[derive(Default, Clone, Eq, PartialEq, Debug, Serialize, Deserialize)]
pub struct DkgFailureProofSet {
pub proofs: Vec<DkgFailureProof>,
pub non_participants: BTreeSet<XorName>,
}

/// A value together with the proof that it was agreed on by the majority of the section elders.
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Serialize, Deserialize)]
pub struct Proven<T: Serialize> {
pub value: T,
pub proof: Proof,
}

impl<T> Borrow<Prefix> for Proven<T>
where
T: Borrow<Prefix> + Serialize,
{
fn borrow(&self) -> &Prefix {
self.value.borrow()
}
}

#[derive(Clone, Eq, PartialEq, Debug, Serialize, Deserialize)]
#[allow(clippy::large_enum_variant)]
pub enum Proposal {
// Proposal to add a node to oursection
Online {
member_info: MemberInfo,
// Previous name if relocated.
previous_name: Option<XorName>,
// The key of the destination section that the joining node knows, if any.
their_knowledge: Option<BlsPublicKey>,
},

// Proposal to remove a node from our section
Offline(MemberInfo),

// Proposal to update info about a section. This has two purposes:
//
// 1. To signal the completion of a DKG by the elder candidates to the current elders.
// This proposal is then signed by the newly generated section key.
// 2. To update information about other section in the network. In this case the proposal is
// signed by an existing key from the chain.
SectionInfo(SectionAuthorityProvider),

// Proposal to change the elders (and possibly the prefix) of our section.
// NOTE: the `SectionAuthorityProvider` is already signed with the new key. This proposal is only to signs the
// new key with the current key. That way, when it aggregates, we obtain all the following
// pieces of information at the same time:
// 1. the new section authority provider
// 2. the new key
// 3. the signature of the new section authority provider using the new key
// 4. the signature of the new key using the current key
// Which we can use to update the section section authority provider and the section chain at
// the same time as a single atomic operation without needing to cache anything.
OurElders(Proven<SectionAuthorityProvider>),

// Proposal to accumulate the message at the source (that is, our section) and then send it to
// its destination.
AccumulateAtSrc {
message: Box<PlainMessage>,
proof_chain: SecuredLinkedList,
},

// Proposal to change whether new nodes are allowed to join our section.
JoinsAllowed(bool),
}
67 changes: 54 additions & 13 deletions src/node/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,30 +7,64 @@
// specific language governing permissions and limitations relating to use of the SAFE Network
// Software.

mod agreement;
mod network;
mod node_msg;
mod plain_message;
mod prefix_map;
mod relocation;
mod section;
mod src_authority;
mod variant;

use crate::{MessageType, WireMsg};
use bytes::Bytes;
pub use agreement::{DkgFailureProof, DkgFailureProofSet, DkgKey, Proposal, Proven};
pub use network::{Network, OtherSection};
pub use node_msg::{
NodeCmd, NodeCmdError, NodeDataError, NodeDataQueryResponse, NodeEvent, NodeMsg, NodeQuery,
NodeQueryResponse, NodeRewardQuery, NodeSystemCmd, NodeSystemQuery, NodeSystemQueryResponse,
NodeTransferCmd, NodeTransferError, NodeTransferQuery, NodeTransferQueryResponse,
};
pub use plain_message::PlainMessage;
pub use prefix_map::PrefixMap;
pub use relocation::{RelocateDetails, RelocatePayload, RelocatePromise, SignedRelocateDetails};
pub use section::{
ElderCandidates, MemberInfo, Peer, PeerState, Section, SectionAuthorityProvider, SectionPeers,
};
pub use src_authority::SrcAuthority;
pub use variant::{JoinRequest, ResourceProofResponse, Variant};

use crate::{Aggregation, DstLocation, MessageId, MessageType, WireMsg};
use bytes::Bytes;
use secured_linked_list::SecuredLinkedList;
use serde::{Deserialize, Serialize};
use std::fmt::{self, Debug, Formatter};
use threshold_crypto::PublicKey as BlsPublicKey;
use xor_name::XorName;

/// Node message sent over the network.
// TODO: this is currently holding just bytes as a placeholder, next step
// is to move all actual node messages structs and definitions within it.
/// Routing message sent over the network.
#[derive(Clone, Eq, Serialize, Deserialize)]
pub struct RoutingMsg(#[serde(with = "serde_bytes")] pub Vec<u8>);
pub struct RoutingMsg {
/// Message ID.
pub id: MessageId,
/// Source authority.
/// Messages do not need to sign this field as it is all verifiable (i.e. if the sig validates
/// agains the public key and we know the pub key then we are good. If the proof is not recognised we
/// ask for a longer chain that can be recognised). Therefore we don't need to sign this field.
pub src: SrcAuthority,
/// Destination location.
pub dst: DstLocation,
/// The aggregation scheme to be used.
pub aggregation: Aggregation,
/// The body of the message.
pub variant: Variant,
/// Proof chain to verify the message trust. Does not need to be signed.
pub proof_chain: Option<SecuredLinkedList>,
}

impl RoutingMsg {
/// Creates a new instance which wraps the provided node message bytes.
pub fn new(bytes: Bytes) -> Self {
Self(bytes.to_vec())
/// Gets the message ID.
pub fn id(&self) -> MessageId {
self.id
}

/// Convenience function to deserialize a 'RoutingMsg' from bytes received over the wire.
Expand All @@ -53,16 +87,23 @@ impl RoutingMsg {
}

impl PartialEq for RoutingMsg {
fn eq(&self, other: &Self) -> bool {
self.0 == other.0
fn eq(&self, other: &RoutingMsg) -> bool {
self.src == other.src
&& self.dst == other.dst
&& self.id == other.id
&& self.variant == other.variant
&& self.proof_chain == other.proof_chain
}
}

impl Debug for RoutingMsg {
fn fmt(&self, formatter: &mut Formatter) -> fmt::Result {
formatter
.debug_tuple("RoutingMsg")
.field(&format_args!("{:10}", hex_fmt::HexFmt(&self.0)))
.debug_struct("RoutingMsg")
.field("id", &self.id)
.field("src", &self.src)
.field("dst", &self.dst)
.field("variant", &self.variant)
.finish()
}
}
35 changes: 35 additions & 0 deletions src/node/network.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Copyright 2020 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 super::{agreement::Proven, prefix_map::PrefixMap, section::SectionAuthorityProvider};
use bls_signature_aggregator::Proof;
use serde::{Deserialize, Serialize};
use std::borrow::Borrow;
use xor_name::Prefix;

/// Container for storing information about other sections in the network.
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct Network {
// Other sections: maps section prefixes to their latest signed section authority providers.
pub sections: PrefixMap<OtherSection>,
}

#[derive(Clone, Eq, PartialEq, Hash, Debug, Serialize, Deserialize)]
pub struct OtherSection {
// If this is signed by our section, then `key_proof` is `None`. If this is signed by our
// sibling section, then `key_proof` contains the proof of the signing key itself signed by our
// section.
pub section_auth: Proven<SectionAuthorityProvider>,
pub key_proof: Option<Proof>,
}

impl Borrow<Prefix> for OtherSection {
fn borrow(&self) -> &Prefix {
&self.section_auth.value.prefix
}
}
26 changes: 26 additions & 0 deletions src/node/plain_message.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Copyright 2020 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 super::Variant;
use crate::DstLocation;
use serde::{Deserialize, Serialize};
use threshold_crypto::PublicKey as BlsPublicKey;
use xor_name::XorName;

/// Section-source message without signature and proof.
#[derive(Clone, Eq, PartialEq, Serialize, Deserialize, Debug)]
pub struct PlainMessage {
/// Name in the source section.
pub src: XorName,
/// Destination location.
pub dst: DstLocation,
/// The latest key of the destination section according to the sender's knowledge.
pub dst_key: BlsPublicKey,
/// Message body.
pub variant: Variant,
}

0 comments on commit c7d8d7b

Please sign in to comment.