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
@@ -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);