1use corevm_host::{fs, Outcome, PageNum};
2use jam_pvm_common::ApiError;
3
4#[derive(thiserror::Error, Debug)]
6pub enum InitError {
7 #[error("JAM error: {0:?}")]
8 Jam(ApiError),
9 #[error("CoreVM FS error: {0:?}")]
10 Fs(fs::Error),
11 #[error("Invalid program blob")]
12 ProgramBlob,
13 #[error("Invalid exec blob")]
14 ExecBlob,
15 #[error("None or both `main` and `_pvm_start` entry points were found")]
16 EntryPoint,
17 #[error("Invalid memory page was imported into the package")]
18 InvalidPage,
19 #[error("Input limit reached while initializing the engine")]
20 InputLimitReached,
21}
22
23impl From<polkavm::program::ProgramParseError> for InitError {
24 fn from(_: polkavm::program::ProgramParseError) -> Self {
25 Self::ProgramBlob
26 }
27}
28
29impl From<ApiError> for InitError {
30 fn from(e: ApiError) -> Self {
31 Self::Jam(e)
32 }
33}
34
35impl From<fs::Error> for InitError {
36 fn from(e: fs::Error) -> Self {
37 Self::Fs(e)
38 }
39}
40
41#[derive(thiserror::Error, Debug)]
43pub enum FatalError {
44 #[error("Input space limit reached while restarting a host-call")]
45 NotEnoughInputSpace,
46 #[error("Output space limit reached while restarting a host-call")]
47 NotEnoughOutputSpace,
48 #[error("Unknown host-call")]
49 UnknownHostCall,
50 #[error("Guest attempted to read/write reserved/unmapped memory address")]
51 InvalidMemoryAccess,
52}
53
54#[derive(thiserror::Error, Debug)]
56pub enum RunError {
57 #[error("JAM error: {0:?}")]
58 Jam(ApiError),
59 #[error("CoreVM FS error: {0:?}")]
60 Fs(fs::Error),
61 #[error("Fatal error: {0:?}")]
62 Fatal(FatalError),
63 #[error("Failed to initialize libc")]
64 LibcInit,
65}
66
67impl From<ApiError> for RunError {
68 fn from(e: ApiError) -> Self {
69 Self::Jam(e)
70 }
71}
72
73impl From<fs::Error> for RunError {
74 fn from(e: fs::Error) -> Self {
75 Self::Fs(e)
76 }
77}
78
79impl From<FatalError> for RunError {
80 fn from(e: FatalError) -> Self {
81 Self::Fatal(e)
82 }
83}
84
85#[derive(Debug)]
86pub(crate) enum HostCallError {
87 Jam(ApiError),
88 Fs(fs::Error),
89 Outcome(Outcome),
90 Fatal(FatalError),
91}
92
93impl From<Outcome> for HostCallError {
94 fn from(outcome: Outcome) -> Self {
95 Self::Outcome(outcome)
96 }
97}
98
99impl From<TimeLimitReached> for HostCallError {
100 fn from(_: TimeLimitReached) -> Self {
101 Self::Outcome(Outcome::TimeLimitReached)
102 }
103}
104
105impl From<OutputLimitReached> for HostCallError {
106 fn from(_: OutputLimitReached) -> Self {
107 Self::Outcome(Outcome::OutputLimitReached)
108 }
109}
110
111impl From<InputLimitReached> for HostCallError {
112 fn from(_: InputLimitReached) -> Self {
113 Self::Outcome(Outcome::InputLimitReached)
114 }
115}
116
117impl From<ApiError> for HostCallError {
118 fn from(e: ApiError) -> Self {
119 Self::Jam(e)
120 }
121}
122
123impl From<fs::Error> for HostCallError {
124 fn from(e: fs::Error) -> Self {
125 Self::Fs(e)
126 }
127}
128
129impl From<FatalError> for HostCallError {
130 fn from(e: FatalError) -> Self {
131 Self::Fatal(e)
132 }
133}
134
135impl From<TouchError> for HostCallError {
136 fn from(e: TouchError) -> Self {
137 match e {
138 TouchError::PageFault { page, num_pages } =>
139 Self::Outcome(Outcome::PageFault { page, num_pages }),
140 TouchError::Jam(e) => Self::Jam(e),
141 TouchError::InvalidMemoryAccess => Self::Fatal(FatalError::InvalidMemoryAccess),
142 TouchError::InputLimitReached => Self::Outcome(Outcome::InputLimitReached),
143 }
144 }
145}
146
147impl From<polkakernel::MachineError> for HostCallError {
148 fn from(e: polkakernel::MachineError) -> Self {
149 match e {
150 polkakernel::MachineError::BadAddress => Self::Fatal(FatalError::InvalidMemoryAccess),
151 }
152 }
153}
154
155impl From<TooLargeWorkOutput> for HostCallError {
156 fn from(_: TooLargeWorkOutput) -> Self {
157 Self::Outcome(Outcome::OutputLimitReached)
158 }
159}
160
161#[derive(Debug)]
162pub(crate) enum TouchError {
163 PageFault { page: PageNum, num_pages: u32 },
164 Jam(ApiError),
165 InvalidMemoryAccess,
166 InputLimitReached,
167}
168
169impl From<ApiError> for TouchError {
170 fn from(e: ApiError) -> Self {
171 Self::Jam(e)
172 }
173}
174
175impl From<InputLimitReached> for TouchError {
176 fn from(_: InputLimitReached) -> Self {
177 Self::InputLimitReached
178 }
179}
180
181#[derive(Debug)]
183pub(crate) struct TimeLimitReached;
184
185#[derive(Debug)]
189pub(crate) struct OutputLimitReached;
190
191#[derive(Debug)]
193pub(crate) struct TooLargeWorkOutput;
194
195#[derive(Debug)]
200pub(crate) struct InputLimitReached;