casper_execution_engine/execution/
error.rs

1//! Execution error and supporting code.
2use std::str::Utf8Error;
3use thiserror::Error;
4
5use casper_storage::{global_state, tracking_copy::TrackingCopyError};
6
7use casper_types::{
8    account::{AddKeyFailure, RemoveKeyFailure, SetThresholdFailure, UpdateKeyFailure},
9    bytesrepr,
10    execution::TransformError,
11    system, AccessRights, AddressableEntityHash, ApiError, ByteCodeHash, CLType, CLValueError,
12    ContractRuntimeTag, EntityVersionKey, Key, PackageHash, StoredValueTypeMismatch, URef,
13};
14use casper_wasm::elements;
15
16use crate::{
17    resolvers::error::ResolverError,
18    runtime::{stack, PreprocessingError},
19};
20
21/// Possible execution errors.
22#[derive(Error, Debug, Clone)]
23#[non_exhaustive]
24pub enum Error {
25    /// WASM interpreter error.
26    #[error("Interpreter error: {}", _0)]
27    Interpreter(String),
28    /// Storage error.
29    #[error("Storage error: {}", _0)]
30    Storage(global_state::error::Error),
31    /// Failed to (de)serialize bytes.
32    #[error("Serialization error: {}", _0)]
33    BytesRepr(bytesrepr::Error),
34    /// Unable to find named key.
35    #[error("Named key {} not found", _0)]
36    NamedKeyNotFound(String),
37    /// Unable to find a key.
38    #[error("Key {} not found", _0)]
39    KeyNotFound(Key),
40    /// Unable to find an account.
41    #[error("Account {:?} not found", _0)]
42    AccountNotFound(Key),
43    /// Type mismatch error.
44    #[error("{}", _0)]
45    TypeMismatch(StoredValueTypeMismatch),
46    /// Invalid access.
47    #[error("Invalid access rights: {}", required)]
48    InvalidAccess {
49        /// Required access rights of the operation.
50        required: AccessRights,
51    },
52    /// Forged reference error.
53    #[error("Forged reference: {}", _0)]
54    ForgedReference(URef),
55    /// Unable to find a function.
56    #[error("Function not found: {}", _0)]
57    FunctionNotFound(String),
58    /// Parity WASM error.
59    #[error("{}", _0)]
60    ParityWasm(elements::Error),
61    /// Error optimizing WASM.
62    #[error("WASM optimizer error")]
63    WasmOptimizer,
64    /// Execution exceeded the gas limit.
65    #[error("Out of gas error")]
66    GasLimit,
67    /// A stored smart contract called a ret function.
68    #[error("Return")]
69    Ret(Vec<URef>),
70    /// Error using WASM host function resolver.
71    #[error("Resolver error: {}", _0)]
72    Resolver(ResolverError),
73    /// Reverts execution with a provided status
74    #[error("{}", _0)]
75    Revert(ApiError),
76    /// Error adding an associated key.
77    #[error("{}", _0)]
78    AddKeyFailure(AddKeyFailure),
79    /// Error removing an associated key.
80    #[error("{}", _0)]
81    RemoveKeyFailure(RemoveKeyFailure),
82    /// Error updating an associated key.
83    #[error("{}", _0)]
84    UpdateKeyFailure(UpdateKeyFailure),
85    /// Error setting threshold on associated key.
86    #[error("{}", _0)]
87    SetThresholdFailure(SetThresholdFailure),
88    /// Error executing system contract.
89    #[error("{}", _0)]
90    SystemContract(system::Error),
91    /// Weight of all used associated keys does not meet account's deploy threshold.
92    #[error("Deployment authorization failure")]
93    DeploymentAuthorizationFailure,
94    /// Host buffer expected a value to be present.
95    #[error("Expected return value")]
96    ExpectedReturnValue,
97    /// Error calling a host function in a wrong context.
98    #[error("Invalid context")]
99    InvalidContext,
100    /// Unable to execute a deploy with invalid major protocol version.
101    #[error("Incompatible protocol major version. Expected version {expected} but actual version is {actual}")]
102    IncompatibleProtocolMajorVersion {
103        /// Expected major version.
104        expected: u32,
105        /// Actual major version supplied.
106        actual: u32,
107    },
108    /// Error converting a CLValue.
109    #[error("{0}")]
110    CLValue(CLValueError),
111    /// WASM bytes contains an unsupported "start" section.
112    #[error("Unsupported Wasm start")]
113    UnsupportedWasmStart,
114    /// Contract package has no active contract versions.
115    #[error("No active contract versions for contract package")]
116    NoActiveEntityVersions(PackageHash),
117    /// Invalid entity version supplied.
118    #[error("Invalid entity version: {}", _0)]
119    InvalidEntityVersion(EntityVersionKey),
120    /// Invalid entity version supplied.
121    #[error("Disabled entity version: {}", _0)]
122    DisabledEntityVersion(EntityVersionKey),
123    /// Invalid entity version supplied.
124    #[error("Missing entity version: {}", _0)]
125    MissingEntityVersion(EntityVersionKey),
126    /// Contract does not have specified entry point.
127    #[error("No such method: {}", _0)]
128    NoSuchMethod(String),
129    /// Contract does
130    #[error("Error calling a template entry point: {}", _0)]
131    TemplateMethod(String),
132    /// Error processing WASM bytes.
133    #[error("Wasm preprocessing error: {}", _0)]
134    WasmPreprocessing(PreprocessingError),
135    /// Unexpected variant of a stored value.
136    #[error("Unexpected variant of a stored value")]
137    UnexpectedStoredValueVariant,
138    /// Error upgrading a locked contract package.
139    #[error("A locked contract cannot be upgraded")]
140    LockedEntity(PackageHash),
141    /// Unable to find a contract by a specified hash address.
142    #[error("Invalid contract: {}", _0)]
143    InvalidEntity(AddressableEntityHash),
144    /// Unable to find the WASM bytes specified by a hash address.
145    #[error("Invalid contract WASM: {}", _0)]
146    InvalidByteCode(ByteCodeHash),
147    /// Error calling a smart contract with a missing argument.
148    #[error("Missing argument: {name}")]
149    MissingArgument {
150        /// Name of the required argument.
151        name: String,
152    },
153    /// Error writing a dictionary item key which exceeded maximum allowed length.
154    #[error("Dictionary item key exceeded maximum length")]
155    DictionaryItemKeyExceedsLength,
156    /// Missing system contract hash.
157    #[error("Missing system contract hash: {0}")]
158    MissingSystemContractHash(String),
159    /// An attempt to push to the runtime stack which is already at the maximum height.
160    #[error("Runtime stack overflow")]
161    RuntimeStackOverflow,
162    /// The runtime stack is `None`.
163    #[error("Runtime stack missing")]
164    MissingRuntimeStack,
165    /// Contract is disabled.
166    #[error("Contract is disabled")]
167    DisabledEntity(AddressableEntityHash),
168    /// Transform error.
169    #[error(transparent)]
170    Transform(TransformError),
171    /// Invalid key
172    #[error("Invalid key {0}")]
173    UnexpectedKeyVariant(Key),
174    /// Failed to transfer tokens on a private chain.
175    #[error("Failed to transfer with unrestricted transfers disabled")]
176    DisabledUnrestrictedTransfers,
177    /// Storage error.
178    #[error("Tracking copy error: {0}")]
179    TrackingCopy(TrackingCopyError),
180    /// Weight of all used associated keys does not meet entity's upgrade threshold.
181    #[error("Deployment authorization failure")]
182    UpgradeAuthorizationFailure,
183    /// The EntryPoints contains an invalid entry.
184    #[error("The EntryPoints contains an invalid entry")]
185    InvalidEntryPointType,
186    /// Invalid operation.
187    #[error("The imputed operation is invalid")]
188    InvalidImputedOperation,
189    /// Invalid string encoding.
190    #[error("Invalid UTF-8 string encoding: {0}")]
191    InvalidUtf8Encoding(Utf8Error),
192    /// Incompatible transaction runtime.
193    #[error("Incompatible runtime: {0}")]
194    IncompatibleRuntime(ContractRuntimeTag),
195    /// No matching entity version key.
196    #[error("No matching entity version key")]
197    NoMatchingEntityVersionKey,
198    /// Ambiguous entity version and unable to determine entity version key.
199    #[error("Ambiguous entity version")]
200    AmbiguousEntityVersion,
201}
202
203impl From<PreprocessingError> for Error {
204    fn from(error: PreprocessingError) -> Self {
205        Error::WasmPreprocessing(error)
206    }
207}
208
209impl From<casper_wasm_utils::OptimizerError> for Error {
210    fn from(_optimizer_error: casper_wasm_utils::OptimizerError) -> Self {
211        Error::WasmOptimizer
212    }
213}
214
215impl Error {
216    /// Returns new type mismatch error.
217    pub fn type_mismatch(expected: CLType, found: CLType) -> Error {
218        Error::TypeMismatch(StoredValueTypeMismatch::new(
219            format!("{:?}", expected),
220            format!("{:?}", found),
221        ))
222    }
223}
224
225impl casper_wasmi::HostError for Error {}
226
227impl From<casper_wasmi::Error> for Error {
228    fn from(error: casper_wasmi::Error) -> Self {
229        match error
230            .as_host_error()
231            .and_then(|host_error| host_error.downcast_ref::<Error>())
232        {
233            Some(error) => error.clone(),
234            None => Error::Interpreter(error.into()),
235        }
236    }
237}
238
239impl From<global_state::error::Error> for Error {
240    fn from(e: global_state::error::Error) -> Self {
241        Error::Storage(e)
242    }
243}
244
245impl From<bytesrepr::Error> for Error {
246    fn from(e: bytesrepr::Error) -> Self {
247        Error::BytesRepr(e)
248    }
249}
250
251impl From<elements::Error> for Error {
252    fn from(e: elements::Error) -> Self {
253        Error::ParityWasm(e)
254    }
255}
256
257impl From<ResolverError> for Error {
258    fn from(err: ResolverError) -> Self {
259        Error::Resolver(err)
260    }
261}
262
263impl From<AddKeyFailure> for Error {
264    fn from(err: AddKeyFailure) -> Self {
265        Error::AddKeyFailure(err)
266    }
267}
268
269impl From<RemoveKeyFailure> for Error {
270    fn from(err: RemoveKeyFailure) -> Self {
271        Error::RemoveKeyFailure(err)
272    }
273}
274
275impl From<UpdateKeyFailure> for Error {
276    fn from(err: UpdateKeyFailure) -> Self {
277        Error::UpdateKeyFailure(err)
278    }
279}
280
281impl From<SetThresholdFailure> for Error {
282    fn from(err: SetThresholdFailure) -> Self {
283        Error::SetThresholdFailure(err)
284    }
285}
286
287impl From<system::Error> for Error {
288    fn from(error: system::Error) -> Self {
289        Error::SystemContract(error)
290    }
291}
292
293impl From<CLValueError> for Error {
294    fn from(e: CLValueError) -> Self {
295        Error::CLValue(e)
296    }
297}
298
299impl From<stack::RuntimeStackOverflow> for Error {
300    fn from(_: stack::RuntimeStackOverflow) -> Self {
301        Error::RuntimeStackOverflow
302    }
303}
304
305impl From<TrackingCopyError> for Error {
306    fn from(e: TrackingCopyError) -> Self {
307        Error::TrackingCopy(e)
308    }
309}