1// This file is part of Substrate.
23// Copyright (C) Parity Technologies (UK) Ltd.
4// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0
56// 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.
1011// 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.
1516// 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/>.
1819//! Rust executor possible errors.
2021/// Result type alias.
22pub type Result<T> = std::result::Result<T, Error>;
2324/// Error type.
25#[derive(Debug, thiserror::Error)]
26#[allow(missing_docs)]
27pub enum Error {
28#[error("Error calling api function: {0}")]
29ApiError(Box<dyn std::error::Error + Send + Sync>),
3031#[error("Method not found: '{0}'")]
32MethodNotFound(String),
3334#[error("On-chain runtime does not specify version")]
35VersionInvalid,
3637#[error("Externalities error")]
38Externalities,
3940#[error("Invalid index provided")]
41InvalidIndex,
4243#[error("Invalid type returned (should be u64)")]
44InvalidReturn,
4546#[error("Runtime panicked: {0}")]
47RuntimePanicked(String),
4849#[error("Invalid memory reference")]
50InvalidMemoryReference,
5152#[error("The runtime doesn't provide a global named `__heap_base` of type `i32`")]
53HeapBaseNotFoundOrInvalid,
5455#[error("The runtime must not have the `start` function defined")]
56RuntimeHasStartFn,
5758#[error("Other: {0}")]
59Other(String),
6061#[error(transparent)]
62Allocator(#[from] sc_allocator::Error),
6364#[error("Host function {0} execution failed with: {1}")]
65FunctionExecution(String, String),
6667#[error("No table exported by wasm blob")]
68NoTable,
6970#[error("No table entry with index {0} in wasm blob exported table")]
71NoTableEntryWithIndex(u32),
7273#[error("Table element with index {0} is not a function in wasm blob exported table")]
74TableElementIsNotAFunction(u32),
7576#[error("Table entry with index {0} in wasm blob is null")]
77FunctionRefIsNull(u32),
7879#[error(transparent)]
80RuntimeConstruction(#[from] WasmError),
8182#[error("Shared memory is not supported")]
83SharedMemUnsupported,
8485#[error("Imported globals are not supported yet")]
86ImportedGlobalsUnsupported,
8788#[error("initializer expression can have only up to 2 expressions in wasm 1.0")]
89InitializerHasTooManyExpressions,
9091#[error("Invalid initializer expression provided {0}")]
92InvalidInitializerExpression(String),
9394#[error("Execution aborted due to panic: {0}")]
95AbortedDueToPanic(MessageWithBacktrace),
9697#[error("Execution aborted due to trap: {0}")]
98AbortedDueToTrap(MessageWithBacktrace),
99100#[error("Output exceeds bounds of wasm memory")]
101OutputExceedsBounds,
102}
103104impl From<&'static str> for Error {
105fn from(err: &'static str) -> Error {
106 Error::Other(err.into())
107 }
108}
109110impl From<String> for Error {
111fn from(err: String) -> Error {
112 Error::Other(err)
113 }
114}
115116/// Type for errors occurring during Wasm runtime construction.
117#[derive(Debug, thiserror::Error)]
118#[allow(missing_docs)]
119pub enum WasmError {
120#[error("Code could not be read from the state.")]
121CodeNotFound,
122123#[error("Failure to reinitialize runtime instance from snapshot.")]
124ApplySnapshotFailed,
125126/// Failure to erase the wasm memory.
127 ///
128 /// Depending on the implementation might mean failure of allocating memory.
129#[error("Failure to erase the wasm memory: {0}")]
130ErasingFailed(String),
131132#[error("Wasm code failed validation.")]
133InvalidModule,
134135#[error("Wasm code could not be deserialized.")]
136CantDeserializeWasm,
137138#[error("The module does not export a linear memory named `memory`.")]
139InvalidMemory,
140141#[error("The number of heap pages requested is disallowed by the module.")]
142InvalidHeapPages,
143144/// Instantiation error.
145#[error("{0}")]
146Instantiation(String),
147148/// Other error happened.
149#[error("Other error happened while constructing the runtime: {0}")]
150Other(String),
151}
152153impl From<polkavm::program::ProgramParseError> for WasmError {
154fn from(error: polkavm::program::ProgramParseError) -> Self {
155 WasmError::Other(error.to_string())
156 }
157}
158159impl From<polkavm::Error> for WasmError {
160fn from(error: polkavm::Error) -> Self {
161 WasmError::Other(error.to_string())
162 }
163}
164165impl From<polkavm::Error> for Error {
166fn from(error: polkavm::Error) -> Self {
167 Error::Other(error.to_string())
168 }
169}
170171/// An error message with an attached backtrace.
172#[derive(Debug)]
173pub struct MessageWithBacktrace {
174/// The error message.
175pub message: String,
176177/// The backtrace associated with the error message.
178pub backtrace: Option<Backtrace>,
179}
180181impl std::fmt::Display for MessageWithBacktrace {
182fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
183 fmt.write_str(&self.message)?;
184if let Some(ref backtrace) = self.backtrace {
185 fmt.write_str("\nWASM backtrace:\n")?;
186 backtrace.backtrace_string.fmt(fmt)?;
187 }
188189Ok(())
190 }
191}
192193/// A WASM backtrace.
194#[derive(Debug)]
195pub struct Backtrace {
196/// The string containing the backtrace.
197pub backtrace_string: String,
198}
199200impl std::fmt::Display for Backtrace {
201fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
202 fmt.write_str(&self.backtrace_string)
203 }
204}