casper_execution_engine/engine_state/
error.rs

1//! Definition of all the possible outcomes of the operation on an `EngineState` instance.
2use datasize::DataSize;
3use thiserror::Error;
4
5use casper_storage::{system::transfer::TransferError, tracking_copy::TrackingCopyError};
6use casper_types::{bytesrepr, system::mint, ApiError, Digest, Key, ProtocolVersion};
7
8use super::InvalidRequest;
9use crate::{
10    execution::ExecError,
11    runtime::{stack, PreprocessingError},
12};
13
14/// Engine state errors.
15#[derive(Clone, Error, Debug)]
16#[non_exhaustive]
17pub enum Error {
18    /// Specified state root hash is not found.
19    #[error("Root not found: {0}")]
20    RootNotFound(Digest),
21    /// Protocol version used in the deploy is invalid.
22    #[error("Invalid protocol version: {0}")]
23    InvalidProtocolVersion(ProtocolVersion),
24    /// WASM preprocessing error.
25    #[error("Wasm preprocessing error: {0}")]
26    WasmPreprocessing(#[from] PreprocessingError),
27    /// Contract execution error.
28    #[error(transparent)]
29    Exec(ExecError),
30    /// Serialization/deserialization error.
31    #[error("Bytesrepr error: {0}")]
32    Bytesrepr(String),
33    /// Mint error.
34    #[error("Mint error: {0}")]
35    Mint(String),
36    /// Invalid key variant.
37    #[error("Unsupported key type: {0}")]
38    InvalidKeyVariant(Key),
39    /// An attempt to push to the runtime stack while already at the maximum height.
40    #[error("Runtime stack overflow")]
41    RuntimeStackOverflow,
42    /// Storage error.
43    #[error("Tracking copy error: {0}")]
44    TrackingCopy(TrackingCopyError),
45    /// Native transfer error.
46    #[error("Transfer error: {0}")]
47    Transfer(TransferError),
48    /// Could not derive a valid item to execute.
49    #[error("Invalid executable item: {0}")]
50    InvalidExecutableItem(#[from] InvalidRequest),
51}
52
53impl Error {
54    /// Creates an [`enum@Error`] instance of an [`Error::Exec`] variant with an API
55    /// error-compatible object.
56    ///
57    /// This method should be used only by native code that has to mimic logic of a WASM executed
58    /// code.
59    pub fn reverter(api_error: impl Into<ApiError>) -> Error {
60        Error::Exec(ExecError::Revert(api_error.into()))
61    }
62}
63
64impl From<TransferError> for Error {
65    fn from(err: TransferError) -> Self {
66        Error::Transfer(err)
67    }
68}
69
70impl From<ExecError> for Error {
71    fn from(error: ExecError) -> Self {
72        match error {
73            ExecError::WasmPreprocessing(preprocessing_error) => {
74                Error::WasmPreprocessing(preprocessing_error)
75            }
76            _ => Error::Exec(error),
77        }
78    }
79}
80
81impl From<bytesrepr::Error> for Error {
82    fn from(error: bytesrepr::Error) -> Self {
83        Error::Bytesrepr(format!("{}", error))
84    }
85}
86
87impl From<mint::Error> for Error {
88    fn from(error: mint::Error) -> Self {
89        Error::Mint(format!("{}", error))
90    }
91}
92
93impl From<stack::RuntimeStackOverflow> for Error {
94    fn from(_: stack::RuntimeStackOverflow) -> Self {
95        Self::RuntimeStackOverflow
96    }
97}
98
99impl From<TrackingCopyError> for Error {
100    fn from(e: TrackingCopyError) -> Self {
101        Error::TrackingCopy(e)
102    }
103}
104
105impl DataSize for Error {
106    const IS_DYNAMIC: bool = true;
107
108    const STATIC_HEAP_SIZE: usize = 0;
109
110    #[inline]
111    fn estimate_heap_size(&self) -> usize {
112        12 // TODO: replace with some actual estimation depending on the variant
113    }
114}