1use crate::hash::sha256;
8use crate::PrimitivesError;
9use serde::{Deserialize, Deserializer, Serialize, Serializer};
10use std::fmt;
11use std::str::FromStr;
12
13pub const HASH_SIZE: usize = 32;
15
16pub const MAX_HASH_STRING_SIZE: usize = HASH_SIZE * 2;
18
19#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, Default)]
24pub struct Hash([u8; HASH_SIZE]);
25
26impl Hash {
27 pub fn new(bytes: [u8; HASH_SIZE]) -> Self {
37 Hash(bytes)
38 }
39
40 pub fn from_bytes(bytes: &[u8]) -> Result<Self, PrimitivesError> {
48 if bytes.len() != HASH_SIZE {
49 return Err(PrimitivesError::InvalidHash(format!(
50 "invalid hash length of {}, want {}",
51 bytes.len(),
52 HASH_SIZE
53 )));
54 }
55 let mut arr = [0u8; HASH_SIZE];
56 arr.copy_from_slice(bytes);
57 Ok(Hash(arr))
58 }
59
60 pub fn from_hex(hex_str: &str) -> Result<Self, PrimitivesError> {
72 if hex_str.is_empty() {
73 return Ok(Hash::default());
74 }
75 if hex_str.len() > MAX_HASH_STRING_SIZE {
76 return Err(PrimitivesError::InvalidHash(format!(
77 "max hash string length is {} bytes",
78 MAX_HASH_STRING_SIZE
79 )));
80 }
81
82 let padded = if !hex_str.len().is_multiple_of(2) {
84 format!("0{}", hex_str)
85 } else {
86 hex_str.to_string()
87 };
88
89 let decoded = hex::decode(&padded)?;
91 let mut reversed_hash = [0u8; HASH_SIZE];
92 let offset = HASH_SIZE - decoded.len();
93 reversed_hash[offset..].copy_from_slice(&decoded);
94
95 let mut dst = [0u8; HASH_SIZE];
97 for i in 0..HASH_SIZE {
98 dst[i] = reversed_hash[HASH_SIZE - 1 - i];
99 }
100
101 Ok(Hash(dst))
102 }
103
104 pub fn clone_bytes(&self) -> Vec<u8> {
109 self.0.to_vec()
110 }
111
112 pub fn set_bytes(&mut self, bytes: &[u8]) -> Result<(), PrimitivesError> {
120 if bytes.len() != HASH_SIZE {
121 return Err(PrimitivesError::InvalidHash(format!(
122 "invalid hash length of {}, want {}",
123 bytes.len(),
124 HASH_SIZE
125 )));
126 }
127 self.0.copy_from_slice(bytes);
128 Ok(())
129 }
130
131 pub fn is_equal(&self, other: Option<&Hash>) -> bool {
141 match other {
142 Some(h) => self.0 == h.0,
143 None => false,
144 }
145 }
146
147 pub fn as_bytes(&self) -> &[u8; HASH_SIZE] {
152 &self.0
153 }
154
155 pub fn size(&self) -> usize {
160 HASH_SIZE
161 }
162}
163
164impl fmt::Display for Hash {
168 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
169 let mut reversed = self.0;
170 reversed.reverse();
171 write!(f, "{}", hex::encode(reversed))
172 }
173}
174
175impl FromStr for Hash {
179 type Err = PrimitivesError;
180
181 fn from_str(s: &str) -> Result<Self, Self::Err> {
182 Hash::from_hex(s)
183 }
184}
185
186impl Serialize for Hash {
188 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
189 serializer.serialize_str(&self.to_string())
190 }
191}
192
193impl<'de> Deserialize<'de> for Hash {
195 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
196 let s = String::deserialize(deserializer)?;
197 Hash::from_hex(&s).map_err(serde::de::Error::custom)
198 }
199}
200
201pub fn hash_h(data: &[u8]) -> Hash {
211 Hash(sha256(data))
212}
213
214pub fn double_hash_h(data: &[u8]) -> Hash {
224 Hash(crate::hash::sha256d(data))
225}
226
227#[cfg(test)]
228mod tests {
229 use super::*;
230
231 const MAIN_NET_GENESIS_HASH: Hash = Hash([
233 0x6f, 0xe2, 0x8c, 0x0a, 0xb6, 0xf1, 0xb3, 0x72, 0xc1, 0xa6, 0xa2, 0x46, 0xae, 0x63, 0xf7,
234 0x4f, 0x93, 0x1e, 0x83, 0x65, 0xe1, 0x5a, 0x08, 0x9c, 0x68, 0xd6, 0x19, 0x00, 0x00, 0x00,
235 0x00, 0x00,
236 ]);
237
238 #[test]
239 fn test_hash_api() {
240 let block_hash_str = "14a0810ac680a3eb3f82edc878cea25ec41d6b790744e5daeef";
242 let block_hash = Hash::from_hex(block_hash_str).unwrap();
243
244 let buf: [u8; 32] = [
246 0x79, 0xa6, 0x1a, 0xdb, 0xc6, 0xe5, 0xa2, 0xe1, 0x39, 0xd2, 0x71, 0x3a, 0x54, 0x6e,
247 0xc7, 0xc8, 0x75, 0x63, 0x2e, 0x75, 0xf1, 0xdf, 0x9c, 0x3f, 0xa6, 0x01, 0x00, 0x00,
248 0x00, 0x00, 0x00, 0x00,
249 ];
250
251 let hash = Hash::from_bytes(&buf).unwrap();
252
253 assert_eq!(hash.size(), HASH_SIZE);
255
256 assert_eq!(hash.as_bytes(), &buf);
258
259 assert!(!hash.is_equal(Some(&block_hash)));
261
262 let mut hash2 = hash;
264 hash2.set_bytes(&block_hash.clone_bytes()).unwrap();
265 assert!(hash2.is_equal(Some(&block_hash)));
266
267 assert!(!hash.is_equal(None));
269
270 let mut h = Hash::default();
272 assert!(h.set_bytes(&[0x00]).is_err());
273
274 let invalid = vec![0u8; HASH_SIZE + 1];
276 assert!(Hash::from_bytes(&invalid).is_err());
277 }
278
279 #[test]
280 fn test_hash_string() {
281 let hash = Hash::new([
283 0x06, 0xe5, 0x33, 0xfd, 0x1a, 0xda, 0x86, 0x39, 0x1f, 0x3f, 0x6c, 0x34, 0x32, 0x04,
284 0xb0, 0xd2, 0x78, 0xd4, 0xaa, 0xec, 0x1c, 0x0b, 0x20, 0xaa, 0x27, 0xba, 0x03, 0x00,
285 0x00, 0x00, 0x00, 0x00,
286 ]);
287 assert_eq!(
288 hash.to_string(),
289 "000000000003ba27aa200b1cecaad478d2b00432346c3f1f3986da1afd33e506"
290 );
291 }
292
293 #[test]
294 fn test_new_hash_from_hex() {
295 let result =
297 Hash::from_hex("000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f")
298 .unwrap();
299 assert_eq!(result, MAIN_NET_GENESIS_HASH);
300
301 let result =
303 Hash::from_hex("19d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f").unwrap();
304 assert_eq!(result, MAIN_NET_GENESIS_HASH);
305
306 let result = Hash::from_hex("").unwrap();
308 assert_eq!(result, Hash::default());
309
310 let result = Hash::from_hex("1").unwrap();
312 let expected = Hash::new([
313 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
314 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
315 0x00, 0x00, 0x00, 0x00,
316 ]);
317 assert_eq!(result, expected);
318
319 let result = Hash::from_hex("3264bc2ac36a60840790ba1d475d01367e7c723da941069e9dc").unwrap();
321 let expected = Hash::new([
322 0xdc, 0xe9, 0x69, 0x10, 0x94, 0xda, 0x23, 0xc7, 0xe7, 0x67, 0x13, 0xd0, 0x75, 0xd4,
323 0xa1, 0x0b, 0x79, 0x40, 0x08, 0xa6, 0x36, 0xac, 0xc2, 0x4b, 0x26, 0x03, 0x00, 0x00,
324 0x00, 0x00, 0x00, 0x00,
325 ]);
326 assert_eq!(result, expected);
327
328 let result =
330 Hash::from_hex("01234567890123456789012345678901234567890123456789012345678912345");
331 assert!(result.is_err());
332
333 let result = Hash::from_hex("abcdefg");
335 assert!(result.is_err());
336 }
337
338 #[test]
339 fn test_marshalling() {
340 #[derive(Serialize, Deserialize)]
342 struct TestData {
343 hash: Hash,
344 }
345
346 let data = TestData {
348 hash: hash_h(b"hello"),
349 };
350 assert_eq!(
351 data.hash.to_string(),
352 "24988b93623304735e42a71f5c1e161b9ee2b9c52a3be8260ea3b05fba4df22c"
353 );
354
355 let json = serde_json::to_string(&data).unwrap();
357 assert_eq!(
358 json,
359 r#"{"hash":"24988b93623304735e42a71f5c1e161b9ee2b9c52a3be8260ea3b05fba4df22c"}"#
360 );
361
362 let data2: TestData = serde_json::from_str(&json).unwrap();
364 assert_eq!(
365 data2.hash.to_string(),
366 "24988b93623304735e42a71f5c1e161b9ee2b9c52a3be8260ea3b05fba4df22c"
367 );
368 }
369}