diff --git a/accounts-db/src/accounts_hash.rs b/accounts-db/src/accounts_hash.rs index d6bfd4947855fc..4dfe32c316a096 100644 --- a/accounts-db/src/accounts_hash.rs +++ b/accounts-db/src/accounts_hash.rs @@ -1311,6 +1311,26 @@ impl AccountLTHash { self.0[i] = self.0[i].wrapping_sub(other.0[i]); } } + + pub fn finalize(&self) -> AccountHash { + let mut hasher = blake3::Hasher::new(); + hasher.update(self.as_ref()); + + AccountHash(Hash::new_from_array(hasher.finalize().into())) + } +} + +impl AsRef<[u8]> for AccountLTHash { + fn as_ref(&self) -> &[u8] { + let ptr = unsafe { slice::from_raw_parts(self.0.as_ptr() as *mut u8, LT_HASH_BYTES) }; + ptr + } +} + +impl AsRef<[u16]> for AccountLTHash { + fn as_ref(&self) -> &[u16] { + &self.0[..] + } } /// Hash of accounts @@ -2642,7 +2662,7 @@ mod tests { 0x9924, ]; let lt_hash_hello = get_lt_hash("hello".as_bytes()); - assert_eq!(lt_hash_hello.to_u16(), LTHASH_HELLO); + assert_eq!(AsRef::<[u16]>::as_ref(<_hash_hello), <HASH_HELLO); // lt hash for "world!" const LTHASH_WORLD: [u16; 1024] = [ @@ -2742,7 +2762,7 @@ mod tests { 0x171f, ]; let lt_hash_world = get_lt_hash("world!".as_bytes()); - assert_eq!(lt_hash_world.to_u16(), LTHASH_WORLD); + assert_eq!(AsRef::<[u16]>::as_ref(<_hash_world), <HASH_WORLD); // add "hello" and "world!" let mut expected_sum = [0_u16; LT_HASH_ELEMENT]; @@ -2765,4 +2785,18 @@ mod tests { assert_eq!(lt_hash.to_u16(), LTHASH_HELLO); } + + #[test] + fn test_lt_hash_finalize() { + let get_lt_hash = |input: &[u8]| -> AccountLTHash { + let mut hasher = blake3::Hasher::new(); + hasher.update(input); + AccountLTHash::new_from_reader(hasher.finalize_xof()) + }; + + let lt_hash_hello = get_lt_hash("hello".as_bytes()); + let final_hash = lt_hash_hello.finalize(); + let expected = Hash::from_str("6MmGXJNfa8JKF5XhtHuKEhnLmr38vcyqBCwEXCCFnRVN").unwrap(); + assert_eq!(final_hash.0, expected); + } }