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;
111
112#[derive(Debug, Error)]
116pub enum CallError {
117 #[error("callee reverted")]
119 CalleeReverted,
120 #[error("callee trapped: {0}")]
122 CalleeTrapped(TrapCode),
123 #[error("callee gas depleted")]
125 CalleeGasDepleted,
126 #[error("not callable")]
128 NotCallable,
129}
130
131impl CallError {
132 #[must_use]
134 pub fn into_u32(self) -> u32 {
135 match self {
136 Self::CalleeReverted => CALLEE_REVERTED,
137 Self::CalleeTrapped(_) => CALLEE_TRAPPED,
138 Self::CalleeGasDepleted => CALLEE_GAS_DEPLETED,
139 Self::NotCallable => CALLEE_NOT_CALLABLE,
140 }
141 }
142}
143
144#[cfg(test)]
145mod tests {
146 use super::*;
147
148 #[test]
149 fn test_from_u32_not_found() {
150 let error = CommonResult::from(HOST_ERROR_NOT_FOUND);
151 assert_eq!(error, CommonResult::NotFound);
152 }
153
154 #[test]
155 fn test_from_u32_invalid_data() {
156 let error = CommonResult::from(HOST_ERROR_INVALID_DATA);
157 assert_eq!(error, CommonResult::InvalidData);
158 }
159
160 #[test]
161 fn test_from_u32_invalid_input() {
162 let error = CommonResult::from(HOST_ERROR_INVALID_INPUT);
163 assert_eq!(error, CommonResult::InvalidInput);
164 }
165
166 #[test]
167 fn test_from_u32_other() {
168 let error = CommonResult::from(10);
169 assert_eq!(error, CommonResult::Other(10));
170 }
171}