get rid of default implementation of Hashed trait for writable things (#2573)

This commit is contained in:
Jeremy Rubin 2019-02-15 05:41:19 -08:00 committed by Antioch Peverell
parent d4540f32a3
commit 99494c6fa6
12 changed files with 74 additions and 34 deletions

View file

@ -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;

View file

@ -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
}
}

View file

@ -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,
@ -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
}
}
@ -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 {
@ -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.
@ -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

View file

@ -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};
@ -137,6 +137,8 @@ pub struct CompactBlock {
body: CompactBlockBody,
}
impl DefaultHashable for CompactBlock {}
impl CompactBlock {
/// "Lightweight" validation.
fn validate_read(&self) -> Result<(), Error> {

View file

@ -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();
@ -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 {}

View file

@ -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;
@ -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.
@ -168,6 +169,8 @@ mod test {
}
}
impl DefaultHashable for Foo {}
let foo = Foo(0);
let expected_hash =

View file

@ -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};
@ -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)?;
@ -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 {
@ -753,6 +756,8 @@ pub struct Transaction {
body: TransactionBody,
}
impl DefaultHashable for Transaction {}
/// PartialEq
impl PartialEq for Transaction {
fn eq(&self, tx: &Transaction) -> bool {
@ -1113,6 +1118,7 @@ pub struct Input {
pub commit: Commitment,
}
impl DefaultHashable for Input {}
hashable_ord!(Input);
impl ::std::hash::Hash for Input {
@ -1218,6 +1224,7 @@ pub struct Output {
pub proof: RangeProof,
}
impl DefaultHashable for Output {}
hashable_ord!(Output);
impl ::std::hash::Hash for Output {
@ -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 {

View file

@ -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};
@ -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)?;

View file

@ -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::{
@ -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),
}
@ -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;
@ -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()
}

View file

@ -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;
@ -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;
}

View file

@ -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};

View file

@ -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,
@ -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;
}