1
2
3extern crate ethereum_types;
4extern crate rlp;
5extern crate rlp_derive;
6extern crate serde;
7extern crate serde_derive;
8
9use std::ops::{Add, Index, IndexMut};
10
11pub use ethereum_types::{
12 Address, BigEndianHash, Bloom, BloomInput, Public, Secret, Signature, H128,
13 H160, H256, H512, H520, H64, U128, U256, U512, U64,
14};
15use rlp::{Decodable, DecoderError, Encodable, Rlp, RlpStream};
16use rlp_derive::{RlpDecodable, RlpEncodable};
17use serde::ser::SerializeMap;
18use serde_derive::{Deserialize, Serialize};
19
20pub use self::space_util::AddressSpaceUtil;
21
22#[derive(
23 Eq,
24 PartialEq,
25 Hash,
26 Copy,
27 Clone,
28 Debug,
29 Ord,
30 PartialOrd,
31 Serialize,
32 Deserialize,
33)]
34#[serde(rename_all = "lowercase")]
35pub enum Space {
36 Native,
37 #[serde(rename(serialize = "evm", deserialize = "evm"))]
38 Ethereum,
39}
40
41impl From<Space> for String {
42 fn from(space: Space) -> Self {
43 let str: &'static str = space.into();
44 str.into()
45 }
46}
47
48impl From<Space> for &'static str {
49 fn from(space: Space) -> Self {
50 match space {
51 Space::Native => "native",
52 Space::Ethereum => "evm",
53 }
54 }
55}
56
57impl Encodable for Space {
58 fn rlp_append(&self, s: &mut RlpStream) {
59 let type_int: u8 = match self {
60 Space::Native => 1,
61 Space::Ethereum => 2,
62 };
63 type_int.rlp_append(s)
64 }
65}
66
67impl Decodable for Space {
68 fn decode(rlp: &Rlp) -> Result<Self, DecoderError> {
69 match u8::decode(rlp)? {
70 1u8 => Ok(Space::Native),
71 2u8 => Ok(Space::Ethereum),
72 _ => Err(DecoderError::Custom("Unrecognized space byte.")),
73 }
74 }
75}
76
77#[derive(
78 Default, Copy, Clone, Debug, Eq, PartialEq, RlpEncodable, RlpDecodable,
79)]
80pub struct AllChainID {
81 native: u32,
82 ethereum: u32,
83}
84
85impl AllChainID {
86 pub fn new(native: u32, ethereum: u32) -> Self { Self { native, ethereum } }
87
88 pub fn fake_for_virtual(chain_id: u32) -> Self {
89 Self {
90 native: chain_id,
91 ethereum: chain_id,
92 }
93 }
94
95 pub fn in_space(&self, space: Space) -> u32 {
96 match space {
97 Space::Native => self.native,
98 Space::Ethereum => self.ethereum,
99 }
100 }
101
102 pub fn in_native_space(&self) -> u32 { self.in_space(Space::Native) }
103
104 pub fn in_evm_space(&self) -> u32 { self.in_space(Space::Ethereum) }
105}
106
107impl Default for Space {
108 fn default() -> Self { Space::Native }
109}
110
111#[derive(Default, Eq, PartialEq, Hash, Copy, Clone, Debug, Ord, PartialOrd)]
112pub struct AddressWithSpace {
113 pub address: Address,
114 pub space: Space,
115}
116
117impl AddressWithSpace {
118 #[inline]
119 pub fn assert_native(&self) { assert_eq!(self.space, Space::Native) }
120}
121
122#[derive(Default, Clone, Copy, PartialEq, Eq, Debug)]
123pub struct SpaceMap<T> {
124 native: T,
125 evm: T,
126}
127
128impl<T> SpaceMap<T> {
129 pub const fn new(native: T, evm: T) -> Self { SpaceMap { native, evm } }
130
131 #[inline]
132 pub fn in_space(&self, space: Space) -> &T {
133 match space {
134 Space::Native => &self.native,
135 Space::Ethereum => &self.evm,
136 }
137 }
138
139 #[inline]
140 pub fn in_space_mut(&mut self, space: Space) -> &mut T {
141 match space {
142 Space::Native => &mut self.native,
143 Space::Ethereum => &mut self.evm,
144 }
145 }
146
147 pub fn zip3<B, C>(
148 a: SpaceMap<T>, b: SpaceMap<B>, c: SpaceMap<C>,
149 ) -> SpaceMap<(T, B, C)> {
150 SpaceMap {
151 native: (a.native, b.native, c.native),
152 evm: (a.evm, b.evm, c.evm),
153 }
154 }
155
156 pub fn zip4<B, C, D>(
157 a: SpaceMap<T>, b: SpaceMap<B>, c: SpaceMap<C>, d: SpaceMap<D>,
158 ) -> SpaceMap<(T, B, C, D)> {
159 SpaceMap {
160 native: (a.native, b.native, c.native, d.native),
161 evm: (a.evm, b.evm, c.evm, d.evm),
162 }
163 }
164
165 pub fn map_sum<F: FnMut(&T) -> U, U: Add<U, Output = U>>(
166 &self, mut f: F,
167 ) -> U {
168 f(&self.native) + f(&self.evm)
169 }
170
171 pub const fn size(&self) -> usize { 2 }
172
173 pub fn map_all<U, F: Fn(T) -> U>(self, f: F) -> SpaceMap<U> {
174 SpaceMap {
175 native: f(self.native),
176 evm: f(self.evm),
177 }
178 }
179
180 pub fn apply_all<U, F: FnMut(&mut T) -> U>(
181 &mut self, mut f: F,
182 ) -> SpaceMap<U> {
183 SpaceMap {
184 native: f(&mut self.native),
185 evm: f(&mut self.evm),
186 }
187 }
188}
189
190impl<T> Index<Space> for SpaceMap<T> {
191 type Output = T;
192
193 fn index(&self, space: Space) -> &Self::Output { self.in_space(space) }
194}
195
196impl<T> IndexMut<Space> for SpaceMap<T> {
197 fn index_mut(&mut self, space: Space) -> &mut Self::Output {
198 self.in_space_mut(space)
199 }
200}
201
202impl<T: serde::Serialize> serde::Serialize for SpaceMap<T> {
203 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
204 where S: serde::Serializer {
205 let mut map = serializer.serialize_map(Some(self.size()))?;
206 map.serialize_entry("core", &self.native)?;
207 map.serialize_entry("espace", &self.evm)?;
208 map.end()
209 }
210}
211
212pub mod space_util {
213 use super::{Address, AddressWithSpace, Space};
214
215 pub trait AddressSpaceUtil: Sized {
216 fn with_space(self, space: Space) -> AddressWithSpace;
217 fn with_native_space(self) -> AddressWithSpace {
218 self.with_space(Space::Native)
219 }
220 fn with_evm_space(self) -> AddressWithSpace {
221 self.with_space(Space::Ethereum)
222 }
223 }
224
225 impl AddressSpaceUtil for Address {
226 fn with_space(self, space: Space) -> AddressWithSpace {
227 AddressWithSpace {
228 address: self,
229 space,
230 }
231 }
232 }
233}
234
235pub fn maybe_address(address: &Address) -> Option<Address> {
236 if address.is_zero() {
237 None
238 } else {
239 Some(*address)
240 }
241}
242
243pub const KECCAK_EMPTY_BLOOM: H256 = H256([
245 0xd3, 0x97, 0xb3, 0xb0, 0x43, 0xd8, 0x7f, 0xcd, 0x6f, 0xad, 0x12, 0x91,
246 0xff, 0x0b, 0xfd, 0x16, 0x40, 0x1c, 0x27, 0x48, 0x96, 0xd8, 0xc6, 0x3a,
247 0x92, 0x37, 0x27, 0xf0, 0x77, 0xb8, 0xe0, 0xb5,
248]);
249
250pub fn hexstr_to_h256(hex_str: &str) -> H256 {
251 assert_eq!(hex_str.len(), 64);
252 let mut bytes: [u8; 32] = Default::default();
253
254 for i in 0..32 {
255 bytes[i] = u8::from_str_radix(&hex_str[i * 2..i * 2 + 2], 16).unwrap();
256 }
257
258 H256::from(bytes)
259}
260
261pub mod address_util {
262 use super::Address;
263
264 pub const TYPE_BITS_BUILTIN: u8 = 0x00;
265 pub const TYPE_BITS_CONTRACT: u8 = 0x80;
266 pub const TYPE_BITS_USER_ACCOUNT: u8 = 0x10;
267
268 pub trait AddressUtil: Sized + Ord {
269 fn type_byte(&self) -> &u8;
270
271 fn type_byte_mut(&mut self) -> &mut u8;
272
273 fn is_null_address(&self) -> bool;
274
275 #[inline]
276 fn address_type_bits(&self) -> u8 { self.type_byte() & 0xf0 }
277
278 #[inline]
279 fn set_address_type_bits(&mut self, type_bits: u8) {
280 let type_byte = self.type_byte_mut();
281 *type_byte &= 0x0f;
282 *type_byte |= type_bits;
283 }
284
285 #[cfg(feature = "storage_benchmark_no_account_space_check")]
286 #[inline]
287 fn is_genesis_valid_address(&self) -> bool { true }
288
289 #[cfg(not(feature = "storage_benchmark_no_account_space_check"))]
290 #[inline]
291 fn is_genesis_valid_address(&self) -> bool {
292 self.is_contract_address()
293 || self.is_user_account_address()
294 || self.is_builtin_address()
295 || self.is_null_address()
296 }
297
298 #[inline]
299 fn is_contract_address(&self) -> bool {
300 self.address_type_bits() == TYPE_BITS_CONTRACT
301 }
302
303 #[inline]
304 fn is_user_account_address(&self) -> bool {
305 self.address_type_bits() == TYPE_BITS_USER_ACCOUNT
306 }
307
308 #[inline]
309 fn is_builtin_address(&self) -> bool {
310 self.address_type_bits() == TYPE_BITS_BUILTIN
311 && !self.is_null_address()
312 }
313
314 #[inline]
315 fn set_contract_type_bits(&mut self) {
316 self.set_address_type_bits(TYPE_BITS_CONTRACT);
317 }
318
319 #[inline]
320 fn set_user_account_type_bits(&mut self) {
321 self.set_address_type_bits(TYPE_BITS_USER_ACCOUNT);
322 }
323 }
324
325 impl AddressUtil for Address {
326 #[inline]
327 fn type_byte(&self) -> &u8 { &self.as_fixed_bytes()[0] }
328
329 #[inline]
330 fn type_byte_mut(&mut self) -> &mut u8 {
331 &mut self.as_fixed_bytes_mut()[0]
332 }
333
334 #[inline]
335 fn is_null_address(&self) -> bool { self.is_zero() }
336 }
337
338 impl AddressUtil for &[u8] {
339 #[inline]
340 fn type_byte(&self) -> &u8 { &self[0] }
341
342 #[inline]
343 fn type_byte_mut(&mut self) -> &mut u8 { unreachable!() }
344
345 #[inline]
346 fn is_null_address(&self) -> bool {
347 self.iter().all(|&byte| byte == 0u8)
348 }
349 }
350
351 #[cfg(test)]
352 mod tests {
353 use super::{Address, AddressUtil};
354
355 #[test]
356 fn test_set_type_bits() {
357 let mut address = Address::default();
358
359 address.set_contract_type_bits();
360 assert!(address.is_contract_address());
361 assert!(!address.is_user_account_address());
362
363 address.set_user_account_type_bits();
364 assert!(address.is_user_account_address());
365
366 for types in 0..16 {
367 let type_bits = types << 4;
368 address.set_address_type_bits(type_bits);
369 assert_eq!(address.address_type_bits(), type_bits);
370 }
371 }
372 }
373}