1use alloc::borrow::Cow;
2use core::fmt;
3
4use crate::opcode::Opcode;
5
6pub type ExitResult = Result<ExitSucceed, ExitError>;
8
9#[derive(Clone, Debug, Eq, PartialEq)]
11#[cfg_attr(
12 feature = "scale",
13 derive(scale_codec::Encode, scale_codec::Decode, scale_info::TypeInfo)
14)]
15#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
16pub enum ExitError {
17 Exception(ExitException),
19 Reverted,
21 Fatal(ExitFatal),
24}
25
26impl From<ExitError> for ExitResult {
27 fn from(s: ExitError) -> Self {
28 Err(s)
29 }
30}
31
32#[cfg(feature = "std")]
33impl std::error::Error for ExitError {}
34
35impl fmt::Display for ExitError {
36 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
37 match self {
38 Self::Exception(_) => f.write_str("EVM exit exception"),
39 Self::Reverted => f.write_str("EVM internal revert"),
40 Self::Fatal(_) => f.write_str("EVM fatal error"),
41 }
42 }
43}
44
45#[derive(Clone, Copy, Debug, Eq, PartialEq)]
47#[cfg_attr(
48 feature = "scale",
49 derive(scale_codec::Encode, scale_codec::Decode, scale_info::TypeInfo)
50)]
51#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
52#[non_exhaustive]
53pub enum ExitSucceed {
54 Stopped,
56 Returned,
58 Suicided,
60}
61
62impl From<ExitSucceed> for ExitResult {
63 fn from(s: ExitSucceed) -> Self {
64 Ok(s)
65 }
66}
67
68#[derive(Clone, Debug, Eq, PartialEq)]
70#[cfg_attr(
71 feature = "scale",
72 derive(scale_codec::Encode, scale_codec::Decode, scale_info::TypeInfo)
73)]
74#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
75#[non_exhaustive]
76pub enum ExitException {
77 #[cfg_attr(feature = "scale", codec(index = 0))]
79 StackUnderflow,
80 #[cfg_attr(feature = "scale", codec(index = 1))]
82 StackOverflow,
83 #[cfg_attr(feature = "scale", codec(index = 2))]
85 InvalidJump,
86 #[cfg_attr(feature = "scale", codec(index = 3))]
88 InvalidRange,
89 #[cfg_attr(feature = "scale", codec(index = 4))]
91 DesignatedInvalid,
92 #[cfg_attr(feature = "scale", codec(index = 5))]
94 CallTooDeep,
95 #[cfg_attr(feature = "scale", codec(index = 6))]
97 CreateCollision,
98 #[cfg_attr(feature = "scale", codec(index = 7))]
100 CreateContractLimit,
101
102 #[cfg_attr(feature = "scale", codec(index = 15))]
104 InvalidOpcode(Opcode),
105
106 #[cfg_attr(feature = "scale", codec(index = 8))]
109 OutOfOffset,
110 #[cfg_attr(feature = "scale", codec(index = 9))]
112 OutOfGas,
113 #[cfg_attr(feature = "scale", codec(index = 10))]
115 OutOfFund,
116
117 #[allow(clippy::upper_case_acronyms)]
119 #[cfg_attr(feature = "scale", codec(index = 11))]
120 PCUnderflow,
121
122 #[cfg_attr(feature = "scale", codec(index = 12))]
124 CreateEmpty,
125
126 #[cfg_attr(feature = "scale", codec(index = 14))]
129 MaxNonce,
130
131 #[cfg_attr(feature = "scale", codec(index = 25))]
133 NotEOA,
134
135 #[cfg_attr(feature = "scale", codec(index = 13))]
137 Other(Cow<'static, str>),
138}
139
140impl From<ExitException> for ExitResult {
141 fn from(s: ExitException) -> Self {
142 Err(ExitError::Exception(s))
143 }
144}
145
146impl From<ExitException> for ExitError {
147 fn from(s: ExitException) -> Self {
148 Self::Exception(s)
149 }
150}
151
152#[derive(Clone, Debug, Eq, PartialEq)]
154#[cfg_attr(
155 feature = "scale",
156 derive(scale_codec::Encode, scale_codec::Decode, scale_info::TypeInfo)
157)]
158#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
159#[non_exhaustive]
160pub enum ExitFatal {
161 NotSupported,
163 UnhandledInterrupt,
165 ExceptionAsFatal(ExitException),
167 AlreadyExited,
169 Unfinished,
171 UnevenSubstate,
173 InvalidFeedback,
175
176 Other(Cow<'static, str>),
178}
179
180impl From<ExitFatal> for ExitResult {
181 fn from(s: ExitFatal) -> Self {
182 Err(ExitError::Fatal(s))
183 }
184}
185
186impl From<ExitFatal> for ExitError {
187 fn from(s: ExitFatal) -> Self {
188 Self::Fatal(s)
189 }
190}