Refactor candidate validation messages (#2219)

This commit is contained in:
s0me0ne-unkn0wn
2023-11-08 15:21:58 +01:00
committed by GitHub
parent 1bc0885829
commit 50390950d8
14 changed files with 384 additions and 354 deletions
@@ -2861,15 +2861,15 @@ async fn launch_approval<Context>(
let (val_tx, val_rx) = oneshot::channel();
sender
.send_message(CandidateValidationMessage::ValidateFromExhaustive(
available_data.validation_data,
.send_message(CandidateValidationMessage::ValidateFromExhaustive {
validation_data: available_data.validation_data,
validation_code,
candidate.clone(),
available_data.pov,
candidate_receipt: candidate.clone(),
pov: available_data.pov,
executor_params,
PvfExecTimeoutKind::Approval,
val_tx,
))
exec_timeout_kind: PvfExecTimeoutKind::Approval,
response_sender: val_tx,
})
.await;
match val_rx.await {
@@ -2704,8 +2704,12 @@ async fn handle_double_assignment_import(
assert_matches!(
overseer_recv(virtual_overseer).await,
AllMessages::CandidateValidation(CandidateValidationMessage::ValidateFromExhaustive(_, _, _, _, _, timeout, tx)) if timeout == PvfExecTimeoutKind::Approval => {
tx.send(Ok(ValidationResult::Valid(Default::default(), Default::default())))
AllMessages::CandidateValidation(CandidateValidationMessage::ValidateFromExhaustive {
exec_timeout_kind,
response_sender,
..
}) if exec_timeout_kind == PvfExecTimeoutKind::Approval => {
response_sender.send(Ok(ValidationResult::Valid(Default::default(), Default::default())))
.unwrap();
}
);
+8 -8
View File
@@ -551,8 +551,8 @@ async fn request_pov(
async fn request_candidate_validation(
sender: &mut impl overseer::CandidateBackingSenderTrait,
pvd: PersistedValidationData,
code: ValidationCode,
validation_data: PersistedValidationData,
validation_code: ValidationCode,
candidate_receipt: CandidateReceipt,
pov: Arc<PoV>,
executor_params: ExecutorParams,
@@ -560,15 +560,15 @@ async fn request_candidate_validation(
let (tx, rx) = oneshot::channel();
sender
.send_message(CandidateValidationMessage::ValidateFromExhaustive(
pvd,
code,
.send_message(CandidateValidationMessage::ValidateFromExhaustive {
validation_data,
validation_code,
candidate_receipt,
pov,
executor_params,
PvfExecTimeoutKind::Backing,
tx,
))
exec_timeout_kind: PvfExecTimeoutKind::Backing,
response_sender: tx,
})
.await;
match rx.await {
+184 -185
View File
@@ -329,32 +329,32 @@ async fn assert_validation_requests(
async fn assert_validate_from_exhaustive(
virtual_overseer: &mut VirtualOverseer,
pvd: &PersistedValidationData,
pov: &PoV,
validation_code: &ValidationCode,
candidate: &CommittedCandidateReceipt,
assert_pvd: &PersistedValidationData,
assert_pov: &PoV,
assert_validation_code: &ValidationCode,
assert_candidate: &CommittedCandidateReceipt,
expected_head_data: &HeadData,
result_validation_data: PersistedValidationData,
) {
assert_matches!(
virtual_overseer.recv().await,
AllMessages::CandidateValidation(
CandidateValidationMessage::ValidateFromExhaustive(
_pvd,
_validation_code,
CandidateValidationMessage::ValidateFromExhaustive {
pov,
validation_data,
validation_code,
candidate_receipt,
_pov,
_,
timeout,
tx,
),
) if _pvd == *pvd &&
_validation_code == *validation_code &&
*_pov == *pov && &candidate_receipt.descriptor == candidate.descriptor() &&
timeout == PvfExecTimeoutKind::Backing &&
candidate.commitments.hash() == candidate_receipt.commitments_hash =>
exec_timeout_kind,
response_sender,
..
},
) if validation_data == *assert_pvd &&
validation_code == *assert_validation_code &&
*pov == *assert_pov && &candidate_receipt.descriptor == assert_candidate.descriptor() &&
exec_timeout_kind == PvfExecTimeoutKind::Backing &&
candidate_receipt.commitments_hash == assert_candidate.commitments.hash() =>
{
tx.send(Ok(ValidationResult::Valid(
response_sender.send(Ok(ValidationResult::Valid(
CandidateCommitments {
head_data: expected_head_data.clone(),
horizontal_messages: Default::default(),
@@ -461,11 +461,11 @@ fn backing_works() {
test_harness(test_state.keystore.clone(), |mut virtual_overseer| async move {
test_startup(&mut virtual_overseer, &test_state).await;
let pov = PoV { block_data: BlockData(vec![1, 2, 3]) };
let pvd = dummy_pvd();
let validation_code = ValidationCode(vec![1, 2, 3]);
let pov_ab = PoV { block_data: BlockData(vec![1, 2, 3]) };
let pvd_ab = dummy_pvd();
let validation_code_ab = ValidationCode(vec![1, 2, 3]);
let pov_hash = pov.hash();
let pov_hash = pov_ab.hash();
let expected_head_data = test_state.head_data.get(&test_state.chain_ids[0]).unwrap();
@@ -474,8 +474,8 @@ fn backing_works() {
relay_parent: test_state.relay_parent,
pov_hash,
head_data: expected_head_data.clone(),
erasure_root: make_erasure_root(&test_state, pov.clone(), pvd.clone()),
validation_code: validation_code.0.clone(),
erasure_root: make_erasure_root(&test_state, pov_ab.clone(), pvd_ab.clone()),
validation_code: validation_code_ab.0.clone(),
..Default::default()
}
.build();
@@ -498,7 +498,7 @@ fn backing_works() {
let signed_a = SignedFullStatementWithPVD::sign(
&test_state.keystore,
StatementWithPVD::Seconded(candidate_a.clone(), pvd.clone()),
StatementWithPVD::Seconded(candidate_a.clone(), pvd_ab.clone()),
&test_state.signing_context,
ValidatorIndex(2),
&public2.into(),
@@ -523,7 +523,7 @@ fn backing_works() {
virtual_overseer.send(FromOrchestra::Communication { msg: statement }).await;
assert_validation_requests(&mut virtual_overseer, validation_code.clone()).await;
assert_validation_requests(&mut virtual_overseer, validation_code_ab.clone()).await;
// Sending a `Statement::Seconded` for our assignment will start
// validation process. The first thing requested is the PoV.
@@ -536,7 +536,7 @@ fn backing_works() {
..
}
) if relay_parent == test_state.relay_parent => {
tx.send(pov.clone()).unwrap();
tx.send(pov_ab.clone()).unwrap();
}
);
@@ -545,22 +545,22 @@ fn backing_works() {
assert_matches!(
virtual_overseer.recv().await,
AllMessages::CandidateValidation(
CandidateValidationMessage::ValidateFromExhaustive(
_pvd,
_validation_code,
CandidateValidationMessage::ValidateFromExhaustive {
validation_data,
validation_code,
candidate_receipt,
_pov,
_,
timeout,
tx,
),
) if _pvd == pvd &&
_validation_code == validation_code &&
*_pov == pov && &candidate_receipt.descriptor == candidate_a.descriptor() &&
timeout == PvfExecTimeoutKind::Backing &&
candidate_a_commitments_hash == candidate_receipt.commitments_hash =>
pov,
exec_timeout_kind,
response_sender,
..
},
) if validation_data == pvd_ab &&
validation_code == validation_code_ab &&
*pov == pov_ab && &candidate_receipt.descriptor == candidate_a.descriptor() &&
exec_timeout_kind == PvfExecTimeoutKind::Backing &&
candidate_receipt.commitments_hash == candidate_a_commitments_hash =>
{
tx.send(Ok(
response_sender.send(Ok(
ValidationResult::Valid(CandidateCommitments {
head_data: expected_head_data.clone(),
upward_messages: Default::default(),
@@ -623,11 +623,11 @@ fn backing_works_while_validation_ongoing() {
test_harness(test_state.keystore.clone(), |mut virtual_overseer| async move {
test_startup(&mut virtual_overseer, &test_state).await;
let pov = PoV { block_data: BlockData(vec![1, 2, 3]) };
let pvd = dummy_pvd();
let validation_code = ValidationCode(vec![1, 2, 3]);
let pov_abc = PoV { block_data: BlockData(vec![1, 2, 3]) };
let pvd_abc = dummy_pvd();
let validation_code_abc = ValidationCode(vec![1, 2, 3]);
let pov_hash = pov.hash();
let pov_hash = pov_abc.hash();
let expected_head_data = test_state.head_data.get(&test_state.chain_ids[0]).unwrap();
@@ -636,8 +636,8 @@ fn backing_works_while_validation_ongoing() {
relay_parent: test_state.relay_parent,
pov_hash,
head_data: expected_head_data.clone(),
erasure_root: make_erasure_root(&test_state, pov.clone(), pvd.clone()),
validation_code: validation_code.0.clone(),
erasure_root: make_erasure_root(&test_state, pov_abc.clone(), pvd_abc.clone()),
validation_code: validation_code_abc.0.clone(),
..Default::default()
}
.build();
@@ -666,7 +666,7 @@ fn backing_works_while_validation_ongoing() {
let signed_a = SignedFullStatementWithPVD::sign(
&test_state.keystore,
StatementWithPVD::Seconded(candidate_a.clone(), pvd.clone()),
StatementWithPVD::Seconded(candidate_a.clone(), pvd_abc.clone()),
&test_state.signing_context,
ValidatorIndex(2),
&public2.into(),
@@ -701,7 +701,7 @@ fn backing_works_while_validation_ongoing() {
CandidateBackingMessage::Statement(test_state.relay_parent, signed_a.clone());
virtual_overseer.send(FromOrchestra::Communication { msg: statement }).await;
assert_validation_requests(&mut virtual_overseer, validation_code.clone()).await;
assert_validation_requests(&mut virtual_overseer, validation_code_abc.clone()).await;
// Sending a `Statement::Seconded` for our assignment will start
// validation process. The first thing requested is PoV from the
@@ -715,7 +715,7 @@ fn backing_works_while_validation_ongoing() {
..
}
) if relay_parent == test_state.relay_parent => {
tx.send(pov.clone()).unwrap();
tx.send(pov_abc.clone()).unwrap();
}
);
@@ -724,24 +724,24 @@ fn backing_works_while_validation_ongoing() {
assert_matches!(
virtual_overseer.recv().await,
AllMessages::CandidateValidation(
CandidateValidationMessage::ValidateFromExhaustive(
_pvd,
_validation_code,
CandidateValidationMessage::ValidateFromExhaustive {
validation_data,
validation_code,
candidate_receipt,
_pov,
_,
timeout,
tx,
),
) if _pvd == pvd &&
_validation_code == validation_code &&
*_pov == pov && &candidate_receipt.descriptor == candidate_a.descriptor() &&
timeout == PvfExecTimeoutKind::Backing &&
pov,
exec_timeout_kind,
response_sender,
..
},
) if validation_data == pvd_abc &&
validation_code == validation_code_abc &&
*pov == pov_abc && &candidate_receipt.descriptor == candidate_a.descriptor() &&
exec_timeout_kind == PvfExecTimeoutKind::Backing &&
candidate_a_commitments_hash == candidate_receipt.commitments_hash =>
{
// we never validate the candidate. our local node
// shouldn't issue any statements.
std::mem::forget(tx);
std::mem::forget(response_sender);
}
);
@@ -812,11 +812,11 @@ fn backing_misbehavior_works() {
test_harness(test_state.keystore.clone(), |mut virtual_overseer| async move {
test_startup(&mut virtual_overseer, &test_state).await;
let pov = PoV { block_data: BlockData(vec![1, 2, 3]) };
let pov_a = PoV { block_data: BlockData(vec![1, 2, 3]) };
let pov_hash = pov.hash();
let pvd = dummy_pvd();
let validation_code = ValidationCode(vec![1, 2, 3]);
let pov_hash = pov_a.hash();
let pvd_a = dummy_pvd();
let validation_code_a = ValidationCode(vec![1, 2, 3]);
let expected_head_data = test_state.head_data.get(&test_state.chain_ids[0]).unwrap();
@@ -824,9 +824,9 @@ fn backing_misbehavior_works() {
para_id: test_state.chain_ids[0],
relay_parent: test_state.relay_parent,
pov_hash,
erasure_root: make_erasure_root(&test_state, pov.clone(), pvd.clone()),
erasure_root: make_erasure_root(&test_state, pov_a.clone(), pvd_a.clone()),
head_data: expected_head_data.clone(),
validation_code: validation_code.0.clone(),
validation_code: validation_code_a.0.clone(),
..Default::default()
}
.build();
@@ -842,7 +842,7 @@ fn backing_misbehavior_works() {
.expect("Insert key into keystore");
let seconded_2 = SignedFullStatementWithPVD::sign(
&test_state.keystore,
StatementWithPVD::Seconded(candidate_a.clone(), pvd.clone()),
StatementWithPVD::Seconded(candidate_a.clone(), pvd_a.clone()),
&test_state.signing_context,
ValidatorIndex(2),
&public2.into(),
@@ -867,7 +867,7 @@ fn backing_misbehavior_works() {
virtual_overseer.send(FromOrchestra::Communication { msg: statement }).await;
assert_validation_requests(&mut virtual_overseer, validation_code.clone()).await;
assert_validation_requests(&mut virtual_overseer, validation_code_a.clone()).await;
assert_matches!(
virtual_overseer.recv().await,
@@ -878,29 +878,29 @@ fn backing_misbehavior_works() {
..
}
) if relay_parent == test_state.relay_parent => {
tx.send(pov.clone()).unwrap();
tx.send(pov_a.clone()).unwrap();
}
);
assert_matches!(
virtual_overseer.recv().await,
AllMessages::CandidateValidation(
CandidateValidationMessage::ValidateFromExhaustive(
_pvd,
_validation_code,
CandidateValidationMessage::ValidateFromExhaustive {
validation_data,
validation_code,
candidate_receipt,
_pov,
_,
timeout,
tx,
),
) if _pvd == pvd &&
_validation_code == validation_code &&
*_pov == pov && &candidate_receipt.descriptor == candidate_a.descriptor() &&
timeout == PvfExecTimeoutKind::Backing &&
pov,
exec_timeout_kind,
response_sender,
..
},
) if validation_data == pvd_a &&
validation_code == validation_code_a &&
*pov == pov_a && &candidate_receipt.descriptor == candidate_a.descriptor() &&
exec_timeout_kind == PvfExecTimeoutKind::Backing &&
candidate_a_commitments_hash == candidate_receipt.commitments_hash =>
{
tx.send(Ok(
response_sender.send(Ok(
ValidationResult::Valid(CandidateCommitments {
head_data: expected_head_data.clone(),
upward_messages: Default::default(),
@@ -1052,22 +1052,22 @@ fn backing_dont_second_invalid() {
assert_matches!(
virtual_overseer.recv().await,
AllMessages::CandidateValidation(
CandidateValidationMessage::ValidateFromExhaustive(
_pvd,
_validation_code,
CandidateValidationMessage::ValidateFromExhaustive {
validation_data,
validation_code,
candidate_receipt,
_pov,
_,
timeout,
tx,
),
) if _pvd == pvd_a &&
_validation_code == validation_code_a &&
*_pov == pov_block_a && &candidate_receipt.descriptor == candidate_a.descriptor() &&
timeout == PvfExecTimeoutKind::Backing &&
pov,
exec_timeout_kind,
response_sender,
..
},
) if validation_data == pvd_a &&
validation_code == validation_code_a &&
*pov == pov_block_a && &candidate_receipt.descriptor == candidate_a.descriptor() &&
exec_timeout_kind == PvfExecTimeoutKind::Backing &&
candidate_a.commitments.hash() == candidate_receipt.commitments_hash =>
{
tx.send(Ok(ValidationResult::Invalid(InvalidCandidate::BadReturn))).unwrap();
response_sender.send(Ok(ValidationResult::Invalid(InvalidCandidate::BadReturn))).unwrap();
}
);
@@ -1092,22 +1092,22 @@ fn backing_dont_second_invalid() {
assert_matches!(
virtual_overseer.recv().await,
AllMessages::CandidateValidation(
CandidateValidationMessage::ValidateFromExhaustive(
pvd,
_validation_code,
CandidateValidationMessage::ValidateFromExhaustive {
validation_data,
validation_code,
candidate_receipt,
_pov,
_,
timeout,
tx,
),
) if pvd == pvd_b &&
_validation_code == validation_code_b &&
*_pov == pov_block_b && &candidate_receipt.descriptor == candidate_b.descriptor() &&
timeout == PvfExecTimeoutKind::Backing &&
pov,
exec_timeout_kind,
response_sender,
..
},
) if validation_data == pvd_b &&
validation_code == validation_code_b &&
*pov == pov_block_b && &candidate_receipt.descriptor == candidate_b.descriptor() &&
exec_timeout_kind == PvfExecTimeoutKind::Backing &&
candidate_b.commitments.hash() == candidate_receipt.commitments_hash =>
{
tx.send(Ok(
response_sender.send(Ok(
ValidationResult::Valid(CandidateCommitments {
head_data: expected_head_data.clone(),
upward_messages: Default::default(),
@@ -1158,19 +1158,19 @@ fn backing_second_after_first_fails_works() {
test_harness(test_state.keystore.clone(), |mut virtual_overseer| async move {
test_startup(&mut virtual_overseer, &test_state).await;
let pov = PoV { block_data: BlockData(vec![42, 43, 44]) };
let pvd = dummy_pvd();
let validation_code = ValidationCode(vec![1, 2, 3]);
let pov_a = PoV { block_data: BlockData(vec![42, 43, 44]) };
let pvd_a = dummy_pvd();
let validation_code_a = ValidationCode(vec![1, 2, 3]);
let pov_hash = pov.hash();
let pov_hash = pov_a.hash();
let candidate = TestCandidateBuilder {
para_id: test_state.chain_ids[0],
relay_parent: test_state.relay_parent,
pov_hash,
erasure_root: make_erasure_root(&test_state, pov.clone(), pvd.clone()),
persisted_validation_data_hash: pvd.hash(),
validation_code: validation_code.0.clone(),
erasure_root: make_erasure_root(&test_state, pov_a.clone(), pvd_a.clone()),
persisted_validation_data_hash: pvd_a.hash(),
validation_code: validation_code_a.0.clone(),
..Default::default()
}
.build();
@@ -1184,7 +1184,7 @@ fn backing_second_after_first_fails_works() {
let signed_a = SignedFullStatementWithPVD::sign(
&test_state.keystore,
StatementWithPVD::Seconded(candidate.clone(), pvd.clone()),
StatementWithPVD::Seconded(candidate.clone(), pvd_a.clone()),
&test_state.signing_context,
ValidatorIndex(2),
&validator2.into(),
@@ -1199,7 +1199,7 @@ fn backing_second_after_first_fails_works() {
virtual_overseer.send(FromOrchestra::Communication { msg: statement }).await;
assert_validation_requests(&mut virtual_overseer, validation_code.clone()).await;
assert_validation_requests(&mut virtual_overseer, validation_code_a.clone()).await;
// Subsystem requests PoV and requests validation.
assert_matches!(
@@ -1211,7 +1211,7 @@ fn backing_second_after_first_fails_works() {
..
}
) if relay_parent == test_state.relay_parent => {
tx.send(pov.clone()).unwrap();
tx.send(pov_a.clone()).unwrap();
}
);
@@ -1219,22 +1219,22 @@ fn backing_second_after_first_fails_works() {
assert_matches!(
virtual_overseer.recv().await,
AllMessages::CandidateValidation(
CandidateValidationMessage::ValidateFromExhaustive(
_pvd,
_validation_code,
CandidateValidationMessage::ValidateFromExhaustive {
validation_data,
validation_code,
candidate_receipt,
_pov,
_,
timeout,
tx,
),
) if _pvd == pvd &&
_validation_code == validation_code &&
*_pov == pov && &candidate_receipt.descriptor == candidate.descriptor() &&
timeout == PvfExecTimeoutKind::Backing &&
pov,
exec_timeout_kind,
response_sender,
..
},
) if validation_data == pvd_a &&
validation_code == validation_code_a &&
*pov == pov_a && &candidate_receipt.descriptor == candidate.descriptor() &&
exec_timeout_kind == PvfExecTimeoutKind::Backing &&
candidate.commitments.hash() == candidate_receipt.commitments_hash =>
{
tx.send(Ok(ValidationResult::Invalid(InvalidCandidate::BadReturn))).unwrap();
response_sender.send(Ok(ValidationResult::Invalid(InvalidCandidate::BadReturn))).unwrap();
}
);
@@ -1243,8 +1243,8 @@ fn backing_second_after_first_fails_works() {
let second = CandidateBackingMessage::Second(
test_state.relay_parent,
candidate.to_plain(),
pvd.clone(),
pov.clone(),
pvd_a.clone(),
pov_a.clone(),
);
virtual_overseer.send(FromOrchestra::Communication { msg: second }).await;
@@ -1287,7 +1287,7 @@ fn backing_second_after_first_fails_works() {
assert_matches!(
virtual_overseer.recv().await,
AllMessages::CandidateValidation(
CandidateValidationMessage::ValidateFromExhaustive(_, _, _, pov, ..),
CandidateValidationMessage::ValidateFromExhaustive { pov, .. },
) => {
assert_eq!(&*pov, &pov_to_second);
}
@@ -1304,18 +1304,18 @@ fn backing_works_after_failed_validation() {
test_harness(test_state.keystore.clone(), |mut virtual_overseer| async move {
test_startup(&mut virtual_overseer, &test_state).await;
let pov = PoV { block_data: BlockData(vec![42, 43, 44]) };
let pvd = dummy_pvd();
let validation_code = ValidationCode(vec![1, 2, 3]);
let pov_a = PoV { block_data: BlockData(vec![42, 43, 44]) };
let pvd_a = dummy_pvd();
let validation_code_a = ValidationCode(vec![1, 2, 3]);
let pov_hash = pov.hash();
let pov_hash = pov_a.hash();
let candidate = TestCandidateBuilder {
para_id: test_state.chain_ids[0],
relay_parent: test_state.relay_parent,
pov_hash,
erasure_root: make_erasure_root(&test_state, pov.clone(), pvd.clone()),
validation_code: validation_code.0.clone(),
erasure_root: make_erasure_root(&test_state, pov_a.clone(), pvd_a.clone()),
validation_code: validation_code_a.0.clone(),
..Default::default()
}
.build();
@@ -1328,7 +1328,7 @@ fn backing_works_after_failed_validation() {
.expect("Insert key into keystore");
let signed_a = SignedFullStatementWithPVD::sign(
&test_state.keystore,
StatementWithPVD::Seconded(candidate.clone(), pvd.clone()),
StatementWithPVD::Seconded(candidate.clone(), pvd_a.clone()),
&test_state.signing_context,
ValidatorIndex(2),
&public2.into(),
@@ -1343,7 +1343,7 @@ fn backing_works_after_failed_validation() {
virtual_overseer.send(FromOrchestra::Communication { msg: statement }).await;
assert_validation_requests(&mut virtual_overseer, validation_code.clone()).await;
assert_validation_requests(&mut virtual_overseer, validation_code_a.clone()).await;
// Subsystem requests PoV and requests validation.
assert_matches!(
@@ -1355,7 +1355,7 @@ fn backing_works_after_failed_validation() {
..
}
) if relay_parent == test_state.relay_parent => {
tx.send(pov.clone()).unwrap();
tx.send(pov_a.clone()).unwrap();
}
);
@@ -1363,22 +1363,22 @@ fn backing_works_after_failed_validation() {
assert_matches!(
virtual_overseer.recv().await,
AllMessages::CandidateValidation(
CandidateValidationMessage::ValidateFromExhaustive(
_pvd,
_validation_code,
CandidateValidationMessage::ValidateFromExhaustive {
validation_data,
validation_code,
candidate_receipt,
_pov,
_,
timeout,
tx,
),
) if _pvd == pvd &&
_validation_code == validation_code &&
*_pov == pov && &candidate_receipt.descriptor == candidate.descriptor() &&
timeout == PvfExecTimeoutKind::Backing &&
pov,
exec_timeout_kind,
response_sender,
..
},
) if validation_data == pvd_a &&
validation_code == validation_code_a &&
*pov == pov_a && &candidate_receipt.descriptor == candidate.descriptor() &&
exec_timeout_kind == PvfExecTimeoutKind::Backing &&
candidate.commitments.hash() == candidate_receipt.commitments_hash =>
{
tx.send(Err(ValidationFailed("Internal test error".into()))).unwrap();
response_sender.send(Err(ValidationFailed("Internal test error".into()))).unwrap();
}
);
@@ -1475,19 +1475,19 @@ fn retry_works() {
test_harness(test_state.keystore.clone(), |mut virtual_overseer| async move {
test_startup(&mut virtual_overseer, &test_state).await;
let pov = PoV { block_data: BlockData(vec![42, 43, 44]) };
let pvd = dummy_pvd();
let validation_code = ValidationCode(vec![1, 2, 3]);
let pov_a = PoV { block_data: BlockData(vec![42, 43, 44]) };
let pvd_a = dummy_pvd();
let validation_code_a = ValidationCode(vec![1, 2, 3]);
let pov_hash = pov.hash();
let pov_hash = pov_a.hash();
let candidate = TestCandidateBuilder {
para_id: test_state.chain_ids[0],
relay_parent: test_state.relay_parent,
pov_hash,
erasure_root: make_erasure_root(&test_state, pov.clone(), pvd.clone()),
persisted_validation_data_hash: pvd.hash(),
validation_code: validation_code.0.clone(),
erasure_root: make_erasure_root(&test_state, pov_a.clone(), pvd_a.clone()),
persisted_validation_data_hash: pvd_a.hash(),
validation_code: validation_code_a.0.clone(),
..Default::default()
}
.build();
@@ -1512,7 +1512,7 @@ fn retry_works() {
.expect("Insert key into keystore");
let signed_a = SignedFullStatementWithPVD::sign(
&test_state.keystore,
StatementWithPVD::Seconded(candidate.clone(), pvd.clone()),
StatementWithPVD::Seconded(candidate.clone(), pvd_a.clone()),
&test_state.signing_context,
ValidatorIndex(2),
&public2.into(),
@@ -1546,7 +1546,7 @@ fn retry_works() {
CandidateBackingMessage::Statement(test_state.relay_parent, signed_a.clone());
virtual_overseer.send(FromOrchestra::Communication { msg: statement }).await;
assert_validation_requests(&mut virtual_overseer, validation_code.clone()).await;
assert_validation_requests(&mut virtual_overseer, validation_code_a.clone()).await;
// Subsystem requests PoV and requests validation.
// We cancel - should mean retry on next backing statement.
@@ -1584,8 +1584,8 @@ fn retry_works() {
AllMessages::RuntimeApi(RuntimeApiMessage::Request(
_,
RuntimeApiRequest::ValidationCodeByHash(hash, tx),
)) if hash == validation_code.hash() => {
tx.send(Ok(Some(validation_code.clone()))).unwrap();
)) if hash == validation_code_a.hash() => {
tx.send(Ok(Some(validation_code_a.clone()))).unwrap();
},
AllMessages::RuntimeApi(RuntimeApiMessage::Request(
_,
@@ -1609,7 +1609,7 @@ fn retry_works() {
CandidateBackingMessage::Statement(test_state.relay_parent, signed_c.clone());
virtual_overseer.send(FromOrchestra::Communication { msg: statement }).await;
assert_validation_requests(&mut virtual_overseer, validation_code.clone()).await;
assert_validation_requests(&mut virtual_overseer, validation_code_a.clone()).await;
assert_matches!(
virtual_overseer.recv().await,
@@ -1622,26 +1622,25 @@ fn retry_works() {
// Subsystem requests PoV and requests validation.
// Now we pass.
) if relay_parent == test_state.relay_parent => {
tx.send(pov.clone()).unwrap();
tx.send(pov_a.clone()).unwrap();
}
);
assert_matches!(
virtual_overseer.recv().await,
AllMessages::CandidateValidation(
CandidateValidationMessage::ValidateFromExhaustive(
_pvd,
_validation_code,
CandidateValidationMessage::ValidateFromExhaustive {
validation_data,
validation_code,
candidate_receipt,
_pov,
_,
timeout,
pov,
exec_timeout_kind,
..
),
) if _pvd == pvd &&
_validation_code == validation_code &&
*_pov == pov && &candidate_receipt.descriptor == candidate.descriptor() &&
timeout == PvfExecTimeoutKind::Backing &&
},
) if validation_data == pvd_a &&
validation_code == validation_code_a &&
*pov == pov_a && &candidate_receipt.descriptor == candidate.descriptor() &&
exec_timeout_kind == PvfExecTimeoutKind::Backing &&
candidate.commitments.hash() == candidate_receipt.commitments_hash
);
virtual_overseer
@@ -1863,9 +1862,9 @@ fn cannot_second_multiple_candidates_per_parent() {
assert_matches!(
virtual_overseer.recv().await,
AllMessages::CandidateValidation(
CandidateValidationMessage::ValidateFromExhaustive(.., tx),
CandidateValidationMessage::ValidateFromExhaustive { response_sender, .. },
) => {
tx.send(Ok(ValidationResult::Valid(
response_sender.send(Ok(ValidationResult::Valid(
CandidateCommitments {
head_data: expected_head_data.clone(),
horizontal_messages: Default::default(),
@@ -202,13 +202,13 @@ async fn assert_validate_seconded_candidate(
virtual_overseer: &mut VirtualOverseer,
relay_parent: Hash,
candidate: &CommittedCandidateReceipt,
pov: &PoV,
pvd: &PersistedValidationData,
validation_code: &ValidationCode,
assert_pov: &PoV,
assert_pvd: &PersistedValidationData,
assert_validation_code: &ValidationCode,
expected_head_data: &HeadData,
fetch_pov: bool,
) {
assert_validation_requests(virtual_overseer, validation_code.clone()).await;
assert_validation_requests(virtual_overseer, assert_validation_code.clone()).await;
if fetch_pov {
assert_matches!(
@@ -220,29 +220,29 @@ async fn assert_validate_seconded_candidate(
..
}
) if hash == relay_parent => {
tx.send(pov.clone()).unwrap();
tx.send(assert_pov.clone()).unwrap();
}
);
}
assert_matches!(
virtual_overseer.recv().await,
AllMessages::CandidateValidation(CandidateValidationMessage::ValidateFromExhaustive(
_pvd,
_validation_code,
AllMessages::CandidateValidation(CandidateValidationMessage::ValidateFromExhaustive {
validation_data,
validation_code,
candidate_receipt,
_pov,
_,
timeout,
tx,
)) if &_pvd == pvd &&
&_validation_code == validation_code &&
&*_pov == pov &&
pov,
exec_timeout_kind,
response_sender,
..
}) if &validation_data == assert_pvd &&
&validation_code == assert_validation_code &&
&*pov == assert_pov &&
&candidate_receipt.descriptor == candidate.descriptor() &&
timeout == PvfExecTimeoutKind::Backing &&
exec_timeout_kind == PvfExecTimeoutKind::Backing &&
candidate.commitments.hash() == candidate_receipt.commitments_hash =>
{
tx.send(Ok(ValidationResult::Valid(
response_sender.send(Ok(ValidationResult::Valid(
CandidateCommitments {
head_data: expected_head_data.clone(),
horizontal_messages: Default::default(),
@@ -251,7 +251,7 @@ async fn assert_validate_seconded_candidate(
processed_downward_messages: 0,
hrmp_watermark: 0,
},
pvd.clone(),
assert_pvd.clone(),
)))
.unwrap();
}
@@ -1293,9 +1293,13 @@ fn concurrent_dependent_candidates() {
tx.send(pov.clone()).unwrap();
},
AllMessages::CandidateValidation(
CandidateValidationMessage::ValidateFromExhaustive(.., candidate, _, _, _, tx),
CandidateValidationMessage::ValidateFromExhaustive {
candidate_receipt,
response_sender,
..
},
) => {
let candidate_hash = candidate.hash();
let candidate_hash = candidate_receipt.hash();
let (head_data, pvd) = if candidate_hash == candidate_a_hash {
(&head_data[1], &pvd_a)
} else if candidate_hash == candidate_b_hash {
@@ -1303,18 +1307,19 @@ fn concurrent_dependent_candidates() {
} else {
panic!("unknown candidate hash")
};
tx.send(Ok(ValidationResult::Valid(
CandidateCommitments {
head_data: head_data.clone(),
horizontal_messages: Default::default(),
upward_messages: Default::default(),
new_validation_code: None,
processed_downward_messages: 0,
hrmp_watermark: 0,
},
pvd.clone(),
)))
.unwrap();
response_sender
.send(Ok(ValidationResult::Valid(
CandidateCommitments {
head_data: head_data.clone(),
horizontal_messages: Default::default(),
upward_messages: Default::default(),
new_validation_code: None,
processed_downward_messages: 0,
hrmp_watermark: 0,
},
pvd.clone(),
)))
.unwrap();
},
AllMessages::AvailabilityStore(AvailabilityStoreMessage::StoreAvailableData {
tx,
@@ -159,13 +159,14 @@ async fn run<Context>(
FromOrchestra::Signal(OverseerSignal::BlockFinalized(..)) => {},
FromOrchestra::Signal(OverseerSignal::Conclude) => return Ok(()),
FromOrchestra::Communication { msg } => match msg {
CandidateValidationMessage::ValidateFromChainState(
CandidateValidationMessage::ValidateFromChainState {
candidate_receipt,
pov,
executor_params,
timeout,
exec_timeout_kind,
response_sender,
) => {
..
} => {
let bg = {
let mut sender = ctx.sender().clone();
let metrics = metrics.clone();
@@ -179,7 +180,7 @@ async fn run<Context>(
candidate_receipt,
pov,
executor_params,
timeout,
exec_timeout_kind,
&metrics,
)
.await;
@@ -191,15 +192,16 @@ async fn run<Context>(
ctx.spawn("validate-from-chain-state", bg.boxed())?;
},
CandidateValidationMessage::ValidateFromExhaustive(
persisted_validation_data,
CandidateValidationMessage::ValidateFromExhaustive {
validation_data,
validation_code,
candidate_receipt,
pov,
executor_params,
timeout,
exec_timeout_kind,
response_sender,
) => {
..
} => {
let bg = {
let metrics = metrics.clone();
let validation_host = validation_host.clone();
@@ -208,12 +210,12 @@ async fn run<Context>(
let _timer = metrics.time_validate_from_exhaustive();
let res = validate_candidate_exhaustive(
validation_host,
persisted_validation_data,
validation_data,
validation_code,
candidate_receipt,
pov,
executor_params,
timeout,
exec_timeout_kind,
&metrics,
)
.await;
@@ -225,11 +227,12 @@ async fn run<Context>(
ctx.spawn("validate-from-exhaustive", bg.boxed())?;
},
CandidateValidationMessage::PreCheck(
CandidateValidationMessage::PreCheck {
relay_parent,
validation_code_hash,
response_sender,
) => {
..
} => {
let bg = {
let mut sender = ctx.sender().clone();
let validation_host = validation_host.clone();
@@ -380,15 +380,15 @@ async fn participate(
// same level of leeway.
let (validation_tx, validation_rx) = oneshot::channel();
sender
.send_message(CandidateValidationMessage::ValidateFromExhaustive(
available_data.validation_data,
.send_message(CandidateValidationMessage::ValidateFromExhaustive {
validation_data: available_data.validation_data,
validation_code,
req.candidate_receipt().clone(),
available_data.pov,
req.executor_params(),
PvfExecTimeoutKind::Approval,
validation_tx,
))
candidate_receipt: req.candidate_receipt().clone(),
pov: available_data.pov,
executor_params: req.executor_params(),
exec_timeout_kind: PvfExecTimeoutKind::Approval,
response_sender: validation_tx,
})
.await;
// we cast votes (either positive or negative) depending on the outcome of
@@ -115,12 +115,12 @@ pub async fn participation_full_happy_path(
assert_matches!(
ctx_handle.recv().await,
AllMessages::CandidateValidation(
CandidateValidationMessage::ValidateFromExhaustive(_, _, candidate_receipt, _, _, timeout, tx)
) if timeout == PvfExecTimeoutKind::Approval => {
CandidateValidationMessage::ValidateFromExhaustive { candidate_receipt, exec_timeout_kind, response_sender, .. }
) if exec_timeout_kind == PvfExecTimeoutKind::Approval => {
if expected_commitments_hash != candidate_receipt.commitments_hash {
tx.send(Ok(ValidationResult::Invalid(InvalidCandidate::CommitmentsHashMismatch))).unwrap();
response_sender.send(Ok(ValidationResult::Invalid(InvalidCandidate::CommitmentsHashMismatch))).unwrap();
} else {
tx.send(Ok(ValidationResult::Valid(dummy_candidate_commitments(None), PersistedValidationData::default()))).unwrap();
response_sender.send(Ok(ValidationResult::Valid(dummy_candidate_commitments(None), PersistedValidationData::default()))).unwrap();
}
},
"overseer did not receive candidate validation message",
@@ -450,9 +450,9 @@ fn cast_invalid_vote_if_validation_fails_or_is_invalid() {
assert_matches!(
ctx_handle.recv().await,
AllMessages::CandidateValidation(
CandidateValidationMessage::ValidateFromExhaustive(_, _, _, _, _, timeout, tx)
) if timeout == PvfExecTimeoutKind::Approval => {
tx.send(Ok(ValidationResult::Invalid(InvalidCandidate::Timeout))).unwrap();
CandidateValidationMessage::ValidateFromExhaustive { exec_timeout_kind, response_sender, .. }
) if exec_timeout_kind == PvfExecTimeoutKind::Approval => {
response_sender.send(Ok(ValidationResult::Invalid(InvalidCandidate::Timeout))).unwrap();
},
"overseer did not receive candidate validation message",
);
@@ -487,9 +487,9 @@ fn cast_invalid_vote_if_commitments_dont_match() {
assert_matches!(
ctx_handle.recv().await,
AllMessages::CandidateValidation(
CandidateValidationMessage::ValidateFromExhaustive(_, _, _, _, _, timeout, tx)
) if timeout == PvfExecTimeoutKind::Approval => {
tx.send(Ok(ValidationResult::Invalid(InvalidCandidate::CommitmentsHashMismatch))).unwrap();
CandidateValidationMessage::ValidateFromExhaustive { exec_timeout_kind, response_sender, .. }
) if exec_timeout_kind == PvfExecTimeoutKind::Approval => {
response_sender.send(Ok(ValidationResult::Invalid(InvalidCandidate::CommitmentsHashMismatch))).unwrap();
},
"overseer did not receive candidate validation message",
);
@@ -524,9 +524,9 @@ fn cast_valid_vote_if_validation_passes() {
assert_matches!(
ctx_handle.recv().await,
AllMessages::CandidateValidation(
CandidateValidationMessage::ValidateFromExhaustive(_, _, _, _, _, timeout, tx)
) if timeout == PvfExecTimeoutKind::Approval => {
tx.send(Ok(ValidationResult::Valid(dummy_candidate_commitments(None), PersistedValidationData::default()))).unwrap();
CandidateValidationMessage::ValidateFromExhaustive { exec_timeout_kind, response_sender, .. }
) if exec_timeout_kind == PvfExecTimeoutKind::Approval => {
response_sender.send(Ok(ValidationResult::Valid(dummy_candidate_commitments(None), PersistedValidationData::default()))).unwrap();
},
"overseer did not receive candidate validation message",
);
+5 -1
View File
@@ -535,7 +535,11 @@ async fn initiate_precheck(
let (tx, rx) = oneshot::channel();
sender
.send_message(CandidateValidationMessage::PreCheck(relay_parent, validation_code_hash, tx))
.send_message(CandidateValidationMessage::PreCheck {
relay_parent,
validation_code_hash,
response_sender: tx,
})
.await;
let timer = metrics.time_pre_check_judgement();
+4 -3
View File
@@ -267,11 +267,12 @@ impl TestState {
handle: &mut VirtualOverseer,
) -> ExpectCandidatePrecheck {
match self.recv_timeout(handle).await.expect("timeout waiting for a message") {
AllMessages::CandidateValidation(CandidateValidationMessage::PreCheck(
AllMessages::CandidateValidation(CandidateValidationMessage::PreCheck {
relay_parent,
validation_code_hash,
tx,
)) => ExpectCandidatePrecheck { relay_parent, validation_code_hash, tx },
response_sender,
..
}) => ExpectCandidatePrecheck { relay_parent, validation_code_hash, tx: response_sender },
msg => panic!("Unexpected message was received: {:#?}", msg),
}
}
+43 -41
View File
@@ -273,30 +273,31 @@ where
// Message sent by the approval voting subsystem
FromOrchestra::Communication {
msg:
CandidateValidationMessage::ValidateFromExhaustive(
CandidateValidationMessage::ValidateFromExhaustive {
validation_data,
validation_code,
candidate_receipt,
pov,
executor_params,
timeout,
sender,
),
exec_timeout_kind,
response_sender,
..
},
} => {
match self.fake_validation {
x if x.misbehaves_valid() && x.should_misbehave(timeout) => {
x if x.misbehaves_valid() && x.should_misbehave(exec_timeout_kind) => {
// Behave normally if the `PoV` is not known to be malicious.
if pov.block_data.0.as_slice() != MALICIOUS_POV {
return Some(FromOrchestra::Communication {
msg: CandidateValidationMessage::ValidateFromExhaustive(
msg: CandidateValidationMessage::ValidateFromExhaustive {
validation_data,
validation_code,
candidate_receipt,
pov,
executor_params,
timeout,
sender,
),
exec_timeout_kind,
response_sender,
},
})
}
// Create the fake response with probability `p` if the `PoV` is malicious,
@@ -313,7 +314,7 @@ where
create_validation_response(
validation_data,
candidate_receipt.descriptor,
sender,
response_sender,
);
None
},
@@ -326,20 +327,20 @@ where
);
Some(FromOrchestra::Communication {
msg: CandidateValidationMessage::ValidateFromExhaustive(
msg: CandidateValidationMessage::ValidateFromExhaustive {
validation_data,
validation_code,
candidate_receipt,
pov,
executor_params,
timeout,
sender,
),
exec_timeout_kind,
response_sender,
},
})
},
}
},
x if x.misbehaves_invalid() && x.should_misbehave(timeout) => {
x if x.misbehaves_invalid() && x.should_misbehave(exec_timeout_kind) => {
// Set the validation result to invalid with probability `p` and trigger a
// dispute
let behave_maliciously = self.distribution.sample(&mut rand::thread_rng());
@@ -358,7 +359,7 @@ where
// We're not even checking the candidate, this makes us appear
// faster than honest validators.
sender.send(Ok(validation_result)).unwrap();
response_sender.send(Ok(validation_result)).unwrap();
None
},
false => {
@@ -366,56 +367,57 @@ where
gum::info!(target: MALUS, "😈 'Decided' to not act maliciously.",);
Some(FromOrchestra::Communication {
msg: CandidateValidationMessage::ValidateFromExhaustive(
msg: CandidateValidationMessage::ValidateFromExhaustive {
validation_data,
validation_code,
candidate_receipt,
pov,
executor_params,
timeout,
sender,
),
exec_timeout_kind,
response_sender,
},
})
},
}
},
// Handle FakeCandidateValidation::Disabled
_ => Some(FromOrchestra::Communication {
msg: CandidateValidationMessage::ValidateFromExhaustive(
msg: CandidateValidationMessage::ValidateFromExhaustive {
validation_data,
validation_code,
candidate_receipt,
pov,
executor_params,
timeout,
sender,
),
exec_timeout_kind,
response_sender,
},
}),
}
},
// Behaviour related to the backing subsystem
FromOrchestra::Communication {
msg:
CandidateValidationMessage::ValidateFromChainState(
CandidateValidationMessage::ValidateFromChainState {
candidate_receipt,
pov,
executor_params,
timeout,
exec_timeout_kind,
response_sender,
),
..
},
} => {
match self.fake_validation {
x if x.misbehaves_valid() && x.should_misbehave(timeout) => {
x if x.misbehaves_valid() && x.should_misbehave(exec_timeout_kind) => {
// Behave normally if the `PoV` is not known to be malicious.
if pov.block_data.0.as_slice() != MALICIOUS_POV {
return Some(FromOrchestra::Communication {
msg: CandidateValidationMessage::ValidateFromChainState(
msg: CandidateValidationMessage::ValidateFromChainState {
candidate_receipt,
pov,
executor_params,
timeout,
exec_timeout_kind,
response_sender,
),
},
})
}
// If the `PoV` is malicious, back the candidate with some probability `p`,
@@ -439,17 +441,17 @@ where
// If the `PoV` is malicious, we behave normally with some probability
// `(1-p)`
false => Some(FromOrchestra::Communication {
msg: CandidateValidationMessage::ValidateFromChainState(
msg: CandidateValidationMessage::ValidateFromChainState {
candidate_receipt,
pov,
executor_params,
timeout,
exec_timeout_kind,
response_sender,
),
},
}),
}
},
x if x.misbehaves_invalid() && x.should_misbehave(timeout) => {
x if x.misbehaves_invalid() && x.should_misbehave(exec_timeout_kind) => {
// Maliciously set the validation result to invalid for a valid candidate
// with probability `p`
let behave_maliciously = self.distribution.sample(&mut rand::thread_rng());
@@ -473,25 +475,25 @@ where
gum::info!(target: MALUS, "😈 'Decided' to not act maliciously.",);
Some(FromOrchestra::Communication {
msg: CandidateValidationMessage::ValidateFromChainState(
msg: CandidateValidationMessage::ValidateFromChainState {
candidate_receipt,
pov,
executor_params,
timeout,
exec_timeout_kind,
response_sender,
),
},
})
},
}
},
_ => Some(FromOrchestra::Communication {
msg: CandidateValidationMessage::ValidateFromChainState(
msg: CandidateValidationMessage::ValidateFromChainState {
candidate_receipt,
pov,
executor_params,
timeout,
exec_timeout_kind,
response_sender,
),
},
}),
}
},
@@ -73,13 +73,13 @@ impl Subsystem1 {
commitments_hash: Hash::zero(),
};
let msg = CandidateValidationMessage::ValidateFromChainState(
let msg = CandidateValidationMessage::ValidateFromChainState {
candidate_receipt,
PoV { block_data: BlockData(Vec::new()) }.into(),
Default::default(),
PvfExecTimeoutKind::Backing,
tx,
);
pov: PoV { block_data: BlockData(Vec::new()) }.into(),
executor_params: Default::default(),
exec_timeout_kind: PvfExecTimeoutKind::Backing,
response_sender: tx,
};
ctx.send_message(msg).await;
}
()
+12 -12
View File
@@ -102,13 +102,13 @@ where
};
let (tx, _) = oneshot::channel();
ctx.send_message(CandidateValidationMessage::ValidateFromChainState(
ctx.send_message(CandidateValidationMessage::ValidateFromChainState {
candidate_receipt,
PoV { block_data: BlockData(Vec::new()) }.into(),
Default::default(),
PvfExecTimeoutKind::Backing,
tx,
))
pov: PoV { block_data: BlockData(Vec::new()) }.into(),
executor_params: Default::default(),
exec_timeout_kind: PvfExecTimeoutKind::Backing,
response_sender: tx,
})
.await;
c += 1;
continue
@@ -793,20 +793,20 @@ where
}
fn test_candidate_validation_msg() -> CandidateValidationMessage {
let (sender, _) = oneshot::channel();
let (response_sender, _) = oneshot::channel();
let pov = Arc::new(PoV { block_data: BlockData(Vec::new()) });
let candidate_receipt = CandidateReceipt {
descriptor: dummy_candidate_descriptor(dummy_hash()),
commitments_hash: Hash::zero(),
};
CandidateValidationMessage::ValidateFromChainState(
CandidateValidationMessage::ValidateFromChainState {
candidate_receipt,
pov,
Default::default(),
PvfExecTimeoutKind::Backing,
sender,
)
executor_params: Default::default(),
exec_timeout_kind: PvfExecTimeoutKind::Backing,
response_sender,
}
}
fn test_candidate_backing_msg() -> CandidateBackingMessage {
+36 -24
View File
@@ -143,14 +143,18 @@ pub enum CandidateValidationMessage {
///
/// If there is no state available which can provide this data or the core for
/// the para is not free at the relay-parent, an error is returned.
ValidateFromChainState(
CandidateReceipt,
Arc<PoV>,
ExecutorParams,
/// Execution timeout
PvfExecTimeoutKind,
oneshot::Sender<Result<ValidationResult, ValidationFailed>>,
),
ValidateFromChainState {
/// The candidate receipt
candidate_receipt: CandidateReceipt,
/// The proof-of-validity
pov: Arc<PoV>,
/// Session's executor parameters
executor_params: ExecutorParams,
/// Execution timeout kind (backing/approvals)
exec_timeout_kind: PvfExecTimeoutKind,
/// The sending side of the response channel
response_sender: oneshot::Sender<Result<ValidationResult, ValidationFailed>>,
},
/// Validate a candidate with provided, exhaustive parameters for validation.
///
/// Explicitly provide the `PersistedValidationData` and `ValidationCode` so this can do full
@@ -160,27 +164,35 @@ pub enum CandidateValidationMessage {
/// cases where the validity of the candidate is established. This is the case for the typical
/// use-case: secondary checkers would use this request relying on the full prior checks
/// performed by the relay-chain.
ValidateFromExhaustive(
PersistedValidationData,
ValidationCode,
CandidateReceipt,
Arc<PoV>,
ExecutorParams,
/// Execution timeout
PvfExecTimeoutKind,
oneshot::Sender<Result<ValidationResult, ValidationFailed>>,
),
ValidateFromExhaustive {
/// Persisted validation data
validation_data: PersistedValidationData,
/// Validation code
validation_code: ValidationCode,
/// The candidate receipt
candidate_receipt: CandidateReceipt,
/// The proof-of-validity
pov: Arc<PoV>,
/// Session's executor parameters
executor_params: ExecutorParams,
/// Execution timeout kind (backing/approvals)
exec_timeout_kind: PvfExecTimeoutKind,
/// The sending side of the response channel
response_sender: oneshot::Sender<Result<ValidationResult, ValidationFailed>>,
},
/// Try to compile the given validation code and send back
/// the outcome.
///
/// The validation code is specified by the hash and will be queried from the runtime API at
/// the given relay-parent.
PreCheck(
// Relay-parent
Hash,
ValidationCodeHash,
oneshot::Sender<PreCheckOutcome>,
),
PreCheck {
/// Relay-parent
relay_parent: Hash,
/// Validation code hash
validation_code_hash: ValidationCodeHash,
/// The sending side of the response channel
response_sender: oneshot::Sender<PreCheckOutcome>,
},
}
/// Messages received by the Collator Protocol subsystem.