Unverified Commit 46b28234 authored by Hero Bird's avatar Hero Bird Committed by GitHub
Browse files

Refactor and improve hash module (#372)

* [core] refactor and improve hash module

* [core] rename hash_raw[_using] -> hash_bytes[_using]

* [examples] fix runtime-storage contract example
parent e1fdb557
Pipeline #85457 passed with stages
in 6 minutes and 34 seconds
......@@ -18,6 +18,14 @@ use super::{
};
use core::marker::PhantomData;
/// Type indicating that no accumulator is in use.
///
/// # Note
///
/// This means that a hash builder with this type as accumulator cannot
/// build hashes for instances based on their SCALE encoding.
pub enum NoAccumulator {}
/// Generic hash builder to construct hashes given a builder strategy.
///
/// - `H` defines the crytographic hash to be conducted.
......@@ -34,7 +42,7 @@ use core::marker::PhantomData;
/// - [`Keccak256`](`crate::hash::Keccak256`)
/// - [`Blake2x256`](`crate::hash::Blake2x256`)
/// - [`Blake2x128`](`crate::hash::Blake2x128`)
pub struct HashBuilder<H, S> {
pub struct HashBuilder<H, S = NoAccumulator> {
/// The strategy used to build up the hash.
strategy: S,
/// The underlying cryptographic hasher.
......@@ -62,6 +70,41 @@ where
}
}
impl<H, S> HashBuilder<H, S>
where
H: Hasher,
{
/// Conducts the hash for the given bytes.
///
/// Puts the resulting hash into the provided output buffer.
///
/// # Note
///
/// Prefer the simpler [`hash_bytes`](`HashBuilder::hash_bytes`)
/// if you do _not_ need full control over the `output` buffer.
pub fn hash_bytes_using(input: &[u8], output: &mut <H as Hasher>::Output)
where
H: Hasher,
{
<H as Hasher>::finalize_immediate(input, output)
}
/// Returns the hash for the given bytes.
///
/// # Note
///
/// Use [`hash_bytes_using`](`HashBuilder::hash_bytes_using`)
/// if you need full control over the `output` buffer.
pub fn hash_bytes(input: &[u8]) -> <H as Hasher>::Output
where
H: Hasher,
{
let mut output = <<H as Hasher>::Output as Default>::default();
Self::hash_bytes_using(input, &mut output);
output
}
}
pub trait Finalize<H>
where
H: Hasher,
......@@ -88,39 +131,9 @@ where
impl<H, S> HashBuilder<H, S>
where
Self: Finalize<H> + scale::Output,
H: Hasher,
S: Accumulator,
{
/// Conducts the hash for the given bytes.
///
/// Puts the resulting hash into the provided output buffer.
///
/// # Note
///
/// Prefer the simpler [`hash_raw`](`HashBuilder::hash_raw`)
/// if you do _not_ need full control over the `output` buffer.
pub fn hash_raw_using(&mut self, input: &[u8], output: &mut <H as Hasher>::Output)
where
H: Hasher,
{
<Self as scale::Output>::write(self, input);
self.finalize_using(output)
}
/// Returns the hash for the given bytes.
///
/// # Note
///
/// Use [`hash_raw_using`](`HashBuilder::hash_raw_using`)
/// if you need full control over the `output` buffer.
pub fn hash_raw(&mut self, input: &[u8]) -> <H as Hasher>::Output
where
H: Hasher,
{
<Self as scale::Output>::write(self, input);
self.finalize()
}
/// Conducts the hash for the encoded input.
///
/// Puts the resulting hash into the provided output buffer.
......
......@@ -23,14 +23,17 @@ pub use self::{
Accumulator,
Wrap,
},
builder::HashBuilder,
builder::{
HashBuilder,
NoAccumulator,
},
};
/// SHA2 256-bit hash builder.
pub type Sha2x256<S> = HashBuilder<hasher::Sha2x256Hasher, S>;
pub type Sha2x256<S = NoAccumulator> = HashBuilder<hasher::Sha2x256Hasher, S>;
/// KECCAK 256-bit hash builder.
pub type Keccak256<S> = HashBuilder<hasher::Keccak256Hasher, S>;
pub type Keccak256<S = NoAccumulator> = HashBuilder<hasher::Keccak256Hasher, S>;
/// BLAKE2 256-bit hash builder.
pub type Blake2x256<S> = HashBuilder<hasher::Blake2x256Hasher, S>;
pub type Blake2x256<S = NoAccumulator> = HashBuilder<hasher::Blake2x256Hasher, S>;
/// BLAKE2 128-bit hash builder.
pub type Blake2x128<S> = HashBuilder<hasher::Blake2x128Hasher, S>;
pub type Blake2x128<S = NoAccumulator> = HashBuilder<hasher::Blake2x128Hasher, S>;
......@@ -25,7 +25,6 @@ mod runtime {
use ink_prelude::{
format,
vec,
vec::Vec,
};
use scale::{
Decode,
......@@ -83,10 +82,8 @@ mod runtime {
185, 157, 136, 14, 198, 129, 121, 156, 12, 243, 14, 136, 134, 55, 29, 169,
];
let encoded_account = &account.encode();
let mut blake2_128 = Blake2x128::from(Vec::new());
let hashed_account = blake2_128.hash_raw(&encoded_account);
let encoded_account = account.encode();
let hashed_account = <Blake2x128>::hash_bytes(&encoded_account);
// The hasher is `Blake2_128Concat` which appends the unhashed account to the hashed account
key.extend_from_slice(&hashed_account);
......@@ -146,8 +143,7 @@ mod runtime {
185, 157, 136, 14, 198, 129, 121, 156, 12, 243, 14, 136, 134, 55, 29, 169,
];
let mut blake2_128 = Blake2x128::from(Vec::new());
let hashed_account = blake2_128.hash_raw(&encoded_account);
let hashed_account = <Blake2x128>::hash_bytes(&encoded_account);
key.extend_from_slice(&hashed_account);
key.extend_from_slice(&encoded_account);
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment