statement-distribution: support inactive local validator in grid (#1571)

Fixes #1437

Co-authored-by: Sophia Gold <sophia@parity.io>
This commit is contained in:
Kristian Sosnin
2023-11-14 22:14:59 +04:00
committed by GitHub
parent 54f84285bf
commit 31c38cea3d
5 changed files with 514 additions and 259 deletions
@@ -142,8 +142,27 @@ struct PerRelayParentState {
session: SessionIndex,
}
impl PerRelayParentState {
fn active_validator_state(&self) -> Option<&ActiveValidatorState> {
self.local_validator.as_ref().and_then(|local| local.active.as_ref())
}
fn active_validator_state_mut(&mut self) -> Option<&mut ActiveValidatorState> {
self.local_validator.as_mut().and_then(|local| local.active.as_mut())
}
}
// per-relay-parent local validator state.
struct LocalValidatorState {
// the grid-level communication at this relay-parent.
grid_tracker: GridTracker,
// additional fields in case local node is an active validator.
active: Option<ActiveValidatorState>,
// local index actually exists in case node is inactive validator, however,
// it's not needed outside of `build_session_topology`, where it's known.
}
struct ActiveValidatorState {
// The index of the validator.
index: ValidatorIndex,
// our validator group
@@ -152,8 +171,14 @@ struct LocalValidatorState {
assignment: Option<ParaId>,
// the 'direct-in-group' communication at this relay-parent.
cluster_tracker: ClusterTracker,
// the grid-level communication at this relay-parent.
grid_tracker: GridTracker,
}
#[derive(Debug, Copy, Clone)]
enum LocalValidatorIndex {
// Local node is an active validator.
Active(ValidatorIndex),
// Local node is not in active validator set.
Inactive,
}
#[derive(Debug)]
@@ -164,7 +189,7 @@ struct PerSessionState {
// is only `None` in the time between seeing a session and
// getting the topology from the gossip-support subsystem
grid_view: Option<grid::SessionTopologyView>,
local_validator: Option<ValidatorIndex>,
local_validator: Option<LocalValidatorIndex>,
}
impl PerSessionState {
@@ -178,15 +203,10 @@ impl PerSessionState {
let local_validator = polkadot_node_subsystem_util::signing_key_and_index(
session_info.validators.iter(),
keystore,
);
)
.map(|(_, index)| LocalValidatorIndex::Active(index));
PerSessionState {
session_info,
groups,
authority_lookup,
grid_view: None,
local_validator: local_validator.map(|(_key, index)| index),
}
PerSessionState { session_info, groups, authority_lookup, grid_view: None, local_validator }
}
fn supply_topology(
@@ -204,6 +224,16 @@ impl PerSessionState {
);
self.grid_view = Some(grid_view);
if local_index.is_some() {
self.local_validator.get_or_insert(LocalValidatorIndex::Inactive);
}
}
/// Returns `true` if local is neither active or inactive validator node.
///
/// `false` is also returned if session topology is not known yet.
fn is_not_validator(&self) -> bool {
self.grid_view.is_some() && self.local_validator.is_none()
}
}
@@ -554,13 +584,17 @@ pub(crate) async fn handle_active_leaves_update<Context>(
.expect("either existed or just inserted; qed");
let local_validator = per_session.local_validator.and_then(|v| {
find_local_validator_state(
v,
&per_session.groups,
&availability_cores,
&group_rotation_info,
seconding_limit,
)
if let LocalValidatorIndex::Active(idx) = v {
find_active_validator_state(
idx,
&per_session.groups,
&availability_cores,
&group_rotation_info,
seconding_limit,
)
} else {
Some(LocalValidatorState { grid_tracker: GridTracker::default(), active: None })
}
});
state.per_relay_parent.insert(
@@ -607,7 +641,7 @@ pub(crate) async fn handle_active_leaves_update<Context>(
Ok(())
}
fn find_local_validator_state(
fn find_active_validator_state(
validator_index: ValidatorIndex,
groups: &Groups,
availability_cores: &[CoreState],
@@ -628,11 +662,13 @@ fn find_local_validator_state(
let group_validators = groups.get(our_group)?.to_owned();
Some(LocalValidatorState {
index: validator_index,
group: our_group,
assignment: para,
cluster_tracker: ClusterTracker::new(group_validators, seconding_limit)
.expect("group is non-empty because we are in it; qed"),
active: Some(ActiveValidatorState {
index: validator_index,
group: our_group,
assignment: para,
cluster_tracker: ClusterTracker::new(group_validators, seconding_limit)
.expect("group is non-empty because we are in it; qed"),
}),
grid_tracker: GridTracker::default(),
})
}
@@ -725,13 +761,17 @@ async fn send_peer_messages_for_relay_parent<Context>(
for validator_id in find_validator_ids(peer_data.iter_known_discovery_ids(), |a| {
per_session_state.authority_lookup.get(a)
}) {
if let Some(local_validator_state) = relay_parent_state.local_validator.as_mut() {
if let Some(active) = relay_parent_state
.local_validator
.as_mut()
.and_then(|local| local.active.as_mut())
{
send_pending_cluster_statements(
ctx,
relay_parent,
&(peer, peer_data.protocol_version),
validator_id,
&mut local_validator_state.cluster_tracker,
&mut active.cluster_tracker,
&state.candidates,
&relay_parent_state.statement_store,
)
@@ -1009,7 +1049,7 @@ pub(crate) async fn share_local_statement<Context>(
};
let (local_index, local_assignment, local_group) =
match per_relay_parent.local_validator.as_ref() {
match per_relay_parent.active_validator_state() {
None => return Err(JfyiError::InvalidShare),
Some(l) => (l.index, l.assignment, l.group),
};
@@ -1086,7 +1126,7 @@ pub(crate) async fn share_local_statement<Context>(
}
{
let l = per_relay_parent.local_validator.as_mut().expect("checked above; qed");
let l = per_relay_parent.active_validator_state_mut().expect("checked above; qed");
l.cluster_tracker.note_issued(local_index, compact_statement.payload().clone());
}
@@ -1173,31 +1213,41 @@ async fn circulate_statement<Context>(
// We're not meant to circulate statements in the cluster until we have the confirmed
// candidate.
let cluster_relevant = Some(local_validator.group) == statement_group;
let cluster_targets = if is_confirmed && cluster_relevant {
Some(
local_validator
.cluster_tracker
.targets()
.iter()
.filter(|&&v| {
local_validator
//
// Cluster is only relevant if local node is an active validator.
let (cluster_relevant, cluster_targets, all_cluster_targets) = local_validator
.active
.as_mut()
.map(|active| {
let cluster_relevant = Some(active.group) == statement_group;
let cluster_targets = if is_confirmed && cluster_relevant {
Some(
active
.cluster_tracker
.can_send(v, originator, compact_statement.clone())
.is_ok()
})
.filter(|&v| v != &local_validator.index)
.map(|v| (*v, DirectTargetKind::Cluster)),
)
} else {
None
};
.targets()
.iter()
.filter(|&&v| {
active
.cluster_tracker
.can_send(v, originator, compact_statement.clone())
.is_ok()
})
.filter(|&v| v != &active.index)
.map(|v| (*v, DirectTargetKind::Cluster)),
)
} else {
None
};
let all_cluster_targets = active.cluster_tracker.targets();
(cluster_relevant, cluster_targets, all_cluster_targets)
})
.unwrap_or((false, None, &[]));
let grid_targets = local_validator
.grid_tracker
.direct_statement_targets(&per_session.groups, originator, &compact_statement)
.into_iter()
.filter(|v| !cluster_relevant || !local_validator.cluster_tracker.targets().contains(v))
.filter(|v| !cluster_relevant || !all_cluster_targets.contains(v))
.map(|v| (v, DirectTargetKind::Grid));
let targets = cluster_targets
@@ -1229,18 +1279,17 @@ async fn circulate_statement<Context>(
match kind {
DirectTargetKind::Cluster => {
let active = local_validator
.active
.as_mut()
.expect("cluster target means local is active validator; qed");
// At this point, all peers in the cluster should 'know'
// the candidate, so we don't expect for this to fail.
if let Ok(()) = local_validator.cluster_tracker.can_send(
target,
originator,
compact_statement.clone(),
) {
local_validator.cluster_tracker.note_sent(
target,
originator,
compact_statement.clone(),
);
if let Ok(()) =
active.cluster_tracker.can_send(target, originator, compact_statement.clone())
{
active.cluster_tracker.note_sent(target, originator, compact_statement.clone());
statement_to_peers.push(peer_id);
}
},
@@ -1387,7 +1436,9 @@ async fn handle_incoming_statement<Context>(
None => {
// we shouldn't be receiving statements unless we're a validator
// this session.
modify_reputation(reputation, ctx.sender(), peer, COST_UNEXPECTED_STATEMENT).await;
if per_session.is_not_validator() {
modify_reputation(reputation, ctx.sender(), peer, COST_UNEXPECTED_STATEMENT).await;
}
return
},
Some(l) => l,
@@ -1402,73 +1453,81 @@ async fn handle_incoming_statement<Context>(
},
};
let cluster_sender_index = {
let (active, cluster_sender_index) = {
// This block of code only returns `Some` when both the originator and
// the sending peer are in the cluster.
let active = local_validator.active.as_mut();
let allowed_senders = local_validator
.cluster_tracker
.senders_for_originator(statement.unchecked_validator_index());
let allowed_senders = active
.as_ref()
.map(|active| {
active
.cluster_tracker
.senders_for_originator(statement.unchecked_validator_index())
})
.unwrap_or_default();
allowed_senders
let idx = allowed_senders
.iter()
.filter_map(|i| session_info.discovery_keys.get(i.0 as usize).map(|ad| (*i, ad)))
.filter(|(_, ad)| peer_state.is_authority(ad))
.map(|(i, _)| i)
.next()
.next();
(active, idx)
};
let checked_statement = if let Some(cluster_sender_index) = cluster_sender_index {
match handle_cluster_statement(
relay_parent,
&mut local_validator.cluster_tracker,
per_relay_parent.session,
&per_session.session_info,
statement,
cluster_sender_index,
) {
Ok(Some(s)) => s,
Ok(None) => return,
Err(rep) => {
modify_reputation(reputation, ctx.sender(), peer, rep).await;
return
},
}
} else {
let grid_sender_index = local_validator
.grid_tracker
.direct_statement_providers(
&per_session.groups,
statement.unchecked_validator_index(),
statement.unchecked_payload(),
)
.into_iter()
.filter_map(|i| session_info.discovery_keys.get(i.0 as usize).map(|ad| (i, ad)))
.filter(|(_, ad)| peer_state.is_authority(ad))
.map(|(i, _)| i)
.next();
if let Some(grid_sender_index) = grid_sender_index {
match handle_grid_statement(
let checked_statement =
if let Some((active, cluster_sender_index)) = active.zip(cluster_sender_index) {
match handle_cluster_statement(
relay_parent,
&mut local_validator.grid_tracker,
&mut active.cluster_tracker,
per_relay_parent.session,
&per_session,
&per_session.session_info,
statement,
grid_sender_index,
cluster_sender_index,
) {
Ok(s) => s,
Ok(Some(s)) => s,
Ok(None) => return,
Err(rep) => {
modify_reputation(reputation, ctx.sender(), peer, rep).await;
return
},
}
} else {
// Not a cluster or grid peer.
modify_reputation(reputation, ctx.sender(), peer, COST_UNEXPECTED_STATEMENT).await;
return
}
};
let grid_sender_index = local_validator
.grid_tracker
.direct_statement_providers(
&per_session.groups,
statement.unchecked_validator_index(),
statement.unchecked_payload(),
)
.into_iter()
.filter_map(|i| session_info.discovery_keys.get(i.0 as usize).map(|ad| (i, ad)))
.filter(|(_, ad)| peer_state.is_authority(ad))
.map(|(i, _)| i)
.next();
if let Some(grid_sender_index) = grid_sender_index {
match handle_grid_statement(
relay_parent,
&mut local_validator.grid_tracker,
per_relay_parent.session,
&per_session,
statement,
grid_sender_index,
) {
Ok(s) => s,
Err(rep) => {
modify_reputation(reputation, ctx.sender(), peer, rep).await;
return
},
}
} else {
// Not a cluster or grid peer.
modify_reputation(reputation, ctx.sender(), peer, COST_UNEXPECTED_STATEMENT).await;
return
}
};
let statement = checked_statement.payload().clone();
let originator_index = checked_statement.validator_index();
@@ -1536,7 +1595,7 @@ async fn handle_incoming_statement<Context>(
local_validator.grid_tracker.learned_fresh_statement(
&per_session.groups,
session_topology,
local_validator.index,
originator_index,
&statement,
);
}
@@ -1834,7 +1893,7 @@ async fn provide_candidate_to_grid<Context>(
gum::debug!(
target: LOG_TARGET,
?candidate_hash,
local_validator = ?local_validator.index,
local_validator = ?per_session.local_validator,
n_peers = manifest_peers_v2.len(),
"Sending manifest to v2 peers"
);
@@ -1853,7 +1912,7 @@ async fn provide_candidate_to_grid<Context>(
gum::debug!(
target: LOG_TARGET,
?candidate_hash,
local_validator = ?local_validator.index,
local_validator = ?per_session.local_validator,
n_peers = manifest_peers_vstaging.len(),
"Sending manifest to vstaging peers"
);
@@ -1874,7 +1933,7 @@ async fn provide_candidate_to_grid<Context>(
gum::debug!(
target: LOG_TARGET,
?candidate_hash,
local_validator = ?local_validator.index,
local_validator = ?per_session.local_validator,
n_peers = ack_peers_v2.len(),
"Sending acknowledgement to v2 peers"
);
@@ -1893,7 +1952,7 @@ async fn provide_candidate_to_grid<Context>(
gum::debug!(
target: LOG_TARGET,
?candidate_hash,
local_validator = ?local_validator.index,
local_validator = ?per_session.local_validator,
n_peers = ack_peers_vstaging.len(),
"Sending acknowledgement to vstaging peers"
);
@@ -2086,13 +2145,15 @@ async fn handle_incoming_manifest_common<'a, Context>(
let local_validator = match relay_parent_state.local_validator.as_mut() {
None => {
modify_reputation(
reputation,
ctx.sender(),
peer,
COST_UNEXPECTED_MANIFEST_MISSING_KNOWLEDGE,
)
.await;
if per_session.is_not_validator() {
modify_reputation(
reputation,
ctx.sender(),
peer,
COST_UNEXPECTED_MANIFEST_MISSING_KNOWLEDGE,
)
.await;
}
return None
},
Some(x) => x,
@@ -2188,7 +2249,7 @@ async fn handle_incoming_manifest_common<'a, Context>(
target: LOG_TARGET,
?candidate_hash,
from = ?sender_index,
local_index = ?local_validator.index,
local_index = ?per_session.local_validator,
?manifest_kind,
"immediate ack, known candidate"
);
@@ -2593,7 +2654,7 @@ async fn send_cluster_candidate_statements<Context>(
Some(s) => s,
};
let local_group = match relay_parent_state.local_validator.as_mut() {
let local_group = match relay_parent_state.active_validator_state_mut() {
None => return,
Some(v) => v.group,
};
@@ -2680,11 +2741,10 @@ pub(crate) async fn dispatch_requests<Context>(ctx: &mut Context, state: &mut St
}) {
// For cluster members, they haven't advertised any statements in particular,
// but have surely sent us some.
if local_validator
.cluster_tracker
.knows_candidate(validator_id, identifier.candidate_hash)
{
return Some(StatementFilter::blank(local_validator.cluster_tracker.targets().len()))
if let Some(active) = local_validator.active.as_ref() {
if active.cluster_tracker.knows_candidate(validator_id, identifier.candidate_hash) {
return Some(StatementFilter::blank(active.cluster_tracker.targets().len()))
}
}
let filter = local_validator
@@ -2715,7 +2775,11 @@ pub(crate) async fn dispatch_requests<Context>(ctx: &mut Context, state: &mut St
}
// don't require a backing threshold for cluster candidates.
let require_backing = relay_parent_state.local_validator.as_ref()?.group != group_index;
let local_validator = relay_parent_state.local_validator.as_ref()?;
let require_backing = local_validator
.active
.as_ref()
.map_or(true, |active| active.group != group_index);
Some(RequestProperties {
unwanted_mask,
@@ -2973,7 +3037,11 @@ pub(crate) fn answer_request(state: &mut State, message: ResponderMessage) {
for v in find_validator_ids(peer_data.iter_known_discovery_ids(), |a| {
per_session.authority_lookup.get(a)
}) {
if local_validator.cluster_tracker.can_request(v, *candidate_hash) {
if local_validator
.active
.as_ref()
.map_or(false, |active| active.cluster_tracker.can_request(v, *candidate_hash))
{
validator_id = Some(v);
is_cluster = true;
break
@@ -3015,11 +3083,16 @@ pub(crate) fn answer_request(state: &mut State, message: ResponderMessage) {
// Update bookkeeping about which statements peers have received.
for statement in &statements {
if is_cluster {
local_validator.cluster_tracker.note_sent(
validator_id,
statement.unchecked_validator_index(),
statement.unchecked_payload().clone(),
);
local_validator
.active
.as_mut()
.expect("cluster peer means local is active validator; qed")
.cluster_tracker
.note_sent(
validator_id,
statement.unchecked_validator_index(),
statement.unchecked_payload().clone(),
);
} else {
local_validator.grid_tracker.sent_or_received_direct_statement(
&per_session.groups,
@@ -23,7 +23,7 @@ fn share_seconded_circulated_to_cluster() {
let config = TestConfig {
validator_count: 20,
group_size: 3,
local_validator: true,
local_validator: LocalRole::Validator,
async_backing_params: None,
};
@@ -34,7 +34,8 @@ fn share_seconded_circulated_to_cluster() {
test_harness(config, |state, mut overseer| async move {
let local_validator = state.local.clone().unwrap();
let local_para = ParaId::from(local_validator.group_index.0);
let local_group_index = local_validator.group_index.unwrap();
let local_para = ParaId::from(local_group_index.0);
let test_leaf = state.make_dummy_leaf(relay_parent);
@@ -52,7 +53,7 @@ fn share_seconded_circulated_to_cluster() {
// peer B is in group, has no relay parent in view.
// peer C is not in group, has relay parent in view.
{
let other_group_validators = state.group_validators(local_validator.group_index, true);
let other_group_validators = state.group_validators(local_group_index, true);
connect_peer(
&mut overseer,
@@ -130,7 +131,7 @@ fn cluster_valid_statement_before_seconded_ignored() {
let config = TestConfig {
validator_count: 20,
group_size: 3,
local_validator: true,
local_validator: LocalRole::Validator,
async_backing_params: None,
};
@@ -139,12 +140,13 @@ fn cluster_valid_statement_before_seconded_ignored() {
test_harness(config, |state, mut overseer| async move {
let local_validator = state.local.clone().unwrap();
let local_group_index = local_validator.group_index.unwrap();
let candidate_hash = CandidateHash(Hash::repeat_byte(42));
let test_leaf = state.make_dummy_leaf(relay_parent);
// peer A is in group, has relay parent in view.
let other_group_validators = state.group_validators(local_validator.group_index, true);
let other_group_validators = state.group_validators(local_group_index, true);
let v_a = other_group_validators[0];
connect_peer(
&mut overseer,
@@ -197,7 +199,7 @@ fn cluster_statement_bad_signature() {
let config = TestConfig {
validator_count: 20,
group_size: 3,
local_validator: true,
local_validator: LocalRole::Validator,
async_backing_params: None,
};
@@ -206,12 +208,13 @@ fn cluster_statement_bad_signature() {
test_harness(config, |state, mut overseer| async move {
let local_validator = state.local.clone().unwrap();
let local_group_index = local_validator.group_index.unwrap();
let candidate_hash = CandidateHash(Hash::repeat_byte(42));
let test_leaf = state.make_dummy_leaf(relay_parent);
// peer A is in group, has relay parent in view.
let other_group_validators = state.group_validators(local_validator.group_index, true);
let other_group_validators = state.group_validators(local_group_index, true);
let v_a = other_group_validators[0];
let v_b = other_group_validators[1];
@@ -277,7 +280,7 @@ fn useful_cluster_statement_from_non_cluster_peer_rejected() {
let config = TestConfig {
validator_count: 20,
group_size: 3,
local_validator: true,
local_validator: LocalRole::Validator,
async_backing_params: None,
};
@@ -286,13 +289,13 @@ fn useful_cluster_statement_from_non_cluster_peer_rejected() {
test_harness(config, |state, mut overseer| async move {
let local_validator = state.local.clone().unwrap();
let local_group_index = local_validator.group_index.unwrap();
let candidate_hash = CandidateHash(Hash::repeat_byte(42));
let test_leaf = state.make_dummy_leaf(relay_parent);
// peer A is not in group, has relay parent in view.
let not_our_group =
if local_validator.group_index.0 == 0 { GroupIndex(1) } else { GroupIndex(0) };
let not_our_group = if local_group_index.0 == 0 { GroupIndex(1) } else { GroupIndex(0) };
let that_group_validators = state.group_validators(not_our_group, false);
let v_non = that_group_validators[0];
@@ -346,7 +349,7 @@ fn statement_from_non_cluster_originator_unexpected() {
let config = TestConfig {
validator_count: 20,
group_size: 3,
local_validator: true,
local_validator: LocalRole::Validator,
async_backing_params: None,
};
@@ -355,12 +358,13 @@ fn statement_from_non_cluster_originator_unexpected() {
test_harness(config, |state, mut overseer| async move {
let local_validator = state.local.clone().unwrap();
let local_group_index = local_validator.group_index.unwrap();
let candidate_hash = CandidateHash(Hash::repeat_byte(42));
let test_leaf = state.make_dummy_leaf(relay_parent);
// peer A is not in group, has relay parent in view.
let other_group_validators = state.group_validators(local_validator.group_index, true);
let other_group_validators = state.group_validators(local_group_index, true);
let v_a = other_group_validators[0];
connect_peer(&mut overseer, peer_a.clone(), None).await;
@@ -408,7 +412,7 @@ fn seconded_statement_leads_to_request() {
let config = TestConfig {
validator_count: 20,
group_size,
local_validator: true,
local_validator: LocalRole::Validator,
async_backing_params: None,
};
@@ -417,7 +421,8 @@ fn seconded_statement_leads_to_request() {
test_harness(config, |state, mut overseer| async move {
let local_validator = state.local.clone().unwrap();
let local_para = ParaId::from(local_validator.group_index.0);
let local_group_index = local_validator.group_index.unwrap();
let local_para = ParaId::from(local_group_index.0);
let test_leaf = state.make_dummy_leaf(relay_parent);
@@ -432,7 +437,7 @@ fn seconded_statement_leads_to_request() {
let candidate_hash = candidate.hash();
// peer A is in group, has relay parent in view.
let other_group_validators = state.group_validators(local_validator.group_index, true);
let other_group_validators = state.group_validators(local_group_index, true);
let v_a = other_group_validators[0];
connect_peer(
@@ -503,7 +508,7 @@ fn cluster_statements_shared_seconded_first() {
let config = TestConfig {
validator_count: 20,
group_size: 3,
local_validator: true,
local_validator: LocalRole::Validator,
async_backing_params: None,
};
@@ -512,7 +517,8 @@ fn cluster_statements_shared_seconded_first() {
test_harness(config, |state, mut overseer| async move {
let local_validator = state.local.clone().unwrap();
let local_para = ParaId::from(local_validator.group_index.0);
let local_group_index = local_validator.group_index.unwrap();
let local_para = ParaId::from(local_group_index.0);
let test_leaf = state.make_dummy_leaf(relay_parent);
@@ -528,7 +534,7 @@ fn cluster_statements_shared_seconded_first() {
// peer A is in group, no relay parent in view.
{
let other_group_validators = state.group_validators(local_validator.group_index, true);
let other_group_validators = state.group_validators(local_group_index, true);
connect_peer(
&mut overseer,
@@ -624,7 +630,7 @@ fn cluster_accounts_for_implicit_view() {
let config = TestConfig {
validator_count: 20,
group_size: 3,
local_validator: true,
local_validator: LocalRole::Validator,
async_backing_params: None,
};
@@ -634,7 +640,8 @@ fn cluster_accounts_for_implicit_view() {
test_harness(config, |state, mut overseer| async move {
let local_validator = state.local.clone().unwrap();
let local_para = ParaId::from(local_validator.group_index.0);
let local_group_index = local_validator.group_index.unwrap();
let local_para = ParaId::from(local_group_index.0);
let test_leaf = state.make_dummy_leaf(relay_parent);
@@ -651,7 +658,7 @@ fn cluster_accounts_for_implicit_view() {
// peer A is in group, has relay parent in view.
// peer B is in group, has no relay parent in view.
{
let other_group_validators = state.group_validators(local_validator.group_index, true);
let other_group_validators = state.group_validators(local_group_index, true);
connect_peer(
&mut overseer,
@@ -775,7 +782,7 @@ fn cluster_messages_imported_after_confirmed_candidate_importable_check() {
let config = TestConfig {
validator_count: 20,
group_size,
local_validator: true,
local_validator: LocalRole::Validator,
async_backing_params: None,
};
@@ -784,7 +791,8 @@ fn cluster_messages_imported_after_confirmed_candidate_importable_check() {
test_harness(config, |state, mut overseer| async move {
let local_validator = state.local.clone().unwrap();
let local_para = ParaId::from(local_validator.group_index.0);
let local_group_index = local_validator.group_index.unwrap();
let local_para = ParaId::from(local_group_index.0);
let test_leaf = state.make_dummy_leaf(relay_parent);
@@ -799,7 +807,7 @@ fn cluster_messages_imported_after_confirmed_candidate_importable_check() {
let candidate_hash = candidate.hash();
// peer A is in group, has relay parent in view.
let other_group_validators = state.group_validators(local_validator.group_index, true);
let other_group_validators = state.group_validators(local_group_index, true);
let v_a = other_group_validators[0];
{
connect_peer(
@@ -907,7 +915,7 @@ fn cluster_messages_imported_after_new_leaf_importable_check() {
let config = TestConfig {
validator_count: 20,
group_size,
local_validator: true,
local_validator: LocalRole::Validator,
async_backing_params: None,
};
@@ -916,7 +924,8 @@ fn cluster_messages_imported_after_new_leaf_importable_check() {
test_harness(config, |state, mut overseer| async move {
let local_validator = state.local.clone().unwrap();
let local_para = ParaId::from(local_validator.group_index.0);
let local_group_index = local_validator.group_index.unwrap();
let local_para = ParaId::from(local_group_index.0);
let test_leaf = state.make_dummy_leaf(relay_parent);
@@ -931,7 +940,7 @@ fn cluster_messages_imported_after_new_leaf_importable_check() {
let candidate_hash = candidate.hash();
// peer A is in group, has relay parent in view.
let other_group_validators = state.group_validators(local_validator.group_index, true);
let other_group_validators = state.group_validators(local_group_index, true);
let v_a = other_group_validators[0];
{
connect_peer(
@@ -1048,7 +1057,7 @@ fn ensure_seconding_limit_is_respected() {
let config = TestConfig {
validator_count: 20,
group_size: 4,
local_validator: true,
local_validator: LocalRole::Validator,
async_backing_params: Some(AsyncBackingParams {
max_candidate_depth: 1,
allowed_ancestry_len: 3,
@@ -1060,7 +1069,8 @@ fn ensure_seconding_limit_is_respected() {
test_harness(config, |state, mut overseer| async move {
let local_validator = state.local.clone().unwrap();
let local_para = ParaId::from(local_validator.group_index.0);
let local_group_index = local_validator.group_index.unwrap();
let local_para = ParaId::from(local_group_index.0);
let test_leaf = state.make_dummy_leaf(relay_parent);
@@ -1092,7 +1102,7 @@ fn ensure_seconding_limit_is_respected() {
let candidate_hash_2 = candidate_2.hash();
let candidate_hash_3 = candidate_3.hash();
let other_group_validators = state.group_validators(local_validator.group_index, true);
let other_group_validators = state.group_validators(local_group_index, true);
let v_a = other_group_validators[0];
// peers A,B,C are in group, have relay parent in view.
@@ -29,7 +29,7 @@ fn backed_candidate_leads_to_advertisement() {
let config = TestConfig {
validator_count,
group_size,
local_validator: true,
local_validator: LocalRole::Validator,
async_backing_params: None,
};
@@ -41,7 +41,8 @@ fn backed_candidate_leads_to_advertisement() {
test_harness(config, |state, mut overseer| async move {
let local_validator = state.local.clone().unwrap();
let local_para = ParaId::from(local_validator.group_index.0);
let local_group_index = local_validator.group_index.unwrap();
let local_para = ParaId::from(local_group_index.0);
let test_leaf = state.make_dummy_leaf(relay_parent);
@@ -55,9 +56,9 @@ fn backed_candidate_leads_to_advertisement() {
);
let candidate_hash = candidate.hash();
let other_group_validators = state.group_validators(local_validator.group_index, true);
let other_group_validators = state.group_validators(local_group_index, true);
let target_group_validators =
state.group_validators((local_validator.group_index.0 + 1).into(), true);
state.group_validators((local_group_index.0 + 1).into(), true);
let v_a = other_group_validators[0];
let v_b = other_group_validators[1];
let v_c = target_group_validators[0];
@@ -219,7 +220,7 @@ fn backed_candidate_leads_to_advertisement() {
assert_eq!(manifest, BackedCandidateManifest {
relay_parent,
candidate_hash,
group_index: local_validator.group_index,
group_index: local_group_index,
para_id: local_para,
parent_head_data_hash: pvd.parent_head.hash(),
statement_knowledge: StatementFilter {
@@ -244,7 +245,7 @@ fn received_advertisement_before_confirmation_leads_to_request() {
let config = TestConfig {
validator_count,
group_size,
local_validator: true,
local_validator: LocalRole::Validator,
async_backing_params: None,
};
@@ -256,9 +257,9 @@ fn received_advertisement_before_confirmation_leads_to_request() {
test_harness(config, |state, mut overseer| async move {
let local_validator = state.local.clone().unwrap();
let local_group_index = local_validator.group_index.unwrap();
let other_group =
next_group_index(local_validator.group_index, validator_count, group_size);
let other_group = next_group_index(local_group_index, validator_count, group_size);
let other_para = ParaId::from(other_group.0);
let test_leaf = state.make_dummy_leaf(relay_parent);
@@ -273,7 +274,7 @@ fn received_advertisement_before_confirmation_leads_to_request() {
);
let candidate_hash = candidate.hash();
let other_group_validators = state.group_validators(local_validator.group_index, true);
let other_group_validators = state.group_validators(local_group_index, true);
let target_group_validators = state.group_validators(other_group, true);
let v_a = other_group_validators[0];
let v_b = other_group_validators[1];
@@ -424,7 +425,7 @@ fn received_advertisement_after_backing_leads_to_acknowledgement() {
let config = TestConfig {
validator_count,
group_size,
local_validator: true,
local_validator: LocalRole::Validator,
async_backing_params: None,
};
@@ -435,9 +436,9 @@ fn received_advertisement_after_backing_leads_to_acknowledgement() {
test_harness(config, |state, mut overseer| async move {
let local_validator = state.local.clone().unwrap();
let local_group_index = local_validator.group_index.unwrap();
let other_group =
next_group_index(local_validator.group_index, validator_count, group_size);
let other_group = next_group_index(local_group_index, validator_count, group_size);
let other_para = ParaId::from(other_group.0);
let test_leaf = state.make_dummy_leaf(relay_parent);
@@ -672,7 +673,7 @@ fn received_advertisement_after_confirmation_before_backing() {
let config = TestConfig {
validator_count,
group_size,
local_validator: true,
local_validator: LocalRole::Validator,
async_backing_params: None,
};
@@ -683,9 +684,9 @@ fn received_advertisement_after_confirmation_before_backing() {
test_harness(config, |state, mut overseer| async move {
let local_validator = state.local.clone().unwrap();
let local_group_index = local_validator.group_index.unwrap();
let other_group =
next_group_index(local_validator.group_index, validator_count, group_size);
let other_group = next_group_index(local_group_index, validator_count, group_size);
let other_para = ParaId::from(other_group.0);
let test_leaf = state.make_dummy_leaf(relay_parent);
@@ -858,7 +859,7 @@ fn additional_statements_are_shared_after_manifest_exchange() {
let config = TestConfig {
validator_count,
group_size,
local_validator: true,
local_validator: LocalRole::Validator,
async_backing_params: None,
};
@@ -869,9 +870,9 @@ fn additional_statements_are_shared_after_manifest_exchange() {
test_harness(config, |state, mut overseer| async move {
let local_validator = state.local.clone().unwrap();
let local_group_index = local_validator.group_index.unwrap();
let other_group =
next_group_index(local_validator.group_index, validator_count, group_size);
let other_group = next_group_index(local_group_index, validator_count, group_size);
let other_para = ParaId::from(other_group.0);
let test_leaf = state.make_dummy_leaf(relay_parent);
@@ -1155,7 +1156,7 @@ fn advertisement_sent_when_peer_enters_relay_parent_view() {
let config = TestConfig {
validator_count,
group_size,
local_validator: true,
local_validator: LocalRole::Validator,
async_backing_params: None,
};
@@ -1167,7 +1168,8 @@ fn advertisement_sent_when_peer_enters_relay_parent_view() {
test_harness(config, |state, mut overseer| async move {
let local_validator = state.local.clone().unwrap();
let local_para = ParaId::from(local_validator.group_index.0);
let local_group_index = local_validator.group_index.unwrap();
let local_para = ParaId::from(local_group_index.0);
let test_leaf = state.make_dummy_leaf(relay_parent);
@@ -1181,9 +1183,9 @@ fn advertisement_sent_when_peer_enters_relay_parent_view() {
);
let candidate_hash = candidate.hash();
let other_group_validators = state.group_validators(local_validator.group_index, true);
let other_group_validators = state.group_validators(local_group_index, true);
let target_group_validators =
state.group_validators((local_validator.group_index.0 + 1).into(), true);
state.group_validators((local_group_index.0 + 1).into(), true);
let v_a = other_group_validators[0];
let v_b = other_group_validators[1];
let v_c = target_group_validators[0];
@@ -1336,7 +1338,7 @@ fn advertisement_sent_when_peer_enters_relay_parent_view() {
let expected_manifest = BackedCandidateManifest {
relay_parent,
candidate_hash,
group_index: local_validator.group_index,
group_index: local_group_index,
para_id: local_para,
parent_head_data_hash: pvd.parent_head.hash(),
statement_knowledge: StatementFilter {
@@ -1377,7 +1379,7 @@ fn advertisement_not_re_sent_when_peer_re_enters_view() {
let config = TestConfig {
validator_count,
group_size,
local_validator: true,
local_validator: LocalRole::Validator,
async_backing_params: None,
};
@@ -1389,7 +1391,8 @@ fn advertisement_not_re_sent_when_peer_re_enters_view() {
test_harness(config, |state, mut overseer| async move {
let local_validator = state.local.clone().unwrap();
let local_para = ParaId::from(local_validator.group_index.0);
let local_group_index = local_validator.group_index.unwrap();
let local_para = ParaId::from(local_group_index.0);
let test_leaf = state.make_dummy_leaf(relay_parent);
@@ -1403,9 +1406,9 @@ fn advertisement_not_re_sent_when_peer_re_enters_view() {
);
let candidate_hash = candidate.hash();
let other_group_validators = state.group_validators(local_validator.group_index, true);
let other_group_validators = state.group_validators(local_group_index, true);
let target_group_validators =
state.group_validators((local_validator.group_index.0 + 1).into(), true);
state.group_validators((local_group_index.0 + 1).into(), true);
let v_a = other_group_validators[0];
let v_b = other_group_validators[1];
let v_c = target_group_validators[0];
@@ -1567,7 +1570,7 @@ fn advertisement_not_re_sent_when_peer_re_enters_view() {
assert_eq!(manifest, BackedCandidateManifest {
relay_parent,
candidate_hash,
group_index: local_validator.group_index,
group_index: local_group_index,
para_id: local_para,
parent_head_data_hash: pvd.parent_head.hash(),
statement_knowledge: StatementFilter {
@@ -1599,7 +1602,7 @@ fn grid_statements_imported_to_backing() {
let config = TestConfig {
validator_count,
group_size,
local_validator: true,
local_validator: LocalRole::Validator,
async_backing_params: None,
};
@@ -1610,9 +1613,9 @@ fn grid_statements_imported_to_backing() {
test_harness(config, |state, mut overseer| async move {
let local_validator = state.local.clone().unwrap();
let local_group_index = local_validator.group_index.unwrap();
let other_group =
next_group_index(local_validator.group_index, validator_count, group_size);
let other_group = next_group_index(local_group_index, validator_count, group_size);
let other_para = ParaId::from(other_group.0);
let test_leaf = state.make_dummy_leaf(relay_parent);
@@ -1803,7 +1806,7 @@ fn advertisements_rejected_from_incorrect_peers() {
let config = TestConfig {
validator_count,
group_size,
local_validator: true,
local_validator: LocalRole::Validator,
async_backing_params: None,
};
@@ -1815,9 +1818,9 @@ fn advertisements_rejected_from_incorrect_peers() {
test_harness(config, |state, mut overseer| async move {
let local_validator = state.local.clone().unwrap();
let local_group_index = local_validator.group_index.unwrap();
let other_group =
next_group_index(local_validator.group_index, validator_count, group_size);
let other_group = next_group_index(local_group_index, validator_count, group_size);
let other_para = ParaId::from(other_group.0);
let test_leaf = state.make_dummy_leaf(relay_parent);
@@ -1832,12 +1835,12 @@ fn advertisements_rejected_from_incorrect_peers() {
);
let candidate_hash = candidate.hash();
let target_group_validators = state.group_validators(local_validator.group_index, true);
let other_group_validators = state.group_validators(other_group, true);
let v_a = target_group_validators[0];
let v_b = target_group_validators[1];
let v_c = other_group_validators[0];
let v_d = other_group_validators[1];
let other_group_validators = state.group_validators(local_group_index, true);
let target_group_validators = state.group_validators(other_group, true);
let v_a = other_group_validators[0];
let v_b = other_group_validators[1];
let v_c = target_group_validators[0];
let v_d = target_group_validators[1];
// peer A is in group, has relay parent in view.
// peer B is in group, has no relay parent in view.
@@ -1948,7 +1951,7 @@ fn manifest_rejected_with_unknown_relay_parent() {
let config = TestConfig {
validator_count,
group_size,
local_validator: true,
local_validator: LocalRole::Validator,
async_backing_params: None,
};
@@ -1959,9 +1962,9 @@ fn manifest_rejected_with_unknown_relay_parent() {
test_harness(config, |state, mut overseer| async move {
let local_validator = state.local.clone().unwrap();
let local_group_index = local_validator.group_index.unwrap();
let other_group =
next_group_index(local_validator.group_index, validator_count, group_size);
let other_group = next_group_index(local_group_index, validator_count, group_size);
let other_para = ParaId::from(other_group.0);
let test_leaf = state.make_dummy_leaf(relay_parent);
@@ -2054,7 +2057,7 @@ fn manifest_rejected_when_not_a_validator() {
let config = TestConfig {
validator_count,
group_size,
local_validator: false,
local_validator: LocalRole::None,
async_backing_params: None,
};
@@ -2156,7 +2159,7 @@ fn manifest_rejected_when_group_does_not_match_para() {
let config = TestConfig {
validator_count,
group_size,
local_validator: true,
local_validator: LocalRole::Validator,
async_backing_params: None,
};
@@ -2166,9 +2169,9 @@ fn manifest_rejected_when_group_does_not_match_para() {
test_harness(config, |state, mut overseer| async move {
let local_validator = state.local.clone().unwrap();
let local_group_index = local_validator.group_index.unwrap();
let other_group =
next_group_index(local_validator.group_index, validator_count, group_size);
let other_group = next_group_index(local_group_index, validator_count, group_size);
// Create a mismatch between group and para.
let other_para = next_group_index(other_group, validator_count, group_size);
let other_para = ParaId::from(other_para.0);
@@ -2263,7 +2266,7 @@ fn peer_reported_for_advertisement_conflicting_with_confirmed_candidate() {
let config = TestConfig {
validator_count,
group_size,
local_validator: true,
local_validator: LocalRole::Validator,
async_backing_params: None,
};
@@ -2274,9 +2277,9 @@ fn peer_reported_for_advertisement_conflicting_with_confirmed_candidate() {
test_harness(config, |state, mut overseer| async move {
let local_validator = state.local.clone().unwrap();
let local_group_index = local_validator.group_index.unwrap();
let other_group =
next_group_index(local_validator.group_index, validator_count, group_size);
let other_group = next_group_index(local_group_index, validator_count, group_size);
let other_para = ParaId::from(other_group.0);
let test_leaf = state.make_dummy_leaf(relay_parent);
@@ -2454,3 +2457,141 @@ fn peer_reported_for_advertisement_conflicting_with_confirmed_candidate() {
overseer
});
}
#[test]
fn inactive_local_participates_in_grid() {
let validator_count = 11;
let group_size = 3;
let config = TestConfig {
validator_count,
group_size,
local_validator: LocalRole::InactiveValidator,
async_backing_params: None,
};
let dummy_relay_parent = Hash::repeat_byte(2);
let relay_parent = Hash::repeat_byte(1);
let peer_a = PeerId::random();
test_harness(config, |state, mut overseer| async move {
let local_validator = state.local.clone().unwrap();
assert_eq!(local_validator.validator_index.0, validator_count as u32);
let group_idx = GroupIndex::from(0);
let para = ParaId::from(0);
// Dummy leaf is needed to update topology.
let dummy_leaf = state.make_dummy_leaf(Hash::repeat_byte(2));
let test_leaf = state.make_dummy_leaf(relay_parent);
let (candidate, pvd) = make_candidate(
relay_parent,
1,
para,
test_leaf.para_data(para).head_data.clone(),
vec![4, 5, 6].into(),
Hash::repeat_byte(42).into(),
);
let candidate_hash = candidate.hash();
let first_group = state.group_validators(group_idx, true);
let v_a = first_group.last().unwrap().clone();
let v_b = first_group.first().unwrap().clone();
{
connect_peer(
&mut overseer,
peer_a.clone(),
Some(vec![state.discovery_id(v_a)].into_iter().collect()),
)
.await;
send_peer_view_change(&mut overseer, peer_a.clone(), view![relay_parent]).await;
}
activate_leaf(&mut overseer, &dummy_leaf, &state, true).await;
answer_expected_hypothetical_depth_request(
&mut overseer,
vec![],
Some(dummy_relay_parent),
false,
)
.await;
// Send gossip topology.
send_new_topology(&mut overseer, state.make_dummy_topology()).await;
activate_leaf(&mut overseer, &test_leaf, &state, false).await;
answer_expected_hypothetical_depth_request(
&mut overseer,
vec![],
Some(relay_parent),
false,
)
.await;
// Receive an advertisement from A.
let manifest = BackedCandidateManifest {
relay_parent,
candidate_hash,
group_index: group_idx,
para_id: para,
parent_head_data_hash: pvd.parent_head.hash(),
statement_knowledge: StatementFilter {
seconded_in_group: bitvec::bitvec![u8, Lsb0; 1, 0, 1],
validated_in_group: bitvec::bitvec![u8, Lsb0; 1, 0, 1],
},
};
send_peer_message(
&mut overseer,
peer_a.clone(),
protocol_vstaging::StatementDistributionMessage::BackedCandidateManifest(manifest),
)
.await;
let statements = vec![
state
.sign_statement(
v_a,
CompactStatement::Seconded(candidate_hash),
&SigningContext { parent_hash: relay_parent, session_index: 1 },
)
.as_unchecked()
.clone(),
state
.sign_statement(
v_b,
CompactStatement::Seconded(candidate_hash),
&SigningContext { parent_hash: relay_parent, session_index: 1 },
)
.as_unchecked()
.clone(),
];
// Inactive node requests this candidate.
handle_sent_request(
&mut overseer,
peer_a,
candidate_hash,
StatementFilter::blank(group_size),
candidate.clone(),
pvd.clone(),
statements,
)
.await;
for _ in 0..2 {
assert_matches!(
overseer.recv().await,
AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r)))
if p == peer_a && r == BENEFIT_VALID_STATEMENT.into() => { }
);
}
assert_matches!(
overseer.recv().await,
AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r)))
if p == peer_a && r == BENEFIT_VALID_RESPONSE.into() => { }
);
answer_expected_hypothetical_depth_request(&mut overseer, vec![], None, false).await;
overseer
});
}
@@ -61,19 +61,30 @@ const DEFAULT_ASYNC_BACKING_PARAMETERS: AsyncBackingParams =
// Some deterministic genesis hash for req/res protocol names
const GENESIS_HASH: Hash = Hash::repeat_byte(0xff);
#[derive(Debug, Copy, Clone)]
enum LocalRole {
/// Active validator.
Validator,
/// Authority, not in active validator set.
InactiveValidator,
/// Not a validator.
None,
}
struct TestConfig {
// number of active validators.
validator_count: usize,
// how many validators to place in each group.
group_size: usize,
// whether the local node should be a validator
local_validator: bool,
local_validator: LocalRole,
async_backing_params: Option<AsyncBackingParams>,
}
#[derive(Debug, Clone)]
struct TestLocalValidator {
validator_index: ValidatorIndex,
group_index: GroupIndex,
group_index: Option<GroupIndex>,
}
struct TestState {
@@ -99,7 +110,7 @@ impl TestState {
let mut assignment_keys = Vec::new();
let mut validator_groups = Vec::new();
let local_validator_pos = if config.local_validator {
let local_validator_pos = if let LocalRole::Validator = config.local_validator {
// ensure local validator is always in a full group.
Some(rng.gen_range(0..config.validator_count).saturating_sub(config.group_size - 1))
} else {
@@ -128,13 +139,19 @@ impl TestState {
}
}
let local = if let Some(local_pos) = local_validator_pos {
Some(TestLocalValidator {
let local = match (config.local_validator, local_validator_pos) {
(LocalRole::Validator, Some(local_pos)) => Some(TestLocalValidator {
validator_index: ValidatorIndex(local_pos as _),
group_index: GroupIndex((local_pos / config.group_size) as _),
})
} else {
None
group_index: Some(GroupIndex((local_pos / config.group_size) as _)),
}),
(LocalRole::InactiveValidator, None) => {
discovery_keys.push(AuthorityDiscoveryPair::generate().0.public());
Some(TestLocalValidator {
validator_index: ValidatorIndex(config.validator_count as u32),
group_index: None,
})
},
_ => None,
};
let validator_public = validator_pubkeys(&validators);
@@ -181,15 +198,23 @@ impl TestState {
fn make_dummy_topology(&self) -> NewGossipTopology {
let validator_count = self.config.validator_count;
let is_local_inactive = matches!(self.config.local_validator, LocalRole::InactiveValidator);
let mut indices: Vec<usize> = (0..validator_count).collect();
if is_local_inactive {
indices.push(validator_count);
}
NewGossipTopology {
session: 1,
topology: SessionGridTopology::new(
(0..validator_count).collect(),
(0..validator_count)
indices.clone(),
indices
.into_iter()
.map(|i| TopologyPeerInfo {
peer_ids: Vec::new(),
validator_index: ValidatorIndex(i as u32),
discovery_id: AuthorityDiscoveryPair::generate().0.public(),
discovery_id: self.session_info.discovery_keys[i].clone(),
})
.collect(),
),
@@ -276,7 +301,7 @@ fn test_harness<T: Future<Output = VirtualOverseer>>(
test: impl FnOnce(TestState, VirtualOverseer) -> T,
) {
let pool = sp_core::testing::TaskExecutor::new();
let keystore = if config.local_validator {
let keystore = if let LocalRole::Validator = config.local_validator {
test_helpers::mock::make_ferdie_keystore()
} else {
Arc::new(LocalKeystore::in_memory()) as KeystorePtr
@@ -32,7 +32,7 @@ fn cluster_peer_allowed_to_send_incomplete_statements() {
let config = TestConfig {
validator_count: 20,
group_size,
local_validator: true,
local_validator: LocalRole::Validator,
async_backing_params: None,
};
@@ -43,7 +43,8 @@ fn cluster_peer_allowed_to_send_incomplete_statements() {
test_harness(config, |state, mut overseer| async move {
let local_validator = state.local.clone().unwrap();
let local_para = ParaId::from(local_validator.group_index.0);
let local_group_index = local_validator.group_index.unwrap();
let local_para = ParaId::from(local_group_index.0);
let test_leaf = state.make_dummy_leaf(relay_parent);
@@ -57,7 +58,7 @@ fn cluster_peer_allowed_to_send_incomplete_statements() {
);
let candidate_hash = candidate.hash();
let other_group_validators = state.group_validators(local_validator.group_index, true);
let other_group_validators = state.group_validators(local_group_index, true);
let v_a = other_group_validators[0];
let v_b = other_group_validators[1];
@@ -188,7 +189,7 @@ fn peer_reported_for_providing_statements_meant_to_be_masked_out() {
let config = TestConfig {
validator_count,
group_size,
local_validator: true,
local_validator: LocalRole::Validator,
async_backing_params: Some(AsyncBackingParams {
// Makes `seconding_limit: 2` (easier to hit the limit).
max_candidate_depth: 1,
@@ -203,9 +204,9 @@ fn peer_reported_for_providing_statements_meant_to_be_masked_out() {
test_harness(config, |state, mut overseer| async move {
let local_validator = state.local.clone().unwrap();
let local_group_index = local_validator.group_index.unwrap();
let other_group =
next_group_index(local_validator.group_index, validator_count, group_size);
let other_group = next_group_index(local_group_index, validator_count, group_size);
let other_para = ParaId::from(other_group.0);
let test_leaf = state.make_dummy_leaf(relay_parent);
@@ -475,7 +476,7 @@ fn peer_reported_for_not_enough_statements() {
let config = TestConfig {
validator_count,
group_size,
local_validator: true,
local_validator: LocalRole::Validator,
async_backing_params: None,
};
@@ -486,9 +487,9 @@ fn peer_reported_for_not_enough_statements() {
test_harness(config, |state, mut overseer| async move {
let local_validator = state.local.clone().unwrap();
let local_group_index = local_validator.group_index.unwrap();
let other_group =
next_group_index(local_validator.group_index, validator_count, group_size);
let other_group = next_group_index(local_group_index, validator_count, group_size);
let other_para = ParaId::from(other_group.0);
let test_leaf = state.make_dummy_leaf(relay_parent);
@@ -670,7 +671,7 @@ fn peer_reported_for_duplicate_statements() {
let config = TestConfig {
validator_count: 20,
group_size,
local_validator: true,
local_validator: LocalRole::Validator,
async_backing_params: None,
};
@@ -681,7 +682,8 @@ fn peer_reported_for_duplicate_statements() {
test_harness(config, |state, mut overseer| async move {
let local_validator = state.local.clone().unwrap();
let local_para = ParaId::from(local_validator.group_index.0);
let local_group_index = local_validator.group_index.unwrap();
let local_para = ParaId::from(local_group_index.0);
let test_leaf = state.make_dummy_leaf(relay_parent);
@@ -695,7 +697,7 @@ fn peer_reported_for_duplicate_statements() {
);
let candidate_hash = candidate.hash();
let other_group_validators = state.group_validators(local_validator.group_index, true);
let other_group_validators = state.group_validators(local_group_index, true);
let v_a = other_group_validators[0];
let v_b = other_group_validators[1];
@@ -830,7 +832,7 @@ fn peer_reported_for_providing_statements_with_invalid_signatures() {
let config = TestConfig {
validator_count: 20,
group_size,
local_validator: true,
local_validator: LocalRole::Validator,
async_backing_params: None,
};
@@ -841,7 +843,8 @@ fn peer_reported_for_providing_statements_with_invalid_signatures() {
test_harness(config, |state, mut overseer| async move {
let local_validator = state.local.clone().unwrap();
let local_para = ParaId::from(local_validator.group_index.0);
let local_group_index = local_validator.group_index.unwrap();
let local_para = ParaId::from(local_group_index.0);
let test_leaf = state.make_dummy_leaf(relay_parent);
@@ -855,8 +858,8 @@ fn peer_reported_for_providing_statements_with_invalid_signatures() {
);
let candidate_hash = candidate.hash();
let other_group_validators = state.group_validators(local_validator.group_index, true);
state.group_validators((local_validator.group_index.0 + 1).into(), true);
let other_group_validators = state.group_validators(local_group_index, true);
state.group_validators((local_group_index.0 + 1).into(), true);
let v_a = other_group_validators[0];
let v_b = other_group_validators[1];
@@ -968,7 +971,7 @@ fn peer_reported_for_providing_statements_with_wrong_validator_id() {
let config = TestConfig {
validator_count: 20,
group_size,
local_validator: true,
local_validator: LocalRole::Validator,
async_backing_params: None,
};
@@ -979,7 +982,8 @@ fn peer_reported_for_providing_statements_with_wrong_validator_id() {
test_harness(config, |state, mut overseer| async move {
let local_validator = state.local.clone().unwrap();
let local_para = ParaId::from(local_validator.group_index.0);
let local_group_index = local_validator.group_index.unwrap();
let local_para = ParaId::from(local_group_index.0);
let test_leaf = state.make_dummy_leaf(relay_parent);
@@ -993,9 +997,8 @@ fn peer_reported_for_providing_statements_with_wrong_validator_id() {
);
let candidate_hash = candidate.hash();
let other_group_validators = state.group_validators(local_validator.group_index, true);
let next_group_validators =
state.group_validators((local_validator.group_index.0 + 1).into(), true);
let other_group_validators = state.group_validators(local_group_index, true);
let next_group_validators = state.group_validators((local_group_index.0 + 1).into(), true);
let v_a = other_group_validators[0];
let v_c = next_group_validators[0];
@@ -1105,7 +1108,7 @@ fn local_node_sanity_checks_incoming_requests() {
let config = TestConfig {
validator_count: 20,
group_size: 3,
local_validator: true,
local_validator: LocalRole::Validator,
async_backing_params: None,
};
@@ -1117,7 +1120,8 @@ fn local_node_sanity_checks_incoming_requests() {
test_harness(config, |mut state, mut overseer| async move {
let local_validator = state.local.clone().unwrap();
let local_para = ParaId::from(local_validator.group_index.0);
let local_group_index = local_validator.group_index.unwrap();
let local_para = ParaId::from(local_group_index.0);
let test_leaf = state.make_dummy_leaf(relay_parent);
@@ -1135,7 +1139,7 @@ fn local_node_sanity_checks_incoming_requests() {
// peer B is in group, has no relay parent in view.
// peer C is not in group, has relay parent in view.
{
let other_group_validators = state.group_validators(local_validator.group_index, true);
let other_group_validators = state.group_validators(local_group_index, true);
connect_peer(
&mut overseer,
@@ -1311,7 +1315,7 @@ fn local_node_checks_that_peer_can_request_before_responding() {
let config = TestConfig {
validator_count: 20,
group_size: 3,
local_validator: true,
local_validator: LocalRole::Validator,
async_backing_params: None,
};
@@ -1321,7 +1325,8 @@ fn local_node_checks_that_peer_can_request_before_responding() {
test_harness(config, |mut state, mut overseer| async move {
let local_validator = state.local.clone().unwrap();
let local_para = ParaId::from(local_validator.group_index.0);
let local_group_index = local_validator.group_index.unwrap();
let local_para = ParaId::from(local_group_index.0);
let test_leaf = state.make_dummy_leaf(relay_parent);
@@ -1336,7 +1341,7 @@ fn local_node_checks_that_peer_can_request_before_responding() {
let candidate_hash = candidate.hash();
// Peers A and B are in group and have relay parent in view.
let other_group_validators = state.group_validators(local_validator.group_index, true);
let other_group_validators = state.group_validators(local_group_index, true);
connect_peer(
&mut overseer,
@@ -1515,7 +1520,7 @@ fn local_node_respects_statement_mask() {
let config = TestConfig {
validator_count,
group_size,
local_validator: true,
local_validator: LocalRole::Validator,
async_backing_params: None,
};
@@ -1527,7 +1532,8 @@ fn local_node_respects_statement_mask() {
test_harness(config, |mut state, mut overseer| async move {
let local_validator = state.local.clone().unwrap();
let local_para = ParaId::from(local_validator.group_index.0);
let local_group_index = local_validator.group_index.unwrap();
let local_para = ParaId::from(local_group_index.0);
let test_leaf = state.make_dummy_leaf(relay_parent);
@@ -1541,9 +1547,9 @@ fn local_node_respects_statement_mask() {
);
let candidate_hash = candidate.hash();
let other_group_validators = state.group_validators(local_validator.group_index, true);
let other_group_validators = state.group_validators(local_group_index, true);
let target_group_validators =
state.group_validators((local_validator.group_index.0 + 1).into(), true);
state.group_validators((local_group_index.0 + 1).into(), true);
let v_a = other_group_validators[0];
let v_b = other_group_validators[1];
let v_c = target_group_validators[0];
@@ -1707,7 +1713,7 @@ fn local_node_respects_statement_mask() {
assert_eq!(manifest, BackedCandidateManifest {
relay_parent,
candidate_hash,
group_index: local_validator.group_index,
group_index: local_group_index,
para_id: local_para,
parent_head_data_hash: pvd.parent_head.hash(),
statement_knowledge: StatementFilter {
@@ -1761,7 +1767,7 @@ fn should_delay_before_retrying_dropped_requests() {
let config = TestConfig {
validator_count,
group_size,
local_validator: true,
local_validator: LocalRole::Validator,
async_backing_params: None,
};
@@ -1772,9 +1778,9 @@ fn should_delay_before_retrying_dropped_requests() {
test_harness(config, |state, mut overseer| async move {
let local_validator = state.local.clone().unwrap();
let local_group_index = local_validator.group_index.unwrap();
let other_group =
next_group_index(local_validator.group_index, validator_count, group_size);
let other_group = next_group_index(local_group_index, validator_count, group_size);
let other_para = ParaId::from(other_group.0);
let test_leaf = state.make_dummy_leaf(relay_parent);