mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-31 14:31:02 +00:00
backing: move the min votes threshold to the runtime (#1200)
* move min backing votes const to runtime also cache it per-session in the backing subsystem Signed-off-by: alindima <alin@parity.io> * add runtime migration * introduce api versioning for min_backing votes also enable it for rococo/versi for testing * also add min_backing_votes runtime calls to statement-distribution this dependency has been recently introduced by async backing * remove explicit version runtime API call this is not needed, as the RuntimeAPISubsystem already takes care of versioning and will return NotSupported if the version is not right. * address review comments - parametrise backing votes runtime API with session index - remove RuntimeInfo usage in backing subsystem, as runtime API caches the min backing votes by session index anyway. - move the logic for adjusting the configured needed backing votes with the size of the backing group to a primitives helper. - move the legacy min backing votes value to a primitives helper. - mark JoinMultiple error as fatal, since the Canceled (non-multiple) counterpart is also fatal. - make backing subsystem handle fatal errors for new leaves update. - add HostConfiguration consistency check for zeroed backing votes threshold - add cumulus accompanying change * fix cumulus test compilation * fix tests * more small fixes * fix merge * bump runtime api version for westend and rollback version for rococo --------- Signed-off-by: alindima <alin@parity.io> Co-authored-by: Javier Viola <javier@parity.io>
This commit is contained in:
@@ -948,8 +948,11 @@ fn default_header() -> primitives::Header {
|
||||
mod sanitizers {
|
||||
use super::*;
|
||||
|
||||
use crate::inclusion::tests::{
|
||||
back_candidate, collator_sign_candidate, BackingKind, TestCandidateBuilder,
|
||||
use crate::{
|
||||
inclusion::tests::{
|
||||
back_candidate, collator_sign_candidate, BackingKind, TestCandidateBuilder,
|
||||
},
|
||||
mock::{new_test_ext, MockGenesisConfig},
|
||||
};
|
||||
use bitvec::order::Lsb0;
|
||||
use primitives::{
|
||||
@@ -1207,131 +1210,133 @@ mod sanitizers {
|
||||
|
||||
#[test]
|
||||
fn candidates() {
|
||||
const RELAY_PARENT_NUM: u32 = 3;
|
||||
new_test_ext(MockGenesisConfig::default()).execute_with(|| {
|
||||
const RELAY_PARENT_NUM: u32 = 3;
|
||||
|
||||
let header = default_header();
|
||||
let relay_parent = header.hash();
|
||||
let session_index = SessionIndex::from(0_u32);
|
||||
let header = default_header();
|
||||
let relay_parent = header.hash();
|
||||
let session_index = SessionIndex::from(0_u32);
|
||||
|
||||
let keystore = LocalKeystore::in_memory();
|
||||
let keystore = Arc::new(keystore) as KeystorePtr;
|
||||
let signing_context = SigningContext { parent_hash: relay_parent, session_index };
|
||||
let keystore = LocalKeystore::in_memory();
|
||||
let keystore = Arc::new(keystore) as KeystorePtr;
|
||||
let signing_context = SigningContext { parent_hash: relay_parent, session_index };
|
||||
|
||||
let validators = vec![
|
||||
keyring::Sr25519Keyring::Alice,
|
||||
keyring::Sr25519Keyring::Bob,
|
||||
keyring::Sr25519Keyring::Charlie,
|
||||
keyring::Sr25519Keyring::Dave,
|
||||
];
|
||||
for validator in validators.iter() {
|
||||
Keystore::sr25519_generate_new(
|
||||
&*keystore,
|
||||
PARACHAIN_KEY_TYPE_ID,
|
||||
Some(&validator.to_seed()),
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
let has_concluded_invalid =
|
||||
|_idx: usize, _backed_candidate: &BackedCandidate| -> bool { false };
|
||||
|
||||
let entry_ttl = 10_000;
|
||||
let scheduled = (0_usize..2)
|
||||
.into_iter()
|
||||
.map(|idx| {
|
||||
let core_idx = CoreIndex::from(idx as u32);
|
||||
let ca = CoreAssignment {
|
||||
paras_entry: ParasEntry::new(
|
||||
Assignment::new(ParaId::from(1_u32 + idx as u32)),
|
||||
entry_ttl,
|
||||
),
|
||||
core: core_idx,
|
||||
};
|
||||
ca
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let group_validators = |group_index: GroupIndex| {
|
||||
match group_index {
|
||||
group_index if group_index == GroupIndex::from(0) => Some(vec![0, 1]),
|
||||
group_index if group_index == GroupIndex::from(1) => Some(vec![2, 3]),
|
||||
_ => panic!("Group index out of bounds for 2 parachains and 1 parathread core"),
|
||||
let validators = vec![
|
||||
keyring::Sr25519Keyring::Alice,
|
||||
keyring::Sr25519Keyring::Bob,
|
||||
keyring::Sr25519Keyring::Charlie,
|
||||
keyring::Sr25519Keyring::Dave,
|
||||
];
|
||||
for validator in validators.iter() {
|
||||
Keystore::sr25519_generate_new(
|
||||
&*keystore,
|
||||
PARACHAIN_KEY_TYPE_ID,
|
||||
Some(&validator.to_seed()),
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
.map(|m| m.into_iter().map(ValidatorIndex).collect::<Vec<_>>())
|
||||
};
|
||||
|
||||
let backed_candidates = (0_usize..2)
|
||||
.into_iter()
|
||||
.map(|idx0| {
|
||||
let idx1 = idx0 + 1;
|
||||
let mut candidate = TestCandidateBuilder {
|
||||
para_id: ParaId::from(idx1),
|
||||
relay_parent,
|
||||
pov_hash: Hash::repeat_byte(idx1 as u8),
|
||||
persisted_validation_data_hash: [42u8; 32].into(),
|
||||
hrmp_watermark: RELAY_PARENT_NUM,
|
||||
..Default::default()
|
||||
}
|
||||
.build();
|
||||
|
||||
collator_sign_candidate(Sr25519Keyring::One, &mut candidate);
|
||||
|
||||
let backed = back_candidate(
|
||||
candidate,
|
||||
&validators,
|
||||
group_validators(GroupIndex::from(idx0 as u32)).unwrap().as_ref(),
|
||||
&keystore,
|
||||
&signing_context,
|
||||
BackingKind::Threshold,
|
||||
);
|
||||
backed
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
// happy path
|
||||
assert_eq!(
|
||||
sanitize_backed_candidates::<Test, _>(
|
||||
backed_candidates.clone(),
|
||||
has_concluded_invalid,
|
||||
&scheduled
|
||||
),
|
||||
backed_candidates
|
||||
);
|
||||
|
||||
// nothing is scheduled, so no paraids match, thus all backed candidates are skipped
|
||||
{
|
||||
let scheduled = &Vec::new();
|
||||
assert!(sanitize_backed_candidates::<Test, _>(
|
||||
backed_candidates.clone(),
|
||||
has_concluded_invalid,
|
||||
&scheduled
|
||||
)
|
||||
.is_empty());
|
||||
}
|
||||
|
||||
// candidates that have concluded as invalid are filtered out
|
||||
{
|
||||
// mark every second one as concluded invalid
|
||||
let set = {
|
||||
let mut set = std::collections::HashSet::new();
|
||||
for (idx, backed_candidate) in backed_candidates.iter().enumerate() {
|
||||
if idx & 0x01 == 0 {
|
||||
set.insert(backed_candidate.hash());
|
||||
}
|
||||
}
|
||||
set
|
||||
};
|
||||
let has_concluded_invalid =
|
||||
|_idx: usize, candidate: &BackedCandidate| set.contains(&candidate.hash());
|
||||
|_idx: usize, _backed_candidate: &BackedCandidate| -> bool { false };
|
||||
|
||||
let entry_ttl = 10_000;
|
||||
let scheduled = (0_usize..2)
|
||||
.into_iter()
|
||||
.map(|idx| {
|
||||
let core_idx = CoreIndex::from(idx as u32);
|
||||
let ca = CoreAssignment {
|
||||
paras_entry: ParasEntry::new(
|
||||
Assignment::new(ParaId::from(1_u32 + idx as u32)),
|
||||
entry_ttl,
|
||||
),
|
||||
core: core_idx,
|
||||
};
|
||||
ca
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let group_validators = |group_index: GroupIndex| {
|
||||
match group_index {
|
||||
group_index if group_index == GroupIndex::from(0) => Some(vec![0, 1]),
|
||||
group_index if group_index == GroupIndex::from(1) => Some(vec![2, 3]),
|
||||
_ => panic!("Group index out of bounds for 2 parachains and 1 parathread core"),
|
||||
}
|
||||
.map(|m| m.into_iter().map(ValidatorIndex).collect::<Vec<_>>())
|
||||
};
|
||||
|
||||
let backed_candidates = (0_usize..2)
|
||||
.into_iter()
|
||||
.map(|idx0| {
|
||||
let idx1 = idx0 + 1;
|
||||
let mut candidate = TestCandidateBuilder {
|
||||
para_id: ParaId::from(idx1),
|
||||
relay_parent,
|
||||
pov_hash: Hash::repeat_byte(idx1 as u8),
|
||||
persisted_validation_data_hash: [42u8; 32].into(),
|
||||
hrmp_watermark: RELAY_PARENT_NUM,
|
||||
..Default::default()
|
||||
}
|
||||
.build();
|
||||
|
||||
collator_sign_candidate(Sr25519Keyring::One, &mut candidate);
|
||||
|
||||
let backed = back_candidate(
|
||||
candidate,
|
||||
&validators,
|
||||
group_validators(GroupIndex::from(idx0 as u32)).unwrap().as_ref(),
|
||||
&keystore,
|
||||
&signing_context,
|
||||
BackingKind::Threshold,
|
||||
);
|
||||
backed
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
// happy path
|
||||
assert_eq!(
|
||||
sanitize_backed_candidates::<Test, _>(
|
||||
backed_candidates.clone(),
|
||||
has_concluded_invalid,
|
||||
&scheduled
|
||||
)
|
||||
.len(),
|
||||
backed_candidates.len() / 2
|
||||
),
|
||||
backed_candidates
|
||||
);
|
||||
}
|
||||
|
||||
// nothing is scheduled, so no paraids match, thus all backed candidates are skipped
|
||||
{
|
||||
let scheduled = &Vec::new();
|
||||
assert!(sanitize_backed_candidates::<Test, _>(
|
||||
backed_candidates.clone(),
|
||||
has_concluded_invalid,
|
||||
&scheduled
|
||||
)
|
||||
.is_empty());
|
||||
}
|
||||
|
||||
// candidates that have concluded as invalid are filtered out
|
||||
{
|
||||
// mark every second one as concluded invalid
|
||||
let set = {
|
||||
let mut set = std::collections::HashSet::new();
|
||||
for (idx, backed_candidate) in backed_candidates.iter().enumerate() {
|
||||
if idx & 0x01 == 0 {
|
||||
set.insert(backed_candidate.hash());
|
||||
}
|
||||
}
|
||||
set
|
||||
};
|
||||
let has_concluded_invalid =
|
||||
|_idx: usize, candidate: &BackedCandidate| set.contains(&candidate.hash());
|
||||
assert_eq!(
|
||||
sanitize_backed_candidates::<Test, _>(
|
||||
backed_candidates.clone(),
|
||||
has_concluded_invalid,
|
||||
&scheduled
|
||||
)
|
||||
.len(),
|
||||
backed_candidates.len() / 2
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user