From a06097555c3d811184a30bed85d1238eca4ae2d6 Mon Sep 17 00:00:00 2001 From: Boluwatife Bakre Date: Sat, 22 Oct 2022 09:39:11 +0100 Subject: [PATCH] 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 * Update primitives/src/v2/mod.rs Co-authored-by: Andronik * Update primitives/src/v2/mod.rs Co-authored-by: Andronik * Update primitives/src/v2/mod.rs Co-authored-by: Andronik * Update primitives/src/v2/mod.rs Co-authored-by: Andronik * 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 * Update primitives/src/v2/mod.rs Co-authored-by: Andronik * Update primitives/src/v2/mod.rs Co-authored-by: Andronik * removed IterMut * Update node/core/dispute-coordinator/src/import.rs Co-authored-by: Andronik * Update node/core/dispute-coordinator/src/initialized.rs Co-authored-by: Andronik * Update primitives/src/v2/mod.rs Co-authored-by: Andronik * fmt * IterMut * documentation update Co-authored-by: Andronik * minor adjustments and new TypeIndex trait * spelling fix * TypeIndex fix Co-authored-by: Andronik --- node/core/approval-voting/src/criteria.rs | 24 ++-- node/core/approval-voting/src/import.rs | 44 +++++--- node/core/approval-voting/src/lib.rs | 4 +- node/core/approval-voting/src/tests.rs | 35 +++--- node/core/dispute-coordinator/src/import.rs | 12 +- .../dispute-coordinator/src/initialized.rs | 15 ++- node/core/dispute-coordinator/src/tests.rs | 16 +-- node/core/runtime-api/src/tests.rs | 4 +- .../src/tests/mock.rs | 13 ++- node/network/availability-recovery/src/lib.rs | 6 +- .../availability-recovery/src/tests.rs | 10 +- .../src/collator_side/mod.rs | 6 +- .../src/collator_side/tests.rs | 10 +- .../dispute-distribution/src/sender/mod.rs | 4 +- .../dispute-distribution/src/tests/mock.rs | 6 +- node/network/gossip-support/src/tests.rs | 5 +- .../network/statement-distribution/src/lib.rs | 15 ++- .../statement-distribution/src/tests.rs | 10 +- node/primitives/src/disputes/message.rs | 10 +- .../src/rolling_session_window.rs | 4 +- node/subsystem-util/src/runtime/mod.rs | 13 ++- primitives/src/v2/mod.rs | 105 +++++++++++++++++- runtime/parachains/src/builder.rs | 15 +-- runtime/parachains/src/disputes.rs | 3 +- runtime/parachains/src/disputes/slashing.rs | 2 +- .../src/disputes/slashing/benchmarking.rs | 2 +- runtime/parachains/src/session_info.rs | 4 +- runtime/parachains/src/session_info/tests.rs | 2 +- 28 files changed, 261 insertions(+), 138 deletions(-) diff --git a/node/core/approval-voting/src/criteria.rs b/node/core/approval-voting/src/criteria.rs index d7bedc9b0a7f..fea71d79c098 100644 --- a/node/core/approval-voting/src/criteria.rs +++ b/node/core/approval-voting/src/criteria.rs @@ -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, /// The groups of validators assigned to each core. - validator_groups: Vec>, + validator_groups: IndexedVec>, /// 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], + validator_groups: &IndexedVec>, 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> { + fn basic_groups( + n_validators: usize, + n_groups: usize, + ) -> IndexedVec> { 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::>::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::>::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, diff --git a/node/core/approval-voting/src/import.rs b/node/core/approval-voting/src/import.rs index 5413c271e0d6..df713143750f 100644 --- a/node/core/approval-voting/src/import.rs +++ b/node/core/approval-voting/src/import.rs @@ -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::::from( + vec![Sr25519Keyring::Alice.public().into(); 6], + ), + discovery_keys: Vec::new(), + assignment_keys: Vec::new(), + validator_groups: IndexedVec::>::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); diff --git a/node/core/approval-voting/src/lib.rs b/node/core/approval-voting/src/lib.rs index 467d8be612e9..cff420fa46b6 100644 --- a/node/core/approval-voting/src/lib.rs +++ b/node/core/approval-voting/src/lib.rs @@ -1803,7 +1803,7 @@ fn check_and_import_approval( )), }; - 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( }, }; - 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!( diff --git a/node/core/approval-voting/src/tests.rs b/node/core/approval-voting/src/tests.rs index bdb7a8c929b3..d5c8d3c01da4 100644 --- a/node/core/approval-voting/src/tests.rs +++ b/node/core/approval-voting/src/tests.rs @@ -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::>::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::>::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::>::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::>::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::>::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::>::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::>::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::>::from(vec![ vec![ValidatorIndex(0), ValidatorIndex(1)], vec![ValidatorIndex(2), ValidatorIndex(5)], vec![ValidatorIndex(3), ValidatorIndex(4)], - ], + ]), ..session_info(&validators) }; diff --git a/node/core/dispute-coordinator/src/import.rs b/node/core/dispute-coordinator/src/import.rs index 020d04792191..8eb3d173dcf7 100644 --- a/node/core/dispute-coordinator/src/import.rs +++ b/node/core/dispute-coordinator/src/import.rs @@ -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 { + pub fn validators(&self) -> &IndexedVec { &self.session.validators } @@ -229,7 +229,7 @@ impl CandidateVoteState { 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, ) -> HashSet { let mut controlled = HashSet::new(); for (index, validator) in validators.iter().enumerate() { diff --git a/node/core/dispute-coordinator/src/initialized.rs b/node/core/dispute-coordinator/src/initialized.rs index 5f29245f33f8..9229f61f3a78 100644 --- a/node/core/dispute-coordinator/src/initialized.rs +++ b/node/core/dispute-coordinator/src/initialized.rs @@ -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(), diff --git a/node/core/dispute-coordinator/src/tests.rs b/node/core/dispute-coordinator/src/tests.rs index aaef00999259..c6fe328d9537 100644 --- a/node/core/dispute-coordinator/src/tests.rs +++ b/node/core/dispute-coordinator/src/tests.rs @@ -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, - validator_public: Vec, - validator_groups: Vec>, + validator_public: IndexedVec, + validator_groups: IndexedVec>, master_keystore: Arc, subsystem_keystore: Arc, db: Arc, @@ -163,11 +163,11 @@ impl Default for TestState { .map(|k| ValidatorId::from(k.0.public())) .collect(); - let validator_groups = vec![ + let validator_groups = IndexedVec::>::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; diff --git a/node/core/runtime-api/src/tests.rs b/node/core/runtime-api/src/tests.rs index 2fab84179433..45286431e49d 100644 --- a/node/core/runtime-api/src/tests.rs +++ b/node/core/runtime-api/src/tests.rs @@ -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, diff --git a/node/network/availability-distribution/src/tests/mock.rs b/node/network/availability-distribution/src/tests/mock.rs index 86be0a1e230d..15ea1ab1bc53 100644 --- a/node/network/availability-distribution/src/tests/mock.rs +++ b/node/network/availability-distribution/src/tests/mock.rs @@ -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![5, 0, 3], vec![1, 6, 2, 4]] - .iter() - .map(|g| g.into_iter().map(|v| ValidatorIndex(*v)).collect()) - .collect(); + let validator_groups: IndexedVec> = + [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(), diff --git a/node/network/availability-recovery/src/lib.rs b/node/network/availability-recovery/src/lib.rs index a07f4e0baa52..4ca28c955f9e 100644 --- a/node/network/availability-recovery/src/lib.rs +++ b/node/network/availability-recovery/src/lib.rs @@ -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, /// Validators relevant to this `RecoveryTask`. - validators: Vec, + validators: IndexedVec, /// The number of pieces needed. threshold: usize, @@ -871,7 +871,7 @@ async fn launch_recovery_task( }; 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 _)) diff --git a/node/network/availability-recovery/src/tests.rs b/node/network/availability-recovery/src/tests.rs index 3e898088c7f9..c77278f645c1 100644 --- a/node/network/availability-recovery/src/tests.rs +++ b/node/network/availability-recovery/src/tests.rs @@ -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; @@ -179,7 +181,7 @@ impl Has { #[derive(Clone)] struct TestState { validators: Vec, - validator_public: Vec, + validator_public: IndexedVec, validator_authority_id: Vec, 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::>::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 { +fn validator_pubkeys(val_ids: &[Sr25519Keyring]) -> IndexedVec { val_ids.iter().map(|v| v.public().into()).collect() } diff --git a/node/network/collator-protocol/src/collator_side/mod.rs b/node/network/collator-protocol/src/collator_side/mod.rs index 4f2eea2ca747..7a603a8a404a 100644 --- a/node/network/collator-protocol/src/collator_side/mod.rs +++ b/node/network/collator-protocol/src/collator_side/mod.rs @@ -448,10 +448,8 @@ async fn determine_our_validators( 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; diff --git a/node/network/collator-protocol/src/collator_side/tests.rs b/node/network/collator-protocol/src/collator_side/tests.rs index c20a2d6c97a5..6575259b37b3 100644 --- a/node/network/collator-protocol/src/collator_side/tests.rs +++ b/node/network/collator-protocol/src/collator_side/tests.rs @@ -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 { +fn validator_pubkeys(val_ids: &[Sr25519Keyring]) -> IndexedVec { 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(); diff --git a/node/network/dispute-distribution/src/sender/mod.rs b/node/network/dispute-distribution/src/sender/mod.rs index 09b902173ede..331fe12c61e2 100644 --- a/node/network/dispute-distribution/src/sender/mod.rs +++ b/node/network/dispute-distribution/src/sender/mod.rs @@ -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()), diff --git a/node/network/dispute-distribution/src/tests/mock.rs b/node/network/dispute-distribution/src/tests/mock.rs index aa2a4485d480..bc64734d57a0 100644 --- a/node/network/dispute-distribution/src/tests/mock.rs +++ b/node/network/dispute-distribution/src/tests/mock.rs @@ -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, diff --git a/node/network/gossip-support/src/tests.rs b/node/network/gossip-support/src/tests.rs index 79f2a9a6db42..4b2b91f7cdba 100644 --- a/node/network/gossip-support/src/tests.rs +++ b/node/network/gossip-support/src/tests.rs @@ -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::>::from(vec![ + all_validator_indices, + ]), n_cores: 1, zeroth_delay_tranche_width: 1, relay_vrf_modulo_samples: 1, diff --git a/node/network/statement-distribution/src/lib.rs b/node/network/statement-distribution/src/lib.rs index 17ca5d8ea4ac..c0ac09dbe3f8 100644 --- a/node/network/statement-distribution/src/lib.rs +++ b/node/network/statement-distribution/src/lib.rs @@ -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, /// The parachain validators at the head's child session index. - validators: Vec, + validators: IndexedVec, /// 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, + validators: IndexedVec, 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 StatementDistributionSubsystem { // 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() diff --git a/node/network/statement-distribution/src/tests.rs b/node/network/statement-distribution/src/tests.rs index f3b9db00aef4..c1636557fdca 100644 --- a/node/network/statement-distribution/src/tests.rs +++ b/node/network/statement-distribution/src/tests.rs @@ -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::::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::::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, groups: Vec>) -> SessionInfo { - let validator_groups: Vec> = groups + let validator_groups: IndexedVec> = groups .iter() .map(|g| g.into_iter().map(|v| ValidatorIndex(*v)).collect()) .collect(); diff --git a/node/primitives/src/disputes/message.rs b/node/primitives/src/disputes/message.rs index 88a65ab04015..93d4e804f906 100644 --- a/node/primitives/src/disputes/message.rs +++ b/node/primitives/src/disputes/message.rs @@ -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( diff --git a/node/subsystem-util/src/rolling_session_window.rs b/node/subsystem-util/src/rolling_session_window.rs index 0ff2dc6deb13..700feb2ccff8 100644 --- a/node/subsystem-util/src/rolling_session_window.rs +++ b/node/subsystem-util/src/rolling_session_window.rs @@ -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 _, diff --git a/node/subsystem-util/src/runtime/mod.rs b/node/subsystem-util/src/runtime/mod.rs index 7fcae2c57b09..5b8baad0f94f 100644 --- a/node/subsystem-util/src/runtime/mod.rs +++ b/node/subsystem-util/src/runtime/mod.rs @@ -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 { + async fn get_our_index( + &self, + validators: &IndexedVec, + ) -> Option { 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)) } diff --git a/primitives/src/v2/mod.rs b/primitives/src/v2/mod.rs index e31d0e4d36f9..ea1f4fcca0b9 100644 --- a/primitives/src/v2/mod.rs +++ b/primitives/src/v2/mod.rs @@ -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 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 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 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(Vec, PhantomData K>); + +impl Default for IndexedVec { + fn default() -> Self { + Self(vec![], PhantomData) + } +} + +impl From> for IndexedVec { + fn from(validators: Vec) -> Self { + Self(validators, PhantomData) + } +} + +impl FromIterator for IndexedVec { + fn from_iter>(iter: T) -> Self { + Self(Vec::from_iter(iter), PhantomData) + } +} + +impl IndexedVec +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 { + 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 { + 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, + pub validators: IndexedVec, /// 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>, + pub validator_groups: IndexedVec>, /// 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, + pub validators: IndexedVec, /// 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>, + pub validator_groups: IndexedVec>, /// The number of availability cores used by the protocol during this session. pub n_cores: u32, /// The zeroth delay tranche width. diff --git a/runtime/parachains/src/builder.rs b/runtime/parachains/src/builder.rs index 42f54ecb3417..f4bc58f2d4f2 100644 --- a/runtime/parachains/src/builder.rs +++ b/runtime/parachains/src/builder.rs @@ -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 { /// Active validators. Validators should be declared prior to all other setup. - validators: Option>, + validators: Option>, /// 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 BenchBuilder { assert_eq!(>::session_index(), target_session); // We need to refetch validators since they have been shuffled. - let validators_shuffled: Vec<_> = session_info::Pallet::::session_info(target_session) + let validators_shuffled = session_info::Pallet::::session_info(target_session) .unwrap() .validators .clone(); @@ -549,7 +550,7 @@ impl BenchBuilder { .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::::benchmark_sign( public, CompactStatement::Valid(candidate_hash.clone()), @@ -606,7 +607,7 @@ impl BenchBuilder { 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. diff --git a/runtime/parachains/src/disputes.rs b/runtime/parachains/src/disputes.rs index a26eccad0daf..9f458421e2ed 100644 --- a/runtime/parachains/src/disputes.rs +++ b/runtime/parachains/src/disputes.rs @@ -985,8 +985,7 @@ impl Pallet { 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 diff --git a/runtime/parachains/src/disputes/slashing.rs b/runtime/parachains/src/disputes/slashing.rs index fd6708de6ba0..2dfdc87c4b4e 100644 --- a/runtime/parachains/src/disputes/slashing.rs +++ b/runtime/parachains/src/disputes/slashing.rs @@ -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 }; >::insert(session_index, candidate_hash, unapplied); diff --git a/runtime/parachains/src/disputes/slashing/benchmarking.rs b/runtime/parachains/src/disputes/slashing/benchmarking.rs index 2a21c3a0f62b..552172dc1901 100644 --- a/runtime/parachains/src/disputes/slashing/benchmarking.rs +++ b/runtime/parachains/src/disputes/slashing/benchmarking.rs @@ -80,7 +80,7 @@ where let session_index = crate::shared::Pallet::::session_index(); let session_info = crate::session_info::Pallet::::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::::prove(key).unwrap(); diff --git a/runtime/parachains/src/session_info.rs b/runtime/parachains/src/session_info.rs index c903638423c2..cbd67a200a16 100644 --- a/runtime/parachains/src/session_info.rs +++ b/runtime/parachains/src/session_info.rs @@ -126,12 +126,12 @@ impl Pallet { let dispute_period = config.dispute_period; - let validators = notification.validators.clone(); + let validators = notification.validators.clone().into(); let discovery_keys = ::authorities(); let assignment_keys = AssignmentKeysUnsafe::::get(); let active_set = >::active_validator_indices(); - let validator_groups = >::validator_groups(); + let validator_groups = >::validator_groups().into(); let n_cores = >::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; diff --git a/runtime/parachains/src/session_info/tests.rs b/runtime/parachains/src/session_info/tests.rs index 168bd3d1cc27..7bf68736b572 100644 --- a/runtime/parachains/src/session_info/tests.rs +++ b/runtime/parachains/src/session_info/tests.rs @@ -201,7 +201,7 @@ fn session_info_active_subsets() { }); let session = Sessions::::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),