corevm_engine/
error.rs

1use corevm_host::{fs, Outcome};
2use jam_pvm_common::ApiError;
3
4/// Engine initialization error.
5#[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}
18
19impl From<polkavm::program::ProgramParseError> for InitError {
20	fn from(_: polkavm::program::ProgramParseError) -> Self {
21		Self::ProgramBlob
22	}
23}
24
25impl From<ApiError> for InitError {
26	fn from(e: ApiError) -> Self {
27		Self::Jam(e)
28	}
29}
30
31impl From<fs::Error> for InitError {
32	fn from(e: fs::Error) -> Self {
33		Self::Fs(e)
34	}
35}
36
37/// Fatal engine error after which the continuation is not possible.
38#[derive(thiserror::Error, Debug)]
39pub enum FatalError {
40	#[error("Input space limit reached while restarting a host-call")]
41	NotEnoughInputSpace,
42	#[error("Output space limit reached while restarting a host-call")]
43	NotEnoughOutputSpace,
44	#[error("Unknown host-call")]
45	UnknownHostCall,
46}
47
48/// Engine runtime error.
49#[derive(thiserror::Error, Debug)]
50pub enum RunError {
51	#[error("JAM error: {0:?}")]
52	Jam(ApiError),
53	#[error("CoreVM FS error: {0:?}")]
54	Fs(fs::Error),
55	#[error("Fatal error: {0:?}")]
56	Fatal(FatalError),
57	#[error("Failed to initialize libc")]
58	LibcInit,
59}
60
61impl From<ApiError> for RunError {
62	fn from(e: ApiError) -> Self {
63		Self::Jam(e)
64	}
65}
66
67impl From<fs::Error> for RunError {
68	fn from(e: fs::Error) -> Self {
69		Self::Fs(e)
70	}
71}
72
73impl From<FatalError> for RunError {
74	fn from(e: FatalError) -> Self {
75		Self::Fatal(e)
76	}
77}
78
79#[derive(Debug)]
80pub(crate) enum HostCallError {
81	Jam(ApiError),
82	Fs(fs::Error),
83	Outcome(Outcome),
84	Fatal(FatalError),
85}
86
87impl From<Outcome> for HostCallError {
88	fn from(outcome: Outcome) -> Self {
89		Self::Outcome(outcome)
90	}
91}
92
93impl From<TimeLimitReached> for HostCallError {
94	fn from(_: TimeLimitReached) -> Self {
95		Self::Outcome(Outcome::TimeLimitReached)
96	}
97}
98
99impl From<OutputLimitReached> for HostCallError {
100	fn from(_: OutputLimitReached) -> Self {
101		Self::Outcome(Outcome::OutputLimitReached)
102	}
103}
104
105impl From<ApiError> for HostCallError {
106	fn from(e: ApiError) -> Self {
107		Self::Jam(e)
108	}
109}
110
111impl From<fs::Error> for HostCallError {
112	fn from(e: fs::Error) -> Self {
113		Self::Fs(e)
114	}
115}
116
117impl From<FatalError> for HostCallError {
118	fn from(e: FatalError) -> Self {
119		Self::Fatal(e)
120	}
121}
122
123impl From<TouchError> for HostCallError {
124	fn from(e: TouchError) -> Self {
125		match e {
126			TouchError::PageFault { page, num_pages } =>
127				Self::Outcome(Outcome::PageFault { page, num_pages }),
128			TouchError::Jam(e) => Self::Jam(e),
129		}
130	}
131}
132
133#[derive(Debug)]
134pub(crate) enum TouchError {
135	PageFault { page: u64, num_pages: u64 },
136	Jam(ApiError),
137}
138
139impl From<ApiError> for TouchError {
140	fn from(e: ApiError) -> Self {
141		Self::Jam(e)
142	}
143}
144
145/// The guest produced/consumed one time-slot worth of video frames and audio samples.
146#[derive(Debug)]
147pub(crate) struct TimeLimitReached;
148
149/// The guest produced `WorkItem::export_count` worth of export segments.
150///
151/// These include updated memory pages, video/audio/console output and page map.
152#[derive(Debug)]
153pub(crate) struct OutputLimitReached;