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