casper_executor_wasm_common/
error.rs1use thiserror::Error;
6
7#[derive(Debug, Default, PartialEq)]
8#[non_exhaustive]
9#[repr(u32)]
10pub enum CommonResult {
11 #[default]
12 Success = 0,
13 NotFound = 1,
15 InvalidData = 2,
19 InvalidInput = 3,
21 TopicTooLong = 4,
23 TooManyTopics = 5,
25 PayloadTooLong = 6,
27 MessageTopicFull = 7,
29 MaxMessagesPerBlockExceeded = 8,
32 Internal = 9,
34 Other(u32),
36}
37
38pub const HOST_ERROR_SUCCESS: u32 = 0;
39pub const HOST_ERROR_NOT_FOUND: u32 = 1;
40pub const HOST_ERROR_INVALID_DATA: u32 = 2;
41pub const HOST_ERROR_INVALID_INPUT: u32 = 3;
42pub const HOST_ERROR_TOPIC_TOO_LONG: u32 = 4;
43pub const HOST_ERROR_TOO_MANY_TOPICS: u32 = 5;
44pub const HOST_ERROR_PAYLOAD_TOO_LONG: u32 = 6;
45pub const HOST_ERROR_MESSAGE_TOPIC_FULL: u32 = 7;
46pub const HOST_ERROR_MAX_MESSAGES_PER_BLOCK_EXCEEDED: u32 = 8;
47pub const HOST_ERROR_INTERNAL: u32 = 9;
48
49impl From<u32> for CommonResult {
50 fn from(value: u32) -> Self {
51 match value {
52 HOST_ERROR_SUCCESS => Self::Success,
53 HOST_ERROR_NOT_FOUND => Self::NotFound,
54 HOST_ERROR_INVALID_DATA => Self::InvalidData,
55 HOST_ERROR_INVALID_INPUT => Self::InvalidInput,
56 HOST_ERROR_TOPIC_TOO_LONG => Self::TopicTooLong,
57 HOST_ERROR_TOO_MANY_TOPICS => Self::TooManyTopics,
58 HOST_ERROR_PAYLOAD_TOO_LONG => Self::PayloadTooLong,
59 HOST_ERROR_MESSAGE_TOPIC_FULL => Self::MessageTopicFull,
60 HOST_ERROR_MAX_MESSAGES_PER_BLOCK_EXCEEDED => Self::MaxMessagesPerBlockExceeded,
61 HOST_ERROR_INTERNAL => Self::Internal,
62 other => Self::Other(other),
63 }
64 }
65}
66
67pub fn result_from_code(code: u32) -> Result<(), CommonResult> {
68 match code {
69 HOST_ERROR_SUCCESS => Ok(()),
70 other => Err(CommonResult::from(other)),
71 }
72}
73
74#[derive(Debug, Error)]
76pub enum TrapCode {
77 #[error("call stack exhausted")]
79 StackOverflow,
80 #[error("out of bounds memory access")]
82 MemoryOutOfBounds,
83 #[error("undefined element: out of bounds table access")]
85 TableAccessOutOfBounds,
86 #[error("uninitialized element")]
88 IndirectCallToNull,
89 #[error("indirect call type mismatch")]
91 BadSignature,
92 #[error("integer overflow")]
94 IntegerOverflow,
95 #[error("integer divide by zero")]
97 IntegerDivisionByZero,
98 #[error("invalid conversion to integer")]
100 BadConversionToInteger,
101 #[error("unreachable")]
103 UnreachableCodeReached,
104}
105
106pub const CALLEE_SUCCEEDED: u32 = 0;
107pub const CALLEE_REVERTED: u32 = 1;
108pub const CALLEE_TRAPPED: u32 = 2;
109pub const CALLEE_GAS_DEPLETED: u32 = 3;
110pub const CALLEE_NOT_CALLABLE: u32 = 4;
111pub const CALLEE_HOST_ERROR: u32 = 5;
112
113#[derive(Debug, Error)]
117pub enum CallError {
118 #[error("callee reverted")]
120 CalleeReverted,
121 #[error("callee trapped: {0}")]
123 CalleeTrapped(TrapCode),
124 #[error("callee gas depleted")]
126 CalleeGasDepleted,
127 #[error("not callable")]
129 NotCallable,
130 #[error("internal host")]
132 InternalHost,
133}
134
135impl CallError {
136 #[must_use]
138 pub fn into_u32(self) -> u32 {
139 match self {
140 Self::CalleeReverted => CALLEE_REVERTED,
141 Self::CalleeTrapped(_) => CALLEE_TRAPPED,
142 Self::CalleeGasDepleted => CALLEE_GAS_DEPLETED,
143 Self::NotCallable => CALLEE_NOT_CALLABLE,
144 Self::InternalHost => CALLEE_HOST_ERROR,
145 }
146 }
147}
148
149#[cfg(test)]
150mod tests {
151 use super::*;
152
153 #[test]
154 fn test_from_u32_not_found() {
155 let error = CommonResult::from(HOST_ERROR_NOT_FOUND);
156 assert_eq!(error, CommonResult::NotFound);
157 }
158
159 #[test]
160 fn test_from_u32_invalid_data() {
161 let error = CommonResult::from(HOST_ERROR_INVALID_DATA);
162 assert_eq!(error, CommonResult::InvalidData);
163 }
164
165 #[test]
166 fn test_from_u32_invalid_input() {
167 let error = CommonResult::from(HOST_ERROR_INVALID_INPUT);
168 assert_eq!(error, CommonResult::InvalidInput);
169 }
170
171 #[test]
172 fn test_from_u32_other() {
173 let error = CommonResult::from(10);
174 assert_eq!(error, CommonResult::Other(10));
175 }
176}