mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-26 15:47:58 +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:
@@ -1074,7 +1074,7 @@ mod tests {
|
||||
fn dummy_groups(group_size: usize) -> Groups {
|
||||
let groups = vec![(0..(group_size as u32)).map(ValidatorIndex).collect()].into();
|
||||
|
||||
Groups::new(groups)
|
||||
Groups::new(groups, 2)
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -16,8 +16,10 @@
|
||||
|
||||
//! A utility for tracking groups and their members within a session.
|
||||
|
||||
use polkadot_node_primitives::minimum_votes;
|
||||
use polkadot_primitives::vstaging::{GroupIndex, IndexedVec, ValidatorIndex};
|
||||
use polkadot_primitives::{
|
||||
effective_minimum_backing_votes,
|
||||
vstaging::{GroupIndex, IndexedVec, ValidatorIndex},
|
||||
};
|
||||
|
||||
use std::collections::HashMap;
|
||||
|
||||
@@ -27,12 +29,16 @@ use std::collections::HashMap;
|
||||
pub struct Groups {
|
||||
groups: IndexedVec<GroupIndex, Vec<ValidatorIndex>>,
|
||||
by_validator_index: HashMap<ValidatorIndex, GroupIndex>,
|
||||
backing_threshold: u32,
|
||||
}
|
||||
|
||||
impl Groups {
|
||||
/// Create a new [`Groups`] tracker with the groups and discovery keys
|
||||
/// from the session.
|
||||
pub fn new(groups: IndexedVec<GroupIndex, Vec<ValidatorIndex>>) -> Self {
|
||||
pub fn new(
|
||||
groups: IndexedVec<GroupIndex, Vec<ValidatorIndex>>,
|
||||
backing_threshold: u32,
|
||||
) -> Self {
|
||||
let mut by_validator_index = HashMap::new();
|
||||
|
||||
for (i, group) in groups.iter().enumerate() {
|
||||
@@ -42,7 +48,7 @@ impl Groups {
|
||||
}
|
||||
}
|
||||
|
||||
Groups { groups, by_validator_index }
|
||||
Groups { groups, by_validator_index, backing_threshold }
|
||||
}
|
||||
|
||||
/// Access all the underlying groups.
|
||||
@@ -60,7 +66,8 @@ impl Groups {
|
||||
&self,
|
||||
group_index: GroupIndex,
|
||||
) -> Option<(usize, usize)> {
|
||||
self.get(group_index).map(|g| (g.len(), minimum_votes(g.len())))
|
||||
self.get(group_index)
|
||||
.map(|g| (g.len(), effective_minimum_backing_votes(g.len(), self.backing_threshold)))
|
||||
}
|
||||
|
||||
/// Get the group index for a validator by index.
|
||||
|
||||
@@ -41,8 +41,9 @@ use polkadot_node_subsystem::{
|
||||
overseer, ActivatedLeaf,
|
||||
};
|
||||
use polkadot_node_subsystem_util::{
|
||||
backing_implicit_view::View as ImplicitView, reputation::ReputationAggregator,
|
||||
runtime::ProspectiveParachainsMode,
|
||||
backing_implicit_view::View as ImplicitView,
|
||||
reputation::ReputationAggregator,
|
||||
runtime::{request_min_backing_votes, ProspectiveParachainsMode},
|
||||
};
|
||||
use polkadot_primitives::vstaging::{
|
||||
AuthorityDiscoveryId, CandidateHash, CompactStatement, CoreIndex, CoreState, GroupIndex,
|
||||
@@ -163,8 +164,8 @@ struct PerSessionState {
|
||||
}
|
||||
|
||||
impl PerSessionState {
|
||||
fn new(session_info: SessionInfo, keystore: &KeystorePtr) -> Self {
|
||||
let groups = Groups::new(session_info.validator_groups.clone());
|
||||
fn new(session_info: SessionInfo, keystore: &KeystorePtr, backing_threshold: u32) -> Self {
|
||||
let groups = Groups::new(session_info.validator_groups.clone(), backing_threshold);
|
||||
let mut authority_lookup = HashMap::new();
|
||||
for (i, ad) in session_info.discovery_keys.iter().cloned().enumerate() {
|
||||
authority_lookup.insert(ad, ValidatorIndex(i as _));
|
||||
@@ -504,9 +505,13 @@ pub(crate) async fn handle_active_leaves_update<Context>(
|
||||
Some(s) => s,
|
||||
};
|
||||
|
||||
state
|
||||
.per_session
|
||||
.insert(session_index, PerSessionState::new(session_info, &state.keystore));
|
||||
let minimum_backing_votes =
|
||||
request_min_backing_votes(new_relay_parent, session_index, ctx.sender()).await?;
|
||||
|
||||
state.per_session.insert(
|
||||
session_index,
|
||||
PerSessionState::new(session_info, &state.keystore, minimum_backing_votes),
|
||||
);
|
||||
}
|
||||
|
||||
let per_session = state
|
||||
@@ -2502,7 +2507,7 @@ pub(crate) async fn dispatch_requests<Context>(ctx: &mut Context, state: &mut St
|
||||
Some(RequestProperties {
|
||||
unwanted_mask,
|
||||
backing_threshold: if require_backing {
|
||||
Some(polkadot_node_primitives::minimum_votes(group.len()))
|
||||
Some(per_session.groups.get_size_and_backing_threshold(group_index)?.1)
|
||||
} else {
|
||||
None
|
||||
},
|
||||
|
||||
@@ -356,7 +356,7 @@ async fn activate_leaf(
|
||||
virtual_overseer: &mut VirtualOverseer,
|
||||
leaf: &TestLeaf,
|
||||
test_state: &TestState,
|
||||
expect_session_info_request: bool,
|
||||
is_new_session: bool,
|
||||
) {
|
||||
let activated = ActivatedLeaf {
|
||||
hash: leaf.hash,
|
||||
@@ -371,14 +371,14 @@ async fn activate_leaf(
|
||||
))))
|
||||
.await;
|
||||
|
||||
handle_leaf_activation(virtual_overseer, leaf, test_state, expect_session_info_request).await;
|
||||
handle_leaf_activation(virtual_overseer, leaf, test_state, is_new_session).await;
|
||||
}
|
||||
|
||||
async fn handle_leaf_activation(
|
||||
virtual_overseer: &mut VirtualOverseer,
|
||||
leaf: &TestLeaf,
|
||||
test_state: &TestState,
|
||||
expect_session_info_request: bool,
|
||||
is_new_session: bool,
|
||||
) {
|
||||
let TestLeaf { number, hash, parent_hash, para_data, session, availability_cores } = leaf;
|
||||
|
||||
@@ -447,7 +447,7 @@ async fn handle_leaf_activation(
|
||||
}
|
||||
);
|
||||
|
||||
if expect_session_info_request {
|
||||
if is_new_session {
|
||||
assert_matches!(
|
||||
virtual_overseer.recv().await,
|
||||
AllMessages::RuntimeApi(
|
||||
@@ -455,6 +455,16 @@ async fn handle_leaf_activation(
|
||||
tx.send(Ok(Some(test_state.session_info.clone()))).unwrap();
|
||||
}
|
||||
);
|
||||
|
||||
assert_matches!(
|
||||
virtual_overseer.recv().await,
|
||||
AllMessages::RuntimeApi(RuntimeApiMessage::Request(
|
||||
parent,
|
||||
RuntimeApiRequest::MinimumBackingVotes(session_index, tx),
|
||||
)) if parent == *hash && session_index == *session => {
|
||||
tx.send(Ok(2)).unwrap();
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user