Skip to content

Commit

Permalink
get rid of default implementation of Hashed trait for writable things (
Browse files Browse the repository at this point in the history
  • Loading branch information
JeremyRubin authored and antiochp committed Feb 15, 2019
1 parent d4540f3 commit 99494c6
Show file tree
Hide file tree
Showing 12 changed files with 74 additions and 34 deletions.
2 changes: 1 addition & 1 deletion chain/src/txhashset/utxo_view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

//! Lightweight readonly view into output MMR for convenience.
use crate::core::core::hash::Hash;
use crate::core::core::hash::{Hash, Hashed};
use crate::core::core::pmmr::{self, ReadonlyPMMR};
use crate::core::core::{Block, BlockHeader, Input, Output, Transaction};
use crate::core::global;
Expand Down
7 changes: 4 additions & 3 deletions chain/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,11 @@ impl Tip {
total_difficulty: header.total_difficulty(),
}
}
}

/// *Really* easy to accidentally call hash() on a tip (thinking its a header).
/// So lets make hash() do the right thing here.
pub fn hash(&self) -> Hash {
impl Hashed for Tip {
/// The hash of the underlying block.
fn hash(&self) -> Hash {
self.last_block_h
}
}
Expand Down
19 changes: 11 additions & 8 deletions core/src/core/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ use std::sync::Arc;
use crate::consensus::{reward, REWARD};
use crate::core::committed::{self, Committed};
use crate::core::compact_block::{CompactBlock, CompactBlockBody};
use crate::core::hash::{Hash, Hashed, ZERO_HASH};
use crate::core::hash::{DefaultHashable, Hash, Hashed, ZERO_HASH};
use crate::core::verifier_cache::VerifierCache;
use crate::core::{
transaction, Commitment, Input, Output, Transaction, TransactionBody, TxKernel, Weighting,
Expand Down Expand Up @@ -160,9 +160,9 @@ impl FixedLength for HeaderEntry {
const LEN: usize = Hash::LEN + 8 + Difficulty::LEN + 4 + 1;
}

impl HeaderEntry {
impl Hashed for HeaderEntry {
/// The hash of the underlying block.
pub fn hash(&self) -> Hash {
fn hash(&self) -> Hash {
self.hash
}
}
Expand Down Expand Up @@ -197,6 +197,7 @@ pub struct BlockHeader {
/// Proof of work and related
pub pow: ProofOfWork,
}
impl DefaultHashable for BlockHeader {}

impl Default for BlockHeader {
fn default() -> BlockHeader {
Expand Down Expand Up @@ -353,6 +354,13 @@ pub struct Block {
body: TransactionBody,
}

impl Hashed for Block {
/// The hash of the underlying block.
fn hash(&self) -> Hash {
self.header.hash()
}
}

/// Implementation of Writeable for a block, defines how to write the block to a
/// binary writer. Differentiates between writing the block for the purpose of
/// full serialization and the one of just extracting a hash.
Expand Down Expand Up @@ -570,11 +578,6 @@ impl Block {
&mut self.body.kernels
}

/// Blockhash, computed using only the POW
pub fn hash(&self) -> Hash {
self.header.hash()
}

/// Sum of all fees (inputs less outputs) in the block
pub fn total_fees(&self) -> u64 {
self.body
Expand Down
4 changes: 3 additions & 1 deletion core/src/core/compact_block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
use rand::{thread_rng, Rng};

use crate::core::block::{Block, BlockHeader, Error};
use crate::core::hash::Hashed;
use crate::core::hash::{DefaultHashable, Hashed};
use crate::core::id::ShortIdentifiable;
use crate::core::{Output, ShortId, TxKernel};
use crate::ser::{self, read_multi, Readable, Reader, VerifySortedAndUnique, Writeable, Writer};
Expand Down Expand Up @@ -137,6 +137,8 @@ pub struct CompactBlock {
body: CompactBlockBody,
}

impl DefaultHashable for CompactBlock {}

impl CompactBlock {
/// "Lightweight" validation.
fn validate_read(&self) -> Result<(), Error> {
Expand Down
40 changes: 27 additions & 13 deletions core/src/core/hash.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,19 @@ pub const ZERO_HASH: Hash = Hash([0; 32]);
#[derive(Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash, Serialize, Deserialize)]
pub struct Hash([u8; 32]);

impl DefaultHashable for Hash {}

impl Hash {
fn hash_with<T: Writeable>(&self, other: T) -> Hash {
let mut hasher = HashWriter::default();
ser::Writeable::write(self, &mut hasher).unwrap();
ser::Writeable::write(&other, &mut hasher).unwrap();
let mut ret = [0; 32];
hasher.finalize(&mut ret);
Hash(ret)
}
}

impl fmt::Debug for Hash {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let hash_hex = self.to_hex();
Expand Down Expand Up @@ -212,25 +225,26 @@ impl ser::Writer for HashWriter {
pub trait Hashed {
/// Obtain the hash of the object
fn hash(&self) -> Hash;
/// Hash the object together with another writeable object
fn hash_with<T: Writeable>(&self, other: T) -> Hash;
}

impl<W: ser::Writeable> Hashed for W {
/// Implementing this trait enables the default
/// hash implementation
pub trait DefaultHashable: Writeable {}
impl<D: DefaultHashable> Hashed for D {
fn hash(&self) -> Hash {
let mut hasher = HashWriter::default();
ser::Writeable::write(self, &mut hasher).unwrap();
let mut ret = [0; 32];
hasher.finalize(&mut ret);
Hash(ret)
}

fn hash_with<T: Writeable>(&self, other: T) -> Hash {
let mut hasher = HashWriter::default();
ser::Writeable::write(self, &mut hasher).unwrap();
ser::Writeable::write(&other, &mut hasher).unwrap();
Writeable::write(self, &mut hasher).unwrap();
let mut ret = [0; 32];
hasher.finalize(&mut ret);
Hash(ret)
}
}

impl<D: DefaultHashable> DefaultHashable for &D {}
impl<D: DefaultHashable, E: DefaultHashable> DefaultHashable for (D, E) {}
impl<D: DefaultHashable, E: DefaultHashable, F: DefaultHashable> DefaultHashable for (D, E, F) {}

/// Implement Hashed trait for external types here
impl DefaultHashable for crate::util::secp::pedersen::RangeProof {}
impl DefaultHashable for Vec<u8> {}
impl DefaultHashable for u64 {}
5 changes: 4 additions & 1 deletion core/src/core/id.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use std::cmp::Ordering;
use byteorder::{ByteOrder, LittleEndian};
use siphasher::sip::SipHasher24;

use crate::core::hash::{Hash, Hashed};
use crate::core::hash::{DefaultHashable, Hash, Hashed};
use crate::ser::{self, Readable, Reader, Writeable, Writer};
use crate::util;

Expand Down Expand Up @@ -73,6 +73,7 @@ impl<H: Hashed> ShortIdentifiable for H {
#[derive(Clone, Serialize, Deserialize, Hash)]
pub struct ShortId([u8; 6]);

impl DefaultHashable for ShortId {}
/// We want to sort short_ids in a canonical and consistent manner so we can
/// verify sort order in the same way we do for full inputs|outputs|kernels
/// themselves.
Expand Down Expand Up @@ -168,6 +169,8 @@ mod test {
}
}

impl DefaultHashable for Foo {}

let foo = Foo(0);

let expected_hash =
Expand Down
11 changes: 10 additions & 1 deletion core/src/core/transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

//! Transactions
use crate::core::hash::Hashed;
use crate::core::hash::{DefaultHashable, Hashed};
use crate::core::verifier_cache::VerifierCache;
use crate::core::{committed, Committed};
use crate::keychain::{self, BlindingFactor};
Expand Down Expand Up @@ -50,6 +50,8 @@ enum_from_primitive! {
}
}

impl DefaultHashable for KernelFeatures {}

impl Writeable for KernelFeatures {
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), ser::Error> {
writer.write_u8(*self as u8)?;
Expand Down Expand Up @@ -170,6 +172,7 @@ pub struct TxKernel {
pub excess_sig: secp::Signature,
}

impl DefaultHashable for TxKernel {}
hashable_ord!(TxKernel);

impl ::std::hash::Hash for TxKernel {
Expand Down Expand Up @@ -753,6 +756,8 @@ pub struct Transaction {
body: TransactionBody,
}

impl DefaultHashable for Transaction {}

/// PartialEq
impl PartialEq for Transaction {
fn eq(&self, tx: &Transaction) -> bool {
Expand Down Expand Up @@ -1113,6 +1118,7 @@ pub struct Input {
pub commit: Commitment,
}

impl DefaultHashable for Input {}
hashable_ord!(Input);

impl ::std::hash::Hash for Input {
Expand Down Expand Up @@ -1218,6 +1224,7 @@ pub struct Output {
pub proof: RangeProof,
}

impl DefaultHashable for Output {}
hashable_ord!(Output);

impl ::std::hash::Hash for Output {
Expand Down Expand Up @@ -1330,6 +1337,8 @@ pub struct OutputIdentifier {
pub commit: Commitment,
}

impl DefaultHashable for OutputIdentifier {}

impl OutputIdentifier {
/// Build a new output_identifier.
pub fn new(features: OutputFeatures, commit: &Commitment) -> OutputIdentifier {
Expand Down
4 changes: 3 additions & 1 deletion core/src/pow/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use rand::{thread_rng, Rng};
use serde::{de, Deserialize, Deserializer, Serialize, Serializer};

use crate::consensus::{graph_weight, MIN_DIFFICULTY, SECOND_POW_EDGE_BITS};
use crate::core::hash::Hashed;
use crate::core::hash::{DefaultHashable, Hashed};
use crate::global;
use crate::ser::{self, FixedLength, Readable, Reader, Writeable, Writer};

Expand Down Expand Up @@ -324,6 +324,8 @@ pub struct Proof {
pub nonces: Vec<u64>,
}

impl DefaultHashable for Proof {}

impl fmt::Debug for Proof {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "Cuckoo{}(", self.edge_bits)?;
Expand Down
8 changes: 4 additions & 4 deletions core/src/ser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
//! To use it simply implement `Writeable` or `Readable` and then use the
//! `serialize` or `deserialize` functions on them as appropriate.
use crate::core::hash::{Hash, Hashed};
use crate::core::hash::{DefaultHashable, Hash, Hashed};
use crate::keychain::{BlindingFactor, Identifier, IDENTIFIER_SIZE};
use crate::util::read_write::read_exact;
use crate::util::secp::constants::{
Expand Down Expand Up @@ -615,7 +615,7 @@ where
match elem {
Ok(e) => buf.push(e),
Err(Error::IOErr(ref _d, ref kind)) if *kind == io::ErrorKind::UnexpectedEof => {
break
break;
}
Err(e) => return Err(e),
}
Expand Down Expand Up @@ -706,7 +706,7 @@ pub trait FixedLength {
}

/// Trait for types that can be added to a PMMR.
pub trait PMMRable: Writeable + Clone + Debug {
pub trait PMMRable: Writeable + Clone + Debug + DefaultHashable {
/// The type of element actually stored in the MMR data file.
/// This allows us to store Hash elements in the header MMR for variable size BlockHeaders.
type E: FixedLength + Readable + Writeable;
Expand All @@ -721,7 +721,7 @@ pub trait PMMRIndexHashable {
fn hash_with_index(&self, index: u64) -> Hash;
}

impl<T: Writeable> PMMRIndexHashable for T {
impl<T: DefaultHashable> PMMRIndexHashable for T {
fn hash_with_index(&self, index: u64) -> Hash {
(index, self).hash()
}
Expand Down
4 changes: 3 additions & 1 deletion core/tests/vec_backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.

use self::core::core::hash::Hash;
use self::core::core::hash::{DefaultHashable, Hash};
use self::core::core::pmmr::{self, Backend};
use self::core::core::BlockHeader;
use self::core::ser;
Expand All @@ -25,6 +25,8 @@ use std::path::Path;
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub struct TestElem(pub [u32; 4]);

impl DefaultHashable for TestElem {}

impl FixedLength for TestElem {
const LEN: usize = 16;
}
Expand Down
1 change: 1 addition & 0 deletions servers/src/mining/stratumserver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ use std::{cmp, thread};
use crate::chain;
use crate::common::stats::{StratumStats, WorkerStats};
use crate::common::types::{StratumServerConfig, SyncState};
use crate::core::core::hash::Hashed;
use crate::core::core::verifier_cache::VerifierCache;
use crate::core::core::Block;
use crate::core::{pow, ser};
Expand Down
3 changes: 3 additions & 0 deletions store/tests/pmmr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ use std::fs;
use chrono::prelude::Utc;
use croaring::Bitmap;

use crate::core::core::hash::DefaultHashable;
use crate::core::core::pmmr::{Backend, PMMR};
use crate::core::ser::{
Error, FixedLength, PMMRIndexHashable, PMMRable, Readable, Reader, Writeable, Writer,
Expand Down Expand Up @@ -903,6 +904,8 @@ fn load(pos: u64, elems: &[TestElem], backend: &mut store::pmmr::PMMRBackend<Tes
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
struct TestElem(u32);

impl DefaultHashable for TestElem {}

impl FixedLength for TestElem {
const LEN: usize = 4;
}
Expand Down

0 comments on commit 99494c6

Please sign in to comment.