polkadot_node_subsystem_types/messages/network_bridge_event.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
17use std::collections::HashSet;
18
19pub use sc_network::ReputationChange;
20pub use sc_network_types::PeerId;
21
22use polkadot_node_network_protocol::{
23 grid_topology::SessionGridTopology, peer_set::ProtocolVersion, ObservedRole, OurView, View,
24 WrongVariant,
25};
26use polkadot_primitives::{AuthorityDiscoveryId, SessionIndex, ValidatorIndex};
27
28/// A struct indicating new gossip topology.
29#[derive(Debug, Clone, PartialEq)]
30pub struct NewGossipTopology {
31 /// The session index this topology corresponds to.
32 pub session: SessionIndex,
33 /// The topology itself.
34 pub topology: SessionGridTopology,
35 /// The local validator index, if any.
36 pub local_index: Option<ValidatorIndex>,
37}
38
39/// Events from network.
40#[derive(Debug, Clone, PartialEq)]
41pub enum NetworkBridgeEvent<M> {
42 /// A peer has connected.
43 PeerConnected(PeerId, ObservedRole, ProtocolVersion, Option<HashSet<AuthorityDiscoveryId>>),
44
45 /// A peer has disconnected.
46 PeerDisconnected(PeerId),
47
48 /// Our neighbors in the new gossip topology for the session.
49 /// We're not necessarily connected to all of them.
50 ///
51 /// This message is issued only on the validation peer set.
52 ///
53 /// Note, that the distribution subsystems need to handle the last
54 /// view update of the newly added gossip peers manually.
55 NewGossipTopology(NewGossipTopology),
56
57 /// Peer has sent a message.
58 PeerMessage(PeerId, M),
59
60 /// Peer's `View` has changed.
61 PeerViewChange(PeerId, View),
62
63 /// Our view has changed.
64 OurViewChange(OurView),
65
66 /// The authority discovery session key has been rotated.
67 UpdatedAuthorityIds(PeerId, HashSet<AuthorityDiscoveryId>),
68}
69
70impl<M> NetworkBridgeEvent<M> {
71 /// Focus an overarching network-bridge event into some more specific variant.
72 ///
73 /// This tries to transform M in `PeerMessage` to a message type specific to a subsystem.
74 /// It is used to dispatch events coming from a peer set to the various subsystems that are
75 /// handled within that peer set. More concretely a `ValidationProtocol` will be transformed
76 /// for example into a `BitfieldDistributionMessage` in case of the `BitfieldDistribution`
77 /// constructor.
78 ///
79 /// Therefore a `NetworkBridgeEvent<ValidationProtocol>` will become for example a
80 /// `NetworkBridgeEvent<BitfieldDistributionMessage>`, with the more specific message type
81 /// `BitfieldDistributionMessage`.
82 ///
83 /// This acts as a call to `clone`, except in the case where the event is a message event,
84 /// in which case the clone can be expensive and it only clones if the message type can
85 /// be focused.
86 pub fn focus<'a, T>(&'a self) -> Result<NetworkBridgeEvent<T>, WrongVariant>
87 where
88 T: 'a + Clone,
89 T: TryFrom<&'a M, Error = WrongVariant>,
90 {
91 Ok(match *self {
92 NetworkBridgeEvent::PeerMessage(ref peer, ref msg) =>
93 NetworkBridgeEvent::PeerMessage(*peer, T::try_from(msg)?),
94 NetworkBridgeEvent::PeerConnected(
95 ref peer,
96 ref role,
97 ref version,
98 ref authority_id,
99 ) => NetworkBridgeEvent::PeerConnected(*peer, *role, *version, authority_id.clone()),
100 NetworkBridgeEvent::PeerDisconnected(ref peer) =>
101 NetworkBridgeEvent::PeerDisconnected(*peer),
102 NetworkBridgeEvent::NewGossipTopology(ref topology) =>
103 NetworkBridgeEvent::NewGossipTopology(topology.clone()),
104 NetworkBridgeEvent::PeerViewChange(ref peer, ref view) =>
105 NetworkBridgeEvent::PeerViewChange(*peer, view.clone()),
106 NetworkBridgeEvent::OurViewChange(ref view) =>
107 NetworkBridgeEvent::OurViewChange(view.clone()),
108 NetworkBridgeEvent::UpdatedAuthorityIds(ref peer, ref authority_ids) =>
109 NetworkBridgeEvent::UpdatedAuthorityIds(*peer, authority_ids.clone()),
110 })
111 }
112}