muta_protocol/types/
primitive.rs

1use std::fmt;
2
3use bytes::{Bytes, BytesMut};
4use hasher::{Hasher, HasherKeccak};
5use lazy_static::lazy_static;
6use num_bigint::BigUint;
7use serde::de;
8use serde::{Deserialize, Serialize};
9
10use crate::types::TypesError;
11use crate::ProtocolResult;
12
13pub const METADATA_KEY: &str = "metadata";
14
15lazy_static! {
16    static ref HASHER_INST: HasherKeccak = HasherKeccak::new();
17}
18
19/// The epoch ID of the genesis epoch.
20pub const GENESIS_EPOCH_ID: u64 = 0;
21
22/// Hash length
23const HASH_LEN: usize = 32;
24
25#[derive(Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
26pub struct Hash([u8; HASH_LEN]);
27/// Balance
28pub type Balance = BigUint;
29/// Merkel root hash
30pub type MerkleRoot = Hash;
31/// Json string
32pub type JsonString = String;
33
34impl Serialize for Hash {
35    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
36    where
37        S: serde::ser::Serializer,
38    {
39        serializer.serialize_str(&self.as_hex())
40    }
41}
42
43struct HashVisitor;
44
45impl<'de> de::Visitor<'de> for HashVisitor {
46    type Value = Hash;
47
48    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
49        formatter.write_str("Expect a hex string")
50    }
51
52    fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
53    where
54        E: de::Error,
55    {
56        Hash::from_hex(&v).map_err(|e| de::Error::custom(e.to_string()))
57    }
58
59    fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
60    where
61        E: de::Error,
62    {
63        Hash::from_hex(&v).map_err(|e| de::Error::custom(e.to_string()))
64    }
65}
66
67impl<'de> Deserialize<'de> for Hash {
68    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
69    where
70        D: de::Deserializer<'de>,
71    {
72        deserializer.deserialize_string(HashVisitor)
73    }
74}
75
76impl Hash {
77    /// Enter an array of bytes to get a 32-bit hash.
78    /// Note: sha3 is used for the time being and may be replaced with other
79    /// hashing algorithms later.
80    pub fn digest(bytes: Bytes) -> Self {
81        let mut out = [0u8; HASH_LEN];
82        out.copy_from_slice(&HASHER_INST.digest(&bytes));
83
84        Self(out)
85    }
86
87    pub fn from_empty() -> Self {
88        let mut out = [0u8; HASH_LEN];
89        out.copy_from_slice(&HASHER_INST.digest(&rlp::NULL_RLP));
90
91        Self(out)
92    }
93
94    /// Converts the byte array to a Hash type.
95    /// Note: if you want to compute the hash value of the byte array, you
96    /// should call `fn digest`.
97    pub fn from_bytes(bytes: Bytes) -> ProtocolResult<Self> {
98        ensure_len(bytes.len(), HASH_LEN)?;
99
100        let mut out = [0u8; HASH_LEN];
101        out.copy_from_slice(&bytes);
102        Ok(Self(out))
103    }
104
105    pub fn from_hex(s: &str) -> ProtocolResult<Self> {
106        let s = clean_0x(s);
107        let bytes = hex::decode(s).map_err(TypesError::from)?;
108
109        let bytes = Bytes::from(bytes);
110        Self::from_bytes(bytes)
111    }
112
113    pub fn as_bytes(&self) -> Bytes {
114        BytesMut::from(self.0.as_ref()).freeze()
115    }
116
117    pub fn as_hex(&self) -> String {
118        hex::encode(self.0)
119    }
120}
121
122impl Default for Hash {
123    fn default() -> Self {
124        Hash::from_empty()
125    }
126}
127
128impl fmt::Debug for Hash {
129    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
130        write!(f, "{}", self.as_hex())
131    }
132}
133
134/// Address length.
135const ADDRESS_LEN: usize = 20;
136
137#[derive(Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
138pub struct Address([u8; ADDRESS_LEN]);
139
140impl Serialize for Address {
141    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
142    where
143        S: serde::ser::Serializer,
144    {
145        serializer.serialize_str(&self.as_hex())
146    }
147}
148
149struct AddressVisitor;
150
151impl<'de> de::Visitor<'de> for AddressVisitor {
152    type Value = Address;
153
154    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
155        formatter.write_str("Expect a hex string")
156    }
157
158    fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
159    where
160        E: de::Error,
161    {
162        Address::from_hex(&v).map_err(|e| de::Error::custom(e.to_string()))
163    }
164
165    fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
166    where
167        E: de::Error,
168    {
169        Address::from_hex(&v).map_err(|e| de::Error::custom(e.to_string()))
170    }
171}
172
173impl<'de> Deserialize<'de> for Address {
174    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
175    where
176        D: de::Deserializer<'de>,
177    {
178        deserializer.deserialize_string(AddressVisitor)
179    }
180}
181
182impl Address {
183    pub fn from_pubkey_bytes(bytes: Bytes) -> ProtocolResult<Self> {
184        let hash = Hash::digest(bytes);
185
186        Self::from_hash(hash)
187    }
188
189    pub fn from_hash(hash: Hash) -> ProtocolResult<Self> {
190        let mut hash_val = hash.as_bytes();
191        hash_val.truncate(20);
192
193        Self::from_bytes(hash_val)
194    }
195
196    pub fn from_bytes(bytes: Bytes) -> ProtocolResult<Self> {
197        ensure_len(bytes.len(), ADDRESS_LEN)?;
198
199        let mut out = [0u8; ADDRESS_LEN];
200        out.copy_from_slice(&bytes);
201        Ok(Self(out))
202    }
203
204    pub fn from_hex(s: &str) -> ProtocolResult<Self> {
205        let s = clean_0x(s);
206        let bytes = hex::decode(s).map_err(TypesError::from)?;
207
208        let bytes = Bytes::from(bytes);
209        Self::from_bytes(bytes)
210    }
211
212    pub fn as_bytes(&self) -> Bytes {
213        BytesMut::from(self.0.as_ref()).freeze()
214    }
215
216    pub fn as_hex(&self) -> String {
217        hex::encode(self.0)
218    }
219}
220
221impl fmt::Debug for Address {
222    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
223        write!(f, "{}", self.as_hex())
224    }
225}
226
227#[derive(Deserialize, Serialize, Clone, Debug)]
228pub struct Metadata {
229    pub chain_id:           Hash,
230    pub verifier_list:      Vec<Address>,
231    pub consensus_interval: u64,
232    pub cycles_limit:       u64,
233    pub cycles_price:       u64,
234}
235
236fn clean_0x(s: &str) -> &str {
237    if s.starts_with("0x") {
238        &s[2..]
239    } else {
240        s
241    }
242}
243
244fn ensure_len(real: usize, expect: usize) -> ProtocolResult<()> {
245    if real != expect {
246        Err(TypesError::LengthMismatch { expect, real }.into())
247    } else {
248        Ok(())
249    }
250}
251
252#[cfg(test)]
253mod tests {
254    use bytes::Bytes;
255
256    use super::{Address, Hash};
257
258    #[test]
259    fn test_hash() {
260        let hash = Hash::digest(Bytes::from("xxxxxx"));
261
262        let bytes = hash.as_bytes();
263        Hash::from_bytes(bytes).unwrap();
264    }
265
266    #[test]
267    fn test_from_pubkey_bytes() {
268        let pubkey = "031313016e9670deb49779c1b0c646d6a25a545712658f9781995f623bcd0d0b3d";
269        let expect_addr = "c38f8210896e11a75e1a1f13805d39088d157d7f";
270
271        let pubkey_bytes = Bytes::from(hex::decode(pubkey).unwrap());
272        let addr = Address::from_pubkey_bytes(pubkey_bytes).unwrap();
273
274        assert_eq!(addr.as_hex(), expect_addr);
275    }
276
277    #[test]
278    fn test_address() {
279        let add_str = "CAB8EEA4799C21379C20EF5BAA2CC8AF1BEC475B";
280        let bytes = Bytes::from(hex::decode(add_str).unwrap());
281
282        let address = Address::from_bytes(bytes).unwrap();
283        assert_eq!(add_str, address.as_hex().to_uppercase());
284    }
285}