1use std::cmp;
20use std::sync::Arc;
21use hash::keccak;
22use ethereum_types::{U256, H256, Address};
23use ethjson;
24
25type BlockNumber = u64;
26
27pub type LastHashes = Vec<H256>;
30
31#[derive(Debug, Clone)]
33pub struct EnvInfo {
34 pub number: BlockNumber,
36 pub author: Address,
38 pub timestamp: u64,
40 pub difficulty: U256,
42 pub gas_limit: U256,
44 pub last_hashes: Arc<LastHashes>,
46 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}