referrerpolicy=no-referrer-when-downgrade

sc_network_gossip/
validator.rs

1// This file is part of Substrate.
2
3// Copyright (C) Parity Technologies (UK) Ltd.
4// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0
5
6// This program is free software: you can redistribute it and/or modify
7// it under the terms of the GNU General Public License as published by
8// the Free Software Foundation, either version 3 of the License, or
9// (at your option) any later version.
10
11// This program is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
15
16// You should have received a copy of the GNU General Public License
17// along with this program. If not, see <https://www.gnu.org/licenses/>.
18
19use sc_network_common::role::ObservedRole;
20use sc_network_types::PeerId;
21use sp_runtime::traits::Block as BlockT;
22
23/// Validates consensus messages.
24pub trait Validator<B: BlockT>: Send + Sync {
25	/// New peer is connected.
26	fn new_peer(&self, _context: &mut dyn ValidatorContext<B>, _who: &PeerId, _role: ObservedRole) {
27	}
28
29	/// New connection is dropped.
30	fn peer_disconnected(&self, _context: &mut dyn ValidatorContext<B>, _who: &PeerId) {}
31
32	/// Validate consensus message.
33	fn validate(
34		&self,
35		context: &mut dyn ValidatorContext<B>,
36		sender: &PeerId,
37		data: &[u8],
38	) -> ValidationResult<B::Hash>;
39
40	/// Produce a closure for validating messages on a given topic.
41	fn message_expired<'a>(&'a self) -> Box<dyn FnMut(B::Hash, &[u8]) -> bool + 'a> {
42		Box::new(move |_topic, _data| false)
43	}
44
45	/// Produce a closure for filtering egress messages.
46	fn message_allowed<'a>(
47		&'a self,
48	) -> Box<dyn FnMut(&PeerId, MessageIntent, &B::Hash, &[u8]) -> bool + 'a> {
49		Box::new(move |_who, _intent, _topic, _data| true)
50	}
51}
52
53/// Validation context. Allows reacting to incoming messages by sending out further messages.
54pub trait ValidatorContext<B: BlockT> {
55	/// Broadcast all messages with given topic to peers that do not have it yet.
56	fn broadcast_topic(&mut self, topic: B::Hash, force: bool);
57	/// Broadcast a message to all peers that have not received it previously.
58	fn broadcast_message(&mut self, topic: B::Hash, message: Vec<u8>, force: bool);
59	/// Send addressed message to a peer.
60	fn send_message(&mut self, who: &PeerId, message: Vec<u8>);
61	/// Send all messages with given topic to a peer.
62	fn send_topic(&mut self, who: &PeerId, topic: B::Hash, force: bool);
63}
64
65/// The reason for sending out the message.
66#[derive(Eq, PartialEq, Copy, Clone)]
67#[cfg_attr(test, derive(Debug))]
68pub enum MessageIntent {
69	/// Requested broadcast.
70	Broadcast,
71	/// Requested broadcast to all peers.
72	ForcedBroadcast,
73	/// Periodic rebroadcast of all messages to all peers.
74	PeriodicRebroadcast,
75}
76
77/// Message validation result.
78pub enum ValidationResult<H> {
79	/// Message should be stored and propagated under given topic.
80	ProcessAndKeep(H),
81	/// Message should be processed, but not propagated.
82	ProcessAndDiscard(H),
83	/// Message should be ignored.
84	Discard,
85}
86
87/// A gossip message validator that discards all messages.
88pub struct DiscardAll;
89
90impl<B: BlockT> Validator<B> for DiscardAll {
91	fn validate(
92		&self,
93		_context: &mut dyn ValidatorContext<B>,
94		_sender: &PeerId,
95		_data: &[u8],
96	) -> ValidationResult<B::Hash> {
97		ValidationResult::Discard
98	}
99
100	fn message_expired<'a>(&'a self) -> Box<dyn FnMut(B::Hash, &[u8]) -> bool + 'a> {
101		Box::new(move |_topic, _data| true)
102	}
103
104	fn message_allowed<'a>(
105		&'a self,
106	) -> Box<dyn FnMut(&PeerId, MessageIntent, &B::Hash, &[u8]) -> bool + 'a> {
107		Box::new(move |_who, _intent, _topic, _data| false)
108	}
109}