1use std::fmt;
8use std::str::FromStr;
9use serde::{Serialize, Deserialize, Serializer, Deserializer};
10use crate::hash::sha256;
11use crate::PrimitivesError;
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(
50 format!("invalid hash length of {}, want {}", bytes.len(), HASH_SIZE)
51 ));
52 }
53 let mut arr = [0u8; HASH_SIZE];
54 arr.copy_from_slice(bytes);
55 Ok(Hash(arr))
56 }
57
58 pub fn from_hex(hex_str: &str) -> Result<Self, PrimitivesError> {
70 if hex_str.is_empty() {
71 return Ok(Hash::default());
72 }
73 if hex_str.len() > MAX_HASH_STRING_SIZE {
74 return Err(PrimitivesError::InvalidHash(
75 format!("max hash string length is {} bytes", MAX_HASH_STRING_SIZE)
76 ));
77 }
78
79 let padded = if !hex_str.len().is_multiple_of(2) {
81 format!("0{}", hex_str)
82 } else {
83 hex_str.to_string()
84 };
85
86 let decoded = hex::decode(&padded)?;
88 let mut reversed_hash = [0u8; HASH_SIZE];
89 let offset = HASH_SIZE - decoded.len();
90 reversed_hash[offset..].copy_from_slice(&decoded);
91
92 let mut dst = [0u8; HASH_SIZE];
94 for i in 0..HASH_SIZE {
95 dst[i] = reversed_hash[HASH_SIZE - 1 - i];
96 }
97
98 Ok(Hash(dst))
99 }
100
101 pub fn clone_bytes(&self) -> Vec<u8> {
106 self.0.to_vec()
107 }
108
109 pub fn set_bytes(&mut self, bytes: &[u8]) -> Result<(), PrimitivesError> {
117 if bytes.len() != HASH_SIZE {
118 return Err(PrimitivesError::InvalidHash(
119 format!("invalid hash length of {}, want {}", bytes.len(), HASH_SIZE)
120 ));
121 }
122 self.0.copy_from_slice(bytes);
123 Ok(())
124 }
125
126 pub fn is_equal(&self, other: Option<&Hash>) -> bool {
136 match other {
137 Some(h) => self.0 == h.0,
138 None => false,
139 }
140 }
141
142 pub fn as_bytes(&self) -> &[u8; HASH_SIZE] {
147 &self.0
148 }
149
150 pub fn size(&self) -> usize {
155 HASH_SIZE
156 }
157}
158
159impl fmt::Display for Hash {
163 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
164 let mut reversed = self.0;
165 reversed.reverse();
166 write!(f, "{}", hex::encode(reversed))
167 }
168}
169
170impl FromStr for Hash {
174 type Err = PrimitivesError;
175
176 fn from_str(s: &str) -> Result<Self, Self::Err> {
177 Hash::from_hex(s)
178 }
179}
180
181impl Serialize for Hash {
183 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
184 serializer.serialize_str(&self.to_string())
185 }
186}
187
188impl<'de> Deserialize<'de> for Hash {
190 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
191 let s = String::deserialize(deserializer)?;
192 Hash::from_hex(&s).map_err(serde::de::Error::custom)
193 }
194}
195
196pub fn hash_h(data: &[u8]) -> Hash {
206 Hash(sha256(data))
207}
208
209pub fn double_hash_h(data: &[u8]) -> Hash {
219 Hash(crate::hash::sha256d(data))
220}
221
222#[cfg(test)]
223mod tests {
224 use super::*;
225
226 const MAIN_NET_GENESIS_HASH: Hash = Hash([
228 0x6f, 0xe2, 0x8c, 0x0a, 0xb6, 0xf1, 0xb3, 0x72,
229 0xc1, 0xa6, 0xa2, 0x46, 0xae, 0x63, 0xf7, 0x4f,
230 0x93, 0x1e, 0x83, 0x65, 0xe1, 0x5a, 0x08, 0x9c,
231 0x68, 0xd6, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00,
232 ]);
233
234 #[test]
235 fn test_hash_api() {
236 let block_hash_str = "14a0810ac680a3eb3f82edc878cea25ec41d6b790744e5daeef";
238 let block_hash = Hash::from_hex(block_hash_str).unwrap();
239
240 let buf: [u8; 32] = [
242 0x79, 0xa6, 0x1a, 0xdb, 0xc6, 0xe5, 0xa2, 0xe1,
243 0x39, 0xd2, 0x71, 0x3a, 0x54, 0x6e, 0xc7, 0xc8,
244 0x75, 0x63, 0x2e, 0x75, 0xf1, 0xdf, 0x9c, 0x3f,
245 0xa6, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
246 ];
247
248 let hash = Hash::from_bytes(&buf).unwrap();
249
250 assert_eq!(hash.size(), HASH_SIZE);
252
253 assert_eq!(hash.as_bytes(), &buf);
255
256 assert!(!hash.is_equal(Some(&block_hash)));
258
259 let mut hash2 = hash;
261 hash2.set_bytes(&block_hash.clone_bytes()).unwrap();
262 assert!(hash2.is_equal(Some(&block_hash)));
263
264 assert!(!hash.is_equal(None));
266
267 let mut h = Hash::default();
269 assert!(h.set_bytes(&[0x00]).is_err());
270
271 let invalid = vec![0u8; HASH_SIZE + 1];
273 assert!(Hash::from_bytes(&invalid).is_err());
274 }
275
276 #[test]
277 fn test_hash_string() {
278 let hash = Hash::new([
280 0x06, 0xe5, 0x33, 0xfd, 0x1a, 0xda, 0x86, 0x39,
281 0x1f, 0x3f, 0x6c, 0x34, 0x32, 0x04, 0xb0, 0xd2,
282 0x78, 0xd4, 0xaa, 0xec, 0x1c, 0x0b, 0x20, 0xaa,
283 0x27, 0xba, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
284 ]);
285 assert_eq!(
286 hash.to_string(),
287 "000000000003ba27aa200b1cecaad478d2b00432346c3f1f3986da1afd33e506"
288 );
289 }
290
291 #[test]
292 fn test_new_hash_from_hex() {
293 let result = Hash::from_hex(
295 "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f"
296 ).unwrap();
297 assert_eq!(result, MAIN_NET_GENESIS_HASH);
298
299 let result = Hash::from_hex(
301 "19d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f"
302 ).unwrap();
303 assert_eq!(result, MAIN_NET_GENESIS_HASH);
304
305 let result = Hash::from_hex("").unwrap();
307 assert_eq!(result, Hash::default());
308
309 let result = Hash::from_hex("1").unwrap();
311 let expected = Hash::new([
312 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
313 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
314 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
315 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
316 ]);
317 assert_eq!(result, expected);
318
319 let result = Hash::from_hex(
321 "3264bc2ac36a60840790ba1d475d01367e7c723da941069e9dc"
322 ).unwrap();
323 let expected = Hash::new([
324 0xdc, 0xe9, 0x69, 0x10, 0x94, 0xda, 0x23, 0xc7,
325 0xe7, 0x67, 0x13, 0xd0, 0x75, 0xd4, 0xa1, 0x0b,
326 0x79, 0x40, 0x08, 0xa6, 0x36, 0xac, 0xc2, 0x4b,
327 0x26, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
328 ]);
329 assert_eq!(result, expected);
330
331 let result = Hash::from_hex(
333 "01234567890123456789012345678901234567890123456789012345678912345"
334 );
335 assert!(result.is_err());
336
337 let result = Hash::from_hex("abcdefg");
339 assert!(result.is_err());
340 }
341
342 #[test]
343 fn test_marshalling() {
344 #[derive(Serialize, Deserialize)]
346 struct TestData {
347 hash: Hash,
348 }
349
350 let data = TestData {
352 hash: hash_h(b"hello"),
353 };
354 assert_eq!(
355 data.hash.to_string(),
356 "24988b93623304735e42a71f5c1e161b9ee2b9c52a3be8260ea3b05fba4df22c"
357 );
358
359 let json = serde_json::to_string(&data).unwrap();
361 assert_eq!(
362 json,
363 r#"{"hash":"24988b93623304735e42a71f5c1e161b9ee2b9c52a3be8260ea3b05fba4df22c"}"#
364 );
365
366 let data2: TestData = serde_json::from_str(&json).unwrap();
368 assert_eq!(
369 data2.hash.to_string(),
370 "24988b93623304735e42a71f5c1e161b9ee2b9c52a3be8260ea3b05fba4df22c"
371 );
372 }
373}