mazze_types/
lib.rs

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
243/// The KECCAK hash of an empty bloom filter (0x00 * 256)
244pub 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}