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))]
52pub enum ExitSucceed {
53 Stopped,
55 Returned,
57 Suicided,
59}
60
61impl From<ExitSucceed> for ExitResult {
62 fn from(s: ExitSucceed) -> Self {
63 Ok(s)
64 }
65}
66
67#[derive(Clone, Debug, Eq, PartialEq)]
69#[cfg_attr(
70 feature = "scale",
71 derive(scale_codec::Encode, scale_codec::Decode, scale_info::TypeInfo)
72)]
73#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
74pub enum ExitException {
75 #[cfg_attr(feature = "scale", codec(index = 0))]
77 StackUnderflow,
78 #[cfg_attr(feature = "scale", codec(index = 1))]
80 StackOverflow,
81 #[cfg_attr(feature = "scale", codec(index = 2))]
83 InvalidJump,
84 #[cfg_attr(feature = "scale", codec(index = 3))]
86 InvalidRange,
87 #[cfg_attr(feature = "scale", codec(index = 4))]
89 DesignatedInvalid,
90 #[cfg_attr(feature = "scale", codec(index = 5))]
92 CallTooDeep,
93 #[cfg_attr(feature = "scale", codec(index = 6))]
95 CreateCollision,
96 #[cfg_attr(feature = "scale", codec(index = 7))]
98 CreateContractLimit,
99
100 #[cfg_attr(feature = "scale", codec(index = 15))]
102 InvalidOpcode(Opcode),
103
104 #[cfg_attr(feature = "scale", codec(index = 8))]
107 OutOfOffset,
108 #[cfg_attr(feature = "scale", codec(index = 9))]
110 OutOfGas,
111 #[cfg_attr(feature = "scale", codec(index = 10))]
113 OutOfFund,
114
115 #[allow(clippy::upper_case_acronyms)]
117 #[cfg_attr(feature = "scale", codec(index = 11))]
118 PCUnderflow,
119
120 #[cfg_attr(feature = "scale", codec(index = 12))]
122 CreateEmpty,
123
124 #[cfg_attr(feature = "scale", codec(index = 14))]
127 MaxNonce,
128
129 #[cfg_attr(feature = "scale", codec(index = 25))]
131 NotEOA,
132
133 #[cfg_attr(feature = "scale", codec(index = 13))]
135 Other(Cow<'static, str>),
136}
137
138impl From<ExitException> for ExitResult {
139 fn from(s: ExitException) -> Self {
140 Err(ExitError::Exception(s))
141 }
142}
143
144impl From<ExitException> for ExitError {
145 fn from(s: ExitException) -> Self {
146 Self::Exception(s)
147 }
148}
149
150#[derive(Clone, Debug, Eq, PartialEq)]
152#[cfg_attr(
153 feature = "scale",
154 derive(scale_codec::Encode, scale_codec::Decode, scale_info::TypeInfo)
155)]
156#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
157pub enum ExitFatal {
158 NotSupported,
160 UnhandledInterrupt,
162 ExceptionAsFatal(ExitException),
164 AlreadyExited,
166 Unfinished,
168 UnevenSubstate,
170 InvalidFeedback,
172
173 Other(Cow<'static, str>),
175}
176
177impl From<ExitFatal> for ExitResult {
178 fn from(s: ExitFatal) -> Self {
179 Err(ExitError::Fatal(s))
180 }
181}
182
183impl From<ExitFatal> for ExitError {
184 fn from(s: ExitFatal) -> Self {
185 Self::Fatal(s)
186 }
187}