use fuel_core_storage::{
Error as StorageError,
MerkleRoot,
};
use fuel_core_types::{
blockchain::primitives::BlockId,
fuel_types::BlockHeight,
services::executor,
};
use tokio::sync::{
TryAcquireError,
mpsc,
oneshot,
};
#[derive(Debug, derive_more::Display, derive_more::From)]
pub enum Error {
#[display("The commit is already in the progress: {_0}.")]
Semaphore(TryAcquireError),
#[display("The wrong state of database during insertion of the genesis block.")]
InvalidUnderlyingDatabaseGenesisState,
#[display(
"The wrong state of storage after execution of the block.\
The actual root is {_1:?}, when the expected root is {_0:?}."
)]
InvalidDatabaseStateAfterExecution(Option<MerkleRoot>, Option<MerkleRoot>),
#[display("Got overflow during increasing the height.")]
Overflow,
#[display("The non-generic block can't have zero height.")]
ZeroNonGenericHeight,
#[display("The actual height is {_1}, when the next expected height is {_0}.")]
IncorrectBlockHeight(BlockHeight, BlockHeight),
#[display(
"Got another block id after validation of the block. Expected {_0} != Actual {_1}"
)]
BlockIdMismatch(BlockId, BlockId),
#[display("Some of the block fields are not valid: {_0}.")]
FailedVerification(anyhow::Error),
#[display("The execution of the block failed: {_0}.")]
FailedExecution(executor::Error),
#[display("It is not possible to execute the genesis block.")]
ExecuteGenesis,
#[display("The database already contains the data at the height {_0}.")]
NotUnique(BlockHeight),
#[display("The previous block processing is not finished yet.")]
PreviousBlockProcessingNotFinished,
#[display("Failed to publish produced block to block reconciliation: {_0}.")]
FailedBlockReconciliationWrite(anyhow::Error),
#[display("The send command to the inner task failed.")]
SendCommandToInnerTaskFailed,
#[display("The inner import task is not running.")]
InnerTaskIsNotRunning,
#[from]
Storage(StorageError),
UnsupportedConsensusVariant(String),
ActiveBlockResultsSemaphoreClosed(tokio::sync::AcquireError),
RayonTaskWasCanceled,
}
impl From<Error> for anyhow::Error {
fn from(error: Error) -> Self {
anyhow::Error::msg(error)
}
}
impl From<oneshot::error::RecvError> for Error {
fn from(_: oneshot::error::RecvError) -> Self {
Error::InnerTaskIsNotRunning
}
}
impl<T> From<mpsc::error::SendError<T>> for Error {
fn from(_: mpsc::error::SendError<T>) -> Self {
Error::SendCommandToInnerTaskFailed
}
}
#[cfg(test)]
impl PartialEq for Error {
fn eq(&self, other: &Self) -> bool {
format!("{self}") == format!("{other}")
}
}