use ckb_error::{Error, def_error_base_on_kind, prelude::*};
use ckb_types::{core::Version, packed::Byte32};
use derive_more::Display;
pub use ckb_types::core::{
EpochNumberWithFraction,
error::{TransactionError, TransactionErrorSource},
};
#[derive(Debug, PartialEq, Eq, Clone, Copy, Display)]
pub enum HeaderErrorKind {
InvalidParent,
Pow,
Timestamp,
Number,
Epoch,
Version,
}
def_error_base_on_kind!(
HeaderError,
HeaderErrorKind,
"Errors due the fact that the header rule is not respected."
);
#[derive(Debug, PartialEq, Eq, Clone, Copy, Display)]
pub enum BlockErrorKind {
ProposalTransactionDuplicate,
CommitTransactionDuplicate,
ProposalTransactionsHash,
TransactionsRoot,
InvalidDAO,
BlockTransactions,
UnknownParent,
Uncles,
Cellbase,
Commit,
ExceededMaximumProposalsLimit,
ExceededMaximumCycles,
ExceededMaximumBlockBytes,
EmptyBlockExtension,
ExceededMaximumBlockExtensionBytes,
NoBlockExtension,
InvalidBlockExtension,
UnknownFields,
InvalidExtraHash,
InvalidChainRoot,
}
def_error_base_on_kind!(
BlockError,
BlockErrorKind,
"Errors due the fact that the block rule is not respected."
);
#[derive(Error, Debug)]
#[error("BlockTransactionsError(index: {index}, error: {error})")]
pub struct BlockTransactionsError {
pub index: u32,
pub error: Error,
}
#[derive(Error, Debug, PartialEq, Eq, Clone)]
#[error("UnknownParentError(parent_hash: {parent_hash})")]
pub struct UnknownParentError {
pub parent_hash: Byte32,
}
#[derive(Error, Debug, PartialEq, Eq, Clone, Display)]
pub enum CommitError {
AncestorNotFound,
Invalid,
}
#[derive(Error, Debug, PartialEq, Eq, Clone, Display)]
pub enum CellbaseError {
InvalidInput,
InvalidRewardAmount,
InvalidRewardTarget,
InvalidWitness,
InvalidTypeScript,
InvalidOutputQuantity,
InvalidQuantity,
InvalidPosition,
InvalidOutputData,
InvalidOutputLock,
}
#[derive(Error, Debug, PartialEq, Eq, Clone)]
pub enum UnclesError {
#[error("OverCount(max: {max}, actual: {actual})")]
OverCount {
max: u32,
actual: u32,
},
#[error("InvalidNumber")]
InvalidNumber,
#[error("InvalidTarget")]
InvalidTarget,
#[error("InvalidDifficultyEpoch")]
InvalidDifficultyEpoch,
#[error("ProposalsHash")]
ProposalsHash,
#[error("ProposalDuplicate")]
ProposalDuplicate,
#[error("Duplicate({0})")]
Duplicate(Byte32),
#[error("DoubleInclusion({0})")]
DoubleInclusion(Byte32),
#[error("DescendantLimit")]
DescendantLimit,
#[error("ExceededMaximumProposalsLimit")]
ExceededMaximumProposalsLimit,
}
#[derive(Error, Debug, PartialEq, Eq, Clone)]
#[error("BlockVersionError(expected: {expected}, actual: {actual})")]
pub struct BlockVersionError {
pub expected: Version,
pub actual: Version,
}
#[derive(Error, Debug, PartialEq, Eq, Clone)]
#[error("InvalidParentError(parent_hash: {parent_hash})")]
pub struct InvalidParentError {
pub parent_hash: Byte32,
}
#[derive(Error, Debug, PartialEq, Eq, Clone)]
pub enum PowError {
#[error(
"InvalidNonce: please set logger.filter to \"info,ckb-pow=debug\" for detailed PoW verification information"
)]
InvalidNonce,
}
#[derive(Error, Debug, PartialEq, Eq, Clone)]
pub enum TimestampError {
#[error("BlockTimeTooOld(min: {min}, actual: {actual})")]
BlockTimeTooOld {
min: u64,
actual: u64,
},
#[error("BlockTimeTooNew(max: {max}, actual: {actual})")]
BlockTimeTooNew {
max: u64,
actual: u64,
},
}
impl TimestampError {
#[doc(hidden)]
pub fn is_too_new(&self) -> bool {
match self {
Self::BlockTimeTooOld { .. } => false,
Self::BlockTimeTooNew { .. } => true,
}
}
}
#[derive(Error, Debug, PartialEq, Eq, Clone)]
#[error("NumberError(expected: {expected}, actual: {actual})")]
pub struct NumberError {
pub expected: u64,
pub actual: u64,
}
#[derive(Error, Debug, PartialEq, Eq, Clone)]
pub enum EpochError {
#[error("Malformed(value: {value:#})")]
Malformed {
value: EpochNumberWithFraction,
},
#[error("NonContinuous(current: {current:#}, parent: {parent:#})")]
NonContinuous {
current: EpochNumberWithFraction,
parent: EpochNumberWithFraction,
},
#[error("TargetMismatch(expected: {expected:x}, actual: {actual:x})")]
TargetMismatch {
expected: u32,
actual: u32,
},
#[error("NumberMismatch(expected: {expected}, actual: {actual})")]
NumberMismatch {
expected: u64,
actual: u64,
},
}
impl HeaderError {
#[doc(hidden)]
pub fn is_too_new(&self) -> bool {
self.downcast_ref::<TimestampError>()
.map(|e| e.is_too_new())
.unwrap_or(false)
}
}