sn_interface 0.22.4

Safe Network Interfaces. Messaging and Types.
Documentation
// Copyright 2023 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 dkg;
mod join;
mod node_msgs;
mod section_sig;

use crate::messaging::AuthorityProof;
use crate::network_knowledge::node_state::RelocationTrigger;
use crate::network_knowledge::{NodeState, RelocationProof, SapCandidate};
use crate::SectionAuthorityProvider;

pub use dkg::DkgSessionId;
pub use join::JoinResponse;
pub use node_msgs::{NodeDataCmd, NodeEvent, NodeQueryResponse};
pub use section_sig::{SectionSig, SectionSigShare, SectionSigned};

use sn_consensus::{Decision, Generation, SignedVote};
use sn_sdkg::DkgSignedVote;

use bls::PublicKey as BlsPublicKey;
use ed25519::Signature;
use serde::{Deserialize, Serialize};
use std::{
    collections::BTreeMap,
    fmt::{Display, Formatter},
};
use xor_name::XorName;

/// List of section decisions since the last SAP change
pub type SectionDecisions = Vec<Decision<NodeState>>;

#[derive(Clone, PartialEq, Serialize, Deserialize, custom_debug::Debug)]
#[allow(clippy::large_enum_variant, clippy::derive_partial_eq_without_eq)]
/// Message sent over the among nodes
pub enum NodeMsg {
    /// Sent to a node to begin the relocation process of it. This is so that the node can keep
    /// polling the elders to ask them to run the relocation request through consensus.
    /// The node will continue to poll until it receives the AE Update showing that the Elders
    /// successfully decided for it to be relocated, at which point the node can start the join
    /// process at the target section, including the necessary proof from src section for it to
    /// be handled as a relocation.
    PrepareToRelocate(RelocationTrigger),
    /// Sent by the relocating node to its section to proceed the relocation process by initiating a
    /// membership change, where the node is considered `Relocated`.
    ProceedRelocation(RelocationTrigger),
    /// Sent from the section of a node that is undergoing the relocation process, containing the
    /// signed membership change. This is used by the node to complete the relocation by including
    /// it in a `proof` when joining the new section.
    CompleteRelocation(SectionSigned<NodeState>),
    /// Membership Votes, in order they should be processed in.
    MembershipVotes(Vec<SignedVote<NodeState>>),
    /// Membership Anti-Entropy request
    MembershipAE(Generation),
    /// Try to join a section in the network.
    TryJoin(Option<RelocationProof>),
    /// Response to a join request.
    JoinResponse(JoinResponse),
    /// Sent to the new elder candidates to start the DKG process, along with a sig of the DkgSessionId
    DkgStart(DkgSessionId, SectionSigShare),
    /// Sent when DKG is triggered to other participant
    DkgEphemeralPubKey {
        /// The identifier of the DKG session this message is for.
        session_id: DkgSessionId,
        /// Section authority for the DkgSessionId (if you missed the DkgStart you can trust this)
        section_auth: AuthorityProof<SectionSig>,
        /// The ephemeral bls key chosen by candidate
        pub_key: BlsPublicKey,
        /// The ed25519 signature of the candidate
        sig: Signature,
    },
    /// Votes exchanged for DKG process.
    DkgVotes {
        /// The identifier of the DKG session this message is for.
        session_id: DkgSessionId,
        /// The ephemeral bls public keys used for this Dkg round
        pub_keys: BTreeMap<XorName, (BlsPublicKey, Signature)>,
        /// The DKG message.
        votes: Vec<DkgSignedVote>,
    },
    /// Dkg Anti-Entropy request when receiving votes that are ahead of our knowledge
    DkgAE(DkgSessionId),
    /// After DKG, elder candidates request handover with this to the current elders
    /// by submitting their new SAP along with their sig share
    /// The elders can then aggregate it and confirm the SAP is valid before accepting it for Handover
    RequestHandover {
        /// SAP generated by the candidate's finished DKG session
        sap: SectionAuthorityProvider,
        /// BLS sig share of the candidate over the SAP
        sig_share: SectionSigShare,
    },
    /// Section handover consensus vote message
    HandoverVotes(Vec<SignedVote<SapCandidate>>),
    /// Handover Anti-Entropy request
    HandoverAE(Generation),
    /// After Handover consensus, the elders inform the new elder candidates that they are promoted
    /// The candidates can aggregate the sig_share to obtain SectionSigned proof that they are promoted
    SectionHandoverPromotion {
        /// The promoted SAP (signed by themselves)
        sap: SectionSigned<SectionAuthorityProvider>,
        /// BLS signature share of an Elder over the sap's pubkey
        sig_share: SectionSigShare,
    },
    /// After Handover consensus, the elders inform the new elder candidates that they are promoted
    /// The candidates can aggregate the sig_shares to obtain SectionSigned proof that they are promoted
    SectionSplitPromotion {
        /// The promoted SAP of section 0 (signed by themselves)
        sap0: SectionSigned<SectionAuthorityProvider>,
        /// BLS signature share of an Elder over the sap0's pubkey
        sig_share0: SectionSigShare,
        /// The promoted SAP of section 1 (signed by themselves)
        sap1: SectionSigned<SectionAuthorityProvider>,
        /// BLS signature share of an Elder over the sap1's pubkey
        sig_share1: SectionSigShare,
    },
    /// Elders propose voting nodes off
    /// Once fully aggregated in the SectionStateVote aggregator, the proposal is accepted
    ProposeNodeOff {
        vote_node_off: NodeState,
        /// BLS signature share of an Elder over the vote
        sig_share: SectionSigShare,
    },
    /// Node events are Node to Elder events about something that happened on a Node.
    NodeEvent(NodeEvent),
    /// Data cmds are orders to perform some data operation, only sent internally in the network.
    NodeDataCmd(NodeDataCmd),
}

impl NodeMsg {
    pub fn is_join(&self) -> bool {
        // we could also differentiate, say if it's a relocation
        matches!(self, NodeMsg::TryJoin(_))
    }
}

impl Display for NodeMsg {
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
        match self {
            Self::PrepareToRelocate { .. } => write!(f, "NodeMsg::PrepareToRelocate"),
            Self::ProceedRelocation { .. } => write!(f, "NodeMsg::ProceedRelocation"),
            Self::CompleteRelocation { .. } => write!(f, "NodeMsg::CompleteRelocation"),
            Self::MembershipVotes { .. } => write!(f, "NodeMsg::MembershipVotes"),
            Self::MembershipAE { .. } => write!(f, "NodeMsg::MembershipAE"),
            Self::TryJoin(_) => write!(f, "NodeMsg::TryJoin"),
            Self::JoinResponse { .. } => write!(f, "NodeMsg::JoinResponse"),
            Self::DkgStart { .. } => write!(f, "NodeMsg::DkgStart"),
            Self::DkgEphemeralPubKey { .. } => write!(f, "NodeMsg::DkgEphemeralPubKey"),
            Self::DkgVotes { .. } => write!(f, "NodeMsg::DkgVotes"),
            Self::DkgAE { .. } => write!(f, "NodeMsg::DkgAE"),
            Self::RequestHandover { .. } => write!(f, "NodeMsg::RequestHandover"),
            Self::HandoverVotes { .. } => write!(f, "NodeMsg::HandoverVotes"),
            Self::HandoverAE { .. } => write!(f, "NodeMsg::HandoverAE"),
            Self::SectionHandoverPromotion { .. } => write!(f, "NodeMsg::SectionHandoverPromotion"),
            Self::SectionSplitPromotion { .. } => write!(f, "NodeMsg::SectionSplitPromotion"),
            Self::ProposeNodeOff { .. } => write!(f, "NodeMsg::ProposeSectionState"),
            Self::NodeEvent { .. } => write!(f, "NodeMsg::NodeEvent"),
            Self::NodeDataCmd { .. } => write!(f, "NodeMsg::NodeCmd"),
        }
    }
}