referrerpolicy=no-referrer-when-downgrade

sc_consensus_grandpa/
authorities.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
19//! Utilities for dealing with authorities, authority sets, and handoffs.
20
21use std::{cmp::Ord, fmt::Debug, ops::Add};
22
23use codec::{Decode, Encode};
24use finality_grandpa::voter_set::VoterSet;
25use fork_tree::{FilterAction, ForkTree};
26use log::debug;
27use parking_lot::MappedMutexGuard;
28use sc_consensus::shared_data::{SharedData, SharedDataLocked};
29use sc_telemetry::{telemetry, TelemetryHandle, CONSENSUS_INFO};
30use sp_consensus_grandpa::{AuthorityId, AuthorityList};
31
32use crate::{SetId, LOG_TARGET};
33
34/// Error type returned on operations on the `AuthoritySet`.
35#[derive(Debug, thiserror::Error)]
36pub enum Error<N, E> {
37	#[error("Invalid authority set, either empty or with an authority weight set to 0.")]
38	InvalidAuthoritySet,
39	#[error("Client error during ancestry lookup: {0}")]
40	Client(E),
41	#[error("Duplicate authority set change.")]
42	DuplicateAuthoritySetChange,
43	#[error("Multiple pending forced authority set changes are not allowed.")]
44	MultiplePendingForcedAuthoritySetChanges,
45	#[error(
46		"A pending forced authority set change could not be applied since it must be applied \
47		after the pending standard change at #{0}"
48	)]
49	ForcedAuthoritySetChangeDependencyUnsatisfied(N),
50	#[error("Invalid operation in the pending changes tree: {0}")]
51	ForkTree(fork_tree::Error<E>),
52}
53
54impl<N, E> From<fork_tree::Error<E>> for Error<N, E> {
55	fn from(err: fork_tree::Error<E>) -> Error<N, E> {
56		match err {
57			fork_tree::Error::Client(err) => Error::Client(err),
58			fork_tree::Error::Duplicate => Error::DuplicateAuthoritySetChange,
59			err => Error::ForkTree(err),
60		}
61	}
62}
63
64impl<N, E: std::error::Error> From<E> for Error<N, E> {
65	fn from(err: E) -> Error<N, E> {
66		Error::Client(err)
67	}
68}
69
70/// A shared authority set.
71pub struct SharedAuthoritySet<H, N> {
72	inner: SharedData<AuthoritySet<H, N>>,
73}
74
75impl<H, N> Clone for SharedAuthoritySet<H, N> {
76	fn clone(&self) -> Self {
77		SharedAuthoritySet { inner: self.inner.clone() }
78	}
79}
80
81impl<H, N> SharedAuthoritySet<H, N> {
82	/// Returns access to the [`AuthoritySet`].
83	pub(crate) fn inner(&self) -> MappedMutexGuard<'_, AuthoritySet<H, N>> {
84		self.inner.shared_data()
85	}
86
87	/// Returns access to the [`AuthoritySet`] and locks it.
88	///
89	/// For more information see [`SharedDataLocked`].
90	pub(crate) fn inner_locked(&self) -> SharedDataLocked<'_, AuthoritySet<H, N>> {
91		self.inner.shared_data_locked()
92	}
93}
94
95impl<H: Eq, N> SharedAuthoritySet<H, N>
96where
97	N: Add<Output = N> + Ord + Clone + Debug,
98	H: Clone + Debug,
99{
100	/// Get the earliest limit-block number that's higher or equal to the given
101	/// min number, if any.
102	pub(crate) fn current_limit(&self, min: N) -> Option<N> {
103		self.inner().current_limit(min)
104	}
105
106	/// Get the current set ID. This is incremented every time the set changes.
107	pub fn set_id(&self) -> u64 {
108		self.inner().set_id
109	}
110
111	/// Get the current authorities and their weights (for the current set ID).
112	pub fn current_authorities(&self) -> VoterSet<AuthorityId> {
113		self.inner().current_voter_set()
114	}
115
116	/// Clone the inner `AuthoritySet`.
117	pub fn clone_inner(&self) -> AuthoritySet<H, N> {
118		self.inner().clone()
119	}
120
121	/// Clone the inner `AuthoritySetChanges`.
122	pub fn authority_set_changes(&self) -> AuthoritySetChanges<N> {
123		self.inner().authority_set_changes.clone()
124	}
125}
126
127impl<H, N> From<AuthoritySet<H, N>> for SharedAuthoritySet<H, N> {
128	fn from(set: AuthoritySet<H, N>) -> Self {
129		SharedAuthoritySet { inner: SharedData::new(set) }
130	}
131}
132
133/// Status of the set after changes were applied.
134#[derive(Debug)]
135pub(crate) struct Status<H, N> {
136	/// Whether internal changes were made.
137	pub(crate) changed: bool,
138	/// `Some` when underlying authority set has changed, containing the
139	/// block where that set changed.
140	pub(crate) new_set_block: Option<(H, N)>,
141}
142
143/// A set of authorities.
144#[derive(Debug, Clone, Encode, Decode, PartialEq)]
145pub struct AuthoritySet<H, N> {
146	/// The current active authorities.
147	pub(crate) current_authorities: AuthorityList,
148	/// The current set id.
149	pub(crate) set_id: u64,
150	/// Tree of pending standard changes across forks. Standard changes are
151	/// enacted on finality and must be enacted (i.e. finalized) in-order across
152	/// a given branch
153	pub(crate) pending_standard_changes: ForkTree<H, N, PendingChange<H, N>>,
154	/// Pending forced changes across different forks (at most one per fork).
155	/// Forced changes are enacted on block depth (not finality), for this
156	/// reason only one forced change should exist per fork. When trying to
157	/// apply forced changes we keep track of any pending standard changes that
158	/// they may depend on, this is done by making sure that any pending change
159	/// that is an ancestor of the forced changed and its effective block number
160	/// is lower than the last finalized block (as signaled in the forced
161	/// change) must be applied beforehand.
162	pending_forced_changes: Vec<PendingChange<H, N>>,
163	/// Track at which blocks the set id changed. This is useful when we need to prove finality for
164	/// a given block since we can figure out what set the block belongs to and when the set
165	/// started/ended.
166	pub(crate) authority_set_changes: AuthoritySetChanges<N>,
167}
168
169impl<H, N> AuthoritySet<H, N>
170where
171	H: PartialEq,
172	N: Ord + Clone,
173{
174	// authority sets must be non-empty and all weights must be greater than 0
175	fn invalid_authority_list(authorities: &AuthorityList) -> bool {
176		authorities.is_empty() || authorities.iter().any(|(_, w)| *w == 0)
177	}
178
179	/// Get a genesis set with given authorities.
180	pub(crate) fn genesis(initial: AuthorityList) -> Option<Self> {
181		if Self::invalid_authority_list(&initial) {
182			return None;
183		}
184
185		Some(AuthoritySet {
186			current_authorities: initial,
187			set_id: 0,
188			pending_standard_changes: ForkTree::new(),
189			pending_forced_changes: Vec::new(),
190			authority_set_changes: AuthoritySetChanges::empty(),
191		})
192	}
193
194	/// Create a new authority set.
195	pub(crate) fn new(
196		authorities: AuthorityList,
197		set_id: u64,
198		pending_standard_changes: ForkTree<H, N, PendingChange<H, N>>,
199		pending_forced_changes: Vec<PendingChange<H, N>>,
200		authority_set_changes: AuthoritySetChanges<N>,
201	) -> Option<Self> {
202		if Self::invalid_authority_list(&authorities) {
203			return None;
204		}
205
206		Some(AuthoritySet {
207			current_authorities: authorities,
208			set_id,
209			pending_standard_changes,
210			pending_forced_changes,
211			authority_set_changes,
212		})
213	}
214
215	/// Get the current set id and a reference to the current authority set.
216	pub(crate) fn current(&self) -> (u64, &[(AuthorityId, u64)]) {
217		(self.set_id, &self.current_authorities[..])
218	}
219
220	/// Get the current authorities as a [`VoterSet`].
221	pub(crate) fn current_voter_set(&self) -> VoterSet<AuthorityId> {
222		VoterSet::new(self.current_authorities.iter().cloned()).expect(
223			"current_authorities is non-empty and weights are non-zero; \
224			 constructor and all mutating operations on `AuthoritySet` ensure this; \
225			 qed.",
226		)
227	}
228
229	/// Revert to a specified block given its `hash` and `number`.
230	/// This removes all the authority set changes that were announced after
231	/// the revert point.
232	/// Revert point is identified by `number` and `hash`.
233	pub(crate) fn revert<F, E>(&mut self, hash: H, number: N, is_descendent_of: &F)
234	where
235		F: Fn(&H, &H) -> Result<bool, E>,
236	{
237		let filter = |node_hash: &H, node_num: &N, _: &PendingChange<H, N>| {
238			if number >= *node_num &&
239				(is_descendent_of(node_hash, &hash).unwrap_or_default() || *node_hash == hash)
240			{
241				// Continue the search in this subtree.
242				FilterAction::KeepNode
243			} else if number < *node_num && is_descendent_of(&hash, node_hash).unwrap_or_default() {
244				// Found a node to be removed.
245				FilterAction::Remove
246			} else {
247				// Not a parent or child of the one we're looking for, stop processing this branch.
248				FilterAction::KeepTree
249			}
250		};
251
252		// Remove standard changes.
253		let _ = self.pending_standard_changes.drain_filter(&filter);
254
255		// Remove forced changes.
256		self.pending_forced_changes
257			.retain(|change| !is_descendent_of(&hash, &change.canon_hash).unwrap_or_default());
258	}
259}
260
261impl<H: Eq, N> AuthoritySet<H, N>
262where
263	N: Add<Output = N> + Ord + Clone + Debug,
264	H: Clone + Debug,
265{
266	/// Returns the block hash and height at which the next pending change in
267	/// the given chain (i.e. it includes `best_hash`) was signalled, `None` if
268	/// there are no pending changes for the given chain.
269	///
270	/// This is useful since we know that when a change is signalled the
271	/// underlying runtime authority set management module (e.g. session module)
272	/// has updated its internal state (e.g. a new session started).
273	pub(crate) fn next_change<F, E>(
274		&self,
275		best_hash: &H,
276		is_descendent_of: &F,
277	) -> Result<Option<(H, N)>, Error<N, E>>
278	where
279		F: Fn(&H, &H) -> Result<bool, E>,
280		E: std::error::Error,
281	{
282		let mut forced = None;
283		for change in &self.pending_forced_changes {
284			if is_descendent_of(&change.canon_hash, best_hash)? {
285				forced = Some((change.canon_hash.clone(), change.canon_height.clone()));
286				break;
287			}
288		}
289
290		let mut standard = None;
291		for (_, _, change) in self.pending_standard_changes.roots() {
292			if is_descendent_of(&change.canon_hash, best_hash)? {
293				standard = Some((change.canon_hash.clone(), change.canon_height.clone()));
294				break;
295			}
296		}
297
298		let earliest = match (forced, standard) {
299			(Some(forced), Some(standard)) => {
300				Some(if forced.1 < standard.1 { forced } else { standard })
301			},
302			(Some(forced), None) => Some(forced),
303			(None, Some(standard)) => Some(standard),
304			(None, None) => None,
305		};
306
307		Ok(earliest)
308	}
309
310	fn add_standard_change<F, E>(
311		&mut self,
312		pending: PendingChange<H, N>,
313		is_descendent_of: &F,
314	) -> Result<(), Error<N, E>>
315	where
316		F: Fn(&H, &H) -> Result<bool, E>,
317		E: std::error::Error,
318	{
319		let hash = pending.canon_hash.clone();
320		let number = pending.canon_height.clone();
321
322		debug!(
323			target: LOG_TARGET,
324			"Inserting potential standard set change signaled at block {:?} (delayed by {:?} blocks).",
325			(&number, &hash),
326			pending.delay,
327		);
328
329		self.pending_standard_changes.import(hash, number, pending, is_descendent_of)?;
330
331		debug!(
332			target: LOG_TARGET,
333			"There are now {} alternatives for the next pending standard change (roots), and a \
334			 total of {} pending standard changes (across all forks).",
335			self.pending_standard_changes.roots().count(),
336			self.pending_standard_changes.iter().count(),
337		);
338
339		Ok(())
340	}
341
342	fn add_forced_change<F, E>(
343		&mut self,
344		pending: PendingChange<H, N>,
345		is_descendent_of: &F,
346	) -> Result<(), Error<N, E>>
347	where
348		F: Fn(&H, &H) -> Result<bool, E>,
349		E: std::error::Error,
350	{
351		for change in &self.pending_forced_changes {
352			if change.canon_hash == pending.canon_hash {
353				return Err(Error::DuplicateAuthoritySetChange);
354			}
355
356			if is_descendent_of(&change.canon_hash, &pending.canon_hash)? {
357				return Err(Error::MultiplePendingForcedAuthoritySetChanges);
358			}
359		}
360
361		// ordered first by effective number and then by signal-block number.
362		let key = (pending.effective_number(), pending.canon_height.clone());
363		let idx = self
364			.pending_forced_changes
365			.binary_search_by_key(&key, |change| {
366				(change.effective_number(), change.canon_height.clone())
367			})
368			.unwrap_or_else(|i| i);
369
370		debug!(
371			target: LOG_TARGET,
372			"Inserting potential forced set change at block {:?} (delayed by {:?} blocks).",
373			(&pending.canon_height, &pending.canon_hash),
374			pending.delay,
375		);
376
377		self.pending_forced_changes.insert(idx, pending);
378
379		debug!(
380			target: LOG_TARGET,
381			"There are now {} pending forced changes.",
382			self.pending_forced_changes.len()
383		);
384
385		Ok(())
386	}
387
388	/// Note an upcoming pending transition. Multiple pending standard changes
389	/// on the same branch can be added as long as they don't overlap. Forced
390	/// changes are restricted to one per fork. This method assumes that changes
391	/// on the same branch will be added in-order. The given function
392	/// `is_descendent_of` should return `true` if the second hash (target) is a
393	/// descendent of the first hash (base).
394	pub(crate) fn add_pending_change<F, E>(
395		&mut self,
396		pending: PendingChange<H, N>,
397		is_descendent_of: &F,
398	) -> Result<(), Error<N, E>>
399	where
400		F: Fn(&H, &H) -> Result<bool, E>,
401		E: std::error::Error,
402	{
403		if Self::invalid_authority_list(&pending.next_authorities) {
404			return Err(Error::InvalidAuthoritySet);
405		}
406
407		match pending.delay_kind {
408			DelayKind::Best { .. } => self.add_forced_change(pending, is_descendent_of),
409			DelayKind::Finalized => self.add_standard_change(pending, is_descendent_of),
410		}
411	}
412
413	/// Inspect pending changes. Standard pending changes are iterated first,
414	/// and the changes in the tree are traversed in pre-order, afterwards all
415	/// forced changes are iterated.
416	pub(crate) fn pending_changes(&self) -> impl Iterator<Item = &PendingChange<H, N>> {
417		self.pending_standard_changes
418			.iter()
419			.map(|(_, _, c)| c)
420			.chain(self.pending_forced_changes.iter())
421	}
422
423	/// Get the earliest limit-block number, if any. If there are pending changes across
424	/// different forks, this method will return the earliest effective number (across the
425	/// different branches) that is higher or equal to the given min number.
426	///
427	/// Only standard changes are taken into account for the current
428	/// limit, since any existing forced change should preclude the voter from voting.
429	pub(crate) fn current_limit(&self, min: N) -> Option<N> {
430		self.pending_standard_changes
431			.roots()
432			.filter(|&(_, _, c)| c.effective_number() >= min)
433			.min_by_key(|&(_, _, c)| c.effective_number())
434			.map(|(_, _, c)| c.effective_number())
435	}
436
437	/// Apply or prune any pending transitions based on a best-block trigger.
438	///
439	/// Returns `Ok((median, new_set))` when a forced change has occurred. The
440	/// median represents the median last finalized block at the time the change
441	/// was signaled, and it should be used as the canon block when starting the
442	/// new grandpa voter. Only alters the internal state in this case.
443	///
444	/// These transitions are always forced and do not lead to justifications
445	/// which light clients can follow.
446	///
447	/// Forced changes can only be applied after all pending standard changes
448	/// that it depends on have been applied. If any pending standard change
449	/// exists that is an ancestor of a given forced changed and which effective
450	/// block number is lower than the last finalized block (as defined by the
451	/// forced change), then the forced change cannot be applied. An error will
452	/// be returned in that case which will prevent block import.
453	pub(crate) fn apply_forced_changes<F, E>(
454		&self,
455		best_hash: H,
456		best_number: N,
457		is_descendent_of: &F,
458		initial_sync: bool,
459		telemetry: Option<TelemetryHandle>,
460	) -> Result<Option<(N, Self)>, Error<N, E>>
461	where
462		F: Fn(&H, &H) -> Result<bool, E>,
463		E: std::error::Error,
464	{
465		let mut new_set = None;
466
467		for change in self
468			.pending_forced_changes
469			.iter()
470			.take_while(|c| c.effective_number() <= best_number) // to prevent iterating too far
471			.filter(|c| c.effective_number() == best_number)
472		{
473			// check if the given best block is in the same branch as
474			// the block that signaled the change.
475			if change.canon_hash == best_hash || is_descendent_of(&change.canon_hash, &best_hash)? {
476				let median_last_finalized = match change.delay_kind {
477					DelayKind::Best { ref median_last_finalized } => median_last_finalized.clone(),
478					_ => unreachable!(
479						"pending_forced_changes only contains forced changes; forced changes have delay kind Best; qed."
480					),
481				};
482
483				// check if there's any pending standard change that we depend on
484				for (_, _, standard_change) in self.pending_standard_changes.roots() {
485					if standard_change.effective_number() <= median_last_finalized &&
486						is_descendent_of(&standard_change.canon_hash, &change.canon_hash)?
487					{
488						log::info!(target: LOG_TARGET,
489							"Not applying authority set change forced at block #{:?}, due to pending standard change at block #{:?}",
490							change.canon_height,
491							standard_change.effective_number(),
492						);
493
494						return Err(Error::ForcedAuthoritySetChangeDependencyUnsatisfied(
495							standard_change.effective_number(),
496						));
497					}
498				}
499
500				// apply this change: make the set canonical
501				grandpa_log!(
502					initial_sync,
503					"👴 Applying authority set change forced at block #{:?}",
504					change.canon_height,
505				);
506
507				telemetry!(
508					telemetry;
509					CONSENSUS_INFO;
510					"afg.applying_forced_authority_set_change";
511					"block" => ?change.canon_height
512				);
513
514				let mut authority_set_changes = self.authority_set_changes.clone();
515				authority_set_changes.append(self.set_id, median_last_finalized.clone());
516
517				new_set = Some((
518					median_last_finalized,
519					AuthoritySet {
520						current_authorities: change.next_authorities.clone(),
521						set_id: self.set_id + 1,
522						pending_standard_changes: ForkTree::new(), // new set, new changes.
523						pending_forced_changes: Vec::new(),
524						authority_set_changes,
525					},
526				));
527
528				break;
529			}
530		}
531
532		// we don't wipe forced changes until another change is applied, hence
533		// why we return a new set instead of mutating.
534		Ok(new_set)
535	}
536
537	/// Apply or prune any pending transitions based on a finality trigger. This
538	/// method ensures that if there are multiple changes in the same branch,
539	/// finalizing this block won't finalize past multiple transitions (i.e.
540	/// transitions must be finalized in-order). The given function
541	/// `is_descendent_of` should return `true` if the second hash (target) is a
542	/// descendent of the first hash (base).
543	///
544	/// When the set has changed, the return value will be `Ok(Some((H, N)))`
545	/// which is the canonical block where the set last changed (i.e. the given
546	/// hash and number).
547	pub(crate) fn apply_standard_changes<F, E>(
548		&mut self,
549		finalized_hash: H,
550		finalized_number: N,
551		is_descendent_of: &F,
552		initial_sync: bool,
553		telemetry: Option<&TelemetryHandle>,
554	) -> Result<Status<H, N>, Error<N, E>>
555	where
556		F: Fn(&H, &H) -> Result<bool, E>,
557		E: std::error::Error,
558	{
559		let mut status = Status { changed: false, new_set_block: None };
560
561		match self.pending_standard_changes.finalize_with_descendent_if(
562			&finalized_hash,
563			finalized_number.clone(),
564			is_descendent_of,
565			|change| change.effective_number() <= finalized_number,
566		)? {
567			fork_tree::FinalizationResult::Changed(change) => {
568				status.changed = true;
569
570				let pending_forced_changes = std::mem::take(&mut self.pending_forced_changes);
571
572				// we will keep all forced changes for any later blocks and that are a
573				// descendent of the finalized block (i.e. they are part of this branch).
574				for change in pending_forced_changes {
575					if change.effective_number() > finalized_number &&
576						is_descendent_of(&finalized_hash, &change.canon_hash)?
577					{
578						self.pending_forced_changes.push(change)
579					}
580				}
581
582				if let Some(change) = change {
583					grandpa_log!(
584						initial_sync,
585						"👴 Applying authority set change scheduled at block #{:?}",
586						change.canon_height,
587					);
588					telemetry!(
589						telemetry;
590						CONSENSUS_INFO;
591						"afg.applying_scheduled_authority_set_change";
592						"block" => ?change.canon_height
593					);
594
595					// Store the set_id together with the last block_number for the set
596					self.authority_set_changes.append(self.set_id, finalized_number.clone());
597
598					self.current_authorities = change.next_authorities;
599					self.set_id += 1;
600
601					status.new_set_block = Some((finalized_hash, finalized_number));
602				}
603			},
604			fork_tree::FinalizationResult::Unchanged => {},
605		}
606
607		Ok(status)
608	}
609
610	/// Check whether the given finalized block number enacts any standard
611	/// authority set change (without triggering it), ensuring that if there are
612	/// multiple changes in the same branch, finalizing this block won't
613	/// finalize past multiple transitions (i.e. transitions must be finalized
614	/// in-order). Returns `Some(true)` if the block being finalized enacts a
615	/// change that can be immediately applied, `Some(false)` if the block being
616	/// finalized enacts a change but it cannot be applied yet since there are
617	/// other dependent changes, and `None` if no change is enacted. The given
618	/// function `is_descendent_of` should return `true` if the second hash
619	/// (target) is a descendent of the first hash (base).
620	pub fn enacts_standard_change<F, E>(
621		&self,
622		finalized_hash: H,
623		finalized_number: N,
624		is_descendent_of: &F,
625	) -> Result<Option<bool>, Error<N, E>>
626	where
627		F: Fn(&H, &H) -> Result<bool, E>,
628		E: std::error::Error,
629	{
630		self.pending_standard_changes
631			.finalizes_any_with_descendent_if(
632				&finalized_hash,
633				finalized_number.clone(),
634				is_descendent_of,
635				|change| change.effective_number() == finalized_number,
636			)
637			.map_err(Error::ForkTree)
638	}
639}
640
641/// Kinds of delays for pending changes.
642#[derive(Debug, Clone, Encode, Decode, PartialEq)]
643pub enum DelayKind<N> {
644	/// Depth in finalized chain.
645	Finalized,
646	/// Depth in best chain. The median last finalized block is calculated at the time the
647	/// change was signaled.
648	Best { median_last_finalized: N },
649}
650
651/// A pending change to the authority set.
652///
653/// This will be applied when the announcing block is at some depth within
654/// the finalized or unfinalized chain.
655#[derive(Debug, Clone, Encode, PartialEq)]
656pub struct PendingChange<H, N> {
657	/// The new authorities and weights to apply.
658	pub(crate) next_authorities: AuthorityList,
659	/// How deep in the chain the announcing block must be
660	/// before the change is applied.
661	pub(crate) delay: N,
662	/// The announcing block's height.
663	pub(crate) canon_height: N,
664	/// The announcing block's hash.
665	pub(crate) canon_hash: H,
666	/// The delay kind.
667	pub(crate) delay_kind: DelayKind<N>,
668}
669
670impl<H: Decode, N: Decode> Decode for PendingChange<H, N> {
671	fn decode<I: codec::Input>(value: &mut I) -> Result<Self, codec::Error> {
672		let next_authorities = Decode::decode(value)?;
673		let delay = Decode::decode(value)?;
674		let canon_height = Decode::decode(value)?;
675		let canon_hash = Decode::decode(value)?;
676
677		let delay_kind = DelayKind::decode(value).unwrap_or(DelayKind::Finalized);
678
679		Ok(PendingChange { next_authorities, delay, canon_height, canon_hash, delay_kind })
680	}
681}
682
683impl<H, N: Add<Output = N> + Clone> PendingChange<H, N> {
684	/// Returns the effective number this change will be applied at.
685	pub fn effective_number(&self) -> N {
686		self.canon_height.clone() + self.delay.clone()
687	}
688}
689
690/// Inserting a historical change would reuse a set id that is already
691/// tracked at a higher block.
692#[derive(Debug, thiserror::Error)]
693#[error("authority set change would duplicate set id {0}")]
694pub(crate) struct SetIdConflict(SetId);
695
696/// Tracks historical authority set changes. We store the block numbers for the last block
697/// of each authority set, once they have been finalized. These blocks are guaranteed to
698/// have a justification unless they were triggered by a forced change.
699#[derive(Debug, Encode, Decode, Clone, PartialEq)]
700pub struct AuthoritySetChanges<N>(Vec<(u64, N)>);
701
702/// The response when querying for a set id for a specific block. Either we get a set id
703/// together with a block number for the last block in the set, or that the requested block is in
704/// the latest set, or that we don't know what set id the given block belongs to.
705#[derive(Debug, PartialEq)]
706pub enum AuthoritySetChangeId<N> {
707	/// The requested block is in the latest set.
708	Latest,
709	/// Tuple containing the set id and the last block number of that set.
710	Set(SetId, N),
711	/// We don't know which set id the request block belongs to (this can only happen due to
712	/// missing data).
713	Unknown,
714}
715
716impl<N> From<Vec<(u64, N)>> for AuthoritySetChanges<N> {
717	fn from(changes: Vec<(u64, N)>) -> AuthoritySetChanges<N> {
718		AuthoritySetChanges(changes)
719	}
720}
721
722impl<N: Ord + Clone> AuthoritySetChanges<N> {
723	pub(crate) fn empty() -> Self {
724		Self(Default::default())
725	}
726
727	pub(crate) fn append(&mut self, set_id: u64, block_number: N) {
728		self.0.push((set_id, block_number));
729	}
730
731	pub(crate) fn get_set_id(&self, block_number: N) -> AuthoritySetChangeId<N> {
732		if self
733			.0
734			.last()
735			.map(|last_auth_change| last_auth_change.1 < block_number)
736			.unwrap_or(false)
737		{
738			return AuthoritySetChangeId::Latest;
739		}
740
741		let idx = self
742			.0
743			.binary_search_by_key(&block_number, |(_, n)| n.clone())
744			.unwrap_or_else(|b| b);
745
746		if idx < self.0.len() {
747			let (set_id, block_number) = self.0[idx].clone();
748
749			// if this is the first index but not the first set id then we are missing data.
750			if idx == 0 && set_id != 0 {
751				return AuthoritySetChangeId::Unknown;
752			}
753
754			AuthoritySetChangeId::Set(set_id, block_number)
755		} else {
756			AuthoritySetChangeId::Unknown
757		}
758	}
759
760	/// Insert a historical authority set change.
761	///
762	/// Set ids are derived from the position in the list,
763	/// so changes must be inserted in ascending block order.
764	pub(crate) fn insert(&mut self, block_number: N) -> Result<(), SetIdConflict> {
765		let idx = self
766			.0
767			.binary_search_by_key(&block_number, |(_, n)| n.clone())
768			.unwrap_or_else(|b| b);
769
770		let set_id = if idx == 0 { 0 } else { self.0[idx - 1].0 + 1 };
771		if idx != self.0.len() && self.0[idx].0 == set_id {
772			return Err(SetIdConflict(set_id));
773		}
774
775		self.0.insert(idx, (set_id, block_number));
776		Ok(())
777	}
778
779	/// Returns an iterator over all historical authority set changes starting at the given block
780	/// number (excluded). The iterator yields a tuple representing the set id and the block number
781	/// of the last block in that set.
782	pub fn iter_from(&self, block_number: N) -> Option<impl Iterator<Item = &(u64, N)>> {
783		let idx = self
784			.0
785			.binary_search_by_key(&block_number, |(_, n)| n.clone())
786			// if there was a change at the given block number then we should start on the next
787			// index since we want to exclude the current block number
788			.map(|n| n + 1)
789			.unwrap_or_else(|b| b);
790
791		if idx < self.0.len() {
792			let (set_id, _) = self.0[idx].clone();
793
794			// if this is the first index but not the first set id then we are missing data.
795			if idx == 0 && set_id != 0 {
796				return None;
797			}
798		}
799
800		Some(self.0[idx..].iter())
801	}
802}
803
804#[cfg(test)]
805mod tests {
806	use super::*;
807	use sp_core::crypto::{ByteArray, UncheckedFrom};
808
809	fn static_is_descendent_of<A>(value: bool) -> impl Fn(&A, &A) -> Result<bool, std::io::Error> {
810		move |_, _| Ok(value)
811	}
812
813	fn is_descendent_of<A, F>(f: F) -> impl Fn(&A, &A) -> Result<bool, std::io::Error>
814	where
815		F: Fn(&A, &A) -> bool,
816	{
817		move |base, hash| Ok(f(base, hash))
818	}
819
820	#[test]
821	fn current_limit_filters_min() {
822		let current_authorities = vec![(AuthorityId::from_slice(&[1; 32]).unwrap(), 1)];
823
824		let mut authorities = AuthoritySet {
825			current_authorities: current_authorities.clone(),
826			set_id: 0,
827			pending_standard_changes: ForkTree::new(),
828			pending_forced_changes: Vec::new(),
829			authority_set_changes: AuthoritySetChanges::empty(),
830		};
831
832		let change = |height| PendingChange {
833			next_authorities: current_authorities.clone(),
834			delay: 0,
835			canon_height: height,
836			canon_hash: height.to_string(),
837			delay_kind: DelayKind::Finalized,
838		};
839
840		let is_descendent_of = static_is_descendent_of(false);
841
842		authorities.add_pending_change(change(1), &is_descendent_of).unwrap();
843		authorities.add_pending_change(change(2), &is_descendent_of).unwrap();
844
845		assert_eq!(authorities.current_limit(0), Some(1));
846
847		assert_eq!(authorities.current_limit(1), Some(1));
848
849		assert_eq!(authorities.current_limit(2), Some(2));
850
851		assert_eq!(authorities.current_limit(3), None);
852	}
853
854	#[test]
855	fn changes_iterated_in_pre_order() {
856		let current_authorities = vec![(AuthorityId::from_slice(&[1; 32]).unwrap(), 1)];
857
858		let mut authorities = AuthoritySet {
859			current_authorities: current_authorities.clone(),
860			set_id: 0,
861			pending_standard_changes: ForkTree::new(),
862			pending_forced_changes: Vec::new(),
863			authority_set_changes: AuthoritySetChanges::empty(),
864		};
865
866		let change_a = PendingChange {
867			next_authorities: current_authorities.clone(),
868			delay: 10,
869			canon_height: 5,
870			canon_hash: "hash_a",
871			delay_kind: DelayKind::Finalized,
872		};
873
874		let change_b = PendingChange {
875			next_authorities: current_authorities.clone(),
876			delay: 0,
877			canon_height: 5,
878			canon_hash: "hash_b",
879			delay_kind: DelayKind::Finalized,
880		};
881
882		let change_c = PendingChange {
883			next_authorities: current_authorities.clone(),
884			delay: 5,
885			canon_height: 10,
886			canon_hash: "hash_c",
887			delay_kind: DelayKind::Finalized,
888		};
889
890		authorities
891			.add_pending_change(change_a.clone(), &static_is_descendent_of(false))
892			.unwrap();
893		authorities
894			.add_pending_change(change_b.clone(), &static_is_descendent_of(false))
895			.unwrap();
896		authorities
897			.add_pending_change(
898				change_c.clone(),
899				&is_descendent_of(|base, hash| match (*base, *hash) {
900					("hash_a", "hash_c") => true,
901					("hash_b", "hash_c") => false,
902					_ => unreachable!(),
903				}),
904			)
905			.unwrap();
906
907		// forced changes are iterated last
908		let change_d = PendingChange {
909			next_authorities: current_authorities.clone(),
910			delay: 2,
911			canon_height: 1,
912			canon_hash: "hash_d",
913			delay_kind: DelayKind::Best { median_last_finalized: 0 },
914		};
915
916		let change_e = PendingChange {
917			next_authorities: current_authorities.clone(),
918			delay: 2,
919			canon_height: 0,
920			canon_hash: "hash_e",
921			delay_kind: DelayKind::Best { median_last_finalized: 0 },
922		};
923
924		authorities
925			.add_pending_change(change_d.clone(), &static_is_descendent_of(false))
926			.unwrap();
927		authorities
928			.add_pending_change(change_e.clone(), &static_is_descendent_of(false))
929			.unwrap();
930
931		// ordered by subtree depth
932		assert_eq!(
933			authorities.pending_changes().collect::<Vec<_>>(),
934			vec![&change_a, &change_c, &change_b, &change_e, &change_d],
935		);
936	}
937
938	#[test]
939	fn apply_change() {
940		let mut authorities = AuthoritySet {
941			current_authorities: Vec::new(),
942			set_id: 0,
943			pending_standard_changes: ForkTree::new(),
944			pending_forced_changes: Vec::new(),
945			authority_set_changes: AuthoritySetChanges::empty(),
946		};
947
948		let set_a = vec![(AuthorityId::from_slice(&[1; 32]).unwrap(), 5)];
949		let set_b = vec![(AuthorityId::from_slice(&[2; 32]).unwrap(), 5)];
950
951		// two competing changes at the same height on different forks
952		let change_a = PendingChange {
953			next_authorities: set_a.clone(),
954			delay: 10,
955			canon_height: 5,
956			canon_hash: "hash_a",
957			delay_kind: DelayKind::Finalized,
958		};
959
960		let change_b = PendingChange {
961			next_authorities: set_b.clone(),
962			delay: 10,
963			canon_height: 5,
964			canon_hash: "hash_b",
965			delay_kind: DelayKind::Finalized,
966		};
967
968		authorities
969			.add_pending_change(change_a.clone(), &static_is_descendent_of(true))
970			.unwrap();
971		authorities
972			.add_pending_change(change_b.clone(), &static_is_descendent_of(true))
973			.unwrap();
974
975		assert_eq!(authorities.pending_changes().collect::<Vec<_>>(), vec![&change_a, &change_b]);
976
977		// finalizing "hash_c" won't enact the change signaled at "hash_a" but it will prune out
978		// "hash_b"
979		let status = authorities
980			.apply_standard_changes(
981				"hash_c",
982				11,
983				&is_descendent_of(|base, hash| match (*base, *hash) {
984					("hash_a", "hash_c") => true,
985					("hash_b", "hash_c") => false,
986					_ => unreachable!(),
987				}),
988				false,
989				None,
990			)
991			.unwrap();
992
993		assert!(status.changed);
994		assert_eq!(status.new_set_block, None);
995		assert_eq!(authorities.pending_changes().collect::<Vec<_>>(), vec![&change_a]);
996		assert_eq!(authorities.authority_set_changes, AuthoritySetChanges::empty());
997
998		// finalizing "hash_d" will enact the change signaled at "hash_a"
999		let status = authorities
1000			.apply_standard_changes(
1001				"hash_d",
1002				15,
1003				&is_descendent_of(|base, hash| match (*base, *hash) {
1004					("hash_a", "hash_d") => true,
1005					_ => unreachable!(),
1006				}),
1007				false,
1008				None,
1009			)
1010			.unwrap();
1011
1012		assert!(status.changed);
1013		assert_eq!(status.new_set_block, Some(("hash_d", 15)));
1014
1015		assert_eq!(authorities.current_authorities, set_a);
1016		assert_eq!(authorities.set_id, 1);
1017		assert_eq!(authorities.pending_changes().count(), 0);
1018		assert_eq!(authorities.authority_set_changes, AuthoritySetChanges(vec![(0, 15)]));
1019	}
1020
1021	#[test]
1022	fn disallow_multiple_changes_being_finalized_at_once() {
1023		let mut authorities = AuthoritySet {
1024			current_authorities: Vec::new(),
1025			set_id: 0,
1026			pending_standard_changes: ForkTree::new(),
1027			pending_forced_changes: Vec::new(),
1028			authority_set_changes: AuthoritySetChanges::empty(),
1029		};
1030
1031		let set_a = vec![(AuthorityId::from_slice(&[1; 32]).unwrap(), 5)];
1032		let set_c = vec![(AuthorityId::from_slice(&[2; 32]).unwrap(), 5)];
1033
1034		// two competing changes at the same height on different forks
1035		let change_a = PendingChange {
1036			next_authorities: set_a.clone(),
1037			delay: 10,
1038			canon_height: 5,
1039			canon_hash: "hash_a",
1040			delay_kind: DelayKind::Finalized,
1041		};
1042
1043		let change_c = PendingChange {
1044			next_authorities: set_c.clone(),
1045			delay: 10,
1046			canon_height: 30,
1047			canon_hash: "hash_c",
1048			delay_kind: DelayKind::Finalized,
1049		};
1050
1051		authorities
1052			.add_pending_change(change_a.clone(), &static_is_descendent_of(true))
1053			.unwrap();
1054		authorities
1055			.add_pending_change(change_c.clone(), &static_is_descendent_of(true))
1056			.unwrap();
1057
1058		let is_descendent_of = is_descendent_of(|base, hash| match (*base, *hash) {
1059			("hash_a", "hash_b") => true,
1060			("hash_a", "hash_c") => true,
1061			("hash_a", "hash_d") => true,
1062
1063			("hash_c", "hash_b") => false,
1064			("hash_c", "hash_d") => true,
1065
1066			("hash_b", "hash_c") => true,
1067			_ => unreachable!(),
1068		});
1069
1070		// trying to finalize past `change_c` without finalizing `change_a` first
1071		assert!(matches!(
1072			authorities.apply_standard_changes("hash_d", 40, &is_descendent_of, false, None),
1073			Err(Error::ForkTree(fork_tree::Error::UnfinalizedAncestor))
1074		));
1075		assert_eq!(authorities.authority_set_changes, AuthoritySetChanges::empty());
1076
1077		let status = authorities
1078			.apply_standard_changes("hash_b", 15, &is_descendent_of, false, None)
1079			.unwrap();
1080
1081		assert!(status.changed);
1082		assert_eq!(status.new_set_block, Some(("hash_b", 15)));
1083
1084		assert_eq!(authorities.current_authorities, set_a);
1085		assert_eq!(authorities.set_id, 1);
1086		assert_eq!(authorities.authority_set_changes, AuthoritySetChanges(vec![(0, 15)]));
1087
1088		// after finalizing `change_a` it should be possible to finalize `change_c`
1089		let status = authorities
1090			.apply_standard_changes("hash_d", 40, &is_descendent_of, false, None)
1091			.unwrap();
1092
1093		assert!(status.changed);
1094		assert_eq!(status.new_set_block, Some(("hash_d", 40)));
1095
1096		assert_eq!(authorities.current_authorities, set_c);
1097		assert_eq!(authorities.set_id, 2);
1098		assert_eq!(authorities.authority_set_changes, AuthoritySetChanges(vec![(0, 15), (1, 40)]));
1099	}
1100
1101	#[test]
1102	fn enacts_standard_change_works() {
1103		let mut authorities = AuthoritySet {
1104			current_authorities: Vec::new(),
1105			set_id: 0,
1106			pending_standard_changes: ForkTree::new(),
1107			pending_forced_changes: Vec::new(),
1108			authority_set_changes: AuthoritySetChanges::empty(),
1109		};
1110
1111		let set_a = vec![(AuthorityId::from_slice(&[1; 32]).unwrap(), 5)];
1112
1113		let change_a = PendingChange {
1114			next_authorities: set_a.clone(),
1115			delay: 10,
1116			canon_height: 5,
1117			canon_hash: "hash_a",
1118			delay_kind: DelayKind::Finalized,
1119		};
1120
1121		let change_b = PendingChange {
1122			next_authorities: set_a.clone(),
1123			delay: 10,
1124			canon_height: 20,
1125			canon_hash: "hash_b",
1126			delay_kind: DelayKind::Finalized,
1127		};
1128
1129		authorities
1130			.add_pending_change(change_a.clone(), &static_is_descendent_of(false))
1131			.unwrap();
1132		authorities
1133			.add_pending_change(change_b.clone(), &static_is_descendent_of(true))
1134			.unwrap();
1135
1136		let is_descendent_of = is_descendent_of(|base, hash| match (*base, *hash) {
1137			("hash_a", "hash_d") => true,
1138			("hash_a", "hash_e") => true,
1139			("hash_b", "hash_d") => true,
1140			("hash_b", "hash_e") => true,
1141			("hash_a", "hash_c") => false,
1142			("hash_b", "hash_c") => false,
1143			_ => unreachable!(),
1144		});
1145
1146		// "hash_c" won't finalize the existing change since it isn't a descendent
1147		assert_eq!(
1148			authorities.enacts_standard_change("hash_c", 15, &is_descendent_of).unwrap(),
1149			None,
1150		);
1151
1152		// "hash_d" at depth 14 won't work either
1153		assert_eq!(
1154			authorities.enacts_standard_change("hash_d", 14, &is_descendent_of).unwrap(),
1155			None,
1156		);
1157
1158		// but it should work at depth 15 (change height + depth)
1159		assert_eq!(
1160			authorities.enacts_standard_change("hash_d", 15, &is_descendent_of).unwrap(),
1161			Some(true),
1162		);
1163
1164		// finalizing "hash_e" at depth 20 will trigger change at "hash_b", but
1165		// it can't be applied yet since "hash_a" must be applied first
1166		assert_eq!(
1167			authorities.enacts_standard_change("hash_e", 30, &is_descendent_of).unwrap(),
1168			Some(false),
1169		);
1170	}
1171
1172	#[test]
1173	fn forced_changes() {
1174		let mut authorities = AuthoritySet {
1175			current_authorities: Vec::new(),
1176			set_id: 0,
1177			pending_standard_changes: ForkTree::new(),
1178			pending_forced_changes: Vec::new(),
1179			authority_set_changes: AuthoritySetChanges::empty(),
1180		};
1181
1182		let set_a = vec![(AuthorityId::from_slice(&[1; 32]).unwrap(), 5)];
1183		let set_b = vec![(AuthorityId::from_slice(&[2; 32]).unwrap(), 5)];
1184
1185		let change_a = PendingChange {
1186			next_authorities: set_a.clone(),
1187			delay: 10,
1188			canon_height: 5,
1189			canon_hash: "hash_a",
1190			delay_kind: DelayKind::Best { median_last_finalized: 42 },
1191		};
1192
1193		let change_b = PendingChange {
1194			next_authorities: set_b.clone(),
1195			delay: 10,
1196			canon_height: 5,
1197			canon_hash: "hash_b",
1198			delay_kind: DelayKind::Best { median_last_finalized: 0 },
1199		};
1200
1201		authorities
1202			.add_pending_change(change_a, &static_is_descendent_of(false))
1203			.unwrap();
1204		authorities
1205			.add_pending_change(change_b.clone(), &static_is_descendent_of(false))
1206			.unwrap();
1207
1208		// no duplicates are allowed
1209		assert!(matches!(
1210			authorities.add_pending_change(change_b, &static_is_descendent_of(false)),
1211			Err(Error::DuplicateAuthoritySetChange)
1212		));
1213
1214		// there's an effective change triggered at block 15 but not a standard one.
1215		// so this should do nothing.
1216		assert_eq!(
1217			authorities
1218				.enacts_standard_change("hash_c", 15, &static_is_descendent_of(true))
1219				.unwrap(),
1220			None,
1221		);
1222
1223		// there can only be one pending forced change per fork
1224		let change_c = PendingChange {
1225			next_authorities: set_b.clone(),
1226			delay: 3,
1227			canon_height: 8,
1228			canon_hash: "hash_a8",
1229			delay_kind: DelayKind::Best { median_last_finalized: 0 },
1230		};
1231
1232		let is_descendent_of_a = is_descendent_of(|base: &&str, _| base.starts_with("hash_a"));
1233
1234		assert!(matches!(
1235			authorities.add_pending_change(change_c, &is_descendent_of_a),
1236			Err(Error::MultiplePendingForcedAuthoritySetChanges)
1237		));
1238
1239		// let's try and apply the forced changes.
1240		// too early and there's no forced changes to apply.
1241		assert!(authorities
1242			.apply_forced_changes("hash_a10", 10, &static_is_descendent_of(true), false, None)
1243			.unwrap()
1244			.is_none());
1245
1246		// too late.
1247		assert!(authorities
1248			.apply_forced_changes("hash_a16", 16, &is_descendent_of_a, false, None)
1249			.unwrap()
1250			.is_none());
1251
1252		// on time -- chooses the right change for this fork.
1253		assert_eq!(
1254			authorities
1255				.apply_forced_changes("hash_a15", 15, &is_descendent_of_a, false, None)
1256				.unwrap()
1257				.unwrap(),
1258			(
1259				42,
1260				AuthoritySet {
1261					current_authorities: set_a,
1262					set_id: 1,
1263					pending_standard_changes: ForkTree::new(),
1264					pending_forced_changes: Vec::new(),
1265					authority_set_changes: AuthoritySetChanges(vec![(0, 42)]),
1266				},
1267			)
1268		);
1269	}
1270
1271	#[test]
1272	fn forced_changes_with_no_delay() {
1273		// NOTE: this is a regression test
1274		let mut authorities = AuthoritySet {
1275			current_authorities: Vec::new(),
1276			set_id: 0,
1277			pending_standard_changes: ForkTree::new(),
1278			pending_forced_changes: Vec::new(),
1279			authority_set_changes: AuthoritySetChanges::empty(),
1280		};
1281
1282		let set_a = vec![(AuthorityId::from_slice(&[1; 32]).unwrap(), 5)];
1283
1284		// we create a forced change with no delay
1285		let change_a = PendingChange {
1286			next_authorities: set_a.clone(),
1287			delay: 0,
1288			canon_height: 5,
1289			canon_hash: "hash_a",
1290			delay_kind: DelayKind::Best { median_last_finalized: 0 },
1291		};
1292
1293		// and import it
1294		authorities
1295			.add_pending_change(change_a, &static_is_descendent_of(false))
1296			.unwrap();
1297
1298		// it should be enacted at the same block that signaled it
1299		assert!(authorities
1300			.apply_forced_changes("hash_a", 5, &static_is_descendent_of(false), false, None)
1301			.unwrap()
1302			.is_some());
1303	}
1304
1305	#[test]
1306	fn forced_changes_blocked_by_standard_changes() {
1307		let set_a = vec![(AuthorityId::from_slice(&[1; 32]).unwrap(), 1)];
1308
1309		let mut authorities = AuthoritySet {
1310			current_authorities: set_a.clone(),
1311			set_id: 0,
1312			pending_standard_changes: ForkTree::new(),
1313			pending_forced_changes: Vec::new(),
1314			authority_set_changes: AuthoritySetChanges::empty(),
1315		};
1316
1317		// effective at #15
1318		let change_a = PendingChange {
1319			next_authorities: set_a.clone(),
1320			delay: 5,
1321			canon_height: 10,
1322			canon_hash: "hash_a",
1323			delay_kind: DelayKind::Finalized,
1324		};
1325
1326		// effective #20
1327		let change_b = PendingChange {
1328			next_authorities: set_a.clone(),
1329			delay: 0,
1330			canon_height: 20,
1331			canon_hash: "hash_b",
1332			delay_kind: DelayKind::Finalized,
1333		};
1334
1335		// effective at #35
1336		let change_c = PendingChange {
1337			next_authorities: set_a.clone(),
1338			delay: 5,
1339			canon_height: 30,
1340			canon_hash: "hash_c",
1341			delay_kind: DelayKind::Finalized,
1342		};
1343
1344		// add some pending standard changes all on the same fork
1345		authorities
1346			.add_pending_change(change_a, &static_is_descendent_of(true))
1347			.unwrap();
1348		authorities
1349			.add_pending_change(change_b, &static_is_descendent_of(true))
1350			.unwrap();
1351		authorities
1352			.add_pending_change(change_c, &static_is_descendent_of(true))
1353			.unwrap();
1354
1355		// effective at #45
1356		let change_d = PendingChange {
1357			next_authorities: set_a.clone(),
1358			delay: 5,
1359			canon_height: 40,
1360			canon_hash: "hash_d",
1361			delay_kind: DelayKind::Best { median_last_finalized: 31 },
1362		};
1363
1364		// now add a forced change on the same fork
1365		authorities
1366			.add_pending_change(change_d, &static_is_descendent_of(true))
1367			.unwrap();
1368
1369		// the forced change cannot be applied since the pending changes it depends on
1370		// have not been applied yet.
1371		assert!(matches!(
1372			authorities.apply_forced_changes(
1373				"hash_d45",
1374				45,
1375				&static_is_descendent_of(true),
1376				false,
1377				None
1378			),
1379			Err(Error::ForcedAuthoritySetChangeDependencyUnsatisfied(15))
1380		));
1381		assert_eq!(authorities.authority_set_changes, AuthoritySetChanges::empty());
1382
1383		// we apply the first pending standard change at #15
1384		authorities
1385			.apply_standard_changes("hash_a15", 15, &static_is_descendent_of(true), false, None)
1386			.unwrap();
1387		assert_eq!(authorities.authority_set_changes, AuthoritySetChanges(vec![(0, 15)]));
1388
1389		// but the forced change still depends on the next standard change
1390		assert!(matches!(
1391			authorities.apply_forced_changes(
1392				"hash_d",
1393				45,
1394				&static_is_descendent_of(true),
1395				false,
1396				None
1397			),
1398			Err(Error::ForcedAuthoritySetChangeDependencyUnsatisfied(20))
1399		));
1400		assert_eq!(authorities.authority_set_changes, AuthoritySetChanges(vec![(0, 15)]));
1401
1402		// we apply the pending standard change at #20
1403		authorities
1404			.apply_standard_changes("hash_b", 20, &static_is_descendent_of(true), false, None)
1405			.unwrap();
1406		assert_eq!(authorities.authority_set_changes, AuthoritySetChanges(vec![(0, 15), (1, 20)]));
1407
1408		// afterwards the forced change at #45 can already be applied since it signals
1409		// that finality stalled at #31, and the next pending standard change is effective
1410		// at #35. subsequent forced changes on the same branch must be kept
1411		assert_eq!(
1412			authorities
1413				.apply_forced_changes("hash_d", 45, &static_is_descendent_of(true), false, None)
1414				.unwrap()
1415				.unwrap(),
1416			(
1417				31,
1418				AuthoritySet {
1419					current_authorities: set_a.clone(),
1420					set_id: 3,
1421					pending_standard_changes: ForkTree::new(),
1422					pending_forced_changes: Vec::new(),
1423					authority_set_changes: AuthoritySetChanges(vec![(0, 15), (1, 20), (2, 31)]),
1424				}
1425			),
1426		);
1427		assert_eq!(authorities.authority_set_changes, AuthoritySetChanges(vec![(0, 15), (1, 20)]));
1428	}
1429
1430	#[test]
1431	fn next_change_works() {
1432		let current_authorities = vec![(AuthorityId::from_slice(&[1; 32]).unwrap(), 1)];
1433
1434		let mut authorities = AuthoritySet {
1435			current_authorities: current_authorities.clone(),
1436			set_id: 0,
1437			pending_standard_changes: ForkTree::new(),
1438			pending_forced_changes: Vec::new(),
1439			authority_set_changes: AuthoritySetChanges::empty(),
1440		};
1441
1442		let new_set = current_authorities.clone();
1443
1444		// We have three pending changes with 2 possible roots that are enacted
1445		// immediately on finality (i.e. standard changes).
1446		let change_a0 = PendingChange {
1447			next_authorities: new_set.clone(),
1448			delay: 0,
1449			canon_height: 5,
1450			canon_hash: "hash_a0",
1451			delay_kind: DelayKind::Finalized,
1452		};
1453
1454		let change_a1 = PendingChange {
1455			next_authorities: new_set.clone(),
1456			delay: 0,
1457			canon_height: 10,
1458			canon_hash: "hash_a1",
1459			delay_kind: DelayKind::Finalized,
1460		};
1461
1462		let change_b = PendingChange {
1463			next_authorities: new_set.clone(),
1464			delay: 0,
1465			canon_height: 4,
1466			canon_hash: "hash_b",
1467			delay_kind: DelayKind::Finalized,
1468		};
1469
1470		// A0 (#5) <- A10 (#8) <- A1 (#10) <- best_a
1471		// B (#4) <- best_b
1472		let is_descendent_of = is_descendent_of(|base, hash| match (*base, *hash) {
1473			("hash_a0", "hash_a1") => true,
1474			("hash_a0", "best_a") => true,
1475			("hash_a1", "best_a") => true,
1476			("hash_a10", "best_a") => true,
1477			("hash_b", "best_b") => true,
1478			_ => false,
1479		});
1480
1481		// add the three pending changes
1482		authorities.add_pending_change(change_b, &is_descendent_of).unwrap();
1483		authorities.add_pending_change(change_a0, &is_descendent_of).unwrap();
1484		authorities.add_pending_change(change_a1, &is_descendent_of).unwrap();
1485
1486		// the earliest change at block `best_a` should be the change at A0 (#5)
1487		assert_eq!(
1488			authorities.next_change(&"best_a", &is_descendent_of).unwrap(),
1489			Some(("hash_a0", 5)),
1490		);
1491
1492		// the earliest change at block `best_b` should be the change at B (#4)
1493		assert_eq!(
1494			authorities.next_change(&"best_b", &is_descendent_of).unwrap(),
1495			Some(("hash_b", 4)),
1496		);
1497
1498		// we apply the change at A0 which should prune it and the fork at B
1499		authorities
1500			.apply_standard_changes("hash_a0", 5, &is_descendent_of, false, None)
1501			.unwrap();
1502
1503		// the next change is now at A1 (#10)
1504		assert_eq!(
1505			authorities.next_change(&"best_a", &is_descendent_of).unwrap(),
1506			Some(("hash_a1", 10)),
1507		);
1508
1509		// there's no longer any pending change at `best_b` fork
1510		assert_eq!(authorities.next_change(&"best_b", &is_descendent_of).unwrap(), None);
1511
1512		// we a forced change at A10 (#8)
1513		let change_a10 = PendingChange {
1514			next_authorities: new_set.clone(),
1515			delay: 0,
1516			canon_height: 8,
1517			canon_hash: "hash_a10",
1518			delay_kind: DelayKind::Best { median_last_finalized: 0 },
1519		};
1520
1521		authorities
1522			.add_pending_change(change_a10, &static_is_descendent_of(false))
1523			.unwrap();
1524
1525		// it should take precedence over the change at A1 (#10)
1526		assert_eq!(
1527			authorities.next_change(&"best_a", &is_descendent_of).unwrap(),
1528			Some(("hash_a10", 8)),
1529		);
1530	}
1531
1532	#[test]
1533	fn maintains_authority_list_invariants() {
1534		// empty authority lists are invalid
1535		assert_eq!(AuthoritySet::<(), ()>::genesis(vec![]), None);
1536		assert_eq!(
1537			AuthoritySet::<(), ()>::new(
1538				vec![],
1539				0,
1540				ForkTree::new(),
1541				Vec::new(),
1542				AuthoritySetChanges::empty(),
1543			),
1544			None,
1545		);
1546
1547		let invalid_authorities_weight = vec![
1548			(AuthorityId::from_slice(&[1; 32]).unwrap(), 5),
1549			(AuthorityId::from_slice(&[2; 32]).unwrap(), 0),
1550		];
1551
1552		// authority weight of zero is invalid
1553		assert_eq!(AuthoritySet::<(), ()>::genesis(invalid_authorities_weight.clone()), None);
1554		assert_eq!(
1555			AuthoritySet::<(), ()>::new(
1556				invalid_authorities_weight.clone(),
1557				0,
1558				ForkTree::new(),
1559				Vec::new(),
1560				AuthoritySetChanges::empty(),
1561			),
1562			None,
1563		);
1564
1565		let mut authority_set =
1566			AuthoritySet::<(), u64>::genesis(vec![(AuthorityId::unchecked_from([1; 32]), 5)])
1567				.unwrap();
1568
1569		let invalid_change_empty_authorities = PendingChange {
1570			next_authorities: vec![],
1571			delay: 10,
1572			canon_height: 5,
1573			canon_hash: (),
1574			delay_kind: DelayKind::Finalized,
1575		};
1576
1577		// pending change contains an empty authority set
1578		assert!(matches!(
1579			authority_set.add_pending_change(
1580				invalid_change_empty_authorities.clone(),
1581				&static_is_descendent_of(false)
1582			),
1583			Err(Error::InvalidAuthoritySet)
1584		));
1585
1586		let invalid_change_authorities_weight = PendingChange {
1587			next_authorities: invalid_authorities_weight,
1588			delay: 10,
1589			canon_height: 5,
1590			canon_hash: (),
1591			delay_kind: DelayKind::Best { median_last_finalized: 0 },
1592		};
1593
1594		// pending change contains an an authority set
1595		// where one authority has weight of 0
1596		assert!(matches!(
1597			authority_set.add_pending_change(
1598				invalid_change_authorities_weight,
1599				&static_is_descendent_of(false)
1600			),
1601			Err(Error::InvalidAuthoritySet)
1602		));
1603	}
1604
1605	#[test]
1606	fn cleans_up_stale_forced_changes_when_applying_standard_change() {
1607		let current_authorities = vec![(AuthorityId::from_slice(&[1; 32]).unwrap(), 1)];
1608
1609		let mut authorities = AuthoritySet {
1610			current_authorities: current_authorities.clone(),
1611			set_id: 0,
1612			pending_standard_changes: ForkTree::new(),
1613			pending_forced_changes: Vec::new(),
1614			authority_set_changes: AuthoritySetChanges::empty(),
1615		};
1616
1617		let new_set = current_authorities.clone();
1618
1619		// Create the following pending changes tree:
1620		//
1621		//               [#C3]
1622		//              /
1623		//             /- (#C2)
1624		//            /
1625		// (#A) - (#B) - [#C1]
1626		//            \
1627		//             (#C0) - [#D]
1628		//
1629		// () - Standard change
1630		// [] - Forced change
1631
1632		let is_descendent_of = {
1633			let hashes = vec!["B", "C0", "C1", "C2", "C3", "D"];
1634			is_descendent_of(move |base, hash| match (*base, *hash) {
1635				("B", "B") => false, // required to have the simpler case below
1636				("A", b) | ("B", b) => hashes.iter().any(|h| *h == b),
1637				("C0", "D") => true,
1638				_ => false,
1639			})
1640		};
1641
1642		let mut add_pending_change = |canon_height, canon_hash, forced| {
1643			let change = PendingChange {
1644				next_authorities: new_set.clone(),
1645				delay: 0,
1646				canon_height,
1647				canon_hash,
1648				delay_kind: if forced {
1649					DelayKind::Best { median_last_finalized: 0 }
1650				} else {
1651					DelayKind::Finalized
1652				},
1653			};
1654
1655			authorities.add_pending_change(change, &is_descendent_of).unwrap();
1656		};
1657
1658		add_pending_change(5, "A", false);
1659		add_pending_change(10, "B", false);
1660		add_pending_change(15, "C0", false);
1661		add_pending_change(15, "C1", true);
1662		add_pending_change(15, "C2", false);
1663		add_pending_change(15, "C3", true);
1664		add_pending_change(20, "D", true);
1665
1666		// applying the standard change at A should not prune anything
1667		// other then the change that was applied
1668		authorities
1669			.apply_standard_changes("A", 5, &is_descendent_of, false, None)
1670			.unwrap();
1671
1672		assert_eq!(authorities.pending_changes().count(), 6);
1673
1674		// same for B
1675		authorities
1676			.apply_standard_changes("B", 10, &is_descendent_of, false, None)
1677			.unwrap();
1678
1679		assert_eq!(authorities.pending_changes().count(), 5);
1680
1681		let authorities2 = authorities.clone();
1682
1683		// finalizing C2 should clear all forced changes
1684		authorities
1685			.apply_standard_changes("C2", 15, &is_descendent_of, false, None)
1686			.unwrap();
1687
1688		assert_eq!(authorities.pending_forced_changes.len(), 0);
1689
1690		// finalizing C0 should clear all forced changes but D
1691		let mut authorities = authorities2;
1692		authorities
1693			.apply_standard_changes("C0", 15, &is_descendent_of, false, None)
1694			.unwrap();
1695
1696		assert_eq!(authorities.pending_forced_changes.len(), 1);
1697		assert_eq!(authorities.pending_forced_changes.first().unwrap().canon_hash, "D");
1698	}
1699
1700	#[test]
1701	fn authority_set_changes_insert() {
1702		let mut authority_set_changes = AuthoritySetChanges::empty();
1703		authority_set_changes.append(0, 41);
1704		authority_set_changes.append(1, 81);
1705		authority_set_changes.append(4, 121);
1706
1707		authority_set_changes.insert(101).unwrap();
1708		assert_eq!(authority_set_changes.get_set_id(100), AuthoritySetChangeId::Set(2, 101));
1709		assert_eq!(authority_set_changes.get_set_id(101), AuthoritySetChangeId::Set(2, 101));
1710	}
1711
1712	#[test]
1713	fn authority_set_changes_insert_rejects_duplicate_set_id() {
1714		let mut changes = AuthoritySetChanges::empty();
1715		changes.insert(10).unwrap();
1716		changes.insert(20).unwrap();
1717		changes.insert(30).unwrap();
1718
1719		let before = changes.clone();
1720		assert_eq!(changes.insert(25).unwrap_err().0, 2);
1721		assert_eq!(changes, before);
1722	}
1723
1724	#[test]
1725	fn authority_set_changes_for_complete_data() {
1726		let mut authority_set_changes = AuthoritySetChanges::empty();
1727		authority_set_changes.append(0, 41);
1728		authority_set_changes.append(1, 81);
1729		authority_set_changes.append(2, 121);
1730
1731		assert_eq!(authority_set_changes.get_set_id(20), AuthoritySetChangeId::Set(0, 41));
1732		assert_eq!(authority_set_changes.get_set_id(40), AuthoritySetChangeId::Set(0, 41));
1733		assert_eq!(authority_set_changes.get_set_id(41), AuthoritySetChangeId::Set(0, 41));
1734		assert_eq!(authority_set_changes.get_set_id(42), AuthoritySetChangeId::Set(1, 81));
1735		assert_eq!(authority_set_changes.get_set_id(141), AuthoritySetChangeId::Latest);
1736	}
1737
1738	#[test]
1739	fn authority_set_changes_for_incomplete_data() {
1740		let mut authority_set_changes = AuthoritySetChanges::empty();
1741		authority_set_changes.append(2, 41);
1742		authority_set_changes.append(3, 81);
1743		authority_set_changes.append(4, 121);
1744
1745		assert_eq!(authority_set_changes.get_set_id(20), AuthoritySetChangeId::Unknown);
1746		assert_eq!(authority_set_changes.get_set_id(40), AuthoritySetChangeId::Unknown);
1747		assert_eq!(authority_set_changes.get_set_id(41), AuthoritySetChangeId::Unknown);
1748		assert_eq!(authority_set_changes.get_set_id(42), AuthoritySetChangeId::Set(3, 81));
1749		assert_eq!(authority_set_changes.get_set_id(141), AuthoritySetChangeId::Latest);
1750	}
1751
1752	#[test]
1753	fn iter_from_works() {
1754		let mut authority_set_changes = AuthoritySetChanges::empty();
1755		authority_set_changes.append(1, 41);
1756		authority_set_changes.append(2, 81);
1757
1758		// we are missing the data for the first set, therefore we should return `None`
1759		assert_eq!(None, authority_set_changes.iter_from(40).map(|it| it.collect::<Vec<_>>()));
1760
1761		// after adding the data for the first set the same query should work
1762		let mut authority_set_changes = AuthoritySetChanges::empty();
1763		authority_set_changes.append(0, 21);
1764		authority_set_changes.append(1, 41);
1765		authority_set_changes.append(2, 81);
1766		authority_set_changes.append(3, 121);
1767
1768		assert_eq!(
1769			Some(vec![(1, 41), (2, 81), (3, 121)]),
1770			authority_set_changes.iter_from(40).map(|it| it.cloned().collect::<Vec<_>>()),
1771		);
1772
1773		assert_eq!(
1774			Some(vec![(2, 81), (3, 121)]),
1775			authority_set_changes.iter_from(41).map(|it| it.cloned().collect::<Vec<_>>()),
1776		);
1777
1778		assert_eq!(0, authority_set_changes.iter_from(121).unwrap().count());
1779
1780		assert_eq!(0, authority_set_changes.iter_from(200).unwrap().count());
1781	}
1782}