mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-31 11:01:01 +00:00
remove retry from backers on failed candidate validation (#2182)
Hey guys, as discussed I've changed the name to a more general one `PvfExecKind`, is this good or too general? Creating this as a draft, I still have to fix the tests. Closes #1585 Kusama address: FkB6QEo8VnV3oifugNj5NeVG3Mvq1zFbrUu4P5YwRoe5mQN --------- Co-authored-by: command-bot <> Co-authored-by: Marcin S <marcin@realemail.net>
This commit is contained in:
@@ -436,7 +436,7 @@ fn candidate_validation_ok_is_ok() {
|
||||
candidate_receipt,
|
||||
Arc::new(pov),
|
||||
ExecutorParams::default(),
|
||||
PvfExecTimeoutKind::Backing,
|
||||
PvfExecKind::Backing,
|
||||
&Default::default(),
|
||||
))
|
||||
.unwrap();
|
||||
@@ -488,7 +488,7 @@ fn candidate_validation_bad_return_is_invalid() {
|
||||
candidate_receipt,
|
||||
Arc::new(pov),
|
||||
ExecutorParams::default(),
|
||||
PvfExecTimeoutKind::Backing,
|
||||
PvfExecKind::Backing,
|
||||
&Default::default(),
|
||||
))
|
||||
.unwrap();
|
||||
@@ -496,6 +496,33 @@ fn candidate_validation_bad_return_is_invalid() {
|
||||
assert_matches!(v, ValidationResult::Invalid(InvalidCandidate::Timeout));
|
||||
}
|
||||
|
||||
fn perform_basic_checks_on_valid_candidate(
|
||||
pov: &PoV,
|
||||
validation_code: &ValidationCode,
|
||||
validation_data: &PersistedValidationData,
|
||||
head_data_hash: Hash,
|
||||
) -> CandidateDescriptor {
|
||||
let descriptor = make_valid_candidate_descriptor(
|
||||
ParaId::from(1_u32),
|
||||
dummy_hash(),
|
||||
validation_data.hash(),
|
||||
pov.hash(),
|
||||
validation_code.hash(),
|
||||
head_data_hash,
|
||||
head_data_hash,
|
||||
Sr25519Keyring::Alice,
|
||||
);
|
||||
|
||||
let check = perform_basic_checks(
|
||||
&descriptor,
|
||||
validation_data.max_pov_size,
|
||||
&pov,
|
||||
&validation_code.hash(),
|
||||
);
|
||||
assert!(check.is_ok());
|
||||
descriptor
|
||||
}
|
||||
|
||||
// Test that we vote valid if we get `AmbiguousWorkerDeath`, retry, and then succeed.
|
||||
#[test]
|
||||
fn candidate_validation_one_ambiguous_error_is_valid() {
|
||||
@@ -505,24 +532,12 @@ fn candidate_validation_one_ambiguous_error_is_valid() {
|
||||
let head_data = HeadData(vec![1, 1, 1]);
|
||||
let validation_code = ValidationCode(vec![2; 16]);
|
||||
|
||||
let descriptor = make_valid_candidate_descriptor(
|
||||
ParaId::from(1_u32),
|
||||
dummy_hash(),
|
||||
validation_data.hash(),
|
||||
pov.hash(),
|
||||
validation_code.hash(),
|
||||
head_data.hash(),
|
||||
dummy_hash(),
|
||||
Sr25519Keyring::Alice,
|
||||
);
|
||||
|
||||
let check = perform_basic_checks(
|
||||
&descriptor,
|
||||
validation_data.max_pov_size,
|
||||
let descriptor = perform_basic_checks_on_valid_candidate(
|
||||
&pov,
|
||||
&validation_code.hash(),
|
||||
&validation_code,
|
||||
&validation_data,
|
||||
head_data.hash(),
|
||||
);
|
||||
assert!(check.is_ok());
|
||||
|
||||
let validation_result = WasmValidationResult {
|
||||
head_data,
|
||||
@@ -554,7 +569,7 @@ fn candidate_validation_one_ambiguous_error_is_valid() {
|
||||
candidate_receipt,
|
||||
Arc::new(pov),
|
||||
ExecutorParams::default(),
|
||||
PvfExecTimeoutKind::Backing,
|
||||
PvfExecKind::Approval,
|
||||
&Default::default(),
|
||||
))
|
||||
.unwrap();
|
||||
@@ -576,24 +591,12 @@ fn candidate_validation_multiple_ambiguous_errors_is_invalid() {
|
||||
let pov = PoV { block_data: BlockData(vec![1; 32]) };
|
||||
let validation_code = ValidationCode(vec![2; 16]);
|
||||
|
||||
let descriptor = make_valid_candidate_descriptor(
|
||||
ParaId::from(1_u32),
|
||||
dummy_hash(),
|
||||
validation_data.hash(),
|
||||
pov.hash(),
|
||||
validation_code.hash(),
|
||||
dummy_hash(),
|
||||
dummy_hash(),
|
||||
Sr25519Keyring::Alice,
|
||||
);
|
||||
|
||||
let check = perform_basic_checks(
|
||||
&descriptor,
|
||||
validation_data.max_pov_size,
|
||||
let descriptor = perform_basic_checks_on_valid_candidate(
|
||||
&pov,
|
||||
&validation_code.hash(),
|
||||
&validation_code,
|
||||
&validation_data,
|
||||
dummy_hash(),
|
||||
);
|
||||
assert!(check.is_ok());
|
||||
|
||||
let candidate_receipt = CandidateReceipt { descriptor, commitments_hash: Hash::zero() };
|
||||
|
||||
@@ -607,7 +610,7 @@ fn candidate_validation_multiple_ambiguous_errors_is_invalid() {
|
||||
candidate_receipt,
|
||||
Arc::new(pov),
|
||||
ExecutorParams::default(),
|
||||
PvfExecTimeoutKind::Backing,
|
||||
PvfExecKind::Approval,
|
||||
&Default::default(),
|
||||
))
|
||||
.unwrap();
|
||||
@@ -615,58 +618,79 @@ fn candidate_validation_multiple_ambiguous_errors_is_invalid() {
|
||||
assert_matches!(v, ValidationResult::Invalid(InvalidCandidate::ExecutionError(_)));
|
||||
}
|
||||
|
||||
// Test that we retry on internal errors.
|
||||
// Test that we retry for approval on internal errors.
|
||||
#[test]
|
||||
fn candidate_validation_retry_internal_errors() {
|
||||
let validation_data = PersistedValidationData { max_pov_size: 1024, ..Default::default() };
|
||||
|
||||
let pov = PoV { block_data: BlockData(vec![1; 32]) };
|
||||
let validation_code = ValidationCode(vec![2; 16]);
|
||||
|
||||
let descriptor = make_valid_candidate_descriptor(
|
||||
ParaId::from(1_u32),
|
||||
dummy_hash(),
|
||||
validation_data.hash(),
|
||||
pov.hash(),
|
||||
validation_code.hash(),
|
||||
dummy_hash(),
|
||||
dummy_hash(),
|
||||
Sr25519Keyring::Alice,
|
||||
let v = candidate_validation_retry_on_error_helper(
|
||||
PvfExecKind::Approval,
|
||||
vec![
|
||||
Err(InternalValidationError::HostCommunication("foo".into()).into()),
|
||||
// Throw an AJD error, we should still retry again.
|
||||
Err(ValidationError::InvalidCandidate(WasmInvalidCandidate::AmbiguousJobDeath(
|
||||
"baz".into(),
|
||||
))),
|
||||
// Throw another internal error.
|
||||
Err(InternalValidationError::HostCommunication("bar".into()).into()),
|
||||
],
|
||||
);
|
||||
assert_matches!(v, Err(ValidationFailed(s)) if s.contains("bar"));
|
||||
}
|
||||
|
||||
let check = perform_basic_checks(
|
||||
&descriptor,
|
||||
validation_data.max_pov_size,
|
||||
&pov,
|
||||
&validation_code.hash(),
|
||||
);
|
||||
assert!(check.is_ok());
|
||||
|
||||
let candidate_receipt = CandidateReceipt { descriptor, commitments_hash: Hash::zero() };
|
||||
|
||||
let v = executor::block_on(validate_candidate_exhaustive(
|
||||
MockValidateCandidateBackend::with_hardcoded_result_list(vec![
|
||||
// Test that we don't retry for backing on internal errors.
|
||||
#[test]
|
||||
fn candidate_validation_dont_retry_internal_errors() {
|
||||
let v = candidate_validation_retry_on_error_helper(
|
||||
PvfExecKind::Backing,
|
||||
vec![
|
||||
Err(InternalValidationError::HostCommunication("foo".into()).into()),
|
||||
// Throw an AWD error, we should still retry again.
|
||||
Err(ValidationError::InvalidCandidate(WasmInvalidCandidate::AmbiguousWorkerDeath)),
|
||||
// Throw another internal error.
|
||||
Err(InternalValidationError::HostCommunication("bar".into()).into()),
|
||||
]),
|
||||
validation_data,
|
||||
validation_code,
|
||||
candidate_receipt,
|
||||
Arc::new(pov),
|
||||
ExecutorParams::default(),
|
||||
PvfExecTimeoutKind::Backing,
|
||||
&Default::default(),
|
||||
));
|
||||
],
|
||||
);
|
||||
|
||||
assert_matches!(v, Err(ValidationFailed(s)) if s.contains("bar"));
|
||||
assert_matches!(v, Err(ValidationFailed(s)) if s.contains("foo"));
|
||||
}
|
||||
|
||||
// Test that we retry on panic errors.
|
||||
// Test that we retry for approval on panic errors.
|
||||
#[test]
|
||||
fn candidate_validation_retry_panic_errors() {
|
||||
let v = candidate_validation_retry_on_error_helper(
|
||||
PvfExecKind::Approval,
|
||||
vec![
|
||||
Err(ValidationError::InvalidCandidate(WasmInvalidCandidate::JobError("foo".into()))),
|
||||
// Throw an AWD error, we should still retry again.
|
||||
Err(ValidationError::InvalidCandidate(WasmInvalidCandidate::AmbiguousWorkerDeath)),
|
||||
// Throw another panic error.
|
||||
Err(ValidationError::InvalidCandidate(WasmInvalidCandidate::JobError("bar".into()))),
|
||||
],
|
||||
);
|
||||
|
||||
assert_matches!(v, Ok(ValidationResult::Invalid(InvalidCandidate::ExecutionError(s))) if s == "bar".to_string());
|
||||
}
|
||||
|
||||
// Test that we don't retry for backing on panic errors.
|
||||
#[test]
|
||||
fn candidate_validation_dont_retry_panic_errors() {
|
||||
let v = candidate_validation_retry_on_error_helper(
|
||||
PvfExecKind::Backing,
|
||||
vec![
|
||||
Err(ValidationError::InvalidCandidate(WasmInvalidCandidate::JobError("foo".into()))),
|
||||
// Throw an AWD error, we should still retry again.
|
||||
Err(ValidationError::InvalidCandidate(WasmInvalidCandidate::AmbiguousWorkerDeath)),
|
||||
// Throw another panic error.
|
||||
Err(ValidationError::InvalidCandidate(WasmInvalidCandidate::JobError("bar".into()))),
|
||||
],
|
||||
);
|
||||
|
||||
assert_matches!(v, Ok(ValidationResult::Invalid(InvalidCandidate::ExecutionError(s))) if s == "foo".to_string());
|
||||
}
|
||||
|
||||
fn candidate_validation_retry_on_error_helper(
|
||||
exec_kind: PvfExecKind,
|
||||
mock_errors: Vec<Result<WasmValidationResult, ValidationError>>,
|
||||
) -> Result<ValidationResult, ValidationFailed> {
|
||||
let validation_data = PersistedValidationData { max_pov_size: 1024, ..Default::default() };
|
||||
|
||||
let pov = PoV { block_data: BlockData(vec![1; 32]) };
|
||||
@@ -693,26 +717,16 @@ fn candidate_validation_retry_panic_errors() {
|
||||
|
||||
let candidate_receipt = CandidateReceipt { descriptor, commitments_hash: Hash::zero() };
|
||||
|
||||
let v = executor::block_on(validate_candidate_exhaustive(
|
||||
MockValidateCandidateBackend::with_hardcoded_result_list(vec![
|
||||
Err(ValidationError::InvalidCandidate(WasmInvalidCandidate::JobError("foo".into()))),
|
||||
// Throw an AJD error, we should still retry again.
|
||||
Err(ValidationError::InvalidCandidate(WasmInvalidCandidate::AmbiguousJobDeath(
|
||||
"baz".into(),
|
||||
))),
|
||||
// Throw another panic error.
|
||||
Err(ValidationError::InvalidCandidate(WasmInvalidCandidate::JobError("bar".into()))),
|
||||
]),
|
||||
return executor::block_on(validate_candidate_exhaustive(
|
||||
MockValidateCandidateBackend::with_hardcoded_result_list(mock_errors),
|
||||
validation_data,
|
||||
validation_code,
|
||||
candidate_receipt,
|
||||
Arc::new(pov),
|
||||
ExecutorParams::default(),
|
||||
PvfExecTimeoutKind::Backing,
|
||||
exec_kind,
|
||||
&Default::default(),
|
||||
));
|
||||
|
||||
assert_matches!(v, Ok(ValidationResult::Invalid(InvalidCandidate::ExecutionError(s))) if s == "bar".to_string());
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -752,7 +766,7 @@ fn candidate_validation_timeout_is_internal_error() {
|
||||
candidate_receipt,
|
||||
Arc::new(pov),
|
||||
ExecutorParams::default(),
|
||||
PvfExecTimeoutKind::Backing,
|
||||
PvfExecKind::Backing,
|
||||
&Default::default(),
|
||||
));
|
||||
|
||||
@@ -797,7 +811,7 @@ fn candidate_validation_commitment_hash_mismatch_is_invalid() {
|
||||
candidate_receipt,
|
||||
Arc::new(pov),
|
||||
ExecutorParams::default(),
|
||||
PvfExecTimeoutKind::Backing,
|
||||
PvfExecKind::Backing,
|
||||
&Default::default(),
|
||||
))
|
||||
.unwrap();
|
||||
@@ -846,7 +860,7 @@ fn candidate_validation_code_mismatch_is_invalid() {
|
||||
candidate_receipt,
|
||||
Arc::new(pov),
|
||||
ExecutorParams::default(),
|
||||
PvfExecTimeoutKind::Backing,
|
||||
PvfExecKind::Backing,
|
||||
&Default::default(),
|
||||
))
|
||||
.unwrap();
|
||||
@@ -903,7 +917,7 @@ fn compressed_code_works() {
|
||||
candidate_receipt,
|
||||
Arc::new(pov),
|
||||
ExecutorParams::default(),
|
||||
PvfExecTimeoutKind::Backing,
|
||||
PvfExecKind::Backing,
|
||||
&Default::default(),
|
||||
));
|
||||
|
||||
@@ -954,7 +968,7 @@ fn code_decompression_failure_is_error() {
|
||||
candidate_receipt,
|
||||
Arc::new(pov),
|
||||
ExecutorParams::default(),
|
||||
PvfExecTimeoutKind::Backing,
|
||||
PvfExecKind::Backing,
|
||||
&Default::default(),
|
||||
));
|
||||
|
||||
@@ -1006,7 +1020,7 @@ fn pov_decompression_failure_is_invalid() {
|
||||
candidate_receipt,
|
||||
Arc::new(pov),
|
||||
ExecutorParams::default(),
|
||||
PvfExecTimeoutKind::Backing,
|
||||
PvfExecKind::Backing,
|
||||
&Default::default(),
|
||||
));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user