ethereum_types/
hash.rs
1use crate::{U128, U256, U512, U64};
10use fixed_hash::*;
11#[cfg(feature = "codec")]
12use impl_codec::impl_fixed_hash_codec;
13#[cfg(feature = "rlp")]
14use impl_rlp::impl_fixed_hash_rlp;
15#[cfg(feature = "serialize")]
16use impl_serde::impl_fixed_hash_serde;
17
18pub trait BigEndianHash {
19 type Uint;
20
21 fn from_uint(val: &Self::Uint) -> Self;
22 fn into_uint(&self) -> Self::Uint;
23}
24
25construct_fixed_hash! { pub struct H32(4); }
26#[cfg(feature = "rlp")]
27impl_fixed_hash_rlp!(H32, 4);
28#[cfg(feature = "serialize")]
29impl_fixed_hash_serde!(H32, 4);
30#[cfg(feature = "codec")]
31impl_fixed_hash_codec!(H32, 4);
32
33construct_fixed_hash! {
34 #[cfg_attr(feature = "codec", derive(scale_info::TypeInfo))]
35 pub struct H64(8);
36}
37#[cfg(feature = "rlp")]
38impl_fixed_hash_rlp!(H64, 8);
39#[cfg(feature = "serialize")]
40impl_fixed_hash_serde!(H64, 8);
41#[cfg(feature = "codec")]
42impl_fixed_hash_codec!(H64, 8);
43
44pub use primitive_types::{H128, H160, H256};
45
46construct_fixed_hash! {
47 #[cfg_attr(feature = "codec", derive(scale_info::TypeInfo))]
48 pub struct H264(33);
49}
50#[cfg(feature = "rlp")]
51impl_fixed_hash_rlp!(H264, 33);
52#[cfg(feature = "serialize")]
53impl_fixed_hash_serde!(H264, 33);
54#[cfg(feature = "codec")]
55impl_fixed_hash_codec!(H264, 33);
56
57pub use primitive_types::H512;
58
59construct_fixed_hash! {
60 #[cfg_attr(feature = "codec", derive(scale_info::TypeInfo))]
61 pub struct H520(65);
62}
63#[cfg(feature = "rlp")]
64impl_fixed_hash_rlp!(H520, 65);
65#[cfg(feature = "serialize")]
66impl_fixed_hash_serde!(H520, 65);
67#[cfg(feature = "codec")]
68impl_fixed_hash_codec!(H520, 65);
69
70macro_rules! impl_uint_conversions {
71 ($hash: ident, $uint: ident) => {
72 impl BigEndianHash for $hash {
73 type Uint = $uint;
74
75 fn from_uint(value: &$uint) -> Self {
76 let mut ret = $hash::zero();
77 value.to_big_endian(ret.as_bytes_mut());
78 ret
79 }
80
81 fn into_uint(&self) -> $uint {
82 $uint::from(self.as_ref() as &[u8])
83 }
84 }
85 };
86}
87
88impl_uint_conversions!(H64, U64);
89impl_uint_conversions!(H128, U128);
90impl_uint_conversions!(H256, U256);
91impl_uint_conversions!(H512, U512);
92
93#[cfg(test)]
94mod tests {
95 use super::{H160, H256};
96 use serde_json as ser;
97
98 #[test]
99 fn test_serialize_h160() {
100 let tests = vec![
101 (H160::from_low_u64_be(0), "0x0000000000000000000000000000000000000000"),
102 (H160::from_low_u64_be(2), "0x0000000000000000000000000000000000000002"),
103 (H160::from_low_u64_be(15), "0x000000000000000000000000000000000000000f"),
104 (H160::from_low_u64_be(16), "0x0000000000000000000000000000000000000010"),
105 (H160::from_low_u64_be(1_000), "0x00000000000000000000000000000000000003e8"),
106 (H160::from_low_u64_be(100_000), "0x00000000000000000000000000000000000186a0"),
107 (H160::from_low_u64_be(u64::max_value()), "0x000000000000000000000000ffffffffffffffff"),
108 ];
109
110 for (number, expected) in tests {
111 assert_eq!(format!("{:?}", expected), ser::to_string_pretty(&number).unwrap());
112 assert_eq!(number, ser::from_str(&format!("{:?}", expected)).unwrap());
113 }
114 }
115
116 #[test]
117 fn test_serialize_h256() {
118 let tests = vec![
119 (H256::from_low_u64_be(0), "0x0000000000000000000000000000000000000000000000000000000000000000"),
120 (H256::from_low_u64_be(2), "0x0000000000000000000000000000000000000000000000000000000000000002"),
121 (H256::from_low_u64_be(15), "0x000000000000000000000000000000000000000000000000000000000000000f"),
122 (H256::from_low_u64_be(16), "0x0000000000000000000000000000000000000000000000000000000000000010"),
123 (H256::from_low_u64_be(1_000), "0x00000000000000000000000000000000000000000000000000000000000003e8"),
124 (H256::from_low_u64_be(100_000), "0x00000000000000000000000000000000000000000000000000000000000186a0"),
125 (
126 H256::from_low_u64_be(u64::max_value()),
127 "0x000000000000000000000000000000000000000000000000ffffffffffffffff",
128 ),
129 ];
130
131 for (number, expected) in tests {
132 assert_eq!(format!("{:?}", expected), ser::to_string_pretty(&number).unwrap());
133 assert_eq!(number, ser::from_str(&format!("{:?}", expected)).unwrap());
134 }
135 }
136
137 #[test]
138 fn test_parse_0x() {
139 assert!("0x0000000000000000000000000000000000000000000000000000000000000000"
140 .parse::<H256>()
141 .is_ok())
142 }
143
144 #[test]
145 fn test_serialize_invalid() {
146 assert!(ser::from_str::<H256>("\"0x000000000000000000000000000000000000000000000000000000000000000\"")
147 .unwrap_err()
148 .is_data());
149 assert!(ser::from_str::<H256>("\"0x000000000000000000000000000000000000000000000000000000000000000g\"")
150 .unwrap_err()
151 .is_data());
152 assert!(ser::from_str::<H256>("\"0x00000000000000000000000000000000000000000000000000000000000000000\"")
153 .unwrap_err()
154 .is_data());
155 assert!(ser::from_str::<H256>("\"\"").unwrap_err().is_data());
156 assert!(ser::from_str::<H256>("\"0\"").unwrap_err().is_data());
157 assert!(ser::from_str::<H256>("\"10\"").unwrap_err().is_data());
158 }
159}