// Copyright (C) Parity Technologies (UK) Ltd. and Dijital Kurdistan Tech Institute // This file is part of Pezkuwi. // Pezkuwi is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // Pezkuwi is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with Pezkuwi. If not, see . //! The Network Bridge Subsystem - protocol multiplexer for Pezkuwi. //! //! Split into incoming (`..In`) and outgoing (`..Out`) subsystems. #![deny(unused_crate_dependencies)] #![warn(missing_docs)] use codec::{Decode, Encode}; use futures::prelude::*; use parking_lot::Mutex; use pezsp_consensus::SyncOracle; use pezkuwi_node_network_protocol::{ peer_set::{PeerSet, ProtocolVersion}, PeerId, UnifiedReputationChange as Rep, View, }; /// Peer set info for network initialization. /// /// To be passed to [`FullNetworkConfiguration::add_notification_protocol`](). pub use pezkuwi_node_network_protocol::peer_set::{peer_sets_info, IsAuthority}; use std::{collections::HashMap, sync::Arc}; mod validator_discovery; /// Actual interfacing to the network based on the `Network` trait. /// /// Defines the `Network` trait with an implementation for an `Arc`. mod network; use self::network::Network; mod metrics; pub use self::metrics::Metrics; mod errors; pub(crate) use self::errors::Error; mod tx; pub use self::tx::*; mod rx; pub use self::rx::*; /// The maximum amount of heads a peer is allowed to have in their view at any time. /// /// We use the same limit to compute the view sent to peers locally. pub(crate) const MAX_VIEW_HEADS: usize = 5; pub(crate) const MALFORMED_MESSAGE_COST: Rep = Rep::CostMajor("Malformed Network-bridge message"); pub(crate) const UNCONNECTED_PEERSET_COST: Rep = Rep::CostMinor("Message sent to un-connected peer-set"); pub(crate) const MALFORMED_VIEW_COST: Rep = Rep::CostMajor("Malformed view"); pub(crate) const EMPTY_VIEW_COST: Rep = Rep::CostMajor("Peer sent us an empty view"); /// Messages from and to the network. /// /// As transmitted to and received from subsystems. #[derive(Debug, Encode, Decode, Clone)] pub(crate) enum WireMessage { /// A message from a peer on a specific protocol. #[codec(index = 1)] ProtocolMessage(M), /// A view update from a peer. #[codec(index = 2)] ViewUpdate(View), } #[derive(Debug)] pub(crate) struct PeerData { /// The Latest view sent by the peer. view: View, version: ProtocolVersion, } /// Shared state between incoming and outgoing. #[derive(Default, Clone)] pub(crate) struct Shared(Arc>); #[derive(Default)] struct SharedInner { local_view: Option, validation_peers: HashMap, collation_peers: HashMap, } // Counts the number of peers that are connectioned using `version` fn count_peers_by_version(peers: &HashMap) -> HashMap { let mut by_version_count = HashMap::new(); for peer in peers.values() { *(by_version_count.entry(peer.version).or_default()) += 1; } by_version_count } // Notes the peer count fn note_peers_count(metrics: &Metrics, shared: &Shared) { let guard = shared.0.lock(); let validation_stats = count_peers_by_version(&guard.validation_peers); let collation_stats = count_peers_by_version(&guard.collation_peers); for (version, count) in validation_stats { metrics.note_peer_count(PeerSet::Validation, version, count) } for (version, count) in collation_stats { metrics.note_peer_count(PeerSet::Collation, version, count) } } pub(crate) enum Mode { Syncing(Box), Active, }