arbiter_core/
errors.rs

1//! Errors that can occur when managing or interfacing with Arbiter's sandboxed
2//! Ethereum environment.
3
4use std::sync::{PoisonError, RwLockWriteGuard};
5
6// use crossbeam_channel::SendError;
7use crossbeam_channel::{RecvError, SendError};
8use ethers::{
9    providers::{MiddlewareError, ProviderError},
10    signers::WalletError,
11};
12use revm_primitives::{EVMError, HaltReason};
13use thiserror::Error;
14
15use self::environment::instruction::{Instruction, Outcome};
16use super::*;
17
18/// The error type for `arbiter-core`.
19#[derive(Error, Debug)]
20pub enum ArbiterCoreError {
21    /// Tried to create an account that already exists.
22    #[error("Account already exists!")]
23    AccountCreationError,
24
25    /// Tried to access an account that doesn't exist.
26    #[error("Account doesn't exist!")]
27    AccountDoesNotExistError,
28
29    /// Tried to sign with forked EOA.
30    #[error("Can't sign with a forked EOA!")]
31    ForkedEOASignError,
32
33    /// Failed to upgrade instruction sender in middleware.
34    #[error("Failed to upgrade sender to a strong reference!")]
35    UpgradeSenderError,
36
37    /// Data missing when calling a transaction.
38    #[error("Data missing when calling a transaction!")]
39    MissingDataError,
40
41    /// Invalid data used for a query request.
42    #[error("Invalid data used for a query request!")]
43    InvalidQueryError,
44
45    /// Failed to join environment thread on stop.
46    #[error("Failed to join environment thread on stop!")]
47    JoinError,
48
49    /// Reverted execution.
50    #[error("Execution failed with revert: {gas_used:?} gas used, {output:?}")]
51    ExecutionRevert {
52        /// The amount of gas used.
53        gas_used: u64,
54        /// The output bytes of the execution.
55        output: Vec<u8>,
56    },
57
58    /// Halted execution.
59    #[error("Execution failed with halt: {reason:?}, {gas_used:?} gas used")]
60    ExecutionHalt {
61        /// The halt reason.
62        reason: HaltReason,
63        /// The amount of gas used.
64        gas_used: u64,
65    },
66
67    /// Failed to parse integer.
68    #[error(transparent)]
69    ParseIntError(#[from] std::num::ParseIntError),
70
71    /// Evm had a runtime error.
72    #[error(transparent)]
73    EVMError(#[from] EVMError<Infallible>),
74
75    /// Provider error.
76    #[error(transparent)]
77    ProviderError(#[from] ProviderError),
78
79    /// Wallet error.
80    #[error(transparent)]
81    WalletError(#[from] WalletError),
82
83    /// Send error.
84    #[error(transparent)]
85    SendError(
86        #[from]
87        #[allow(private_interfaces)]
88        SendError<Instruction>,
89    ),
90
91    /// Recv error.
92    #[error(transparent)]
93    RecvError(#[from] RecvError),
94
95    /// Failed to parse integer from string.
96    #[error(transparent)]
97    FromStrRadixError(#[from] uint::FromStrRadixErr),
98
99    /// Failed to handle json.
100    #[error(transparent)]
101    SerdeJsonError(#[from] serde_json::Error),
102
103    /// Failed to reply to instruction.
104    #[error("{0}")]
105    ReplyError(String),
106
107    /// Failed to grab a lock.
108    #[error("{0}")]
109    RwLockError(String),
110}
111
112impl From<SendError<Result<Outcome, ArbiterCoreError>>> for ArbiterCoreError {
113    fn from(e: SendError<Result<Outcome, ArbiterCoreError>>) -> Self {
114        ArbiterCoreError::ReplyError(e.to_string())
115    }
116}
117
118impl<T> From<PoisonError<RwLockWriteGuard<'_, T>>> for ArbiterCoreError {
119    fn from(e: PoisonError<RwLockWriteGuard<'_, T>>) -> Self {
120        ArbiterCoreError::RwLockError(e.to_string())
121    }
122}
123
124impl MiddlewareError for ArbiterCoreError {
125    type Inner = ProviderError;
126
127    fn from_err(e: Self::Inner) -> Self {
128        ArbiterCoreError::from(e)
129    }
130
131    fn as_inner(&self) -> Option<&Self::Inner> {
132        None
133    }
134}