From 7b953283ce41429f67d76bf7f9ada0a064bf06c1 Mon Sep 17 00:00:00 2001 From: Kris Nuttycombe Date: Mon, 16 Aug 2021 13:48:37 -0600 Subject: [PATCH] Add blanket implementation of Hashable for incrementalmerkletree::Hashable + HashSer --- zcash_primitives/src/merkle_tree.rs | 41 ++++++++++++++++++- .../src/merkle_tree/incremental.rs | 13 +----- zcash_primitives/src/sapling.rs | 32 +-------------- 3 files changed, 43 insertions(+), 43 deletions(-) diff --git a/zcash_primitives/src/merkle_tree.rs b/zcash_primitives/src/merkle_tree.rs index 06ce149e5..b196c33e5 100644 --- a/zcash_primitives/src/merkle_tree.rs +++ b/zcash_primitives/src/merkle_tree.rs @@ -1,7 +1,7 @@ //! Implementation of a Merkle tree of commitments used to prove the existence of notes. use byteorder::{LittleEndian, ReadBytesExt}; -use incrementalmerkletree::bridgetree; +use incrementalmerkletree::{self, bridgetree, Altitude}; use std::collections::VecDeque; use std::io::{self, Read, Write}; @@ -29,6 +29,45 @@ pub trait Hashable: Clone + Copy { fn empty_root(_: usize) -> Self; } +/// A hashable node within a Merkle tree. +pub trait HashSer { + /// Parses a node from the given byte source. + fn read(reader: R) -> io::Result + where + Self: Sized; + + /// Serializes this node. + fn write(&self, writer: W) -> io::Result<()>; +} + +impl Hashable for T where T: incrementalmerkletree::Hashable + HashSer + Copy { + /// Parses a node from the given byte source. + fn read(reader: R) -> io::Result { + ::read(reader) + } + + /// Serializes this node. + fn write(&self, writer: W) -> io::Result<()> { + ::write(self, writer) + } + + /// Returns the parent node within the tree of the two given nodes. + fn combine(alt: usize, lhs: &Self, rhs: &Self) -> Self { + ::combine(Altitude::from(alt as u8), lhs, rhs) + } + + /// Returns a blank leaf node. + fn blank() -> Self { + ::empty_leaf() + } + + /// Returns the empty root for the given depth. + fn empty_root(alt: usize) -> Self { + ::empty_root(Altitude::from(alt as u8)) + } +} + + struct PathFiller { queue: VecDeque, } diff --git a/zcash_primitives/src/merkle_tree/incremental.rs b/zcash_primitives/src/merkle_tree/incremental.rs index a7fb65685..33a014b0d 100644 --- a/zcash_primitives/src/merkle_tree/incremental.rs +++ b/zcash_primitives/src/merkle_tree/incremental.rs @@ -13,22 +13,11 @@ use incrementalmerkletree::{ }; use orchard::tree::MerkleCrhOrchardOutput; -use super::CommitmentTree; +use super::{CommitmentTree, HashSer}; use crate::serialize::{Optional, Vector}; pub const SER_V1: u8 = 1; -/// A hashable node within a Merkle tree. -pub trait HashSer { - /// Parses a node from the given byte source. - fn read(reader: R) -> io::Result - where - Self: Sized; - - /// Serializes this node. - fn write(&self, writer: W) -> io::Result<()>; -} - pub fn read_frontier_v0( mut reader: R, ) -> io::Result> { diff --git a/zcash_primitives/src/sapling.rs b/zcash_primitives/src/sapling.rs index 44087f78a..3ab9c84e4 100644 --- a/zcash_primitives/src/sapling.rs +++ b/zcash_primitives/src/sapling.rs @@ -23,7 +23,7 @@ use subtle::{Choice, ConstantTimeEq}; use crate::{ constants::{self, SPENDING_KEY_GENERATOR}, - merkle_tree::Hashable, + merkle_tree::{Hashable, HashSer}, transaction::components::amount::MAX_MONEY, }; @@ -83,34 +83,6 @@ impl Node { } } -impl Hashable for Node { - fn read(mut reader: R) -> io::Result { - let mut repr = [0u8; 32]; - reader.read_exact(&mut repr)?; - Ok(Node::new(repr)) - } - - fn write(&self, mut writer: W) -> io::Result<()> { - writer.write_all(self.repr.as_ref()) - } - - fn combine(depth: usize, lhs: &Self, rhs: &Self) -> Self { - Node { - repr: merkle_hash(depth, &lhs.repr, &rhs.repr), - } - } - - fn blank() -> Self { - Node { - repr: Note::uncommitted().to_repr(), - } - } - - fn empty_root(depth: usize) -> Self { - EMPTY_ROOTS[depth] - } -} - impl incrementalmerkletree::Hashable for Node { fn empty_leaf() -> Self { Node { @@ -129,7 +101,7 @@ impl incrementalmerkletree::Hashable for Node { } } -impl crate::merkle_tree::incremental::HashSer for Node { +impl HashSer for Node { fn read(mut reader: R) -> io::Result { let mut repr = [0u8; 32]; reader.read_exact(&mut repr)?;