mep_vm/
action_type.rs

1// Copyright 2015-2020 Parity Technologies (UK) Ltd.
2// This file is part of Parity Ethereum.
3
4// Parity Ethereum is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8
9// Parity Ethereum is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12// GNU General Public License for more details.
13
14// You should have received a copy of the GNU General Public License
15// along with Parity Ethereum.  If not, see <http://www.gnu.org/licenses/>.
16
17//! EVM action types.
18
19use rlp::{Encodable, Decodable, DecoderError, RlpStream, Rlp};
20
21/// The type of the instruction.
22#[derive(Debug, PartialEq, Clone)]
23pub enum ActionType {
24	/// CREATE.
25	Create,
26	/// CALL.
27	Call,
28	/// CALLCODE.
29	CallCode,
30	/// DELEGATECALL.
31	DelegateCall,
32	/// STATICCALL.
33	StaticCall,
34	/// CREATE2.
35	Create2
36}
37
38impl Encodable for ActionType {
39	fn rlp_append(&self, s: &mut RlpStream) {
40		let v = match *self {
41			ActionType::Create => 0u32,
42			ActionType::Call => 1,
43			ActionType::CallCode => 2,
44			ActionType::DelegateCall => 3,
45			ActionType::StaticCall => 4,
46			ActionType::Create2 => 5,
47		};
48		Encodable::rlp_append(&v, s);
49	}
50}
51
52impl Decodable for ActionType {
53	fn decode(rlp: &Rlp) -> Result<Self, DecoderError> {
54		rlp.as_val().and_then(|v| Ok(match v {
55			0u32 => ActionType::Create,
56			1 => ActionType::Call,
57			2 => ActionType::CallCode,
58			3 => ActionType::DelegateCall,
59			4 => ActionType::StaticCall,
60			5 => ActionType::Create2,
61			_ => return Err(DecoderError::Custom("Invalid value of ActionType item")),
62		}))
63	}
64}
65
66#[cfg(test)]
67mod tests {
68	use rlp::*;
69	use super::ActionType;
70
71	#[test]
72	fn encode_call_type() {
73		let ct = ActionType::Call;
74
75		let mut s = RlpStream::new_list(2);
76		s.append(&ct);
77		assert!(!s.is_finished(), "List shouldn't finished yet");
78		s.append(&ct);
79		assert!(s.is_finished(), "List should be finished now");
80		s.out();
81	}
82
83	#[test]
84	fn should_encode_and_decode_call_type() {
85		let original = ActionType::Call;
86		let encoded = encode(&original);
87		let decoded = decode(&encoded).expect("failure decoding ActionType");
88		assert_eq!(original, decoded);
89	}
90}