mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-09 20:11:09 +00:00
Use a more typesafe approach for managing indexed data (#6150)
* Fix for issue #2403 * Nightly fmt * Quick documentation fixes * Default Implementation * iter() function integrated * Implemented iter functionalities * Fmt * small change * updates node-network * updates in dispute-coordinator * Updates * benchmarking fix * minor fix * test fixes in runtime api * Update primitives/src/v2/mod.rs Co-authored-by: Andronik <write@reusable.software> * Update primitives/src/v2/mod.rs Co-authored-by: Andronik <write@reusable.software> * Update primitives/src/v2/mod.rs Co-authored-by: Andronik <write@reusable.software> * Update primitives/src/v2/mod.rs Co-authored-by: Andronik <write@reusable.software> * Update primitives/src/v2/mod.rs Co-authored-by: Andronik <write@reusable.software> * Removal of [index], shorting of FromIterator, Renaming of GroupValidators to ValidatorGroups * Removal of ops import * documentation fixes for spell check * implementation of generic type * Refactoring * Test and documentation fixes * minor test fix * minor test fix * minor test fix * Update node/network/statement-distribution/src/lib.rs Co-authored-by: Andronik <write@reusable.software> * Update primitives/src/v2/mod.rs Co-authored-by: Andronik <write@reusable.software> * Update primitives/src/v2/mod.rs Co-authored-by: Andronik <write@reusable.software> * removed IterMut * Update node/core/dispute-coordinator/src/import.rs Co-authored-by: Andronik <write@reusable.software> * Update node/core/dispute-coordinator/src/initialized.rs Co-authored-by: Andronik <write@reusable.software> * Update primitives/src/v2/mod.rs Co-authored-by: Andronik <write@reusable.software> * fmt * IterMut * documentation update Co-authored-by: Andronik <write@reusable.software> * minor adjustments and new TypeIndex trait * spelling fix * TypeIndex fix Co-authored-by: Andronik <write@reusable.software>
This commit is contained in:
@@ -21,7 +21,8 @@ use polkadot_node_primitives::approval::{
|
||||
self as approval_types, AssignmentCert, AssignmentCertKind, DelayTranche, RelayVRFStory,
|
||||
};
|
||||
use polkadot_primitives::v2::{
|
||||
AssignmentId, AssignmentPair, CandidateHash, CoreIndex, GroupIndex, SessionInfo, ValidatorIndex,
|
||||
AssignmentId, AssignmentPair, CandidateHash, CoreIndex, GroupIndex, IndexedVec, SessionInfo,
|
||||
ValidatorIndex,
|
||||
};
|
||||
use sc_keystore::LocalKeystore;
|
||||
use sp_application_crypto::ByteArray;
|
||||
@@ -138,7 +139,7 @@ pub(crate) struct Config {
|
||||
/// The assignment public keys for validators.
|
||||
assignment_keys: Vec<AssignmentId>,
|
||||
/// The groups of validators assigned to each core.
|
||||
validator_groups: Vec<Vec<ValidatorIndex>>,
|
||||
validator_groups: IndexedVec<GroupIndex, Vec<ValidatorIndex>>,
|
||||
/// The number of availability cores used by the protocol during this session.
|
||||
n_cores: u32,
|
||||
/// The zeroth delay tranche width.
|
||||
@@ -541,11 +542,11 @@ pub(crate) fn check_assignment_cert(
|
||||
}
|
||||
|
||||
fn is_in_backing_group(
|
||||
validator_groups: &[Vec<ValidatorIndex>],
|
||||
validator_groups: &IndexedVec<GroupIndex, Vec<ValidatorIndex>>,
|
||||
validator: ValidatorIndex,
|
||||
group: GroupIndex,
|
||||
) -> bool {
|
||||
validator_groups.get(group.0 as usize).map_or(false, |g| g.contains(&validator))
|
||||
validator_groups.get(group).map_or(false, |g| g.contains(&validator))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@@ -590,7 +591,10 @@ mod tests {
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn basic_groups(n_validators: usize, n_groups: usize) -> Vec<Vec<ValidatorIndex>> {
|
||||
fn basic_groups(
|
||||
n_validators: usize,
|
||||
n_groups: usize,
|
||||
) -> IndexedVec<GroupIndex, Vec<ValidatorIndex>> {
|
||||
let size = n_validators / n_groups;
|
||||
let big_groups = n_validators % n_groups;
|
||||
let scraps = n_groups * size;
|
||||
@@ -631,10 +635,10 @@ mod tests {
|
||||
Sr25519Keyring::Bob,
|
||||
Sr25519Keyring::Charlie,
|
||||
]),
|
||||
validator_groups: vec![
|
||||
validator_groups: IndexedVec::<GroupIndex, Vec<ValidatorIndex>>::from(vec![
|
||||
vec![ValidatorIndex(0)],
|
||||
vec![ValidatorIndex(1), ValidatorIndex(2)],
|
||||
],
|
||||
]),
|
||||
n_cores: 2,
|
||||
zeroth_delay_tranche_width: 10,
|
||||
relay_vrf_modulo_samples: 3,
|
||||
@@ -666,10 +670,10 @@ mod tests {
|
||||
Sr25519Keyring::Bob,
|
||||
Sr25519Keyring::Charlie,
|
||||
]),
|
||||
validator_groups: vec![
|
||||
validator_groups: IndexedVec::<GroupIndex, Vec<ValidatorIndex>>::from(vec![
|
||||
vec![ValidatorIndex(0)],
|
||||
vec![ValidatorIndex(1), ValidatorIndex(2)],
|
||||
],
|
||||
]),
|
||||
n_cores: 2,
|
||||
zeroth_delay_tranche_width: 10,
|
||||
relay_vrf_modulo_samples: 3,
|
||||
@@ -696,7 +700,7 @@ mod tests {
|
||||
Sr25519Keyring::Bob,
|
||||
Sr25519Keyring::Charlie,
|
||||
]),
|
||||
validator_groups: vec![],
|
||||
validator_groups: Default::default(),
|
||||
n_cores: 0,
|
||||
zeroth_delay_tranche_width: 10,
|
||||
relay_vrf_modulo_samples: 3,
|
||||
|
||||
@@ -620,7 +620,9 @@ pub(crate) mod tests {
|
||||
use polkadot_node_subsystem::messages::{AllMessages, ApprovalVotingMessage};
|
||||
use polkadot_node_subsystem_test_helpers::make_subsystem_context;
|
||||
use polkadot_node_subsystem_util::database::Database;
|
||||
use polkadot_primitives::v2::{Id as ParaId, SessionInfo, ValidatorIndex};
|
||||
use polkadot_primitives::v2::{
|
||||
Id as ParaId, IndexedVec, SessionInfo, ValidatorId, ValidatorIndex,
|
||||
};
|
||||
pub(crate) use sp_consensus_babe::{
|
||||
digests::{CompatibleDigestItem, PreDigest, SecondaryVRFPreDigest},
|
||||
AllowedSlots, BabeEpochConfiguration, Epoch as BabeEpoch,
|
||||
@@ -713,10 +715,10 @@ pub(crate) mod tests {
|
||||
|
||||
fn dummy_session_info(index: SessionIndex) -> SessionInfo {
|
||||
SessionInfo {
|
||||
validators: Vec::new(),
|
||||
validators: Default::default(),
|
||||
discovery_keys: Vec::new(),
|
||||
assignment_keys: Vec::new(),
|
||||
validator_groups: Vec::new(),
|
||||
validator_groups: Default::default(),
|
||||
n_cores: index as _,
|
||||
zeroth_delay_tranche_width: index as _,
|
||||
relay_vrf_modulo_samples: index as _,
|
||||
@@ -1174,21 +1176,27 @@ pub(crate) mod tests {
|
||||
|
||||
let session = 5;
|
||||
let irrelevant = 666;
|
||||
let session_info = SessionInfo {
|
||||
validators: vec![Sr25519Keyring::Alice.public().into(); 6],
|
||||
discovery_keys: Vec::new(),
|
||||
assignment_keys: Vec::new(),
|
||||
validator_groups: vec![vec![ValidatorIndex(0); 5], vec![ValidatorIndex(0); 2]],
|
||||
n_cores: 6,
|
||||
needed_approvals: 2,
|
||||
zeroth_delay_tranche_width: irrelevant,
|
||||
relay_vrf_modulo_samples: irrelevant,
|
||||
n_delay_tranches: irrelevant,
|
||||
no_show_slots: irrelevant,
|
||||
active_validator_indices: Vec::new(),
|
||||
dispute_period: 6,
|
||||
random_seed: [0u8; 32],
|
||||
};
|
||||
let session_info =
|
||||
SessionInfo {
|
||||
validators: IndexedVec::<ValidatorIndex, ValidatorId>::from(
|
||||
vec![Sr25519Keyring::Alice.public().into(); 6],
|
||||
),
|
||||
discovery_keys: Vec::new(),
|
||||
assignment_keys: Vec::new(),
|
||||
validator_groups: IndexedVec::<GroupIndex, Vec<ValidatorIndex>>::from(vec![
|
||||
vec![ValidatorIndex(0); 5],
|
||||
vec![ValidatorIndex(0); 2],
|
||||
]),
|
||||
n_cores: 6,
|
||||
needed_approvals: 2,
|
||||
zeroth_delay_tranche_width: irrelevant,
|
||||
relay_vrf_modulo_samples: irrelevant,
|
||||
n_delay_tranches: irrelevant,
|
||||
no_show_slots: irrelevant,
|
||||
active_validator_indices: Vec::new(),
|
||||
dispute_period: 6,
|
||||
random_seed: [0u8; 32],
|
||||
};
|
||||
|
||||
let slot = Slot::from(10);
|
||||
|
||||
|
||||
@@ -1803,7 +1803,7 @@ fn check_and_import_approval<T>(
|
||||
)),
|
||||
};
|
||||
|
||||
let pubkey = match session_info.validators.get(approval.validator.0 as usize) {
|
||||
let pubkey = match session_info.validators.get(approval.validator) {
|
||||
Some(k) => k,
|
||||
None => respond_early!(ApprovalCheckResult::Bad(
|
||||
ApprovalCheckError::InvalidValidatorIndex(approval.validator),
|
||||
@@ -2503,7 +2503,7 @@ async fn issue_approval<Context>(
|
||||
},
|
||||
};
|
||||
|
||||
let validator_pubkey = match session_info.validators.get(validator_index.0 as usize) {
|
||||
let validator_pubkey = match session_info.validators.get(validator_index) {
|
||||
Some(p) => p,
|
||||
None => {
|
||||
gum::warn!(
|
||||
|
||||
@@ -32,7 +32,7 @@ use polkadot_node_subsystem_test_helpers as test_helpers;
|
||||
use polkadot_node_subsystem_util::TimeoutExt;
|
||||
use polkadot_overseer::HeadSupportsParachains;
|
||||
use polkadot_primitives::v2::{
|
||||
CandidateCommitments, CandidateEvent, CoreIndex, GroupIndex, Header, Id as ParaId,
|
||||
CandidateCommitments, CandidateEvent, CoreIndex, GroupIndex, Header, Id as ParaId, IndexedVec,
|
||||
ValidationCode, ValidatorSignature,
|
||||
};
|
||||
use std::time::Duration;
|
||||
@@ -739,7 +739,10 @@ fn session_info(keys: &[Sr25519Keyring]) -> SessionInfo {
|
||||
validators: keys.iter().map(|v| v.public().into()).collect(),
|
||||
discovery_keys: keys.iter().map(|v| v.public().into()).collect(),
|
||||
assignment_keys: keys.iter().map(|v| v.public().into()).collect(),
|
||||
validator_groups: vec![vec![ValidatorIndex(0)], vec![ValidatorIndex(1)]],
|
||||
validator_groups: IndexedVec::<GroupIndex, Vec<ValidatorIndex>>::from(vec![
|
||||
vec![ValidatorIndex(0)],
|
||||
vec![ValidatorIndex(1)],
|
||||
]),
|
||||
n_cores: keys.len() as _,
|
||||
needed_approvals: 2,
|
||||
zeroth_delay_tranche_width: 5,
|
||||
@@ -1552,11 +1555,11 @@ fn subsystem_second_approval_import_only_schedules_wakeups() {
|
||||
Sr25519Keyring::Eve,
|
||||
];
|
||||
let session_info = SessionInfo {
|
||||
validator_groups: vec![
|
||||
validator_groups: IndexedVec::<GroupIndex, Vec<ValidatorIndex>>::from(vec![
|
||||
vec![ValidatorIndex(0), ValidatorIndex(1)],
|
||||
vec![ValidatorIndex(2)],
|
||||
vec![ValidatorIndex(3), ValidatorIndex(4)],
|
||||
],
|
||||
]),
|
||||
needed_approvals: 1,
|
||||
..session_info(&validators)
|
||||
};
|
||||
@@ -1889,11 +1892,11 @@ fn import_checked_approval_updates_entries_and_schedules() {
|
||||
Sr25519Keyring::Eve,
|
||||
];
|
||||
let session_info = SessionInfo {
|
||||
validator_groups: vec![
|
||||
validator_groups: IndexedVec::<GroupIndex, Vec<ValidatorIndex>>::from(vec![
|
||||
vec![ValidatorIndex(0), ValidatorIndex(1)],
|
||||
vec![ValidatorIndex(2)],
|
||||
vec![ValidatorIndex(3), ValidatorIndex(4)],
|
||||
],
|
||||
]),
|
||||
..session_info(&validators)
|
||||
};
|
||||
|
||||
@@ -2046,11 +2049,11 @@ fn subsystem_import_checked_approval_sets_one_block_bit_at_a_time() {
|
||||
Sr25519Keyring::Eve,
|
||||
];
|
||||
let session_info = SessionInfo {
|
||||
validator_groups: vec![
|
||||
validator_groups: IndexedVec::<GroupIndex, Vec<ValidatorIndex>>::from(vec![
|
||||
vec![ValidatorIndex(0), ValidatorIndex(1)],
|
||||
vec![ValidatorIndex(2)],
|
||||
vec![ValidatorIndex(3), ValidatorIndex(4)],
|
||||
],
|
||||
]),
|
||||
..session_info(&validators)
|
||||
};
|
||||
|
||||
@@ -2336,11 +2339,11 @@ fn subsystem_validate_approvals_cache() {
|
||||
Sr25519Keyring::Eve,
|
||||
];
|
||||
let session_info = SessionInfo {
|
||||
validator_groups: vec![
|
||||
validator_groups: IndexedVec::<GroupIndex, Vec<ValidatorIndex>>::from(vec![
|
||||
vec![ValidatorIndex(0), ValidatorIndex(1)],
|
||||
vec![ValidatorIndex(2)],
|
||||
vec![ValidatorIndex(3), ValidatorIndex(4)],
|
||||
],
|
||||
]),
|
||||
..session_info(&validators)
|
||||
};
|
||||
|
||||
@@ -2548,11 +2551,11 @@ where
|
||||
Sr25519Keyring::Ferdie,
|
||||
];
|
||||
let session_info = SessionInfo {
|
||||
validator_groups: vec![
|
||||
validator_groups: IndexedVec::<GroupIndex, Vec<ValidatorIndex>>::from(vec![
|
||||
vec![ValidatorIndex(0), ValidatorIndex(1)],
|
||||
vec![ValidatorIndex(2), ValidatorIndex(3)],
|
||||
vec![ValidatorIndex(4), ValidatorIndex(5)],
|
||||
],
|
||||
]),
|
||||
relay_vrf_modulo_samples: 2,
|
||||
no_show_slots,
|
||||
..session_info(&validators)
|
||||
@@ -2868,11 +2871,11 @@ fn pre_covers_dont_stall_approval() {
|
||||
Sr25519Keyring::One,
|
||||
];
|
||||
let session_info = SessionInfo {
|
||||
validator_groups: vec![
|
||||
validator_groups: IndexedVec::<GroupIndex, Vec<ValidatorIndex>>::from(vec![
|
||||
vec![ValidatorIndex(0), ValidatorIndex(1)],
|
||||
vec![ValidatorIndex(2), ValidatorIndex(5)],
|
||||
vec![ValidatorIndex(3), ValidatorIndex(4)],
|
||||
],
|
||||
]),
|
||||
..session_info(&validators)
|
||||
};
|
||||
|
||||
@@ -3045,11 +3048,11 @@ fn waits_until_approving_assignments_are_old_enough() {
|
||||
Sr25519Keyring::One,
|
||||
];
|
||||
let session_info = SessionInfo {
|
||||
validator_groups: vec![
|
||||
validator_groups: IndexedVec::<GroupIndex, Vec<ValidatorIndex>>::from(vec![
|
||||
vec![ValidatorIndex(0), ValidatorIndex(1)],
|
||||
vec![ValidatorIndex(2), ValidatorIndex(5)],
|
||||
vec![ValidatorIndex(3), ValidatorIndex(4)],
|
||||
],
|
||||
]),
|
||||
..session_info(&validators)
|
||||
};
|
||||
|
||||
|
||||
@@ -31,8 +31,8 @@ use std::collections::{BTreeMap, HashMap, HashSet};
|
||||
use polkadot_node_primitives::{CandidateVotes, SignedDisputeStatement};
|
||||
use polkadot_node_subsystem_util::rolling_session_window::RollingSessionWindow;
|
||||
use polkadot_primitives::v2::{
|
||||
CandidateReceipt, DisputeStatement, SessionIndex, SessionInfo, ValidDisputeStatementKind,
|
||||
ValidatorId, ValidatorIndex, ValidatorPair, ValidatorSignature,
|
||||
CandidateReceipt, DisputeStatement, IndexedVec, SessionIndex, SessionInfo,
|
||||
ValidDisputeStatementKind, ValidatorId, ValidatorIndex, ValidatorPair, ValidatorSignature,
|
||||
};
|
||||
use sc_keystore::LocalKeystore;
|
||||
|
||||
@@ -63,7 +63,7 @@ impl<'a> CandidateEnvironment<'a> {
|
||||
}
|
||||
|
||||
/// Validators in the candidate's session.
|
||||
pub fn validators(&self) -> &Vec<ValidatorId> {
|
||||
pub fn validators(&self) -> &IndexedVec<ValidatorIndex, ValidatorId> {
|
||||
&self.session.validators
|
||||
}
|
||||
|
||||
@@ -229,7 +229,7 @@ impl CandidateVoteState<CandidateVotes> {
|
||||
for (statement, val_index) in statements {
|
||||
if env
|
||||
.validators()
|
||||
.get(val_index.0 as usize)
|
||||
.get(val_index)
|
||||
.map_or(true, |v| v != statement.validator_public())
|
||||
{
|
||||
gum::error!(
|
||||
@@ -488,7 +488,7 @@ impl ImportResult {
|
||||
for (index, sig) in approval_votes.into_iter() {
|
||||
debug_assert!(
|
||||
{
|
||||
let pub_key = &env.session_info().validators[index.0 as usize];
|
||||
let pub_key = &env.session_info().validators.get(index).expect("indices are validated by approval-voting subsystem; qed");
|
||||
let candidate_hash = votes.candidate_receipt.hash();
|
||||
let session_index = env.session_index();
|
||||
DisputeStatement::Valid(ValidDisputeStatementKind::ApprovalChecking)
|
||||
@@ -538,7 +538,7 @@ impl ImportResult {
|
||||
/// That is all `ValidatorIndex`es we have private keys for. Usually this will only be one.
|
||||
fn find_controlled_validator_indices(
|
||||
keystore: &LocalKeystore,
|
||||
validators: &[ValidatorId],
|
||||
validators: &IndexedVec<ValidatorIndex, ValidatorId>,
|
||||
) -> HashSet<ValidatorIndex> {
|
||||
let mut controlled = HashSet::new();
|
||||
for (index, validator) in validators.iter().enumerate() {
|
||||
|
||||
@@ -372,7 +372,7 @@ impl Initialized {
|
||||
.filter_map(|(validator_index, attestation)| {
|
||||
let validator_public: ValidatorId = session_info
|
||||
.validators
|
||||
.get(validator_index.0 as usize)
|
||||
.get(validator_index)
|
||||
.or_else(|| {
|
||||
gum::error!(
|
||||
target: LOG_TARGET,
|
||||
@@ -473,7 +473,7 @@ impl Initialized {
|
||||
|
||||
let validator_public: ValidatorId = session_info
|
||||
.validators
|
||||
.get(validator_index.0 as usize)
|
||||
.get(validator_index)
|
||||
.or_else(|| {
|
||||
gum::error!(
|
||||
target: LOG_TARGET,
|
||||
@@ -903,7 +903,7 @@ impl Initialized {
|
||||
let no_votes = Vec::new();
|
||||
let our_approval_votes = new_state.own_approval_votes().unwrap_or(&no_votes);
|
||||
for (validator_index, sig) in our_approval_votes {
|
||||
let pub_key = match env.validators().get(validator_index.0 as usize) {
|
||||
let pub_key = match env.validators().get(*validator_index) {
|
||||
None => {
|
||||
gum::error!(
|
||||
target: LOG_TARGET,
|
||||
@@ -1097,7 +1097,10 @@ impl Initialized {
|
||||
valid,
|
||||
candidate_hash,
|
||||
session,
|
||||
env.validators()[index.0 as usize].clone(),
|
||||
env.validators()
|
||||
.get(*index)
|
||||
.expect("`controlled_indices` are derived from `validators`; qed")
|
||||
.clone(),
|
||||
)
|
||||
.await;
|
||||
|
||||
@@ -1238,7 +1241,7 @@ fn make_dispute_message(
|
||||
our_vote.candidate_hash().clone(),
|
||||
our_vote.session_index(),
|
||||
validators
|
||||
.get(validator_index.0 as usize)
|
||||
.get(*validator_index)
|
||||
.ok_or(DisputeMessageCreationError::InvalidValidatorIndex)?
|
||||
.clone(),
|
||||
validator_signature.clone(),
|
||||
@@ -1253,7 +1256,7 @@ fn make_dispute_message(
|
||||
our_vote.candidate_hash().clone(),
|
||||
our_vote.session_index(),
|
||||
validators
|
||||
.get(validator_index.0 as usize)
|
||||
.get(*validator_index)
|
||||
.ok_or(DisputeMessageCreationError::InvalidValidatorIndex)?
|
||||
.clone(),
|
||||
validator_signature.clone(),
|
||||
|
||||
@@ -58,9 +58,9 @@ use polkadot_node_subsystem::{
|
||||
use polkadot_node_subsystem_test_helpers::{make_subsystem_context, TestSubsystemContextHandle};
|
||||
use polkadot_primitives::v2::{
|
||||
ApprovalVote, BlockNumber, CandidateCommitments, CandidateHash, CandidateReceipt,
|
||||
DisputeStatement, Hash, Header, MultiDisputeStatementSet, ScrapedOnChainVotes, SessionIndex,
|
||||
SessionInfo, SigningContext, ValidDisputeStatementKind, ValidatorId, ValidatorIndex,
|
||||
ValidatorSignature,
|
||||
DisputeStatement, GroupIndex, Hash, Header, IndexedVec, MultiDisputeStatementSet,
|
||||
ScrapedOnChainVotes, SessionIndex, SessionInfo, SigningContext, ValidDisputeStatementKind,
|
||||
ValidatorId, ValidatorIndex, ValidatorSignature,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
@@ -125,8 +125,8 @@ impl MockClock {
|
||||
|
||||
struct TestState {
|
||||
validators: Vec<Pair>,
|
||||
validator_public: Vec<ValidatorId>,
|
||||
validator_groups: Vec<Vec<ValidatorIndex>>,
|
||||
validator_public: IndexedVec<ValidatorIndex, ValidatorId>,
|
||||
validator_groups: IndexedVec<GroupIndex, Vec<ValidatorIndex>>,
|
||||
master_keystore: Arc<sc_keystore::LocalKeystore>,
|
||||
subsystem_keystore: Arc<sc_keystore::LocalKeystore>,
|
||||
db: Arc<dyn Database>,
|
||||
@@ -163,11 +163,11 @@ impl Default for TestState {
|
||||
.map(|k| ValidatorId::from(k.0.public()))
|
||||
.collect();
|
||||
|
||||
let validator_groups = vec![
|
||||
let validator_groups = IndexedVec::<GroupIndex, Vec<ValidatorIndex>>::from(vec![
|
||||
vec![ValidatorIndex(0), ValidatorIndex(1)],
|
||||
vec![ValidatorIndex(2), ValidatorIndex(3)],
|
||||
vec![ValidatorIndex(4), ValidatorIndex(5), ValidatorIndex(6)],
|
||||
];
|
||||
]);
|
||||
|
||||
let master_keystore = make_keystore(validators.iter().map(|v| v.1.clone())).into();
|
||||
let subsystem_keystore =
|
||||
@@ -431,7 +431,7 @@ impl TestState {
|
||||
session: SessionIndex,
|
||||
valid: bool,
|
||||
) -> SignedDisputeStatement {
|
||||
let public = self.validator_public[index.0 as usize].clone();
|
||||
let public = self.validator_public.get(index).unwrap().clone();
|
||||
|
||||
let keystore = self.master_keystore.clone() as SyncCryptoStorePtr;
|
||||
|
||||
|
||||
@@ -522,10 +522,10 @@ fn requests_session_index_for_child() {
|
||||
|
||||
fn dummy_session_info() -> SessionInfo {
|
||||
SessionInfo {
|
||||
validators: vec![],
|
||||
validators: Default::default(),
|
||||
discovery_keys: vec![],
|
||||
assignment_keys: vec![],
|
||||
validator_groups: vec![],
|
||||
validator_groups: Default::default(),
|
||||
n_cores: 4u32,
|
||||
zeroth_delay_tranche_width: 0u32,
|
||||
relay_vrf_modulo_samples: 0u32,
|
||||
|
||||
@@ -24,8 +24,8 @@ use polkadot_erasure_coding::{branches, obtain_chunks_v1 as obtain_chunks};
|
||||
use polkadot_node_primitives::{AvailableData, BlockData, ErasureChunk, PoV, Proof};
|
||||
use polkadot_primitives::v2::{
|
||||
CandidateCommitments, CandidateDescriptor, CandidateHash, CommittedCandidateReceipt,
|
||||
GroupIndex, Hash, HeadData, Id as ParaId, OccupiedCore, PersistedValidationData, SessionInfo,
|
||||
ValidatorIndex,
|
||||
GroupIndex, Hash, HeadData, Id as ParaId, IndexedVec, OccupiedCore, PersistedValidationData,
|
||||
SessionInfo, ValidatorIndex,
|
||||
};
|
||||
use polkadot_primitives_test_helpers::{
|
||||
dummy_collator, dummy_collator_signature, dummy_hash, dummy_validation_code,
|
||||
@@ -43,10 +43,11 @@ pub fn make_session_info() -> SessionInfo {
|
||||
Sr25519Keyring::One,
|
||||
];
|
||||
|
||||
let validator_groups: Vec<Vec<ValidatorIndex>> = [vec![5, 0, 3], vec![1, 6, 2, 4]]
|
||||
.iter()
|
||||
.map(|g| g.into_iter().map(|v| ValidatorIndex(*v)).collect())
|
||||
.collect();
|
||||
let validator_groups: IndexedVec<GroupIndex, Vec<ValidatorIndex>> =
|
||||
[vec![5, 0, 3], vec![1, 6, 2, 4]]
|
||||
.iter()
|
||||
.map(|g| g.into_iter().map(|v| ValidatorIndex(*v)).collect())
|
||||
.collect();
|
||||
|
||||
SessionInfo {
|
||||
discovery_keys: validators.iter().map(|k| k.public().into()).collect(),
|
||||
|
||||
@@ -58,7 +58,7 @@ use polkadot_node_subsystem::{
|
||||
use polkadot_node_subsystem_util::request_session_info;
|
||||
use polkadot_primitives::v2::{
|
||||
AuthorityDiscoveryId, BlakeTwo256, BlockNumber, CandidateHash, CandidateReceipt, GroupIndex,
|
||||
Hash, HashT, SessionIndex, SessionInfo, ValidatorId, ValidatorIndex,
|
||||
Hash, HashT, IndexedVec, SessionIndex, SessionInfo, ValidatorId, ValidatorIndex,
|
||||
};
|
||||
|
||||
mod error;
|
||||
@@ -134,7 +134,7 @@ struct RecoveryParams {
|
||||
validator_authority_keys: Vec<AuthorityDiscoveryId>,
|
||||
|
||||
/// Validators relevant to this `RecoveryTask`.
|
||||
validators: Vec<ValidatorId>,
|
||||
validators: IndexedVec<ValidatorIndex, ValidatorId>,
|
||||
|
||||
/// The number of pieces needed.
|
||||
threshold: usize,
|
||||
@@ -871,7 +871,7 @@ async fn launch_recovery_task<Context>(
|
||||
};
|
||||
|
||||
let phase = backing_group
|
||||
.and_then(|g| session_info.validator_groups.get(g.0 as usize))
|
||||
.and_then(|g| session_info.validator_groups.get(g))
|
||||
.map(|group| Source::RequestFromBackers(RequestFromBackers::new(group.clone())))
|
||||
.unwrap_or_else(|| {
|
||||
Source::RequestChunks(RequestChunksFromValidators::new(params.validators.len() as _))
|
||||
|
||||
@@ -36,7 +36,9 @@ use polkadot_node_subsystem::{
|
||||
};
|
||||
use polkadot_node_subsystem_test_helpers::{make_subsystem_context, TestSubsystemContextHandle};
|
||||
use polkadot_node_subsystem_util::TimeoutExt;
|
||||
use polkadot_primitives::v2::{AuthorityDiscoveryId, Hash, HeadData, PersistedValidationData};
|
||||
use polkadot_primitives::v2::{
|
||||
AuthorityDiscoveryId, Hash, HeadData, IndexedVec, PersistedValidationData, ValidatorId,
|
||||
};
|
||||
use polkadot_primitives_test_helpers::{dummy_candidate_receipt, dummy_hash};
|
||||
|
||||
type VirtualOverseer = TestSubsystemContextHandle<AvailabilityRecoveryMessage>;
|
||||
@@ -179,7 +181,7 @@ impl Has {
|
||||
#[derive(Clone)]
|
||||
struct TestState {
|
||||
validators: Vec<Sr25519Keyring>,
|
||||
validator_public: Vec<ValidatorId>,
|
||||
validator_public: IndexedVec<ValidatorIndex, ValidatorId>,
|
||||
validator_authority_id: Vec<AuthorityDiscoveryId>,
|
||||
current: Hash,
|
||||
candidate: CandidateReceipt,
|
||||
@@ -218,7 +220,7 @@ impl TestState {
|
||||
validators: self.validator_public.clone(),
|
||||
discovery_keys: self.validator_authority_id.clone(),
|
||||
// all validators in the same group.
|
||||
validator_groups: vec![(0..self.validators.len()).map(|i| ValidatorIndex(i as _)).collect()],
|
||||
validator_groups: IndexedVec::<GroupIndex,Vec<ValidatorIndex>>::from(vec![(0..self.validators.len()).map(|i| ValidatorIndex(i as _)).collect()]),
|
||||
assignment_keys: vec![],
|
||||
n_cores: 0,
|
||||
zeroth_delay_tranche_width: 0,
|
||||
@@ -402,7 +404,7 @@ impl TestState {
|
||||
}
|
||||
}
|
||||
|
||||
fn validator_pubkeys(val_ids: &[Sr25519Keyring]) -> Vec<ValidatorId> {
|
||||
fn validator_pubkeys(val_ids: &[Sr25519Keyring]) -> IndexedVec<ValidatorIndex, ValidatorId> {
|
||||
val_ids.iter().map(|v| v.public().into()).collect()
|
||||
}
|
||||
|
||||
|
||||
@@ -448,10 +448,8 @@ async fn determine_our_validators<Context>(
|
||||
let rotation_info = get_group_rotation_info(ctx.sender(), relay_parent).await?;
|
||||
|
||||
let current_group_index = rotation_info.group_for_core(core_index, cores);
|
||||
let current_validators = groups
|
||||
.get(current_group_index.0 as usize)
|
||||
.map(|v| v.as_slice())
|
||||
.unwrap_or_default();
|
||||
let current_validators =
|
||||
groups.get(current_group_index).map(|v| v.as_slice()).unwrap_or_default();
|
||||
|
||||
let validators = &info.discovery_keys;
|
||||
|
||||
|
||||
@@ -44,8 +44,8 @@ use polkadot_node_subsystem::{
|
||||
use polkadot_node_subsystem_test_helpers as test_helpers;
|
||||
use polkadot_node_subsystem_util::TimeoutExt;
|
||||
use polkadot_primitives::v2::{
|
||||
AuthorityDiscoveryId, CollatorPair, GroupRotationInfo, ScheduledCore, SessionIndex,
|
||||
SessionInfo, ValidatorId, ValidatorIndex,
|
||||
AuthorityDiscoveryId, CollatorPair, GroupIndex, GroupRotationInfo, IndexedVec, ScheduledCore,
|
||||
SessionIndex, SessionInfo, ValidatorId, ValidatorIndex,
|
||||
};
|
||||
use polkadot_primitives_test_helpers::TestCandidateBuilder;
|
||||
|
||||
@@ -62,7 +62,7 @@ struct TestState {
|
||||
session_index: SessionIndex,
|
||||
}
|
||||
|
||||
fn validator_pubkeys(val_ids: &[Sr25519Keyring]) -> Vec<ValidatorId> {
|
||||
fn validator_pubkeys(val_ids: &[Sr25519Keyring]) -> IndexedVec<ValidatorIndex, ValidatorId> {
|
||||
val_ids.iter().map(|v| v.public().into()).collect()
|
||||
}
|
||||
|
||||
@@ -135,7 +135,7 @@ impl TestState {
|
||||
fn current_group_validator_indices(&self) -> &[ValidatorIndex] {
|
||||
let core_num = self.availability_cores.len();
|
||||
let GroupIndex(group_idx) = self.group_rotation_info.group_for_core(CoreIndex(0), core_num);
|
||||
&self.session_info.validator_groups[group_idx as usize]
|
||||
&self.session_info.validator_groups.get(GroupIndex::from(group_idx)).unwrap()
|
||||
}
|
||||
|
||||
fn current_session_index(&self) -> SessionIndex {
|
||||
@@ -367,7 +367,7 @@ async fn distribute_collation(
|
||||
)) => {
|
||||
assert_eq!(relay_parent, test_state.relay_parent);
|
||||
tx.send(Ok((
|
||||
test_state.session_info.validator_groups.clone(),
|
||||
test_state.session_info.validator_groups.to_vec(),
|
||||
test_state.group_rotation_info.clone(),
|
||||
)))
|
||||
.unwrap();
|
||||
|
||||
@@ -299,7 +299,7 @@ impl DisputeSender {
|
||||
let valid_public = info
|
||||
.session_info
|
||||
.validators
|
||||
.get(valid_index.0 as usize)
|
||||
.get(*valid_index)
|
||||
.ok_or(JfyiError::InvalidStatementFromCoordinator)?;
|
||||
let valid_signed = SignedDisputeStatement::new_checked(
|
||||
DisputeStatement::Valid(kind.clone()),
|
||||
@@ -314,7 +314,7 @@ impl DisputeSender {
|
||||
let invalid_public = info
|
||||
.session_info
|
||||
.validators
|
||||
.get(invalid_index.0 as usize)
|
||||
.get(*invalid_index)
|
||||
.ok_or(JfyiError::InvalidValidatorIndexFromCoordinator)?;
|
||||
let invalid_signed = SignedDisputeStatement::new_checked(
|
||||
DisputeStatement::Invalid(kind.clone()),
|
||||
|
||||
@@ -84,7 +84,7 @@ pub static ref MOCK_SESSION_INFO: SessionInfo =
|
||||
.map(|k| MOCK_VALIDATORS_DISCOVERY_KEYS.get(&k).unwrap().clone())
|
||||
.collect(),
|
||||
assignment_keys: vec![],
|
||||
validator_groups: vec![],
|
||||
validator_groups: Default::default(),
|
||||
n_cores: 0,
|
||||
zeroth_delay_tranche_width: 0,
|
||||
relay_vrf_modulo_samples: 0,
|
||||
@@ -104,9 +104,9 @@ pub static ref MOCK_NEXT_SESSION_INFO: SessionInfo =
|
||||
.iter()
|
||||
.map(|k| MOCK_VALIDATORS_DISCOVERY_KEYS.get(&k).unwrap().clone())
|
||||
.collect(),
|
||||
validators: vec![],
|
||||
validators: Default::default(),
|
||||
assignment_keys: vec![],
|
||||
validator_groups: vec![],
|
||||
validator_groups: Default::default(),
|
||||
n_cores: 0,
|
||||
zeroth_delay_tranche_width: 0,
|
||||
relay_vrf_modulo_samples: 0,
|
||||
|
||||
@@ -37,6 +37,7 @@ use polkadot_node_subsystem::{
|
||||
};
|
||||
use polkadot_node_subsystem_test_helpers as test_helpers;
|
||||
use polkadot_node_subsystem_util::TimeoutExt as _;
|
||||
use polkadot_primitives::v2::{GroupIndex, IndexedVec};
|
||||
use test_helpers::mock::make_ferdie_keystore;
|
||||
|
||||
use super::*;
|
||||
@@ -219,7 +220,9 @@ fn make_session_info() -> SessionInfo {
|
||||
validators: AUTHORITY_KEYRINGS.iter().map(|k| k.public().into()).collect(),
|
||||
discovery_keys: AUTHORITIES.clone(),
|
||||
assignment_keys: AUTHORITY_KEYRINGS.iter().map(|k| k.public().into()).collect(),
|
||||
validator_groups: vec![all_validator_indices],
|
||||
validator_groups: IndexedVec::<GroupIndex, Vec<ValidatorIndex>>::from(vec![
|
||||
all_validator_indices,
|
||||
]),
|
||||
n_cores: 1,
|
||||
zeroth_delay_tranche_width: 1,
|
||||
relay_vrf_modulo_samples: 1,
|
||||
|
||||
@@ -47,8 +47,8 @@ use polkadot_node_subsystem::{
|
||||
};
|
||||
use polkadot_primitives::v2::{
|
||||
AuthorityDiscoveryId, CandidateHash, CommittedCandidateReceipt, CompactStatement, Hash,
|
||||
SignedStatement, SigningContext, UncheckedSignedStatement, ValidatorId, ValidatorIndex,
|
||||
ValidatorSignature,
|
||||
IndexedVec, SignedStatement, SigningContext, UncheckedSignedStatement, ValidatorId,
|
||||
ValidatorIndex, ValidatorSignature,
|
||||
};
|
||||
|
||||
use futures::{
|
||||
@@ -665,7 +665,7 @@ struct ActiveHeadData {
|
||||
/// Large statements we are waiting for with associated meta data.
|
||||
waiting_large_statements: HashMap<CandidateHash, LargeStatementStatus>,
|
||||
/// The parachain validators at the head's child session index.
|
||||
validators: Vec<ValidatorId>,
|
||||
validators: IndexedVec<ValidatorIndex, ValidatorId>,
|
||||
/// The current session index of this fork.
|
||||
session_index: sp_staking::SessionIndex,
|
||||
/// How many `Seconded` statements we've seen per validator.
|
||||
@@ -676,7 +676,7 @@ struct ActiveHeadData {
|
||||
|
||||
impl ActiveHeadData {
|
||||
fn new(
|
||||
validators: Vec<ValidatorId>,
|
||||
validators: IndexedVec<ValidatorIndex, ValidatorId>,
|
||||
session_index: sp_staking::SessionIndex,
|
||||
span: PerLeafSpan,
|
||||
) -> Self {
|
||||
@@ -878,7 +878,7 @@ fn check_statement_signature(
|
||||
SigningContext { session_index: head.session_index, parent_hash: relay_parent };
|
||||
|
||||
head.validators
|
||||
.get(statement.unchecked_validator_index().0 as usize)
|
||||
.get(statement.unchecked_validator_index())
|
||||
.ok_or_else(|| statement.clone())
|
||||
.and_then(|v| statement.try_into_checked(&signing_context, v))
|
||||
}
|
||||
@@ -2072,7 +2072,10 @@ impl<R: rand::Rng> StatementDistributionSubsystem<R> {
|
||||
// directly:
|
||||
let group_peers = {
|
||||
if let Some(our_group) = validator_info.our_group {
|
||||
let our_group = &session_info.validator_groups[our_group.0 as usize];
|
||||
let our_group = &session_info
|
||||
.validator_groups
|
||||
.get(our_group)
|
||||
.expect("`our_group` is derived from `validator_groups`; qed");
|
||||
|
||||
our_group
|
||||
.into_iter()
|
||||
|
||||
@@ -35,7 +35,9 @@ use polkadot_node_subsystem::{
|
||||
ActivatedLeaf, LeafStatus,
|
||||
};
|
||||
use polkadot_node_subsystem_test_helpers::mock::make_ferdie_keystore;
|
||||
use polkadot_primitives::v2::{Hash, Id as ParaId, SessionInfo, ValidationCode};
|
||||
use polkadot_primitives::v2::{
|
||||
GroupIndex, Hash, Id as ParaId, IndexedVec, SessionInfo, ValidationCode, ValidatorId,
|
||||
};
|
||||
use polkadot_primitives_test_helpers::{
|
||||
dummy_committed_candidate_receipt, dummy_hash, AlwaysZeroRng,
|
||||
};
|
||||
@@ -83,7 +85,7 @@ fn active_head_accepts_only_2_seconded_per_validator() {
|
||||
};
|
||||
|
||||
let mut head_data = ActiveHeadData::new(
|
||||
validators,
|
||||
IndexedVec::<ValidatorIndex, ValidatorId>::from(validators),
|
||||
session_index,
|
||||
PerLeafSpan::new(Arc::new(jaeger::Span::Disabled), "test"),
|
||||
);
|
||||
@@ -429,7 +431,7 @@ fn peer_view_update_sends_messages() {
|
||||
|
||||
let new_head_data = {
|
||||
let mut data = ActiveHeadData::new(
|
||||
validators,
|
||||
IndexedVec::<ValidatorIndex, ValidatorId>::from(validators),
|
||||
session_index,
|
||||
PerLeafSpan::new(Arc::new(jaeger::Span::Disabled), "test"),
|
||||
);
|
||||
@@ -2319,7 +2321,7 @@ fn handle_multiple_seconded_statements() {
|
||||
}
|
||||
|
||||
fn make_session_info(validators: Vec<Pair>, groups: Vec<Vec<u32>>) -> SessionInfo {
|
||||
let validator_groups: Vec<Vec<ValidatorIndex>> = groups
|
||||
let validator_groups: IndexedVec<GroupIndex, Vec<ValidatorIndex>> = groups
|
||||
.iter()
|
||||
.map(|g| g.into_iter().map(|v| ValidatorIndex(*v)).collect())
|
||||
.collect();
|
||||
|
||||
@@ -135,11 +135,11 @@ impl DisputeMessage {
|
||||
|
||||
let valid_id = session_info
|
||||
.validators
|
||||
.get(valid_index.0 as usize)
|
||||
.get(valid_index)
|
||||
.ok_or(Error::ValidStatementInvalidValidatorIndex)?;
|
||||
let invalid_id = session_info
|
||||
.validators
|
||||
.get(invalid_index.0 as usize)
|
||||
.get(invalid_index)
|
||||
.ok_or(Error::InvalidStatementInvalidValidatorIndex)?;
|
||||
|
||||
if valid_id != valid_statement.validator_public() {
|
||||
@@ -223,8 +223,7 @@ impl UncheckedDisputeMessage {
|
||||
|
||||
let vote_valid = {
|
||||
let ValidDisputeVote { validator_index, signature, kind } = valid_vote;
|
||||
let validator_public =
|
||||
session_info.validators.get(validator_index.0 as usize).ok_or(())?.clone();
|
||||
let validator_public = session_info.validators.get(validator_index).ok_or(())?.clone();
|
||||
|
||||
(
|
||||
SignedDisputeStatement::new_checked(
|
||||
@@ -240,8 +239,7 @@ impl UncheckedDisputeMessage {
|
||||
|
||||
let vote_invalid = {
|
||||
let InvalidDisputeVote { validator_index, signature, kind } = invalid_vote;
|
||||
let validator_public =
|
||||
session_info.validators.get(validator_index.0 as usize).ok_or(())?.clone();
|
||||
let validator_public = session_info.validators.get(validator_index).ok_or(())?.clone();
|
||||
|
||||
(
|
||||
SignedDisputeStatement::new_checked(
|
||||
|
||||
@@ -399,10 +399,10 @@ mod tests {
|
||||
|
||||
fn dummy_session_info(index: SessionIndex) -> SessionInfo {
|
||||
SessionInfo {
|
||||
validators: Vec::new(),
|
||||
validators: Default::default(),
|
||||
discovery_keys: Vec::new(),
|
||||
assignment_keys: Vec::new(),
|
||||
validator_groups: Vec::new(),
|
||||
validator_groups: Default::default(),
|
||||
n_cores: index as _,
|
||||
zeroth_delay_tranche_width: index as _,
|
||||
relay_vrf_modulo_samples: index as _,
|
||||
|
||||
@@ -27,9 +27,9 @@ use sp_keystore::{CryptoStore, SyncCryptoStorePtr};
|
||||
|
||||
use polkadot_node_subsystem::{messages::RuntimeApiMessage, overseer, SubsystemSender};
|
||||
use polkadot_primitives::v2::{
|
||||
CandidateEvent, CoreState, EncodeAs, GroupIndex, GroupRotationInfo, Hash, OccupiedCore,
|
||||
ScrapedOnChainVotes, SessionIndex, SessionInfo, Signed, SigningContext, UncheckedSigned,
|
||||
ValidationCode, ValidationCodeHash, ValidatorId, ValidatorIndex,
|
||||
CandidateEvent, CoreState, EncodeAs, GroupIndex, GroupRotationInfo, Hash, IndexedVec,
|
||||
OccupiedCore, ScrapedOnChainVotes, SessionIndex, SessionInfo, Signed, SigningContext,
|
||||
UncheckedSigned, ValidationCode, ValidationCodeHash, ValidatorId, ValidatorIndex,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
@@ -228,7 +228,10 @@ impl RuntimeInfo {
|
||||
/// Get our `ValidatorIndex`.
|
||||
///
|
||||
/// Returns: None if we are not a validator.
|
||||
async fn get_our_index(&self, validators: &[ValidatorId]) -> Option<ValidatorIndex> {
|
||||
async fn get_our_index(
|
||||
&self,
|
||||
validators: &IndexedVec<ValidatorIndex, ValidatorId>,
|
||||
) -> Option<ValidatorIndex> {
|
||||
let keystore = self.keystore.as_ref()?;
|
||||
for (i, v) in validators.iter().enumerate() {
|
||||
if CryptoStore::has_keys(&**keystore, &[(v.to_raw_vec(), ValidatorId::ID)]).await {
|
||||
@@ -254,7 +257,7 @@ where
|
||||
|
||||
session_info
|
||||
.validators
|
||||
.get(signed.unchecked_validator_index().0 as usize)
|
||||
.get(signed.unchecked_validator_index())
|
||||
.ok_or_else(|| signed.clone())
|
||||
.and_then(|v| signed.try_into_checked(&signing_context, v))
|
||||
}
|
||||
|
||||
@@ -19,7 +19,12 @@
|
||||
use bitvec::vec::BitVec;
|
||||
use parity_scale_codec::{Decode, Encode};
|
||||
use scale_info::TypeInfo;
|
||||
use sp_std::prelude::*;
|
||||
use sp_std::{
|
||||
marker::PhantomData,
|
||||
prelude::*,
|
||||
slice::{Iter, IterMut},
|
||||
vec::IntoIter,
|
||||
};
|
||||
|
||||
use application_crypto::KeyTypeId;
|
||||
use inherents::InherentIdentifier;
|
||||
@@ -123,6 +128,12 @@ impl MallocSizeOf for ValidatorId {
|
||||
}
|
||||
}
|
||||
|
||||
/// Trait required for type specific indices e.g. `ValidatorIndex` and `GroupIndex`
|
||||
pub trait TypeIndex {
|
||||
/// Returns the index associated to this value.
|
||||
fn type_index(&self) -> usize;
|
||||
}
|
||||
|
||||
/// Index of the validator is used as a lightweight replacement of the `ValidatorId` when appropriate.
|
||||
#[derive(Eq, Ord, PartialEq, PartialOrd, Copy, Clone, Encode, Decode, TypeInfo, RuntimeDebug)]
|
||||
#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Hash, MallocSizeOf))]
|
||||
@@ -135,6 +146,12 @@ impl From<u32> for ValidatorIndex {
|
||||
}
|
||||
}
|
||||
|
||||
impl TypeIndex for ValidatorIndex {
|
||||
fn type_index(&self) -> usize {
|
||||
self.0 as usize
|
||||
}
|
||||
}
|
||||
|
||||
application_crypto::with_pair! {
|
||||
/// A Parachain validator keypair.
|
||||
pub type ValidatorPair = validator_app::Pair;
|
||||
@@ -779,6 +796,12 @@ impl From<u32> for CoreIndex {
|
||||
}
|
||||
}
|
||||
|
||||
impl TypeIndex for CoreIndex {
|
||||
fn type_index(&self) -> usize {
|
||||
self.0 as usize
|
||||
}
|
||||
}
|
||||
|
||||
/// The unique (during session) index of a validator group.
|
||||
#[derive(Encode, Decode, Default, Clone, Copy, Debug, PartialEq, Eq, TypeInfo)]
|
||||
#[cfg_attr(feature = "std", derive(Hash, MallocSizeOf))]
|
||||
@@ -790,6 +813,12 @@ impl From<u32> for GroupIndex {
|
||||
}
|
||||
}
|
||||
|
||||
impl TypeIndex for GroupIndex {
|
||||
fn type_index(&self) -> usize {
|
||||
self.0 as usize
|
||||
}
|
||||
}
|
||||
|
||||
/// A claim on authoring the next block for a given parathread.
|
||||
#[derive(Clone, Encode, Decode, TypeInfo, RuntimeDebug)]
|
||||
#[cfg_attr(feature = "std", derive(PartialEq))]
|
||||
@@ -1569,6 +1598,72 @@ impl CompactStatement {
|
||||
}
|
||||
}
|
||||
|
||||
/// `IndexedVec` struct indexed by type specific indices.
|
||||
#[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo)]
|
||||
#[cfg_attr(feature = "std", derive(PartialEq, MallocSizeOf))]
|
||||
pub struct IndexedVec<K, V>(Vec<V>, PhantomData<fn(K) -> K>);
|
||||
|
||||
impl<K, V> Default for IndexedVec<K, V> {
|
||||
fn default() -> Self {
|
||||
Self(vec![], PhantomData)
|
||||
}
|
||||
}
|
||||
|
||||
impl<K, V> From<Vec<V>> for IndexedVec<K, V> {
|
||||
fn from(validators: Vec<V>) -> Self {
|
||||
Self(validators, PhantomData)
|
||||
}
|
||||
}
|
||||
|
||||
impl<K, V> FromIterator<V> for IndexedVec<K, V> {
|
||||
fn from_iter<T: IntoIterator<Item = V>>(iter: T) -> Self {
|
||||
Self(Vec::from_iter(iter), PhantomData)
|
||||
}
|
||||
}
|
||||
|
||||
impl<K, V> IndexedVec<K, V>
|
||||
where
|
||||
V: Clone,
|
||||
{
|
||||
/// Returns a reference to an element indexed using `K`.
|
||||
pub fn get(&self, index: K) -> Option<&V>
|
||||
where
|
||||
K: TypeIndex,
|
||||
{
|
||||
self.0.get(index.type_index())
|
||||
}
|
||||
|
||||
/// Returns number of elements in vector.
|
||||
pub fn len(&self) -> usize {
|
||||
self.0.len()
|
||||
}
|
||||
|
||||
/// Returns contained vector.
|
||||
pub fn to_vec(&self) -> Vec<V> {
|
||||
self.0.clone()
|
||||
}
|
||||
|
||||
/// Returns an iterator over the underlying vector.
|
||||
pub fn iter(&self) -> Iter<'_, V> {
|
||||
self.0.iter()
|
||||
}
|
||||
|
||||
/// Returns a mutable iterator over the underlying vector.
|
||||
pub fn iter_mut(&mut self) -> IterMut<'_, V> {
|
||||
self.0.iter_mut()
|
||||
}
|
||||
|
||||
/// Creates a consuming iterator.
|
||||
pub fn into_iter(self) -> IntoIter<V> {
|
||||
self.0.into_iter()
|
||||
}
|
||||
|
||||
/// Returns true if the underlying container is empty.
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.0.is_empty()
|
||||
}
|
||||
}
|
||||
|
||||
/// The maximum number of validators `f` which may safely be faulty.
|
||||
///
|
||||
/// The total number of validators is `n = 3f + e` where `e in { 1, 2, 3 }`.
|
||||
@@ -1603,7 +1698,7 @@ pub struct SessionInfo {
|
||||
/// [`max_validators`](https://github.com/paritytech/polkadot/blob/a52dca2be7840b23c19c153cf7e110b1e3e475f8/runtime/parachains/src/configuration.rs#L148).
|
||||
///
|
||||
/// `SessionInfo::validators` will be limited to to `max_validators` when set.
|
||||
pub validators: Vec<ValidatorId>,
|
||||
pub validators: IndexedVec<ValidatorIndex, ValidatorId>,
|
||||
/// Validators' authority discovery keys for the session in canonical ordering.
|
||||
///
|
||||
/// NOTE: The first `validators.len()` entries will match the corresponding validators in
|
||||
@@ -1626,7 +1721,7 @@ pub struct SessionInfo {
|
||||
/// Validators in shuffled ordering - these are the validator groups as produced
|
||||
/// by the `Scheduler` module for the session and are typically referred to by
|
||||
/// `GroupIndex`.
|
||||
pub validator_groups: Vec<Vec<ValidatorIndex>>,
|
||||
pub validator_groups: IndexedVec<GroupIndex, Vec<ValidatorIndex>>,
|
||||
/// The number of availability cores used by the protocol during this session.
|
||||
pub n_cores: u32,
|
||||
/// The zeroth delay tranche width.
|
||||
@@ -1679,7 +1774,7 @@ pub struct OldV1SessionInfo {
|
||||
/// [`max_validators`](https://github.com/paritytech/polkadot/blob/a52dca2be7840b23c19c153cf7e110b1e3e475f8/runtime/parachains/src/configuration.rs#L148).
|
||||
///
|
||||
/// `SessionInfo::validators` will be limited to to `max_validators` when set.
|
||||
pub validators: Vec<ValidatorId>,
|
||||
pub validators: IndexedVec<ValidatorIndex, ValidatorId>,
|
||||
/// Validators' authority discovery keys for the session in canonical ordering.
|
||||
///
|
||||
/// NOTE: The first `validators.len()` entries will match the corresponding validators in
|
||||
@@ -1702,7 +1797,7 @@ pub struct OldV1SessionInfo {
|
||||
/// Validators in shuffled ordering - these are the validator groups as produced
|
||||
/// by the `Scheduler` module for the session and are typically referred to by
|
||||
/// `GroupIndex`.
|
||||
pub validator_groups: Vec<Vec<ValidatorIndex>>,
|
||||
pub validator_groups: IndexedVec<GroupIndex, Vec<ValidatorIndex>>,
|
||||
/// The number of availability cores used by the protocol during this session.
|
||||
pub n_cores: u32,
|
||||
/// The zeroth delay tranche width.
|
||||
|
||||
@@ -25,9 +25,10 @@ use primitives::v2::{
|
||||
collator_signature_payload, AvailabilityBitfield, BackedCandidate, CandidateCommitments,
|
||||
CandidateDescriptor, CandidateHash, CollatorId, CollatorSignature, CommittedCandidateReceipt,
|
||||
CompactStatement, CoreIndex, CoreOccupied, DisputeStatement, DisputeStatementSet, GroupIndex,
|
||||
HeadData, Id as ParaId, InherentData as ParachainsInherentData, InvalidDisputeStatementKind,
|
||||
PersistedValidationData, SessionIndex, SigningContext, UncheckedSigned,
|
||||
ValidDisputeStatementKind, ValidationCode, ValidatorId, ValidatorIndex, ValidityAttestation,
|
||||
HeadData, Id as ParaId, IndexedVec, InherentData as ParachainsInherentData,
|
||||
InvalidDisputeStatementKind, PersistedValidationData, SessionIndex, SigningContext,
|
||||
UncheckedSigned, ValidDisputeStatementKind, ValidationCode, ValidatorId, ValidatorIndex,
|
||||
ValidityAttestation,
|
||||
};
|
||||
use sp_core::{sr25519, H256};
|
||||
use sp_runtime::{
|
||||
@@ -65,7 +66,7 @@ fn byte32_slice_from(n: u32) -> [u8; 32] {
|
||||
/// Paras inherent `enter` benchmark scenario builder.
|
||||
pub(crate) struct BenchBuilder<T: paras_inherent::Config> {
|
||||
/// Active validators. Validators should be declared prior to all other setup.
|
||||
validators: Option<Vec<ValidatorId>>,
|
||||
validators: Option<IndexedVec<ValidatorIndex, ValidatorId>>,
|
||||
/// Starting block number; we expect it to get incremented on session setup.
|
||||
block_number: T::BlockNumber,
|
||||
/// Starting session; we expect it to get incremented on session setup.
|
||||
@@ -410,7 +411,7 @@ impl<T: paras_inherent::Config> BenchBuilder<T> {
|
||||
assert_eq!(<shared::Pallet<T>>::session_index(), target_session);
|
||||
|
||||
// We need to refetch validators since they have been shuffled.
|
||||
let validators_shuffled: Vec<_> = session_info::Pallet::<T>::session_info(target_session)
|
||||
let validators_shuffled = session_info::Pallet::<T>::session_info(target_session)
|
||||
.unwrap()
|
||||
.validators
|
||||
.clone();
|
||||
@@ -549,7 +550,7 @@ impl<T: paras_inherent::Config> BenchBuilder<T> {
|
||||
.iter()
|
||||
.take(*num_votes as usize)
|
||||
.map(|val_idx| {
|
||||
let public = validators.get(val_idx.0 as usize).unwrap();
|
||||
let public = validators.get(*val_idx).unwrap();
|
||||
let sig = UncheckedSigned::<CompactStatement>::benchmark_sign(
|
||||
public,
|
||||
CompactStatement::Valid(candidate_hash.clone()),
|
||||
@@ -606,7 +607,7 @@ impl<T: paras_inherent::Config> BenchBuilder<T> {
|
||||
self.dispute_statements.get(&seed).cloned().unwrap_or(validators.len() as u32);
|
||||
let statements = (0..statements_len)
|
||||
.map(|validator_index| {
|
||||
let validator_public = &validators.get(validator_index as usize).expect("Test case is not borked. `ValidatorIndex` out of bounds of `ValidatorId`s.");
|
||||
let validator_public = &validators.get(ValidatorIndex::from(validator_index)).expect("Test case is not borked. `ValidatorIndex` out of bounds of `ValidatorId`s.");
|
||||
|
||||
// We need dispute statements on each side. And we don't want a revert log
|
||||
// so we make sure that we have a super majority with valid statements.
|
||||
|
||||
@@ -985,8 +985,7 @@ impl<T: Config> Pallet<T> {
|
||||
let mut importer = DisputeStateImporter::new(dispute_state, now);
|
||||
for (i, (statement, validator_index, signature)) in set.statements.iter().enumerate() {
|
||||
// assure the validator index and is present in the session info
|
||||
let validator_public = match session_info.validators.get(validator_index.0 as usize)
|
||||
{
|
||||
let validator_public = match session_info.validators.get(*validator_index) {
|
||||
None => {
|
||||
filter.remove_index(i);
|
||||
continue
|
||||
|
||||
@@ -257,7 +257,7 @@ where
|
||||
|
||||
let keys = losers
|
||||
.into_iter()
|
||||
.filter_map(|i| session_info.validators.get(i.0 as usize).cloned().map(|id| (i, id)))
|
||||
.filter_map(|i| session_info.validators.get(i).cloned().map(|id| (i, id)))
|
||||
.collect();
|
||||
let unapplied = PendingSlashes { keys, kind };
|
||||
<UnappliedSlashes<T>>::insert(session_index, candidate_hash, unapplied);
|
||||
|
||||
@@ -80,7 +80,7 @@ where
|
||||
let session_index = crate::shared::Pallet::<T>::session_index();
|
||||
let session_info = crate::session_info::Pallet::<T>::session_info(session_index);
|
||||
let session_info = session_info.unwrap();
|
||||
let validator_id = session_info.validators[0].clone();
|
||||
let validator_id = session_info.validators.get(ValidatorIndex::from(0)).unwrap().clone();
|
||||
let key = (PARACHAIN_KEY_TYPE_ID, validator_id.clone());
|
||||
let key_owner_proof = pallet_session::historical::Pallet::<T>::prove(key).unwrap();
|
||||
|
||||
|
||||
@@ -126,12 +126,12 @@ impl<T: Config> Pallet<T> {
|
||||
|
||||
let dispute_period = config.dispute_period;
|
||||
|
||||
let validators = notification.validators.clone();
|
||||
let validators = notification.validators.clone().into();
|
||||
let discovery_keys = <T as AuthorityDiscoveryConfig>::authorities();
|
||||
let assignment_keys = AssignmentKeysUnsafe::<T>::get();
|
||||
let active_set = <shared::Pallet<T>>::active_validator_indices();
|
||||
|
||||
let validator_groups = <scheduler::Pallet<T>>::validator_groups();
|
||||
let validator_groups = <scheduler::Pallet<T>>::validator_groups().into();
|
||||
let n_cores = <scheduler::Pallet<T>>::availability_cores().len() as u32;
|
||||
let zeroth_delay_tranche_width = config.zeroth_delay_tranche_width;
|
||||
let relay_vrf_modulo_samples = config.relay_vrf_modulo_samples;
|
||||
|
||||
@@ -201,7 +201,7 @@ fn session_info_active_subsets() {
|
||||
});
|
||||
let session = Sessions::<Test>::get(&1).unwrap();
|
||||
|
||||
assert_eq!(session.validators, validators);
|
||||
assert_eq!(session.validators.to_vec(), validators);
|
||||
assert_eq!(
|
||||
session.discovery_keys,
|
||||
take_active_subset_and_inactive(&active_set, &unscrambled_discovery),
|
||||
|
||||
Reference in New Issue
Block a user