mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-12 13:31:10 +00:00
Pvf thiserror (#2958)
resolve #2157 - [x] fix broken doc links - [x] fix codec macro typo https://github.com/paritytech/polkadot-sdk/blob/master/polkadot/node/core/pvf/common/src/error.rs#L81 (see the comment below) - [x] refactor `ValidationError`, `PrepareError` and related error types to use `thiserror` crate ## `codec` issue `codec` macro was mistakenly applied two times to `Kernel` error (so it was encoded with 10 instead of 11 and the same as `JobDied`). The PR changes it to 11 because - it was an initial goal of the code author - Kernel is less frequent than JobDied so in case of existing error encoding it is more probable to have 10 as JobDied than Kernel See https://github.com/paritytech/parity-scale-codec/issues/555 ---- polkadot address: 13zCyRG2a1W2ih5SioL8byqmQ6mc8vkgFwQgVzJSdRUUmp46 --------- Co-authored-by: s0me0ne-unkn0wn <48632512+s0me0ne-unkn0wn@users.noreply.github.com>
This commit is contained in:
@@ -17,7 +17,7 @@
|
||||
use polkadot_node_core_pvf_common::error::{InternalValidationError, PrepareError};
|
||||
|
||||
/// A error raised during validation of the candidate.
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(thiserror::Error, Debug, Clone)]
|
||||
pub enum ValidationError {
|
||||
/// Deterministic preparation issue. In practice, most of the problems should be caught by
|
||||
/// prechecking, so this may be a sign of internal conditions.
|
||||
@@ -27,35 +27,42 @@ pub enum ValidationError {
|
||||
/// pre-checking enabled only valid runtimes should ever get enacted, so we can be
|
||||
/// reasonably sure that this is some local problem on the current node. However, as this
|
||||
/// particular error *seems* to indicate a deterministic error, we raise a warning.
|
||||
#[error("candidate validation: {0}")]
|
||||
Preparation(PrepareError),
|
||||
/// The error was raised because the candidate is invalid. Should vote against.
|
||||
Invalid(InvalidCandidate),
|
||||
#[error("candidate validation: {0}")]
|
||||
Invalid(#[from] InvalidCandidate),
|
||||
/// Possibly transient issue that may resolve after retries. Should vote against when retries
|
||||
/// fail.
|
||||
PossiblyInvalid(PossiblyInvalidError),
|
||||
#[error("candidate validation: {0}")]
|
||||
PossiblyInvalid(#[from] PossiblyInvalidError),
|
||||
/// Preparation or execution issue caused by an internal condition. Should not vote against.
|
||||
Internal(InternalValidationError),
|
||||
#[error("candidate validation: internal: {0}")]
|
||||
Internal(#[from] InternalValidationError),
|
||||
}
|
||||
|
||||
/// A description of an error raised during executing a PVF and can be attributed to the combination
|
||||
/// of the candidate [`polkadot_parachain_primitives::primitives::ValidationParams`] and the PVF.
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(thiserror::Error, Debug, Clone)]
|
||||
pub enum InvalidCandidate {
|
||||
/// The candidate is reported to be invalid by the execution worker. The string contains the
|
||||
/// error message.
|
||||
#[error("invalid: worker reported: {0}")]
|
||||
WorkerReportedInvalid(String),
|
||||
/// PVF execution (compilation is not included) took more time than was allotted.
|
||||
#[error("invalid: hard timeout")]
|
||||
HardTimeout,
|
||||
}
|
||||
|
||||
/// Possibly transient issue that may resolve after retries.
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(thiserror::Error, Debug, Clone)]
|
||||
pub enum PossiblyInvalidError {
|
||||
/// The worker process (not the job) has died during validation of a candidate.
|
||||
///
|
||||
/// It's unlikely that this is caused by malicious code since workers spawn separate job
|
||||
/// processes, and those job processes are sandboxed. But, it is possible. We retry in this
|
||||
/// case, and if the error persists, we assume it's caused by the candidate and vote against.
|
||||
#[error("possibly invalid: ambiguous worker death")]
|
||||
AmbiguousWorkerDeath,
|
||||
/// The job process (not the worker) has died for one of the following reasons:
|
||||
///
|
||||
@@ -69,6 +76,7 @@ pub enum PossiblyInvalidError {
|
||||
/// (c) Some other reason, perhaps transient or perhaps caused by malicious code.
|
||||
///
|
||||
/// We cannot treat this as an internal error because malicious code may have caused this.
|
||||
#[error("possibly invalid: ambiguous job death: {0}")]
|
||||
AmbiguousJobDeath(String),
|
||||
/// An unexpected error occurred in the job process and we can't be sure whether the candidate
|
||||
/// is really invalid or some internal glitch occurred. Whenever we are unsure, we can never
|
||||
@@ -76,15 +84,10 @@ pub enum PossiblyInvalidError {
|
||||
/// issue was due to the candidate, then all validators would abstain, stalling finality on the
|
||||
/// chain. So we will first retry the candidate, and if the issue persists we are forced to
|
||||
/// vote invalid.
|
||||
#[error("possibly invalid: job error: {0}")]
|
||||
JobError(String),
|
||||
}
|
||||
|
||||
impl From<InternalValidationError> for ValidationError {
|
||||
fn from(error: InternalValidationError) -> Self {
|
||||
Self::Internal(error)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<PrepareError> for ValidationError {
|
||||
fn from(error: PrepareError) -> Self {
|
||||
// Here we need to classify the errors into two errors: deterministic and non-deterministic.
|
||||
|
||||
@@ -372,7 +372,7 @@ fn handle_job_finish(
|
||||
?artifact_id,
|
||||
?worker,
|
||||
worker_rip = idle_worker.is_none(),
|
||||
"execution worker concluded, error occurred: {:?}",
|
||||
"execution worker concluded, error occurred: {}",
|
||||
err
|
||||
);
|
||||
} else {
|
||||
|
||||
@@ -486,7 +486,8 @@ async fn handle_precheck_pvf(
|
||||
///
|
||||
/// If the prepare job failed previously, we may retry it under certain conditions.
|
||||
///
|
||||
/// When preparing for execution, we use a more lenient timeout ([`LENIENT_PREPARATION_TIMEOUT`])
|
||||
/// When preparing for execution, we use a more lenient timeout
|
||||
/// ([`DEFAULT_LENIENT_PREPARATION_TIMEOUT`](polkadot_primitives::executor_params::DEFAULT_LENIENT_PREPARATION_TIMEOUT))
|
||||
/// than when prechecking.
|
||||
async fn handle_execute_pvf(
|
||||
artifacts: &mut Artifacts,
|
||||
|
||||
@@ -45,8 +45,8 @@ pub struct FromQueue {
|
||||
/// Identifier of an artifact.
|
||||
pub(crate) artifact_id: ArtifactId,
|
||||
/// Outcome of the PVF processing. [`Ok`] indicates that compiled artifact
|
||||
/// is successfully stored on disk. Otherwise, an [error](crate::error::PrepareError)
|
||||
/// is supplied.
|
||||
/// is successfully stored on disk. Otherwise, an
|
||||
/// [error](polkadot_node_core_pvf_common::error::PrepareError) is supplied.
|
||||
pub(crate) result: PrepareResult,
|
||||
}
|
||||
|
||||
|
||||
@@ -174,7 +174,7 @@ pub async fn start_work(
|
||||
gum::warn!(
|
||||
target: LOG_TARGET,
|
||||
worker_pid = %pid,
|
||||
"failed to recv a prepare response: {:?}",
|
||||
"failed to recv a prepare response: {}",
|
||||
err,
|
||||
);
|
||||
Outcome::IoErr(err.to_string())
|
||||
|
||||
Reference in New Issue
Block a user