use crate::{
EngineTaskError, InsertTaskError, SynchronizeTaskError,
task_queue::tasks::task::EngineTaskErrorSeverity,
};
use alloy_rpc_types_engine::PayloadStatusEnum;
use alloy_transport::{RpcError, TransportErrorKind};
use kona_protocol::FromBlockError;
use op_alloy_rpc_types_engine::OpExecutionPayloadEnvelope;
use thiserror::Error;
use tokio::sync::mpsc;
#[derive(Debug, Error)]
pub enum EngineBuildError {
#[error("Finalized head is ahead of unsafe head")]
FinalizedAheadOfUnsafe(u64, u64),
#[error("Failed to build payload attributes in the engine. Forkchoice RPC error: {0}")]
AttributesInsertionFailed(#[from] RpcError<TransportErrorKind>),
#[error("The inserted payload is invalid: {0}")]
InvalidPayload(String),
#[error("The inserted payload status is unexpected: {0}")]
UnexpectedPayloadStatus(PayloadStatusEnum),
#[error("The inserted payload ID is missing")]
MissingPayloadId,
#[error("The engine is syncing")]
EngineSyncing,
}
#[derive(Debug, Error)]
pub enum BuildTaskError {
#[error("An error occurred when building the payload attributes to the engine.")]
EngineBuildError(EngineBuildError),
#[error(transparent)]
ForkchoiceUpdateFailed(#[from] SynchronizeTaskError),
#[error(transparent)]
PayloadInsertionFailed(#[from] InsertTaskError),
#[error(transparent)]
GetPayloadFailed(RpcError<TransportErrorKind>),
#[error("Deposit-only payload failed to import")]
DepositOnlyPayloadFailed,
#[error("Failed to re-attempt payload import with deposit-only payload")]
DepositOnlyPayloadReattemptFailed,
#[error("Invalid payload, must flush post-holocene")]
HoloceneInvalidFlush,
#[error(transparent)]
FromBlock(#[from] FromBlockError),
#[error(transparent)]
MpscSend(#[from] mpsc::error::SendError<OpExecutionPayloadEnvelope>),
}
impl EngineTaskError for BuildTaskError {
fn severity(&self) -> EngineTaskErrorSeverity {
match self {
Self::ForkchoiceUpdateFailed(inner) => inner.severity(),
Self::PayloadInsertionFailed(inner) => inner.severity(),
Self::EngineBuildError(EngineBuildError::FinalizedAheadOfUnsafe(_, _)) => {
EngineTaskErrorSeverity::Critical
}
Self::EngineBuildError(EngineBuildError::AttributesInsertionFailed(_)) => {
EngineTaskErrorSeverity::Temporary
}
Self::EngineBuildError(EngineBuildError::InvalidPayload(_)) => {
EngineTaskErrorSeverity::Temporary
}
Self::EngineBuildError(EngineBuildError::UnexpectedPayloadStatus(_)) => {
EngineTaskErrorSeverity::Temporary
}
Self::EngineBuildError(EngineBuildError::MissingPayloadId) => {
EngineTaskErrorSeverity::Temporary
}
Self::EngineBuildError(EngineBuildError::EngineSyncing) => {
EngineTaskErrorSeverity::Temporary
}
Self::GetPayloadFailed(_) => EngineTaskErrorSeverity::Temporary,
Self::HoloceneInvalidFlush => EngineTaskErrorSeverity::Flush,
Self::DepositOnlyPayloadReattemptFailed => EngineTaskErrorSeverity::Critical,
Self::DepositOnlyPayloadFailed => EngineTaskErrorSeverity::Critical,
Self::FromBlock(_) => EngineTaskErrorSeverity::Critical,
Self::MpscSend(_) => EngineTaskErrorSeverity::Critical,
}
}
}