statement-distribution: validator disabling (#1841)

Closes #1591.

The purpose of this PR is filter out backing statements from the network
signed by disabled validators. This is just an optimization, since we
will do filtering in the runtime in #1863 to avoid nodes to filter
garbage out at block production time.

- [x] Ensure it's ok to fiddle with the mask of manifests
- [x] Write more unit tests
- [x] Test locally
- [x] simple zombienet test
- [x] PRDoc

---------

Co-authored-by: Tsvetomir Dimitrov <tsvetomir@parity.io>
This commit is contained in:
ordian
2024-01-10 10:32:52 +01:00
committed by GitHub
parent 01ea45c3a1
commit a4195326b9
14 changed files with 1577 additions and 833 deletions
@@ -75,15 +75,7 @@ fn share_seconded_circulated_to_cluster() {
send_peer_view_change(&mut overseer, peer_c.clone(), view![relay_parent]).await;
}
activate_leaf(&mut overseer, &test_leaf, &state, true).await;
answer_expected_hypothetical_depth_request(
&mut overseer,
vec![],
Some(relay_parent),
false,
)
.await;
activate_leaf(&mut overseer, &test_leaf, &state, true, vec![]).await;
let full_signed = state
.sign_statement(
@@ -120,7 +112,7 @@ fn share_seconded_circulated_to_cluster() {
// sharing a `Seconded` message confirms a candidate, which leads to new
// fragment tree updates.
answer_expected_hypothetical_depth_request(&mut overseer, vec![], None, false).await;
answer_expected_hypothetical_depth_request(&mut overseer, vec![]).await;
overseer
});
@@ -156,15 +148,7 @@ fn cluster_valid_statement_before_seconded_ignored() {
.await;
send_peer_view_change(&mut overseer, peer_a.clone(), view![relay_parent]).await;
activate_leaf(&mut overseer, &test_leaf, &state, true).await;
answer_expected_hypothetical_depth_request(
&mut overseer,
vec![],
Some(relay_parent),
false,
)
.await;
activate_leaf(&mut overseer, &test_leaf, &state, true, vec![]).await;
let signed_valid = state.sign_statement(
v_a,
@@ -226,15 +210,7 @@ fn cluster_statement_bad_signature() {
.await;
send_peer_view_change(&mut overseer, peer_a.clone(), view![relay_parent]).await;
activate_leaf(&mut overseer, &test_leaf, &state, true).await;
answer_expected_hypothetical_depth_request(
&mut overseer,
vec![],
Some(relay_parent),
false,
)
.await;
activate_leaf(&mut overseer, &test_leaf, &state, true, vec![]).await;
// sign statements with wrong signing context, leading to bad signature.
let statements = vec![
@@ -308,15 +284,7 @@ fn useful_cluster_statement_from_non_cluster_peer_rejected() {
.await;
send_peer_view_change(&mut overseer, peer_a.clone(), view![relay_parent]).await;
activate_leaf(&mut overseer, &test_leaf, &state, true).await;
answer_expected_hypothetical_depth_request(
&mut overseer,
vec![],
Some(relay_parent),
false,
)
.await;
activate_leaf(&mut overseer, &test_leaf, &state, true, vec![]).await;
let statement = state
.sign_statement(
@@ -370,15 +338,7 @@ fn statement_from_non_cluster_originator_unexpected() {
connect_peer(&mut overseer, peer_a.clone(), None).await;
send_peer_view_change(&mut overseer, peer_a.clone(), view![relay_parent]).await;
activate_leaf(&mut overseer, &test_leaf, &state, true).await;
answer_expected_hypothetical_depth_request(
&mut overseer,
vec![],
Some(relay_parent),
false,
)
.await;
activate_leaf(&mut overseer, &test_leaf, &state, true, vec![]).await;
let statement = state
.sign_statement(
@@ -448,15 +408,7 @@ fn seconded_statement_leads_to_request() {
.await;
send_peer_view_change(&mut overseer, peer_a.clone(), view![relay_parent]).await;
activate_leaf(&mut overseer, &test_leaf, &state, true).await;
answer_expected_hypothetical_depth_request(
&mut overseer,
vec![],
Some(relay_parent),
false,
)
.await;
activate_leaf(&mut overseer, &test_leaf, &state, true, vec![]).await;
let statement = state
.sign_statement(
@@ -497,7 +449,7 @@ fn seconded_statement_leads_to_request() {
if p == peer_a && r == BENEFIT_VALID_RESPONSE.into() => { }
);
answer_expected_hypothetical_depth_request(&mut overseer, vec![], None, false).await;
answer_expected_hypothetical_depth_request(&mut overseer, vec![]).await;
overseer
});
@@ -544,15 +496,7 @@ fn cluster_statements_shared_seconded_first() {
.await;
}
activate_leaf(&mut overseer, &test_leaf, &state, true).await;
answer_expected_hypothetical_depth_request(
&mut overseer,
vec![],
Some(relay_parent),
false,
)
.await;
activate_leaf(&mut overseer, &test_leaf, &state, true, vec![]).await;
let full_signed = state
.sign_statement(
@@ -579,7 +523,7 @@ fn cluster_statements_shared_seconded_first() {
.await;
// result of new confirmed candidate.
answer_expected_hypothetical_depth_request(&mut overseer, vec![], None, false).await;
answer_expected_hypothetical_depth_request(&mut overseer, vec![]).await;
overseer
.send(FromOrchestra::Communication {
@@ -677,15 +621,7 @@ fn cluster_accounts_for_implicit_view() {
send_peer_view_change(&mut overseer, peer_a.clone(), view![relay_parent]).await;
}
activate_leaf(&mut overseer, &test_leaf, &state, true).await;
answer_expected_hypothetical_depth_request(
&mut overseer,
vec![],
Some(relay_parent),
false,
)
.await;
activate_leaf(&mut overseer, &test_leaf, &state, true, vec![]).await;
let full_signed = state
.sign_statement(
@@ -722,7 +658,7 @@ fn cluster_accounts_for_implicit_view() {
// sharing a `Seconded` message confirms a candidate, which leads to new
// fragment tree updates.
answer_expected_hypothetical_depth_request(&mut overseer, vec![], None, false).await;
answer_expected_hypothetical_depth_request(&mut overseer, vec![]).await;
// activate new leaf, which has relay-parent in implicit view.
let next_relay_parent = Hash::repeat_byte(2);
@@ -730,15 +666,7 @@ fn cluster_accounts_for_implicit_view() {
next_test_leaf.parent_hash = relay_parent;
next_test_leaf.number = 2;
activate_leaf(&mut overseer, &next_test_leaf, &state, false).await;
answer_expected_hypothetical_depth_request(
&mut overseer,
vec![],
Some(next_relay_parent),
false,
)
.await;
activate_leaf(&mut overseer, &next_test_leaf, &state, false, vec![]).await;
send_peer_view_change(&mut overseer, peer_a.clone(), view![next_relay_parent]).await;
send_peer_view_change(&mut overseer, peer_b.clone(), view![next_relay_parent]).await;
@@ -820,15 +748,7 @@ fn cluster_messages_imported_after_confirmed_candidate_importable_check() {
send_peer_view_change(&mut overseer, peer_a.clone(), view![relay_parent]).await;
}
activate_leaf(&mut overseer, &test_leaf, &state, true).await;
answer_expected_hypothetical_depth_request(
&mut overseer,
vec![],
Some(relay_parent),
false,
)
.await;
activate_leaf(&mut overseer, &test_leaf, &state, true, vec![]).await;
// Peer sends `Seconded` statement.
{
@@ -885,8 +805,6 @@ fn cluster_messages_imported_after_confirmed_candidate_importable_check() {
},
vec![(relay_parent, vec![0])],
)],
None,
false,
)
.await;
@@ -953,15 +871,7 @@ fn cluster_messages_imported_after_new_leaf_importable_check() {
send_peer_view_change(&mut overseer, peer_a.clone(), view![relay_parent]).await;
}
activate_leaf(&mut overseer, &test_leaf, &state, true).await;
answer_expected_hypothetical_depth_request(
&mut overseer,
vec![],
Some(relay_parent),
false,
)
.await;
activate_leaf(&mut overseer, &test_leaf, &state, true, vec![]).await;
// Peer sends `Seconded` statement.
{
@@ -1008,17 +918,18 @@ fn cluster_messages_imported_after_new_leaf_importable_check() {
);
}
answer_expected_hypothetical_depth_request(&mut overseer, vec![], None, false).await;
answer_expected_hypothetical_depth_request(&mut overseer, vec![]).await;
let next_relay_parent = Hash::repeat_byte(2);
let mut next_test_leaf = state.make_dummy_leaf(next_relay_parent);
next_test_leaf.parent_hash = relay_parent;
next_test_leaf.number = 2;
activate_leaf(&mut overseer, &next_test_leaf, &state, false).await;
answer_expected_hypothetical_depth_request(
activate_leaf(
&mut overseer,
&next_test_leaf,
&state,
false,
vec![(
HypotheticalCandidate::Complete {
candidate_hash,
@@ -1027,8 +938,6 @@ fn cluster_messages_imported_after_new_leaf_importable_check() {
},
vec![(relay_parent, vec![0])],
)],
Some(next_relay_parent),
false,
)
.await;
@@ -1117,15 +1026,7 @@ fn ensure_seconding_limit_is_respected() {
send_peer_view_change(&mut overseer, peer_a.clone(), view![relay_parent]).await;
}
activate_leaf(&mut overseer, &test_leaf, &state, true).await;
answer_expected_hypothetical_depth_request(
&mut overseer,
vec![],
Some(relay_parent),
false,
)
.await;
activate_leaf(&mut overseer, &test_leaf, &state, true, vec![]).await;
// Confirm the candidates locally so that we don't send out requests.
@@ -1152,7 +1053,7 @@ fn ensure_seconding_limit_is_respected() {
AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::SendValidationMessage(peers, _)) if peers == vec![peer_a]
);
answer_expected_hypothetical_depth_request(&mut overseer, vec![], None, false).await;
answer_expected_hypothetical_depth_request(&mut overseer, vec![]).await;
}
// Candidate 2.
@@ -1178,7 +1079,7 @@ fn ensure_seconding_limit_is_respected() {
AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::SendValidationMessage(peers, _)) if peers == vec![peer_a]
);
answer_expected_hypothetical_depth_request(&mut overseer, vec![], None, false).await;
answer_expected_hypothetical_depth_request(&mut overseer, vec![]).await;
}
// Send first statement from peer A.
@@ -102,15 +102,7 @@ fn backed_candidate_leads_to_advertisement() {
send_peer_view_change(&mut overseer, peer_c.clone(), view![relay_parent]).await;
}
activate_leaf(&mut overseer, &test_leaf, &state, true).await;
answer_expected_hypothetical_depth_request(
&mut overseer,
vec![],
Some(relay_parent),
false,
)
.await;
activate_leaf(&mut overseer, &test_leaf, &state, true, vec![]).await;
// Send gossip topology.
send_new_topology(&mut overseer, state.make_dummy_topology()).await;
@@ -137,7 +129,7 @@ fn backed_candidate_leads_to_advertisement() {
AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::SendValidationMessage(peers, _)) if peers == vec![peer_a]
);
answer_expected_hypothetical_depth_request(&mut overseer, vec![], None, false).await;
answer_expected_hypothetical_depth_request(&mut overseer, vec![]).await;
}
// Send enough statements to make candidate backable, make sure announcements are sent.
@@ -232,7 +224,7 @@ fn backed_candidate_leads_to_advertisement() {
}
);
answer_expected_hypothetical_depth_request(&mut overseer, vec![], None, false).await;
answer_expected_hypothetical_depth_request(&mut overseer, vec![]).await;
}
overseer
@@ -320,15 +312,7 @@ fn received_advertisement_before_confirmation_leads_to_request() {
send_peer_view_change(&mut overseer, peer_d.clone(), view![relay_parent]).await;
}
activate_leaf(&mut overseer, &test_leaf, &state, true).await;
answer_expected_hypothetical_depth_request(
&mut overseer,
vec![],
Some(relay_parent),
false,
)
.await;
activate_leaf(&mut overseer, &test_leaf, &state, true, vec![]).await;
// Send gossip topology.
send_new_topology(&mut overseer, state.make_dummy_topology()).await;
@@ -400,7 +384,7 @@ fn received_advertisement_before_confirmation_leads_to_request() {
if p == peer_c && r == BENEFIT_VALID_RESPONSE.into() => { }
);
answer_expected_hypothetical_depth_request(&mut overseer, vec![], None, false).await;
answer_expected_hypothetical_depth_request(&mut overseer, vec![]).await;
}
overseer
@@ -530,7 +514,7 @@ fn received_advertisement_after_backing_leads_to_acknowledgement() {
assert_peer_reported!(&mut overseer, peer_c, BENEFIT_VALID_STATEMENT);
assert_peer_reported!(&mut overseer, peer_c, BENEFIT_VALID_RESPONSE);
answer_expected_hypothetical_depth_request(&mut overseer, vec![], None, false).await;
answer_expected_hypothetical_depth_request(&mut overseer, vec![]).await;
}
// Receive Backed message.
@@ -561,7 +545,7 @@ fn received_advertisement_after_backing_leads_to_acknowledgement() {
}
);
answer_expected_hypothetical_depth_request(&mut overseer, vec![], None, false).await;
answer_expected_hypothetical_depth_request(&mut overseer, vec![]).await;
}
// Receive a manifest about the same candidate from peer D.
@@ -733,7 +717,7 @@ fn received_acknowledgements_for_locally_confirmed() {
AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::SendValidationMessage(peers, _)) if peers == vec![peer_a]
);
answer_expected_hypothetical_depth_request(&mut overseer, vec![], None, false).await;
answer_expected_hypothetical_depth_request(&mut overseer, vec![]).await;
}
// Receive an unexpected acknowledgement from peer D.
@@ -798,7 +782,7 @@ fn received_acknowledgements_for_locally_confirmed() {
}
);
answer_expected_hypothetical_depth_request(&mut overseer, vec![], None, false).await;
answer_expected_hypothetical_depth_request(&mut overseer, vec![]).await;
}
// Receive an unexpected acknowledgement from peer D.
@@ -930,7 +914,7 @@ fn received_acknowledgements_for_externally_confirmed() {
assert_peer_reported!(&mut overseer, peer_c, BENEFIT_VALID_STATEMENT);
assert_peer_reported!(&mut overseer, peer_c, BENEFIT_VALID_RESPONSE);
answer_expected_hypothetical_depth_request(&mut overseer, vec![], None, false).await;
answer_expected_hypothetical_depth_request(&mut overseer, vec![]).await;
}
let ack = BackedCandidateAcknowledgement {
@@ -1022,15 +1006,7 @@ fn received_advertisement_after_confirmation_before_backing() {
send_peer_view_change(&mut overseer, peer_e.clone(), view![relay_parent]).await;
}
activate_leaf(&mut overseer, &test_leaf, &state, true).await;
answer_expected_hypothetical_depth_request(
&mut overseer,
vec![],
Some(relay_parent),
false,
)
.await;
activate_leaf(&mut overseer, &test_leaf, &state, true, vec![]).await;
// Send gossip topology.
send_new_topology(&mut overseer, state.make_dummy_topology()).await;
@@ -1121,7 +1097,7 @@ fn received_advertisement_after_confirmation_before_backing() {
if p == peer_c && r == BENEFIT_VALID_RESPONSE.into()
);
answer_expected_hypothetical_depth_request(&mut overseer, vec![], None, false).await;
answer_expected_hypothetical_depth_request(&mut overseer, vec![]).await;
}
// Receive advertisement from peer D (after confirmation but before backing).
@@ -1208,15 +1184,7 @@ fn additional_statements_are_shared_after_manifest_exchange() {
send_peer_view_change(&mut overseer, peer_e.clone(), view![relay_parent]).await;
}
activate_leaf(&mut overseer, &test_leaf, &state, true).await;
answer_expected_hypothetical_depth_request(
&mut overseer,
vec![],
Some(relay_parent),
false,
)
.await;
activate_leaf(&mut overseer, &test_leaf, &state, true, vec![]).await;
// Send gossip topology.
send_new_topology(&mut overseer, state.make_dummy_topology()).await;
@@ -1301,13 +1269,8 @@ fn additional_statements_are_shared_after_manifest_exchange() {
persisted_validation_data: pvd.clone(),
};
let membership = vec![(relay_parent, vec![0])];
answer_expected_hypothetical_depth_request(
&mut overseer,
vec![(hypothetical, membership)],
None,
false,
)
.await;
answer_expected_hypothetical_depth_request(&mut overseer, vec![(hypothetical, membership)])
.await;
// Statements are sent to the Backing subsystem.
{
@@ -1371,7 +1334,7 @@ fn additional_statements_are_shared_after_manifest_exchange() {
}
);
answer_expected_hypothetical_depth_request(&mut overseer, vec![], None, false).await;
answer_expected_hypothetical_depth_request(&mut overseer, vec![]).await;
}
// Receive a manifest about the same candidate from peer D. Contains different statements.
@@ -1514,17 +1477,8 @@ fn advertisement_sent_when_peer_enters_relay_parent_view() {
send_peer_view_change(&mut overseer, peer_a.clone(), view![relay_parent]).await;
}
activate_leaf(&mut overseer, &test_leaf, &state, true).await;
activate_leaf(&mut overseer, &test_leaf, &state, true, vec![]).await;
answer_expected_hypothetical_depth_request(
&mut overseer,
vec![],
Some(relay_parent),
false,
)
.await;
// Send gossip topology.
send_new_topology(&mut overseer, state.make_dummy_topology()).await;
// Confirm the candidate locally so that we don't send out requests.
@@ -1549,7 +1503,7 @@ fn advertisement_sent_when_peer_enters_relay_parent_view() {
AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::SendValidationMessage(peers, _)) if peers == vec![peer_a]
);
answer_expected_hypothetical_depth_request(&mut overseer, vec![], None, false).await;
answer_expected_hypothetical_depth_request(&mut overseer, vec![]).await;
}
// Send enough statements to make candidate backable, make sure announcements are sent.
@@ -1616,7 +1570,7 @@ fn advertisement_sent_when_peer_enters_relay_parent_view() {
})
.await;
answer_expected_hypothetical_depth_request(&mut overseer, vec![], None, false).await;
answer_expected_hypothetical_depth_request(&mut overseer, vec![]).await;
// Relay parent enters view of peer C.
{
@@ -1737,17 +1691,8 @@ fn advertisement_not_re_sent_when_peer_re_enters_view() {
send_peer_view_change(&mut overseer, peer_c.clone(), view![relay_parent]).await;
}
activate_leaf(&mut overseer, &test_leaf, &state, true).await;
activate_leaf(&mut overseer, &test_leaf, &state, true, vec![]).await;
answer_expected_hypothetical_depth_request(
&mut overseer,
vec![],
Some(relay_parent),
false,
)
.await;
// Send gossip topology.
send_new_topology(&mut overseer, state.make_dummy_topology()).await;
// Confirm the candidate locally so that we don't send out requests.
@@ -1772,7 +1717,7 @@ fn advertisement_not_re_sent_when_peer_re_enters_view() {
AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::SendValidationMessage(peers, _)) if peers == vec![peer_a]
);
answer_expected_hypothetical_depth_request(&mut overseer, vec![], None, false).await;
answer_expected_hypothetical_depth_request(&mut overseer, vec![]).await;
}
// Send enough statements to make candidate backable, make sure announcements are sent.
@@ -1867,7 +1812,7 @@ fn advertisement_not_re_sent_when_peer_re_enters_view() {
}
);
answer_expected_hypothetical_depth_request(&mut overseer, vec![], None, false).await;
answer_expected_hypothetical_depth_request(&mut overseer, vec![]).await;
}
// Peer leaves view.
@@ -1949,17 +1894,8 @@ fn grid_statements_imported_to_backing() {
send_peer_view_change(&mut overseer, peer_e.clone(), view![relay_parent]).await;
}
activate_leaf(&mut overseer, &test_leaf, &state, true).await;
activate_leaf(&mut overseer, &test_leaf, &state, true, vec![]).await;
answer_expected_hypothetical_depth_request(
&mut overseer,
vec![],
Some(relay_parent),
false,
)
.await;
// Send gossip topology.
send_new_topology(&mut overseer, state.make_dummy_topology()).await;
// Receive an advertisement from C.
@@ -2042,13 +1978,8 @@ fn grid_statements_imported_to_backing() {
persisted_validation_data: pvd.clone(),
};
let membership = vec![(relay_parent, vec![0])];
answer_expected_hypothetical_depth_request(
&mut overseer,
vec![(hypothetical, membership)],
None,
false,
)
.await;
answer_expected_hypothetical_depth_request(&mut overseer, vec![(hypothetical, membership)])
.await;
// Receive messages from Backing subsystem.
{
@@ -2165,17 +2096,8 @@ fn advertisements_rejected_from_incorrect_peers() {
send_peer_view_change(&mut overseer, peer_c.clone(), view![relay_parent]).await;
}
activate_leaf(&mut overseer, &test_leaf, &state, true).await;
activate_leaf(&mut overseer, &test_leaf, &state, true, vec![]).await;
answer_expected_hypothetical_depth_request(
&mut overseer,
vec![],
Some(relay_parent),
false,
)
.await;
// Send gossip topology.
send_new_topology(&mut overseer, state.make_dummy_topology()).await;
let manifest = BackedCandidateManifest {
@@ -2289,17 +2211,8 @@ fn manifest_rejected_with_unknown_relay_parent() {
send_peer_view_change(&mut overseer, peer_c.clone(), view![relay_parent]).await;
}
activate_leaf(&mut overseer, &test_leaf, &state, true).await;
activate_leaf(&mut overseer, &test_leaf, &state, true, vec![]).await;
answer_expected_hypothetical_depth_request(
&mut overseer,
vec![],
Some(relay_parent),
false,
)
.await;
// Send gossip topology.
send_new_topology(&mut overseer, state.make_dummy_topology()).await;
let manifest = BackedCandidateManifest {
@@ -2391,17 +2304,8 @@ fn manifest_rejected_when_not_a_validator() {
send_peer_view_change(&mut overseer, peer_c.clone(), view![relay_parent]).await;
}
activate_leaf(&mut overseer, &test_leaf, &state, true).await;
activate_leaf(&mut overseer, &test_leaf, &state, true, vec![]).await;
answer_expected_hypothetical_depth_request(
&mut overseer,
vec![],
Some(relay_parent),
false,
)
.await;
// Send gossip topology.
send_new_topology(&mut overseer, state.make_dummy_topology()).await;
let manifest = BackedCandidateManifest {
@@ -2498,17 +2402,8 @@ fn manifest_rejected_when_group_does_not_match_para() {
send_peer_view_change(&mut overseer, peer_c.clone(), view![relay_parent]).await;
}
activate_leaf(&mut overseer, &test_leaf, &state, true).await;
activate_leaf(&mut overseer, &test_leaf, &state, true, vec![]).await;
answer_expected_hypothetical_depth_request(
&mut overseer,
vec![],
Some(relay_parent),
false,
)
.await;
// Send gossip topology.
send_new_topology(&mut overseer, state.make_dummy_topology()).await;
let manifest = BackedCandidateManifest {
@@ -2613,17 +2508,8 @@ fn peer_reported_for_advertisement_conflicting_with_confirmed_candidate() {
send_peer_view_change(&mut overseer, peer_e.clone(), view![relay_parent]).await;
}
activate_leaf(&mut overseer, &test_leaf, &state, true).await;
activate_leaf(&mut overseer, &test_leaf, &state, true, vec![]).await;
answer_expected_hypothetical_depth_request(
&mut overseer,
vec![],
Some(relay_parent),
false,
)
.await;
// Send gossip topology.
send_new_topology(&mut overseer, state.make_dummy_topology()).await;
let manifest = BackedCandidateManifest {
@@ -2713,7 +2599,7 @@ fn peer_reported_for_advertisement_conflicting_with_confirmed_candidate() {
if p == peer_c && r == BENEFIT_VALID_RESPONSE.into()
);
answer_expected_hypothetical_depth_request(&mut overseer, vec![], None, false).await;
answer_expected_hypothetical_depth_request(&mut overseer, vec![]).await;
}
// Receive conflicting advertisement from peer C after confirmation.
@@ -2755,7 +2641,6 @@ fn inactive_local_participates_in_grid() {
async_backing_params: None,
};
let dummy_relay_parent = Hash::repeat_byte(2);
let relay_parent = Hash::repeat_byte(1);
let peer_a = PeerId::random();
@@ -2795,25 +2680,10 @@ fn inactive_local_participates_in_grid() {
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;
activate_leaf(&mut overseer, &dummy_leaf, &state, true, vec![]).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;
activate_leaf(&mut overseer, &test_leaf, &state, false, vec![]).await;
// Receive an advertisement from A.
let manifest = BackedCandidateManifest {
@@ -2876,7 +2746,7 @@ fn inactive_local_participates_in_grid() {
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;
answer_expected_hypothetical_depth_request(&mut overseer, vec![]).await;
overseer
});
@@ -187,12 +187,30 @@ impl TestState {
collator: None,
})
}),
disabled_validators: Default::default(),
para_data: (0..self.session_info.validator_groups.len())
.map(|i| (ParaId::from(i as u32), PerParaData::new(1, vec![1, 2, 3].into())))
.collect(),
minimum_backing_votes: 2,
}
}
fn make_dummy_leaf_with_disabled_validators(
&self,
relay_parent: Hash,
disabled_validators: Vec<ValidatorIndex>,
) -> TestLeaf {
TestLeaf { disabled_validators, ..self.make_dummy_leaf(relay_parent) }
}
fn make_dummy_leaf_with_min_backing_votes(
&self,
relay_parent: Hash,
minimum_backing_votes: u32,
) -> TestLeaf {
TestLeaf { minimum_backing_votes, ..self.make_dummy_leaf(relay_parent) }
}
fn make_availability_cores(&self, f: impl Fn(usize) -> CoreState) -> Vec<CoreState> {
(0..self.session_info.validator_groups.len()).map(f).collect()
}
@@ -240,6 +258,19 @@ impl TestState {
.collect()
}
fn index_within_group(
&self,
group_index: GroupIndex,
validator_index: ValidatorIndex,
) -> Option<usize> {
self.session_info
.validator_groups
.get(group_index)
.unwrap()
.iter()
.position(|&i| i == validator_index)
}
fn discovery_id(&self, validator_index: ValidatorIndex) -> AuthorityDiscoveryId {
self.session_info.discovery_keys[validator_index.0 as usize].clone()
}
@@ -284,7 +315,7 @@ impl TestState {
&mut self,
peer: PeerId,
request: AttestedCandidateRequest,
) -> impl Future<Output = sc_network::config::OutgoingResponse> {
) -> impl Future<Output = Option<sc_network::config::OutgoingResponse>> {
let (tx, rx) = futures::channel::oneshot::channel();
let req = sc_network::config::IncomingRequest {
peer,
@@ -293,7 +324,7 @@ impl TestState {
};
self.req_sender.send(req).await.unwrap();
rx.map(|r| r.unwrap())
rx.map(|r| r.ok())
}
}
@@ -366,7 +397,9 @@ struct TestLeaf {
parent_hash: Hash,
session: SessionIndex,
availability_cores: Vec<CoreState>,
disabled_validators: Vec<ValidatorIndex>,
para_data: Vec<(ParaId, PerParaData)>,
minimum_backing_votes: u32,
}
impl TestLeaf {
@@ -447,9 +480,7 @@ async fn setup_test_and_connect_peers(
}
}
activate_leaf(overseer, &test_leaf, &state, true).await;
answer_expected_hypothetical_depth_request(overseer, vec![], Some(relay_parent), false).await;
activate_leaf(overseer, &test_leaf, &state, true, vec![]).await;
// Send gossip topology.
send_new_topology(overseer, state.make_dummy_topology()).await;
@@ -472,6 +503,7 @@ async fn activate_leaf(
leaf: &TestLeaf,
test_state: &TestState,
is_new_session: bool,
hypothetical_frontier: Vec<(HypotheticalCandidate, FragmentTreeMembership)>,
) {
let activated = new_leaf(leaf.hash, leaf.number);
@@ -481,7 +513,14 @@ async fn activate_leaf(
))))
.await;
handle_leaf_activation(virtual_overseer, leaf, test_state, is_new_session).await;
handle_leaf_activation(
virtual_overseer,
leaf,
test_state,
is_new_session,
hypothetical_frontier,
)
.await;
}
async fn handle_leaf_activation(
@@ -489,8 +528,18 @@ async fn handle_leaf_activation(
leaf: &TestLeaf,
test_state: &TestState,
is_new_session: bool,
hypothetical_frontier: Vec<(HypotheticalCandidate, FragmentTreeMembership)>,
) {
let TestLeaf { number, hash, parent_hash, para_data, session, availability_cores } = leaf;
let TestLeaf {
number,
hash,
parent_hash,
para_data,
session,
availability_cores,
disabled_validators,
minimum_backing_votes,
} = leaf;
assert_matches!(
virtual_overseer.recv().await,
@@ -530,51 +579,82 @@ async fn handle_leaf_activation(
}
);
assert_matches!(
virtual_overseer.recv().await,
AllMessages::RuntimeApi(
RuntimeApiMessage::Request(parent, RuntimeApiRequest::SessionIndexForChild(tx))) if parent == *hash => {
tx.send(Ok(*session)).unwrap();
}
);
assert_matches!(
virtual_overseer.recv().await,
AllMessages::RuntimeApi(
RuntimeApiMessage::Request(parent, RuntimeApiRequest::AvailabilityCores(tx))) if parent == *hash => {
tx.send(Ok(availability_cores.clone())).unwrap();
}
);
let validator_groups = test_state.session_info.validator_groups.to_vec();
let group_rotation_info =
GroupRotationInfo { session_start_block: 1, group_rotation_frequency: 12, now: 1 };
assert_matches!(
virtual_overseer.recv().await,
AllMessages::RuntimeApi(
RuntimeApiMessage::Request(parent, RuntimeApiRequest::ValidatorGroups(tx))) if parent == *hash => {
tx.send(Ok((validator_groups, group_rotation_info))).unwrap();
}
);
if is_new_session {
assert_matches!(
virtual_overseer.recv().await,
AllMessages::RuntimeApi(
RuntimeApiMessage::Request(parent, RuntimeApiRequest::SessionInfo(s, tx))) if parent == *hash && s == *session => {
loop {
match virtual_overseer.recv().await {
AllMessages::RuntimeApi(RuntimeApiMessage::Request(
_parent,
RuntimeApiRequest::Version(tx),
)) => {
tx.send(Ok(RuntimeApiRequest::DISABLED_VALIDATORS_RUNTIME_REQUIREMENT)).unwrap();
},
AllMessages::RuntimeApi(RuntimeApiMessage::Request(
parent,
RuntimeApiRequest::DisabledValidators(tx),
)) if parent == *hash => {
tx.send(Ok(disabled_validators.clone())).unwrap();
},
AllMessages::RuntimeApi(RuntimeApiMessage::Request(
_parent,
RuntimeApiRequest::DisabledValidators(tx),
)) => {
tx.send(Ok(Vec::new())).unwrap();
},
AllMessages::RuntimeApi(RuntimeApiMessage::Request(
_parent, // assume all active leaves are in the same session
RuntimeApiRequest::SessionIndexForChild(tx),
)) => {
tx.send(Ok(*session)).unwrap();
},
AllMessages::RuntimeApi(RuntimeApiMessage::Request(
parent,
RuntimeApiRequest::SessionInfo(s, tx),
)) if parent == *hash && s == *session => {
assert!(is_new_session, "only expecting this call in a new session");
tx.send(Ok(Some(test_state.session_info.clone()))).unwrap();
}
);
assert_matches!(
virtual_overseer.recv().await,
},
AllMessages::RuntimeApi(RuntimeApiMessage::Request(
parent,
RuntimeApiRequest::MinimumBackingVotes(session_index, tx),
)) if parent == *hash && session_index == *session => {
tx.send(Ok(2)).unwrap();
}
);
assert!(is_new_session, "only expecting this call in a new session");
tx.send(Ok(*minimum_backing_votes)).unwrap();
},
AllMessages::RuntimeApi(RuntimeApiMessage::Request(
parent,
RuntimeApiRequest::AvailabilityCores(tx),
)) if parent == *hash => {
tx.send(Ok(availability_cores.clone())).unwrap();
},
AllMessages::RuntimeApi(RuntimeApiMessage::Request(
parent,
RuntimeApiRequest::ValidatorGroups(tx),
)) if parent == *hash => {
let validator_groups = test_state.session_info.validator_groups.to_vec();
let group_rotation_info = GroupRotationInfo {
session_start_block: 1,
group_rotation_frequency: 12,
now: 1,
};
tx.send(Ok((validator_groups, group_rotation_info))).unwrap();
},
AllMessages::ProspectiveParachains(
ProspectiveParachainsMessage::GetHypotheticalFrontier(req, tx),
) => {
assert_eq!(req.fragment_tree_relay_parent, Some(*hash));
assert!(!req.backed_in_path_only);
for (i, (candidate, _)) in hypothetical_frontier.iter().enumerate() {
assert!(
req.candidates.iter().any(|c| &c == &candidate),
"did not receive request for hypothetical candidate {}",
i,
);
}
tx.send(hypothetical_frontier).unwrap();
// this is the last expected runtime api call
break
},
msg => panic!("unexpected runtime API call: {msg:?}"),
}
}
}
@@ -614,16 +694,14 @@ async fn handle_sent_request(
async fn answer_expected_hypothetical_depth_request(
virtual_overseer: &mut VirtualOverseer,
responses: Vec<(HypotheticalCandidate, FragmentTreeMembership)>,
expected_leaf_hash: Option<Hash>,
expected_backed_in_path_only: bool,
) {
assert_matches!(
virtual_overseer.recv().await,
AllMessages::ProspectiveParachains(
ProspectiveParachainsMessage::GetHypotheticalFrontier(req, tx)
) => {
assert_eq!(req.fragment_tree_relay_parent, expected_leaf_hash);
assert_eq!(req.backed_in_path_only, expected_backed_in_path_only);
assert_eq!(req.fragment_tree_relay_parent, None);
assert!(!req.backed_in_path_only);
for (i, (candidate, _)) in responses.iter().enumerate() {
assert!(
req.candidates.iter().any(|c| &c == &candidate),
File diff suppressed because it is too large Load Diff