1use ::{ResumeCall, ResumeCreate};
20use ethereum_types::Address;
21use action_params::ActionParams;
22use std::fmt;
23use ethtrie;
24
25#[derive(Debug)]
26pub enum TrapKind {
27	Call(ActionParams),
28	Create(ActionParams, Address),
29}
30
31pub enum TrapError<Call, Create> {
32	Call(ActionParams, Call),
33	Create(ActionParams, Address, Create),
34}
35
36#[derive(Debug, Clone, PartialEq)]
38pub enum Error {
39	OutOfGas,
45	BadJumpDestination {
48		destination: usize
50	},
51	BadInstruction {
53		instruction: u8,
55	},
56	StackUnderflow {
58		instruction: &'static str,
60		wanted: usize,
62		on_stack: usize
64	},
65	OutOfStack {
67		instruction: &'static str,
69		wanted: usize,
71		limit: usize
73	},
74	BuiltIn(&'static str),
76	MutableCallInStaticContext,
78	Internal(String),
80	Wasm(String),
82	OutOfBounds,
84	Reverted,
86}
87
88impl From<Box<ethtrie::TrieError>> for Error {
89	fn from(err: Box<ethtrie::TrieError>) -> Self {
90		Error::Internal(format!("Internal error: {}", err))
91	}
92}
93
94impl From<ethtrie::TrieError> for Error {
95	fn from(err: ethtrie::TrieError) -> Self {
96		Error::Internal(format!("Internal error: {}", err))
97	}
98}
99
100impl fmt::Display for Error {
101	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
102		use self::Error::*;
103		match *self {
104			OutOfGas => write!(f, "Out of gas"),
105			BadJumpDestination { destination } => write!(f, "Bad jump destination {:x}", destination),
106			BadInstruction { instruction } => write!(f, "Bad instruction {:x}",  instruction),
107			StackUnderflow { instruction, wanted, on_stack } => write!(f, "Stack underflow {} {}/{}", instruction, wanted, on_stack),
108			OutOfStack { instruction, wanted, limit } => write!(f, "Out of stack {} {}/{}", instruction, wanted, limit),
109			BuiltIn(name) => write!(f, "Built-in failed: {}", name),
110			Internal(ref msg) => write!(f, "Internal error: {}", msg),
111			MutableCallInStaticContext => write!(f, "Mutable call in static context"),
112			Wasm(ref msg) => write!(f, "Internal error: {}", msg),
113			OutOfBounds => write!(f, "Out of bounds"),
114			Reverted => write!(f, "Reverted"),
115		}
116	}
117}
118
119pub type Result<T> = ::std::result::Result<T, Error>;
120pub type TrapResult<T, Call, Create> = ::std::result::Result<Result<T>, TrapError<Call, Create>>;
121
122pub type ExecTrapResult<T> = TrapResult<T, Box<dyn ResumeCall>, Box<dyn ResumeCreate>>;
123pub type ExecTrapError = TrapError<Box<dyn ResumeCall>, Box<dyn ResumeCreate>>;