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
101
102
103
104
105
106
107
108
use std::cmp;
use std::sync::Arc;
use hash::keccak;
use ethereum_types::{U256, H256, Address};
use types::BlockNumber;
use ethjson;
pub type LastHashes = Vec<H256>;
#[derive(Debug, Clone)]
pub struct EnvInfo {
pub number: BlockNumber,
pub author: Address,
pub timestamp: u64,
pub difficulty: U256,
pub gas_limit: U256,
pub last_hashes: Arc<LastHashes>,
pub gas_used: U256,
}
impl Default for EnvInfo {
fn default() -> Self {
EnvInfo {
number: 0,
author: Address::default(),
timestamp: 0,
difficulty: 0.into(),
gas_limit: 0.into(),
last_hashes: Arc::new(vec![]),
gas_used: 0.into(),
}
}
}
impl From<ethjson::vm::Env> for EnvInfo {
fn from(e: ethjson::vm::Env) -> Self {
let number = e.number.into();
EnvInfo {
number: number,
author: e.author.into(),
difficulty: e.difficulty.into(),
gas_limit: e.gas_limit.into(),
timestamp: e.timestamp.into(),
last_hashes: Arc::new((1..cmp::min(number + 1, 257)).map(|i| keccak(format!("{}", number - i).as_bytes())).collect()),
gas_used: U256::default(),
}
}
}
#[cfg(test)]
mod tests {
use std::str::FromStr;
use super::*;
use ethereum_types::{U256, Address};
use ethjson;
#[test]
fn it_serializes_from_json() {
let env_info = EnvInfo::from(ethjson::vm::Env {
author: ethjson::hash::Address(Address::from_str("000000f00000000f000000000000f00000000f00").unwrap()),
number: ethjson::uint::Uint(U256::from(1_112_339)),
difficulty: ethjson::uint::Uint(U256::from(50_000)),
gas_limit: ethjson::uint::Uint(U256::from(40_000)),
timestamp: ethjson::uint::Uint(U256::from(1_100))
});
assert_eq!(env_info.number, 1112339);
assert_eq!(env_info.author, Address::from_str("000000f00000000f000000000000f00000000f00").unwrap());
assert_eq!(env_info.gas_limit, 40000.into());
assert_eq!(env_info.difficulty, 50000.into());
assert_eq!(env_info.gas_used, 0.into());
}
#[test]
fn it_can_be_created_as_default() {
let default_env_info = EnvInfo::default();
assert_eq!(default_env_info.difficulty, 0.into());
}
}