-
Notifications
You must be signed in to change notification settings - Fork 699
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Pvf thiserror #2958
Pvf thiserror #2958
Changes from 3 commits
7459c3c
d013a67
9edbb1d
d75bf14
9af3376
471a768
d4e7017
031b2d8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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(transparent)] | ||
Preparation(PrepareError), | ||
/// The error was raised because the candidate is invalid. Should vote against. | ||
Invalid(InvalidCandidate), | ||
#[error(transparent)] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we have specific error messages here instead of the fall-through There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let me explain the motivation:)
So I decided to stick with the safest solution in my opinion. But of course, if you think we should expand messages on wrapper, I will do :) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good points! If you want though, you can change this:
Appreciate the humility and respect for the codebase. :) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also not sure if the change is necessary TBH so I'll leave it to your judgment. I think it's fine to err on the side of being a bit too verbose: error messages are rare and the more info they contain, the better. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Agree! I've decided to use |
||
Invalid(#[from] InvalidCandidate), | ||
/// Possibly transient issue that may resolve after retries. Should vote against when retries | ||
/// fail. | ||
PossiblyInvalid(PossiblyInvalidError), | ||
#[error(transparent)] | ||
PossiblyInvalid(#[from] PossiblyInvalidError), | ||
/// Preparation or execution issue caused by an internal condition. Should not vote against. | ||
Internal(InternalValidationError), | ||
#[error(transparent)] | ||
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,22 +76,18 @@ 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 | ||
/// treat an error as internal as we would abstain from voting. This is bad because if the | ||
/// 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. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(That's my bad, I forgot to update this line after renaming
Panic
->JobError
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For sure I will update:) I've noticed it but from the book description it was quite logical
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For consistency we could also make a
prepare:
prefix for other messages inPrepareError
if it is allowedThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is a good point! Thank you! I will check these instances within the PR
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mrcnski I've checked the usage of
{:?}
withinpvf/
and changed several ones to{}
. And also changedPrepareError
messages a little bit for consistency.