use alloc::borrow::Cow;
use core::fmt;
use crate::opcode::Opcode;
pub type ExitResult = Result<ExitSucceed, ExitError>;
#[derive(Clone, Debug, Eq, PartialEq)]
#[cfg_attr(
feature = "scale",
derive(scale_codec::Encode, scale_codec::Decode, scale_info::TypeInfo)
)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum ExitError {
Exception(ExitException),
Reverted,
Fatal(ExitFatal),
}
impl From<ExitError> for ExitResult {
fn from(s: ExitError) -> Self {
Err(s)
}
}
#[cfg(feature = "std")]
impl std::error::Error for ExitError {}
impl fmt::Display for ExitError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Exception(_) => f.write_str("EVM exit exception"),
Self::Reverted => f.write_str("EVM internal revert"),
Self::Fatal(_) => f.write_str("EVM fatal error"),
}
}
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
#[cfg_attr(
feature = "scale",
derive(scale_codec::Encode, scale_codec::Decode, scale_info::TypeInfo)
)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[non_exhaustive]
pub enum ExitSucceed {
Stopped,
Returned,
Suicided,
}
impl From<ExitSucceed> for ExitResult {
fn from(s: ExitSucceed) -> Self {
Ok(s)
}
}
#[derive(Clone, Debug, Eq, PartialEq)]
#[cfg_attr(
feature = "scale",
derive(scale_codec::Encode, scale_codec::Decode, scale_info::TypeInfo)
)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[non_exhaustive]
pub enum ExitException {
#[cfg_attr(feature = "scale", codec(index = 0))]
StackUnderflow,
#[cfg_attr(feature = "scale", codec(index = 1))]
StackOverflow,
#[cfg_attr(feature = "scale", codec(index = 2))]
InvalidJump,
#[cfg_attr(feature = "scale", codec(index = 3))]
InvalidRange,
#[cfg_attr(feature = "scale", codec(index = 4))]
DesignatedInvalid,
#[cfg_attr(feature = "scale", codec(index = 5))]
CallTooDeep,
#[cfg_attr(feature = "scale", codec(index = 6))]
CreateCollision,
#[cfg_attr(feature = "scale", codec(index = 7))]
CreateContractLimit,
#[cfg_attr(feature = "scale", codec(index = 15))]
InvalidOpcode(Opcode),
#[cfg_attr(feature = "scale", codec(index = 8))]
OutOfOffset,
#[cfg_attr(feature = "scale", codec(index = 9))]
OutOfGas,
#[cfg_attr(feature = "scale", codec(index = 10))]
OutOfFund,
#[allow(clippy::upper_case_acronyms)]
#[cfg_attr(feature = "scale", codec(index = 11))]
PCUnderflow,
#[cfg_attr(feature = "scale", codec(index = 12))]
CreateEmpty,
#[cfg_attr(feature = "scale", codec(index = 14))]
MaxNonce,
#[cfg_attr(feature = "scale", codec(index = 25))]
NotEOA,
#[cfg_attr(feature = "scale", codec(index = 13))]
Other(Cow<'static, str>),
}
impl From<ExitException> for ExitResult {
fn from(s: ExitException) -> Self {
Err(ExitError::Exception(s))
}
}
impl From<ExitException> for ExitError {
fn from(s: ExitException) -> Self {
Self::Exception(s)
}
}
#[derive(Clone, Debug, Eq, PartialEq)]
#[cfg_attr(
feature = "scale",
derive(scale_codec::Encode, scale_codec::Decode, scale_info::TypeInfo)
)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[non_exhaustive]
pub enum ExitFatal {
NotSupported,
UnhandledInterrupt,
ExceptionAsFatal(ExitException),
AlreadyExited,
Unfinished,
UnevenSubstate,
InvalidFeedback,
Other(Cow<'static, str>),
}
impl From<ExitFatal> for ExitResult {
fn from(s: ExitFatal) -> Self {
Err(ExitError::Fatal(s))
}
}
impl From<ExitFatal> for ExitError {
fn from(s: ExitFatal) -> Self {
Self::Fatal(s)
}
}