diff --git a/polkadot/runtime/src/parachains.rs b/polkadot/runtime/src/parachains.rs index f4083777bf..f891ac2444 100644 --- a/polkadot/runtime/src/parachains.rs +++ b/polkadot/runtime/src/parachains.rs @@ -639,7 +639,7 @@ impl Module { // check the attestations on these candidates. The candidates should have been checked // that each candidates' chain ID is valid. - fn check_candidates(attested_candidates: &[AttestedCandidate]) -> Result{ + fn check_candidates(attested_candidates: &[AttestedCandidate]) -> Result { use primitives::parachain::ValidityAttestation; use sr_primitives::traits::Verify; @@ -737,12 +737,20 @@ impl Module { let mut encoded_implicit = None; let mut encoded_explicit = None; - for ((auth_index, _), validity_attestation) in candidate.validator_indices + let mut expected_votes_len = 0; + for (vote_index, (auth_index, _)) in candidate.validator_indices .iter() .enumerate() .filter(|(_, bit)| *bit) - .zip(candidate.validity_votes.iter()) + .enumerate() { + let validity_attestation = match candidate.validity_votes.get(vote_index) { + None => return Err("Not enough validity votes"), + Some(v) => { + expected_votes_len = vote_index + 1; + v + } + }; if validator_group.iter().find(|&(idx, _)| *idx == auth_index).is_none() { return Err("Attesting validator not on this chain's validation duty."); @@ -774,6 +782,11 @@ impl Module { "Candidate validity attestation signature is bad." ); } + + ensure!( + candidate.validity_votes.len() == expected_votes_len, + "Extra untagged validity votes along with candidate" + ); } Ok(())