mep_vm/
env_info.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//! Environment information for transaction execution.
18
19use std::cmp;
20use std::sync::Arc;
21use hash::keccak;
22use ethereum_types::{U256, H256, Address};
23use ethjson;
24
25type BlockNumber = u64;
26
27/// Simple vector of hashes, should be at most 256 items large, can be smaller if being used
28/// for a block whose number is less than 257.
29pub type LastHashes = Vec<H256>;
30
31/// Information concerning the execution environment for a message-call/contract-creation.
32#[derive(Debug, Clone)]
33pub struct EnvInfo {
34	/// The block number.
35	pub number: BlockNumber,
36	/// The block author.
37	pub author: Address,
38	/// The block timestamp.
39	pub timestamp: u64,
40	/// The block difficulty.
41	pub difficulty: U256,
42	/// The block gas limit.
43	pub gas_limit: U256,
44	/// The last 256 block hashes.
45	pub last_hashes: Arc<LastHashes>,
46	/// The gas used.
47	pub gas_used: U256,
48}
49
50impl Default for EnvInfo {
51	fn default() -> Self {
52		EnvInfo {
53			number: 0,
54			author: Address::zero(),
55			timestamp: 0,
56			difficulty: 0.into(),
57			gas_limit: 0.into(),
58			last_hashes: Arc::new(vec![]),
59			gas_used: 0.into(),
60		}
61	}
62}
63
64impl From<ethjson::vm::Env> for EnvInfo {
65	fn from(e: ethjson::vm::Env) -> Self {
66		let number = e.number.into();
67		EnvInfo {
68			number,
69			author: e.author.into(),
70			difficulty: e.difficulty.into(),
71			gas_limit: e.gas_limit.into(),
72			timestamp: e.timestamp.into(),
73			last_hashes: Arc::new((1..cmp::min(number + 1, 257)).map(|i| keccak(format!("{}", number - i).as_bytes())).collect()),
74			gas_used: U256::default(),
75		}
76	}
77}
78
79#[cfg(test)]
80mod tests {
81	use std::str::FromStr;
82	use super::*;
83	use ethereum_types::{U256, Address};
84	use ethjson;
85
86	#[test]
87	fn it_serializes_from_json() {
88		let env_info = EnvInfo::from(ethjson::vm::Env {
89			author: ethjson::hash::Address(Address::from_str("000000f00000000f000000000000f00000000f00").unwrap()),
90			number: ethjson::uint::Uint(U256::from(1_112_339)),
91			difficulty: ethjson::uint::Uint(U256::from(50_000)),
92			gas_limit: ethjson::uint::Uint(U256::from(40_000)),
93			timestamp: ethjson::uint::Uint(U256::from(1_100))
94		});
95
96		assert_eq!(env_info.number, 1112339);
97		assert_eq!(env_info.author, Address::from_str("000000f00000000f000000000000f00000000f00").unwrap());
98		assert_eq!(env_info.gas_limit, 40000.into());
99		assert_eq!(env_info.difficulty, 50000.into());
100		assert_eq!(env_info.gas_used, 0.into());
101	}
102
103	#[test]
104	fn it_can_be_created_as_default() {
105		let default_env_info = EnvInfo::default();
106
107		assert_eq!(default_env_info.difficulty, 0.into());
108	}
109}