1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
use std::fmt;
use rlp::{Encodable, RlpStream, Decodable, Decoder, DecoderError, Stream, View};
use evm::Error as EvmError;
#[derive(Debug, PartialEq, Clone)]
#[cfg_attr(feature = "ipc", binary)]
pub enum Error {
OutOfGas,
BadJumpDestination,
BadInstruction,
StackUnderflow,
OutOfStack,
Internal,
}
impl From<EvmError> for Error {
fn from(e: EvmError) -> Self {
match e {
EvmError::OutOfGas => Error::OutOfGas,
EvmError::BadJumpDestination { .. } => Error::BadJumpDestination,
EvmError::BadInstruction { .. } => Error::BadInstruction,
EvmError::StackUnderflow { .. } => Error::StackUnderflow,
EvmError::OutOfStack { .. } => Error::OutOfStack,
EvmError::Internal => Error::Internal,
}
}
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use self::Error::*;
let message = match *self {
OutOfGas => "Out of gas",
BadJumpDestination => "Bad jump destination",
BadInstruction => "Bad instruction",
StackUnderflow => "Stack underflow",
OutOfStack => "Out of stack",
Internal => "Internal error",
};
message.fmt(f)
}
}
impl Encodable for Error {
fn rlp_append(&self, s: &mut RlpStream) {
use self::Error::*;
let value = match *self {
OutOfGas => 0u8,
BadJumpDestination => 1,
BadInstruction => 2,
StackUnderflow => 3,
OutOfStack => 4,
Internal => 5,
};
s.append(&value);
}
}
impl Decodable for Error {
fn decode<D>(decoder: &D) -> Result<Self, DecoderError> where D: Decoder {
use self::Error::*;
let value: u8 = decoder.as_rlp().as_val()?;
match value {
0 => Ok(OutOfGas),
1 => Ok(BadJumpDestination),
2 => Ok(BadInstruction),
3 => Ok(StackUnderflow),
4 => Ok(OutOfStack),
5 => Ok(Internal),
_ => Err(DecoderError::Custom("Invalid error type")),
}
}
}