frame_support/traits/
validation.rs

1// This file is part of Substrate.
2
3// Copyright (C) Parity Technologies (UK) Ltd.
4// SPDX-License-Identifier: Apache-2.0
5
6// Licensed under the Apache License, Version 2.0 (the "License");
7// you may not use this file except in compliance with the License.
8// You may obtain a copy of the License at
9//
10// 	http://www.apache.org/licenses/LICENSE-2.0
11//
12// Unless required by applicable law or agreed to in writing, software
13// distributed under the License is distributed on an "AS IS" BASIS,
14// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15// See the License for the specific language governing permissions and
16// limitations under the License.
17
18//! Traits for dealing with validation and validators.
19
20use crate::{dispatch::Parameter, weights::Weight};
21use alloc::{vec, vec::Vec};
22use codec::{Codec, Decode, MaxEncodedLen};
23use sp_runtime::{
24	traits::{Convert, Zero},
25	BoundToRuntimeAppPublic, ConsensusEngineId, Permill, RuntimeAppPublic,
26};
27use sp_staking::SessionIndex;
28
29/// A trait for online node inspection in a session.
30///
31/// Something that can give information about the current validator set.
32pub trait ValidatorSet<AccountId> {
33	/// Type for representing validator id in a session.
34	type ValidatorId: Parameter + MaxEncodedLen;
35	/// A type for converting `AccountId` to `ValidatorId`.
36	type ValidatorIdOf: Convert<AccountId, Option<Self::ValidatorId>>;
37
38	/// Returns current session index.
39	fn session_index() -> SessionIndex;
40
41	/// Returns the active set of validators.
42	fn validators() -> Vec<Self::ValidatorId>;
43}
44
45/// [`ValidatorSet`] combined with an identification.
46pub trait ValidatorSetWithIdentification<AccountId>: ValidatorSet<AccountId> {
47	/// Full identification of `ValidatorId`.
48	type Identification: Parameter;
49	/// A type for converting `ValidatorId` to `Identification`.
50	type IdentificationOf: Convert<Self::ValidatorId, Option<Self::Identification>>;
51}
52
53/// A trait for finding the author of a block header based on the `PreRuntime` digests contained
54/// within it.
55pub trait FindAuthor<Author> {
56	/// Find the author of a block based on the pre-runtime digests.
57	fn find_author<'a, I>(digests: I) -> Option<Author>
58	where
59		I: 'a + IntoIterator<Item = (ConsensusEngineId, &'a [u8])>;
60}
61
62impl<A> FindAuthor<A> for () {
63	fn find_author<'a, I>(_: I) -> Option<A>
64	where
65		I: 'a + IntoIterator<Item = (ConsensusEngineId, &'a [u8])>,
66	{
67		None
68	}
69}
70
71/// A trait for verifying the seal of a header and returning the author.
72pub trait VerifySeal<Header, Author> {
73	/// Verify a header and return the author, if any.
74	fn verify_seal(header: &Header) -> Result<Option<Author>, &'static str>;
75}
76
77/// A session handler for specific key type.
78pub trait OneSessionHandler<ValidatorId>: BoundToRuntimeAppPublic {
79	/// The key type expected.
80	type Key: Decode + RuntimeAppPublic;
81
82	/// The given validator set will be used for the genesis session.
83	/// It is guaranteed that the given validator set will also be used
84	/// for the second session, therefore the first call to `on_new_session`
85	/// should provide the same validator set.
86	fn on_genesis_session<'a, I: 'a>(validators: I)
87	where
88		I: Iterator<Item = (&'a ValidatorId, Self::Key)>,
89		ValidatorId: 'a;
90
91	/// Session set has changed; act appropriately. Note that this can be called
92	/// before initialization of your module.
93	///
94	/// `changed` is true when at least one of the session keys
95	/// or the underlying economic identities/distribution behind one the
96	/// session keys has changed, false otherwise.
97	///
98	/// The `validators` are the validators of the incoming session, and `queued_validators`
99	/// will follow.
100	fn on_new_session<'a, I: 'a>(changed: bool, validators: I, queued_validators: I)
101	where
102		I: Iterator<Item = (&'a ValidatorId, Self::Key)>,
103		ValidatorId: 'a;
104
105	/// A notification for end of the session.
106	///
107	/// Note it is triggered before any `SessionManager::end_session` handlers,
108	/// so we can still affect the validator set.
109	fn on_before_session_ending() {}
110
111	/// A validator got disabled. Act accordingly until a new session begins.
112	fn on_disabled(_validator_index: u32);
113}
114
115/// Something that can estimate at which block the next session rotation will happen (i.e. a new
116/// session starts).
117///
118/// The accuracy of the estimates is dependent on the specific implementation, but in order to get
119/// the best estimate possible these methods should be called throughout the duration of the session
120/// (rather than calling once and storing the result).
121///
122/// This should be the same logical unit that dictates `ShouldEndSession` to the session module. No
123/// assumptions are made about the scheduling of the sessions.
124pub trait EstimateNextSessionRotation<BlockNumber> {
125	/// Return the average length of a session.
126	///
127	/// This may or may not be accurate.
128	fn average_session_length() -> BlockNumber;
129
130	/// Return an estimate of the current session progress.
131	///
132	/// None should be returned if the estimation fails to come to an answer.
133	fn estimate_current_session_progress(now: BlockNumber) -> (Option<Permill>, Weight);
134
135	/// Return the block number at which the next session rotation is estimated to happen.
136	///
137	/// None should be returned if the estimation fails to come to an answer.
138	fn estimate_next_session_rotation(now: BlockNumber) -> (Option<BlockNumber>, Weight);
139}
140
141impl<BlockNumber: Zero> EstimateNextSessionRotation<BlockNumber> for () {
142	fn average_session_length() -> BlockNumber {
143		Zero::zero()
144	}
145
146	fn estimate_current_session_progress(_: BlockNumber) -> (Option<Permill>, Weight) {
147		(None, Zero::zero())
148	}
149
150	fn estimate_next_session_rotation(_: BlockNumber) -> (Option<BlockNumber>, Weight) {
151		(None, Zero::zero())
152	}
153}
154
155/// Something that can estimate at which block scheduling of the next session will happen (i.e when
156/// we will try to fetch new validators).
157///
158/// This only refers to the point when we fetch the next session details and not when we enact them
159/// (for enactment there's `EstimateNextSessionRotation`). With `pallet-session` this should be
160/// triggered whenever `SessionManager::new_session` is called.
161///
162/// For example, if we are using a staking module this would be the block when the session module
163/// would ask staking what the next validator set will be, as such this must always be implemented
164/// by the session module.
165pub trait EstimateNextNewSession<BlockNumber> {
166	/// Return the average length of a session.
167	///
168	/// This may or may not be accurate.
169	fn average_session_length() -> BlockNumber;
170
171	/// Return the block number at which the next new session is estimated to happen.
172	///
173	/// None should be returned if the estimation fails to come to an answer.
174	fn estimate_next_new_session(_: BlockNumber) -> (Option<BlockNumber>, Weight);
175}
176
177impl<BlockNumber: Zero> EstimateNextNewSession<BlockNumber> for () {
178	fn average_session_length() -> BlockNumber {
179		Zero::zero()
180	}
181
182	fn estimate_next_new_session(_: BlockNumber) -> (Option<BlockNumber>, Weight) {
183		(None, Zero::zero())
184	}
185}
186
187/// Something which can compute and check proofs of
188/// a historical key owner and return full identification data of that
189/// key owner.
190pub trait KeyOwnerProofSystem<Key> {
191	/// The proof of membership itself.
192	type Proof: Codec;
193	/// The full identification of a key owner and the stash account.
194	type IdentificationTuple: Codec;
195
196	/// Prove membership of a key owner in the current block-state.
197	///
198	/// This should typically only be called off-chain, since it may be
199	/// computationally heavy.
200	///
201	/// Returns `Some` iff the key owner referred to by the given `key` is a
202	/// member of the current set.
203	fn prove(key: Key) -> Option<Self::Proof>;
204
205	/// Check a proof of membership on-chain. Return `Some` iff the proof is
206	/// valid and recent enough to check.
207	fn check_proof(key: Key, proof: Self::Proof) -> Option<Self::IdentificationTuple>;
208}
209
210impl<Key> KeyOwnerProofSystem<Key> for () {
211	// The proof and identification tuples is any bottom type to guarantee that the methods of this
212	// implementation can never be called or return anything other than `None`.
213	type Proof = sp_core::Void;
214	type IdentificationTuple = sp_core::Void;
215
216	fn prove(_key: Key) -> Option<Self::Proof> {
217		None
218	}
219
220	fn check_proof(_key: Key, _proof: Self::Proof) -> Option<Self::IdentificationTuple> {
221		None
222	}
223}
224
225/// Trait to be used by block producing consensus engine modules to determine
226/// how late the current block is (e.g. in a slot-based proposal mechanism how
227/// many slots were skipped since the previous block).
228pub trait Lateness<N> {
229	/// Returns a generic measure of how late the current block is compared to
230	/// its parent.
231	fn lateness(&self) -> N;
232}
233
234impl<N: Zero> Lateness<N> for () {
235	fn lateness(&self) -> N {
236		Zero::zero()
237	}
238}
239
240/// Implementors of this trait provide information about whether or not some validator has
241/// been registered with them. The [Session module](../../pallet_session/index.html) is an
242/// implementor.
243pub trait ValidatorRegistration<ValidatorId> {
244	/// Returns true if the provided validator ID has been registered with the implementing runtime
245	/// module
246	fn is_registered(id: &ValidatorId) -> bool;
247}
248
249/// Trait used to check whether a given validator is currently disabled and should not be
250/// participating in consensus (e.g. because they equivocated).
251pub trait DisabledValidators {
252	/// Returns true if the given validator is disabled.
253	fn is_disabled(index: u32) -> bool;
254
255	/// Returns all disabled validators
256	fn disabled_validators() -> Vec<u32>;
257}
258
259impl DisabledValidators for () {
260	fn is_disabled(_index: u32) -> bool {
261		false
262	}
263
264	fn disabled_validators() -> Vec<u32> {
265		vec![]
266	}
267}