mirror of
https://github.com/mimblewimble/grin.git
synced 2025-01-20 19:11:08 +03:00
core: move Hash into its own module
This commit is contained in:
parent
7e2b271865
commit
88b07791fa
5 changed files with 102 additions and 66 deletions
83
core/src/core/hash.rs
Normal file
83
core/src/core/hash.rs
Normal file
|
@ -0,0 +1,83 @@
|
|||
// Copyright 2016 The Developers
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//! Hash Function
|
||||
//!
|
||||
//! Primary hash function used in the protocol
|
||||
//!
|
||||
|
||||
use std::fmt;
|
||||
|
||||
use tiny_keccak::Keccak;
|
||||
|
||||
/// A hash to uniquely (or close enough) identify one of the main blockchain
|
||||
/// constructs. Used pervasively for blocks, transactions and ouputs.
|
||||
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||
pub struct Hash(pub [u8; 32]);
|
||||
|
||||
impl fmt::Display for Hash {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
for i in self.0[..].iter().cloned() {
|
||||
try!(write!(f, "{:02x}", i));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl Hash {
|
||||
/// Creates a new hash from a vector
|
||||
pub fn from_vec(v: Vec<u8>) -> Hash {
|
||||
let mut a = [0; 32];
|
||||
for i in 0..a.len() {
|
||||
a[i] = v[i];
|
||||
}
|
||||
Hash(a)
|
||||
}
|
||||
/// Converts the hash to a byte vector
|
||||
pub fn to_vec(&self) -> Vec<u8> {
|
||||
self.0.to_vec()
|
||||
}
|
||||
/// Converts the hash to a byte slice
|
||||
pub fn to_slice(&self) -> &[u8] {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
pub const ZERO_HASH: Hash = Hash([0; 32]);
|
||||
|
||||
/// A trait for types that get their hash (double SHA256) from their byte
|
||||
/// serialzation.
|
||||
pub trait Hashed {
|
||||
fn hash(&self) -> Hash {
|
||||
let data = self.bytes();
|
||||
Hash(sha3(data))
|
||||
}
|
||||
|
||||
fn bytes(&self) -> Vec<u8>;
|
||||
}
|
||||
|
||||
fn sha3(data: Vec<u8>) -> [u8; 32] {
|
||||
let mut sha3 = Keccak::new_sha3_256();
|
||||
let mut buf = [0; 32];
|
||||
sha3.update(&data);
|
||||
sha3.finalize(&mut buf);
|
||||
buf
|
||||
}
|
||||
|
||||
impl Hashed for [u8] {
|
||||
fn bytes(&self) -> Vec<u8> {
|
||||
self.to_owned()
|
||||
}
|
||||
}
|
||||
|
|
@ -14,9 +14,12 @@
|
|||
|
||||
//! Core types
|
||||
|
||||
pub mod hash;
|
||||
#[allow(dead_code)]
|
||||
#[macro_use]
|
||||
mod ser;
|
||||
|
||||
use self::hash::{Hash, Hashed, ZERO_HASH};
|
||||
use ser::{Writeable, Writer, Error, ser_vec};
|
||||
|
||||
use time;
|
||||
|
@ -41,60 +44,6 @@ pub const BLOCK_TIME_SEC: u8 = 15;
|
|||
/// Cuckoo-cycle proof size (cycle length)
|
||||
pub const PROOFSIZE: usize = 42;
|
||||
|
||||
/// A hash to uniquely (or close enough) identify one of the main blockchain
|
||||
/// constructs. Used pervasively for blocks, transactions and ouputs.
|
||||
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||
pub struct Hash(pub [u8; 32]);
|
||||
|
||||
impl fmt::Display for Hash {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
for i in self.0[..].iter().cloned() {
|
||||
try!(write!(f, "{:02x}", i));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl Hash {
|
||||
/// Creates a new hash from a vector
|
||||
pub fn from_vec(v: Vec<u8>) -> Hash {
|
||||
let mut a = [0; 32];
|
||||
for i in 0..a.len() {
|
||||
a[i] = v[i];
|
||||
}
|
||||
Hash(a)
|
||||
}
|
||||
/// Converts the hash to a byte vector
|
||||
pub fn to_vec(&self) -> Vec<u8> {
|
||||
self.0.to_vec()
|
||||
}
|
||||
/// Converts the hash to a byte slice
|
||||
pub fn to_slice(&self) -> &[u8] {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
pub const ZERO_HASH: Hash = Hash([0; 32]);
|
||||
|
||||
/// A trait for types that get their hash (double SHA256) from their byte
|
||||
/// serialzation.
|
||||
pub trait Hashed {
|
||||
fn hash(&self) -> Hash {
|
||||
let data = self.bytes();
|
||||
Hash(sha3(data))
|
||||
}
|
||||
|
||||
fn bytes(&self) -> Vec<u8>;
|
||||
}
|
||||
|
||||
fn sha3(data: Vec<u8>) -> [u8; 32] {
|
||||
let mut sha3 = Keccak::new_sha3_256();
|
||||
let mut buf = [0; 32];
|
||||
sha3.update(&data);
|
||||
sha3.finalize(&mut buf);
|
||||
buf
|
||||
}
|
||||
|
||||
/// Implemented by types that hold inputs and outputs including Pedersen
|
||||
/// commitments. Handles the collection of the commitments as well as their
|
||||
/// summing, taking potential explicit overages of fees into account.
|
||||
|
@ -755,7 +704,7 @@ impl MerkleRow {
|
|||
}
|
||||
fn root(&self) -> Hash {
|
||||
if self.0.len() == 0 {
|
||||
Hash(sha3(vec![]))
|
||||
vec![].hash()
|
||||
} else if self.0.len() == 1 {
|
||||
self.0[0].hash()
|
||||
} else {
|
||||
|
@ -767,6 +716,7 @@ impl MerkleRow {
|
|||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
use super::hash::{Hash, Hashed, ZERO_HASH};
|
||||
use secp;
|
||||
use secp::Secp256k1;
|
||||
use secp::key::SecretKey;
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
use time;
|
||||
|
||||
use std::io::{Write, Read};
|
||||
use core;
|
||||
use core::{self, hash};
|
||||
use ser::*;
|
||||
|
||||
use secp::Signature;
|
||||
|
@ -43,7 +43,7 @@ impl_slice_bytes!(Signature);
|
|||
impl_slice_bytes!(Commitment);
|
||||
impl_slice_bytes!(Vec<u8>);
|
||||
|
||||
impl AsFixedBytes for core::Hash {
|
||||
impl AsFixedBytes for hash::Hash {
|
||||
fn as_fixed_bytes(&self) -> &[u8] {
|
||||
self.to_slice()
|
||||
}
|
||||
|
@ -124,7 +124,7 @@ impl Writeable for core::Block {
|
|||
impl Readable<core::Input> for core::Input {
|
||||
fn read(reader: &mut Reader) -> Result<core::Input, Error> {
|
||||
reader.read_fixed_bytes(32)
|
||||
.map(|h| core::Input::BareInput { output: core::Hash::from_vec(h) })
|
||||
.map(|h| core::Input::BareInput { output: hash::Hash::from_vec(h) })
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -210,14 +210,14 @@ impl Readable<core::Block> for core::Block {
|
|||
Ok(core::Block {
|
||||
header: core::BlockHeader {
|
||||
height: height,
|
||||
previous: core::Hash::from_vec(previous),
|
||||
previous: hash::Hash::from_vec(previous),
|
||||
timestamp: time::at_utc(time::Timespec {
|
||||
sec: timestamp,
|
||||
nsec: 0,
|
||||
}),
|
||||
td: td,
|
||||
utxo_merkle: core::Hash::from_vec(utxo_merkle),
|
||||
tx_merkle: core::Hash::from_vec(tx_merkle),
|
||||
utxo_merkle: hash::Hash::from_vec(utxo_merkle),
|
||||
tx_merkle: hash::Hash::from_vec(tx_merkle),
|
||||
total_fees: total_fees,
|
||||
pow: core::Proof(pow),
|
||||
nonce: nonce,
|
||||
|
@ -237,6 +237,7 @@ mod test {
|
|||
use secp::*;
|
||||
use secp::key::*;
|
||||
use core::*;
|
||||
use core::hash::ZERO_HASH;
|
||||
use rand::Rng;
|
||||
use rand::os::OsRng;
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ pub fn genesis() -> core::Block {
|
|||
core::Block {
|
||||
header: core::BlockHeader {
|
||||
height: 0,
|
||||
previous: core::ZERO_HASH,
|
||||
previous: core::hash::ZERO_HASH,
|
||||
timestamp: time::Tm {
|
||||
tm_year: 1997,
|
||||
tm_mon: 7,
|
||||
|
@ -39,8 +39,8 @@ pub fn genesis() -> core::Block {
|
|||
..time::empty_tm()
|
||||
},
|
||||
td: 0,
|
||||
utxo_merkle: core::Hash::from_vec(empty_h.to_vec()),
|
||||
tx_merkle: core::Hash::from_vec(empty_h.to_vec()),
|
||||
utxo_merkle: core::hash::Hash::from_vec(empty_h.to_vec()),
|
||||
tx_merkle: core::hash::Hash::from_vec(empty_h.to_vec()),
|
||||
total_fees: 0,
|
||||
nonce: 0,
|
||||
pow: core::Proof::zero(), // TODO get actual PoW solution
|
||||
|
|
|
@ -27,7 +27,8 @@ mod cuckoo;
|
|||
|
||||
use time;
|
||||
|
||||
use core::{Block, BlockHeader, Hashed, Hash, Proof, PROOFSIZE};
|
||||
use core::{Block, BlockHeader, Proof, PROOFSIZE};
|
||||
use core::hash::{Hash, Hashed};
|
||||
use pow::cuckoo::{Cuckoo, Miner, Error};
|
||||
|
||||
use ser;
|
||||
|
@ -175,7 +176,8 @@ fn pow_size(b: &Block, target: Proof, sizeshift: u32) -> Result<(Proof, u64), Er
|
|||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
use core::{BlockHeader, Hash, Proof};
|
||||
use core::{BlockHeader, Proof};
|
||||
use core::hash::Hash;
|
||||
use std::time::Instant;
|
||||
use genesis;
|
||||
|
||||
|
|
Loading…
Reference in a new issue