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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
use ethereum_types::{Address, H256, U256};
use ethjson;
use hash::keccak;
use std::{cmp, sync::Arc};
type BlockNumber = u64;
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,
pub base_fee: Option<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(),
base_fee: None,
}
}
}
impl From<ethjson::vm::Env> for EnvInfo {
fn from(e: ethjson::vm::Env) -> Self {
let number = e.number.into();
EnvInfo {
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(),
base_fee: e.base_fee.map(|i| i.into()),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use ethereum_types::{Address, U256};
use ethjson;
use std::str::FromStr;
#[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)),
base_fee: None,
});
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());
}
}