Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

Commit

Permalink
Second multiple candidates per relay parent test
Browse files Browse the repository at this point in the history
  • Loading branch information
slumber committed Jun 13, 2022
1 parent b8b6ca0 commit b601bbc
Show file tree
Hide file tree
Showing 2 changed files with 132 additions and 1 deletion.
2 changes: 1 addition & 1 deletion node/core/backing/src/tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ fn make_erasure_root(test: &TestState, pov: PoV) -> Hash {
erasure_coding::branches(&chunks).root()
}

#[derive(Default)]
#[derive(Default, Clone)]
struct TestCandidateBuilder {
para_id: ParaId,
head_data: HeadData,
Expand Down
131 changes: 131 additions & 0 deletions node/core/backing/src/tests/prospective_parachains.rs
Original file line number Diff line number Diff line change
Expand Up @@ -787,3 +787,134 @@ fn prospective_parachains_reject_candidate() {
virtual_overseer
});
}

// Test that a validator can second multiple candidates per single relay parent.
#[test]
fn second_multiple_candidates_per_relay_parent() {
let test_state = TestState::default();
test_harness(test_state.keystore.clone(), |mut virtual_overseer| async move {
// Candidate `a` is seconded in a parent of the activated `leaf`.
const LEAF_BLOCK_NUMBER: BlockNumber = 100;
const LEAF_DEPTH: BlockNumber = 3;
let para_id = test_state.chain_ids[0];

let leaf_hash = Hash::from_low_u64_be(130);
let leaf_parent = get_parent_hash(leaf_hash);
let leaf_grandparent = get_parent_hash(leaf_parent);
let activated = ActivatedLeaf {
hash: leaf_hash,
number: LEAF_BLOCK_NUMBER,
status: LeafStatus::Fresh,
span: Arc::new(jaeger::Span::Disabled),
};
let min_relay_parents = vec![(para_id, LEAF_BLOCK_NUMBER - LEAF_DEPTH)];
let test_leaf_a = TestLeaf { activated, min_relay_parents };

activate_leaf(&mut virtual_overseer, test_leaf_a, &test_state, 0).await;

let pov = PoV { block_data: BlockData(vec![42, 43, 44]) };
let pvd = dummy_pvd();
let validation_code = ValidationCode(vec![1, 2, 3]);

let expected_head_data = test_state.head_data.get(&para_id).unwrap();

let pov_hash = pov.hash();
let candidate_a = TestCandidateBuilder {
para_id,
relay_parent: leaf_parent,
pov_hash,
head_data: expected_head_data.clone(),
erasure_root: make_erasure_root(&test_state, pov.clone()),
persisted_validation_data_hash: pvd.hash(),
validation_code: validation_code.0.clone(),
..Default::default()
};
let mut candidate_b = candidate_a.clone();
candidate_b.relay_parent = leaf_grandparent;

// With depths.
let candidate_a = (candidate_a.build(), 1);
let candidate_b = (candidate_b.build(), 2);

for candidate in &[candidate_a, candidate_b] {
let (candidate, depth) = candidate;
let second = CandidateBackingMessage::Second(
leaf_hash,
candidate.to_plain(),
pvd.clone(),
pov.clone(),
);

virtual_overseer.send(FromOverseer::Communication { msg: second }).await;

assert_validate_seconded_candidate(
&mut virtual_overseer,
candidate.descriptor().relay_parent,
&candidate,
&pov,
&pvd,
&validation_code,
expected_head_data,
)
.await;

// `seconding_sanity_check`
let expected_request_a = vec![(
HypotheticalDepthRequest {
candidate_hash: candidate.hash(),
candidate_para: para_id,
parent_head_data_hash: pvd.parent_head.hash(),
candidate_relay_parent: candidate.descriptor().relay_parent,
fragment_tree_relay_parent: leaf_hash,
},
vec![*depth],
)];
assert_hypothetical_depth_requests(&mut virtual_overseer, expected_request_a.clone())
.await;

// Prospective parachains are notified.
assert_matches!(
virtual_overseer.recv().await,
AllMessages::ProspectiveParachains(
ProspectiveParachainsMessage::CandidateSeconded(
candidate_para,
candidate_receipt,
_pvd,
tx,
),
) if &candidate_receipt == candidate && candidate_para == para_id && pvd == _pvd => {
// Any non-empty response will do.
tx.send(vec![(leaf_hash, vec![0, 2, 3])]).unwrap();
}
);

test_dispute_coordinator_notifications(
&mut virtual_overseer,
candidate.hash(),
test_state.session(),
vec![ValidatorIndex(0)],
)
.await;

assert_matches!(
virtual_overseer.recv().await,
AllMessages::StatementDistribution(
StatementDistributionMessage::Share(
parent_hash,
_signed_statement,
)
) if parent_hash == candidate.descriptor().relay_parent => {}
);

assert_matches!(
virtual_overseer.recv().await,
AllMessages::CollatorProtocol(CollatorProtocolMessage::Seconded(hash, statement)) => {
assert_eq!(candidate.descriptor().relay_parent, hash);
assert_matches!(statement.payload(), Statement::Seconded(_));
}
);
}

virtual_overseer
});
}

0 comments on commit b601bbc

Please sign in to comment.