referrerpolicy=no-referrer-when-downgrade

sc_executor_common/
error.rs

1// This file is part of Substrate.
2
3// Copyright (C) Parity Technologies (UK) Ltd.
4// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0
5
6// This program is free software: you can redistribute it and/or modify
7// it under the terms of the GNU General Public License as published by
8// the Free Software Foundation, either version 3 of the License, or
9// (at your option) any later version.
10
11// This program is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
15
16// You should have received a copy of the GNU General Public License
17// along with this program. If not, see <https://www.gnu.org/licenses/>.
18
19//! Rust executor possible errors.
20
21/// Result type alias.
22pub type Result<T> = std::result::Result<T, Error>;
23
24/// Error type.
25#[derive(Debug, thiserror::Error)]
26#[allow(missing_docs)]
27pub enum Error {
28	#[error("Error calling api function: {0}")]
29	ApiError(Box<dyn std::error::Error + Send + Sync>),
30
31	#[error("Method not found: '{0}'")]
32	MethodNotFound(String),
33
34	#[error("On-chain runtime does not specify version")]
35	VersionInvalid,
36
37	#[error("Externalities error")]
38	Externalities,
39
40	#[error("Invalid index provided")]
41	InvalidIndex,
42
43	#[error("Invalid type returned (should be u64)")]
44	InvalidReturn,
45
46	#[error("Runtime panicked: {0}")]
47	RuntimePanicked(String),
48
49	#[error("Invalid memory reference")]
50	InvalidMemoryReference,
51
52	#[error("The runtime doesn't provide a global named `__heap_base` of type `i32`")]
53	HeapBaseNotFoundOrInvalid,
54
55	#[error("The runtime must not have the `start` function defined")]
56	RuntimeHasStartFn,
57
58	#[error("Other: {0}")]
59	Other(String),
60
61	#[error(transparent)]
62	Allocator(#[from] sc_allocator::Error),
63
64	#[error("Host function {0} execution failed with: {1}")]
65	FunctionExecution(String, String),
66
67	#[error("No table exported by wasm blob")]
68	NoTable,
69
70	#[error("No table entry with index {0} in wasm blob exported table")]
71	NoTableEntryWithIndex(u32),
72
73	#[error("Table element with index {0} is not a function in wasm blob exported table")]
74	TableElementIsNotAFunction(u32),
75
76	#[error("Table entry with index {0} in wasm blob is null")]
77	FunctionRefIsNull(u32),
78
79	#[error(transparent)]
80	RuntimeConstruction(#[from] WasmError),
81
82	#[error("Shared memory is not supported")]
83	SharedMemUnsupported,
84
85	#[error("Imported globals are not supported yet")]
86	ImportedGlobalsUnsupported,
87
88	#[error("initializer expression can have only up to 2 expressions in wasm 1.0")]
89	InitializerHasTooManyExpressions,
90
91	#[error("Invalid initializer expression provided {0}")]
92	InvalidInitializerExpression(String),
93
94	#[error("Execution aborted due to panic: {0}")]
95	AbortedDueToPanic(MessageWithBacktrace),
96
97	#[error("Execution aborted due to trap: {0}")]
98	AbortedDueToTrap(MessageWithBacktrace),
99
100	#[error("Output exceeds bounds of wasm memory")]
101	OutputExceedsBounds,
102
103	#[error("Execution timed out")]
104	ExecutionTimeout,
105
106	#[error("Execution timeouts are not supported by this runtime instance")]
107	ExecutionTimeoutUnsupported,
108}
109
110impl From<&'static str> for Error {
111	fn from(err: &'static str) -> Error {
112		Error::Other(err.into())
113	}
114}
115
116impl From<String> for Error {
117	fn from(err: String) -> Error {
118		Error::Other(err)
119	}
120}
121
122/// Type for errors occurring during Wasm runtime construction.
123#[derive(Clone, Debug, thiserror::Error)]
124#[allow(missing_docs)]
125pub enum WasmError {
126	#[error("Code could not be read from the state.")]
127	CodeNotFound,
128
129	#[error("Failure to reinitialize runtime instance from snapshot.")]
130	ApplySnapshotFailed,
131
132	/// Failure to erase the wasm memory.
133	///
134	/// Depending on the implementation might mean failure of allocating memory.
135	#[error("Failure to erase the wasm memory: {0}")]
136	ErasingFailed(String),
137
138	#[error("Code failed validation: {0}")]
139	InvalidModule(String),
140
141	#[error("Wasm code could not be deserialized.")]
142	CantDeserializeWasm,
143
144	#[error("The module does not export a linear memory named `memory`.")]
145	InvalidMemory,
146
147	#[error("The number of heap pages requested is disallowed by the module.")]
148	InvalidHeapPages,
149
150	/// Instantiation error.
151	#[error("{0}")]
152	Instantiation(String),
153
154	/// Other error happened.
155	#[error("Other error happened while constructing the runtime: {0}")]
156	Other(String),
157}
158
159impl From<polkavm::program::ProgramParseError> for WasmError {
160	fn from(error: polkavm::program::ProgramParseError) -> Self {
161		WasmError::Other(error.to_string())
162	}
163}
164
165impl From<polkavm::Error> for WasmError {
166	fn from(error: polkavm::Error) -> Self {
167		WasmError::Other(error.to_string())
168	}
169}
170
171impl From<polkavm::CompileError> for WasmError {
172	fn from(error: polkavm::CompileError) -> Self {
173		match error {
174			polkavm::CompileError::ValidationFailed(msg) => WasmError::InvalidModule(msg),
175			polkavm::CompileError::Error(err) => WasmError::Other(err.to_string()),
176		}
177	}
178}
179
180impl From<polkavm::Error> for Error {
181	fn from(error: polkavm::Error) -> Self {
182		Error::Other(error.to_string())
183	}
184}
185
186/// An error message with an attached backtrace.
187#[derive(Debug)]
188pub struct MessageWithBacktrace {
189	/// The error message.
190	pub message: String,
191
192	/// The backtrace associated with the error message.
193	pub backtrace: Option<Backtrace>,
194}
195
196impl std::fmt::Display for MessageWithBacktrace {
197	fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
198		fmt.write_str(&self.message)?;
199		if let Some(ref backtrace) = self.backtrace {
200			fmt.write_str("\nWASM backtrace:\n")?;
201			backtrace.backtrace_string.fmt(fmt)?;
202		}
203
204		Ok(())
205	}
206}
207
208/// A WASM backtrace.
209#[derive(Debug)]
210pub struct Backtrace {
211	/// The string containing the backtrace.
212	pub backtrace_string: String,
213}
214
215impl std::fmt::Display for Backtrace {
216	fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
217		fmt.write_str(&self.backtrace_string)
218	}
219}