#![deny(unused_crate_dependencies)]
#![warn(missing_docs)]
use codec::{Decode, Encode};
use futures::prelude::*;
use parking_lot::Mutex;
use sp_consensus::SyncOracle;
use polkadot_node_network_protocol::{
peer_set::{PeerSet, ProtocolVersion},
PeerId, UnifiedReputationChange as Rep, View,
};
pub use polkadot_node_network_protocol::peer_set::{peer_sets_info, IsAuthority};
use std::{collections::HashMap, sync::Arc};
mod validator_discovery;
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::*;
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");
#[derive(Debug, Encode, Decode, Clone)]
pub(crate) enum WireMessage<M> {
#[codec(index = 1)]
ProtocolMessage(M),
#[codec(index = 2)]
ViewUpdate(View),
}
#[derive(Debug)]
pub(crate) struct PeerData {
view: View,
version: ProtocolVersion,
}
#[derive(Default, Clone)]
pub(crate) struct Shared(Arc<Mutex<SharedInner>>);
#[derive(Default)]
struct SharedInner {
local_view: Option<View>,
validation_peers: HashMap<PeerId, PeerData>,
collation_peers: HashMap<PeerId, PeerData>,
}
fn count_peers_by_version(peers: &HashMap<PeerId, PeerData>) -> HashMap<ProtocolVersion, usize> {
let mut by_version_count = HashMap::new();
for peer in peers.values() {
*(by_version_count.entry(peer.version).or_default()) += 1;
}
by_version_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<dyn SyncOracle + Send>),
Active,
}