1use crate::{
3 trap::{Trap, TrapCode},
4 Value,
5};
6use ceres_std::{fmt, format, String, Vec};
7use parity_scale_codec::{Decode, Encode};
8
9bitflags::bitflags! {
10 #[derive(Encode, Decode, Default)]
12 pub struct ReturnFlags: u32 {
13 const REVERT = 0x0000_0001;
15 }
16}
17
18#[derive(PartialEq, Eq, Debug, Clone, Default, Encode, Decode)]
20pub struct ReturnData {
21 pub flags: ReturnFlags,
23 pub data: Vec<u8>,
25}
26
27#[repr(i32)]
28#[derive(Debug, PartialEq, Eq, Clone, Copy)]
29pub enum ReturnCode {
30 Success = 0,
32 CalleeTrapped = 1,
35 CalleeReverted = 2,
38 KeyNotFound = 3,
40 BelowSubsistenceThreshold = 4,
43 TransferFailed = 5,
46 NewContractNotFunded = 6,
49 CodeNotFound = 7,
51 NotCallable = 8,
54 LoggingDisabled = 9,
57 UnExpectedReturnCode = 10,
59}
60
61impl From<i32> for ReturnCode {
62 fn from(n: i32) -> ReturnCode {
63 match n {
64 0 => ReturnCode::Success,
65 1 => ReturnCode::CalleeTrapped,
66 2 => ReturnCode::CalleeReverted,
67 3 => ReturnCode::KeyNotFound,
68 4 => ReturnCode::BelowSubsistenceThreshold,
69 5 => ReturnCode::TransferFailed,
70 6 => ReturnCode::NewContractNotFunded,
71 7 => ReturnCode::CodeNotFound,
72 8 => ReturnCode::NotCallable,
73 9 => ReturnCode::LoggingDisabled,
74 _ => ReturnCode::UnExpectedReturnCode,
75 }
76 }
77}
78
79#[derive(Debug, Eq, PartialEq, Clone)]
81pub enum Error {
82 InitMemoryFailed,
83 OutOfBounds,
85 InitModuleFailed,
86 ExecuteFailed(ReturnCode),
87 UnkownError,
88 Trap(Trap),
89 GetFunctionNameFailed,
90 CreateWasmtimeConfigFailed,
91 GetExternalFailed(String),
92 DecodeRuntimeValueFailed,
93 OutputBufferTooSmall,
94 WrongArugmentLength,
95 SetStorageFailed,
96 Return(ReturnData),
97 TooManyTopics,
99 DuplicateTopics,
100 TopicValueTooLarge,
101 OutOfGas,
103 Custom(&'static str),
105 UnExpectedReturnValue,
107 ParseWasmModuleFailed,
108 ExecutorNotInited,
109 CodeNotFound,
110 ExitedAllFrames,
111 CalcuateMemoryLimitFailed,
112 InitExecutorFailed,
113 DecodeBucketFailed([u8; 32]),
114 MemoryNotFound,
115 SerializationError(String),
116 StateNotFound,
117 CodeHashNotFound,
118 DecodeContractFailed,
119 FlushDataFailed,
120}
121
122impl From<parity_wasm::SerializationError> for Error {
123 fn from(e: parity_wasm::SerializationError) -> Error {
124 Error::SerializationError(format!("{}", e))
125 }
126}
127
128impl From<&'static str> for Error {
129 fn from(e: &'static str) -> Error {
130 Error::Custom(e)
131 }
132}
133
134#[cfg(feature = "wasmtime")]
135impl std::error::Error for Error {}
136
137impl fmt::Display for Error {
138 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
139 write!(f, "{:?}", self)
140 }
141}
142
143pub type Result<T> = core::result::Result<T, Error>;
145
146#[derive(Clone, Default)]
148pub struct ExecResult {
149 pub data: ReturnData,
150 pub value: Value,
151}
152
153impl ExecResult {
154 pub fn from_res(v: Result<Value>) -> Result<ExecResult> {
156 Ok(match v {
157 Ok(value) => ExecResult {
158 value,
159 ..Default::default()
160 },
161 Err(Error::Trap(Trap {
162 code: TrapCode::HostError(e),
163 trace: _,
164 })) => Self::from_res(Err(*e))?,
165 Err(Error::Return(data)) => {
166 if data.flags.contains(ReturnFlags::REVERT) {
167 return Err(Error::ExecuteFailed(ReturnCode::CalleeReverted));
168 }
169 ExecResult {
170 data,
171 ..Default::default()
172 }
173 }
174 Err(e) => return Err(e),
175 })
176 }
177}