Skip to content

Commit

Permalink
Fix for issue #2403
Browse files Browse the repository at this point in the history
  • Loading branch information
tifecool committed Oct 13, 2022
1 parent 15709ee commit b5c02e8
Show file tree
Hide file tree
Showing 9 changed files with 98 additions and 31 deletions.
8 changes: 4 additions & 4 deletions node/primitives/src/disputes/message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down Expand Up @@ -224,7 +224,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();
session_info.validators.get(validator_index).ok_or(())?.clone();

(
SignedDisputeStatement::new_checked(
Expand All @@ -241,7 +241,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();
session_info.validators.get(validator_index).ok_or(())?.clone();

(
SignedDisputeStatement::new_checked(
Expand Down
6 changes: 3 additions & 3 deletions node/subsystem-util/src/rolling_session_window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -392,17 +392,17 @@ mod tests {
SubsystemContext,
};
use polkadot_node_subsystem_test_helpers::make_subsystem_context;
use polkadot_primitives::v2::Header;
use polkadot_primitives::v2::{Header, Validators, GroupValidators};
use sp_core::testing::TaskExecutor;

pub const TEST_WINDOW_SIZE: SessionWindowSize = new_session_window_size!(6);

fn dummy_session_info(index: SessionIndex) -> SessionInfo {
SessionInfo {
validators: Vec::new(),
validators: Validators::from(Vec::new()),
discovery_keys: Vec::new(),
assignment_keys: Vec::new(),
validator_groups: Vec::new(),
validator_groups: GroupValidators::from(Vec::new()),
n_cores: index as _,
zeroth_delay_tranche_width: index as _,
relay_vrf_modulo_samples: index as _,
Expand Down
6 changes: 3 additions & 3 deletions node/subsystem-util/src/runtime/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -207,10 +207,10 @@ impl RuntimeInfo {
///
/// Returns: `None` if not a parachain validator.
async fn get_validator_info(&self, session_info: &SessionInfo) -> Result<ValidatorInfo> {
if let Some(our_index) = self.get_our_index(&session_info.validators).await {
if let Some(our_index) = self.get_our_index(&session_info.validators.to_vec()).await {
// Get our group index:
let our_group =
session_info.validator_groups.iter().enumerate().find_map(|(i, g)| {
session_info.validator_groups.to_vec().iter().enumerate().find_map(|(i, g)| {
g.iter().find_map(|v| {
if *v == our_index {
Some(GroupIndex(i as u32))
Expand Down Expand Up @@ -254,7 +254,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))
}
Expand Down
81 changes: 77 additions & 4 deletions primitives/src/v2/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ use bitvec::vec::BitVec;
use parity_scale_codec::{Decode, Encode};
use scale_info::TypeInfo;
use sp_std::prelude::*;
use sp_std::ops::Index;

use application_crypto::KeyTypeId;
use inherents::InherentIdentifier;
Expand Down Expand Up @@ -1569,6 +1570,78 @@ impl CompactStatement {
}
}

/// Validators struct indexed by ValidatorIndex.
#[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo)]
#[cfg_attr(feature = "std", derive(PartialEq, MallocSizeOf))]
pub struct Validators (Vec<ValidatorId>);

impl Index<ValidatorIndex> for Validators{
type Output = ValidatorId;

fn index(&self, index: ValidatorIndex) -> &Self::Output {
&self.0.get(index.0 as usize).unwrap()
}
}

impl From<Vec<ValidatorId>> for Validators{
fn from(validators: Vec<ValidatorId>) -> Self {
Validators(validators)
}
}

impl Validators {
/// Returns a reference to an element indexed using ValidatorIndex.
pub fn get(&self, index: ValidatorIndex) -> Option<&ValidatorId>{
self.0.get(index.0 as usize)
}

///Returns number of elements in vector.
pub fn len(&self) -> usize{
self.0.len()
}

///Returns contained vector
pub fn to_vec(&self) -> Vec<ValidatorId> {
self.0.clone()
}
}

/// GroupValidators struct indexed by GroupIndex.
#[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo)]
#[cfg_attr(feature = "std", derive(PartialEq, MallocSizeOf))]
pub struct GroupValidators (Vec<Vec<ValidatorIndex>>);

impl Index<GroupIndex> for GroupValidators{
type Output = Vec<ValidatorIndex>;

fn index(&self, index: GroupIndex) -> &Self::Output {
self.0.get(index.0 as usize).unwrap()
}
}

impl From<Vec<Vec<ValidatorIndex>>> for GroupValidators{
fn from(group_validators: Vec<Vec<ValidatorIndex>>) -> Self {
GroupValidators(group_validators)
}
}

impl GroupValidators {
/// Returns a reference to an element indexed using GroupIndex.
pub fn get(&self, index: GroupIndex) -> Option<&Vec<ValidatorIndex>>{
self.0.get(index.0 as usize)
}

///Returns number of elements in vector.
pub fn len(&self) -> usize{
self.0.len()
}

///Returns contained vector
pub fn to_vec(&self) -> Vec<Vec<ValidatorIndex>> {
self.0.clone()
}
}

/// 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 }`.
Expand Down Expand Up @@ -1603,7 +1676,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: Validators,
/// Validators' authority discovery keys for the session in canonical ordering.
///
/// NOTE: The first `validators.len()` entries will match the corresponding validators in
Expand All @@ -1626,7 +1699,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: GroupValidators,
/// The number of availability cores used by the protocol during this session.
pub n_cores: u32,
/// The zeroth delay tranche width.
Expand Down Expand Up @@ -1679,7 +1752,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: Validators,
/// Validators' authority discovery keys for the session in canonical ordering.
///
/// NOTE: The first `validators.len()` entries will match the corresponding validators in
Expand All @@ -1702,7 +1775,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: GroupValidators,
/// The number of availability cores used by the protocol during this session.
pub n_cores: u32,
/// The zeroth delay tranche width.
Expand Down
18 changes: 6 additions & 12 deletions runtime/parachains/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,7 @@ use crate::{
};
use bitvec::{order::Lsb0 as BitOrderLsb0, vec::BitVec};
use frame_support::pallet_prelude::*;
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,
};
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, Validators};
use sp_core::{sr25519, H256};
use sp_runtime::{
generic::Digest,
Expand Down Expand Up @@ -65,7 +58,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<Validators>,
/// 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.
Expand Down Expand Up @@ -410,7 +403,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();
Expand Down Expand Up @@ -438,6 +431,7 @@ impl<T: paras_inherent::Config> BenchBuilder<T> {
let availability_bitvec = Self::availability_bitvec(concluding_cores, total_cores);

let bitfields: Vec<UncheckedSigned<AvailabilityBitfield>> = validators
.to_vec()
.iter()
.enumerate()
.map(|(i, public)| {
Expand Down Expand Up @@ -549,7 +543,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()),
Expand Down Expand Up @@ -606,7 +600,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.
Expand Down
2 changes: 1 addition & 1 deletion runtime/parachains/src/disputes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -985,7 +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);
Expand Down
2 changes: 1 addition & 1 deletion runtime/parachains/src/disputes/slashing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
4 changes: 2 additions & 2 deletions runtime/parachains/src/session_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion runtime/parachains/src/session_info/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down

0 comments on commit b5c02e8

Please sign in to comment.