referrerpolicy=no-referrer-when-downgrade

polkadot_network_bridge/
lib.rs

1// Copyright (C) Parity Technologies (UK) Ltd.
2// This file is part of Polkadot.
3
4// Polkadot is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8
9// Polkadot is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12// GNU General Public License for more details.
13
14// You should have received a copy of the GNU General Public License
15// along with Polkadot.  If not, see <http://www.gnu.org/licenses/>.
16
17//! The Network Bridge Subsystem - protocol multiplexer for Polkadot.
18//!
19//! Split into incoming (`..In`) and outgoing (`..Out`) subsystems.
20
21#![deny(unused_crate_dependencies)]
22#![warn(missing_docs)]
23
24use codec::{Decode, Encode};
25use futures::prelude::*;
26use parking_lot::Mutex;
27
28use sp_consensus::SyncOracle;
29
30use polkadot_node_network_protocol::{
31	peer_set::{PeerSet, ProtocolVersion},
32	PeerId, UnifiedReputationChange as Rep, View,
33};
34
35/// Peer set info for network initialization.
36///
37/// To be passed to [`FullNetworkConfiguration::add_notification_protocol`]().
38pub use polkadot_node_network_protocol::peer_set::{peer_sets_info, IsAuthority};
39
40use std::{collections::HashMap, sync::Arc};
41
42mod validator_discovery;
43
44/// Actual interfacing to the network based on the `Network` trait.
45///
46/// Defines the `Network` trait with an implementation for an `Arc<NetworkService>`.
47mod network;
48use self::network::Network;
49
50mod metrics;
51pub use self::metrics::Metrics;
52
53mod errors;
54pub(crate) use self::errors::Error;
55
56mod tx;
57pub use self::tx::*;
58
59mod rx;
60pub use self::rx::*;
61
62/// The maximum amount of heads a peer is allowed to have in their view at any time.
63///
64/// We use the same limit to compute the view sent to peers locally.
65pub(crate) const MAX_VIEW_HEADS: usize = 5;
66
67pub(crate) const MALFORMED_MESSAGE_COST: Rep = Rep::CostMajor("Malformed Network-bridge message");
68pub(crate) const UNCONNECTED_PEERSET_COST: Rep =
69	Rep::CostMinor("Message sent to un-connected peer-set");
70pub(crate) const MALFORMED_VIEW_COST: Rep = Rep::CostMajor("Malformed view");
71pub(crate) const EMPTY_VIEW_COST: Rep = Rep::CostMajor("Peer sent us an empty view");
72
73/// Messages from and to the network.
74///
75/// As transmitted to and received from subsystems.
76#[derive(Debug, Encode, Decode, Clone)]
77pub(crate) enum WireMessage<M> {
78	/// A message from a peer on a specific protocol.
79	#[codec(index = 1)]
80	ProtocolMessage(M),
81	/// A view update from a peer.
82	#[codec(index = 2)]
83	ViewUpdate(View),
84}
85
86#[derive(Debug)]
87pub(crate) struct PeerData {
88	/// The Latest view sent by the peer.
89	view: View,
90	version: ProtocolVersion,
91}
92
93/// Shared state between incoming and outgoing.
94
95#[derive(Default, Clone)]
96pub(crate) struct Shared(Arc<Mutex<SharedInner>>);
97
98#[derive(Default)]
99struct SharedInner {
100	local_view: Option<View>,
101	validation_peers: HashMap<PeerId, PeerData>,
102	collation_peers: HashMap<PeerId, PeerData>,
103}
104
105// Counts the number of peers that are connectioned using `version`
106fn count_peers_by_version(peers: &HashMap<PeerId, PeerData>) -> HashMap<ProtocolVersion, usize> {
107	let mut by_version_count = HashMap::new();
108	for peer in peers.values() {
109		*(by_version_count.entry(peer.version).or_default()) += 1;
110	}
111	by_version_count
112}
113
114// Notes the peer count
115fn note_peers_count(metrics: &Metrics, shared: &Shared) {
116	let guard = shared.0.lock();
117	let validation_stats = count_peers_by_version(&guard.validation_peers);
118	let collation_stats = count_peers_by_version(&guard.collation_peers);
119
120	for (version, count) in validation_stats {
121		metrics.note_peer_count(PeerSet::Validation, version, count)
122	}
123
124	for (version, count) in collation_stats {
125		metrics.note_peer_count(PeerSet::Collation, version, count)
126	}
127}
128
129pub(crate) enum Mode {
130	Syncing(Box<dyn SyncOracle + Send>),
131	Active,
132}