referrerpolicy=no-referrer-when-downgrade

polkadot_statement_distribution/v2/
groups.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//! A utility for tracking groups and their members within a session.
18
19use polkadot_primitives::{
20	effective_minimum_backing_votes, GroupIndex, IndexedVec, ValidatorIndex,
21};
22
23use std::collections::HashMap;
24
25/// Validator groups within a session, plus some helpful indexing for
26/// looking up groups by validator indices or authority discovery ID.
27#[derive(Debug, Clone)]
28pub struct Groups {
29	groups: IndexedVec<GroupIndex, Vec<ValidatorIndex>>,
30	by_validator_index: HashMap<ValidatorIndex, GroupIndex>,
31	backing_threshold: u32,
32}
33
34impl Groups {
35	/// Create a new [`Groups`] tracker with the groups and discovery keys
36	/// from the session.
37	pub fn new(
38		groups: IndexedVec<GroupIndex, Vec<ValidatorIndex>>,
39		backing_threshold: u32,
40	) -> Self {
41		let mut by_validator_index = HashMap::new();
42
43		for (i, group) in groups.iter().enumerate() {
44			let index = GroupIndex(i as _);
45			for v in group {
46				by_validator_index.insert(*v, index);
47			}
48		}
49
50		Groups { groups, by_validator_index, backing_threshold }
51	}
52
53	/// Access all the underlying groups.
54	pub fn all(&self) -> &IndexedVec<GroupIndex, Vec<ValidatorIndex>> {
55		&self.groups
56	}
57
58	/// Get the underlying group validators by group index.
59	pub fn get(&self, group_index: GroupIndex) -> Option<&[ValidatorIndex]> {
60		self.groups.get(group_index).map(|x| &x[..])
61	}
62
63	/// Get the backing group size and backing threshold.
64	pub fn get_size_and_backing_threshold(
65		&self,
66		group_index: GroupIndex,
67	) -> Option<(usize, usize)> {
68		self.get(group_index)
69			.map(|g| (g.len(), effective_minimum_backing_votes(g.len(), self.backing_threshold)))
70	}
71
72	/// Get the group index for a validator by index.
73	pub fn by_validator_index(&self, validator_index: ValidatorIndex) -> Option<GroupIndex> {
74		self.by_validator_index.get(&validator_index).map(|x| *x)
75	}
76}