Protocol Buffers (#9)

* Add protocol buffer messages for Proof and Lemma.

* Implement Protobuf serialization for Proof and Lemma.

* Implement Protobuf unserialization for Proof and Lemma.

* Add write_to_bytes and parse_from_bytes methods to Proof.

* Put the Protobuf-related code behind a feature flag.

* Enable more flags. See #10

* Fix clippy warnings. See #10
This commit is contained in:
Romain Ruetschi
2016-11-21 17:18:41 +01:00
committed by Frederic Jacobs
parent 28d7824b8c
commit b395f224f5
11 changed files with 959 additions and 75 deletions

View File

@ -10,3 +10,11 @@ matrix:
allow_failures:
- rust: nightly
script:
- cargo build
- cargo test
- cargo doc --no-deps
- cargo build --all-features
- cargo test --all-features
- cargo doc --all-features --no-deps

View File

@ -1,5 +1,5 @@
[package]
name = "merkle"
name = "merkle"
version = "0.1.0"
authors = [
"Frederic Jacobs <me@fredericjacobs.com>",
@ -7,12 +7,16 @@ authors = [
"Romain Ruetschi <romain.ruetschi@gmail.com>"
]
description = "Merkle is a Rust implementation of a Merkle tree with support for generation of inclusion proofs."
license = "BSD-3-Clause"
description = "Merkle is a Rust implementation of a Merkle tree with support for generation of inclusion proofs."
license = "BSD-3-Clause"
documentation = "https://spinresearch.github.io/merkle.rs/merkle/index.html"
homepage = "https://github.com/SpinResearch/merkle.rs"
repository = "https://github.com/SpinResearch/merkle.rs"
homepage = "https://github.com/SpinResearch/merkle.rs"
repository = "https://github.com/SpinResearch/merkle.rs"
[dependencies]
rust-crypto = "^0.2.36"
protobuf = { version = "^1.0.0", optional = true }
[features]
serialization-protobuf = [ "protobuf" ]

18
protobuf/proof.proto Normal file
View File

@ -0,0 +1,18 @@
syntax = "proto3";
message ProofProto {
bytes root_hash = 1;
LemmaProto lemma = 2;
}
message LemmaProto {
bytes node_hash = 1;
LemmaProto sub_lemma = 2;
oneof sibling_hash {
bytes left_sibling_hash = 3;
bytes right_sibling_hash = 4;
}
}

View File

@ -1,9 +1,18 @@
#![warn(missing_docs)]
#![deny(
missing_docs,
missing_debug_implementations, missing_copy_implementations,
trivial_casts, trivial_numeric_casts,
unsafe_code, unstable_features,
unused_import_braces, unused_qualifications
)]
//! *merkle* implements a Merkle Tree in Rust.
extern crate crypto;
#[cfg(feature = "serialization-protobuf")]
extern crate protobuf;
mod merkletree;
pub use merkletree::MerkleTree;
@ -14,6 +23,9 @@ mod merkledigest;
mod tree;
#[cfg(feature = "serialization-protobuf")]
mod proto;
#[cfg(test)]
mod tests;

View File

@ -5,15 +5,15 @@ use crypto::digest::Digest;
pub trait MerkleDigest {
/// Compute the hash the given byte array
fn hash_bytes(&mut self, bytes: &Vec<u8>) -> Vec<u8>;
fn hash_bytes(&mut self, bytes: &[u8]) -> Vec<u8>;
/// Compute the hash of the concatenation of `left` and `right`
fn combine_hashes(&mut self, left: &Vec<u8>, right: &Vec<u8>) -> Vec<u8>;
fn combine_hashes(&mut self, left: &[u8], right: &[u8]) -> Vec<u8>;
}
impl <D> MerkleDigest for D where D: Digest {
fn hash_bytes(&mut self, bytes: &Vec<u8>) -> Vec<u8> {
fn hash_bytes(&mut self, bytes: &[u8]) -> Vec<u8> {
let mut hash = vec![0; self.output_bytes()];
self.reset();
@ -24,7 +24,7 @@ impl <D> MerkleDigest for D where D: Digest {
hash
}
fn combine_hashes(&mut self, left: &Vec<u8>, right: &Vec<u8>) -> Vec<u8> {
fn combine_hashes(&mut self, left: &[u8], right: &[u8]) -> Vec<u8> {
let mut hash = vec![0; self.output_bytes()];
self.reset();

View File

@ -9,6 +9,7 @@ use proof::{ Proof, Lemma };
/// A Merkle tree is a binary tree, with values of type `T` at the leafs,
/// and where every node holds the hash of the concatenation of the hashes of
/// its children nodes.
#[derive(Debug)]
pub struct MerkleTree<D, T> {
/// The hashing function used by this Merkle tree
digest: D,
@ -42,14 +43,14 @@ impl <D, T> MerkleTree<D, T> where D: Digest + Clone, T: Into<Vec<u8>> + Clone {
let mut height = 0;
let mut cur = Vec::with_capacity(count);
for v in values.into_iter() {
for v in values {
let leaf = Tree::make_leaf(&mut digest, v);
cur.push(leaf);
}
while cur.len() > 1 {
let mut next = Vec::new();
while cur.len() > 0 {
while !cur.is_empty() {
if cur.len() == 1 {
next.push(cur.remove(0));
}

View File

@ -8,14 +8,22 @@ use merkledigest::MerkleDigest;
/// An inclusion proof represent the fact that a `value` is a member
/// of a `MerkleTree` with root hash `root_hash`, and hash function `digest`.
#[derive(Debug)]
pub struct Proof<D, T> {
digest: D,
root_hash: Vec<u8>,
lemma: Lemma,
/// The hash function used in the original `MerkleTree`
pub digest: D,
/// The hash of the root of the original `MerkleTree`
pub root_hash: Vec<u8>,
/// The first `Lemma` of the `Proof`
pub lemma: Lemma,
_value_marker: PhantomData<T>
}
impl <D, T> Proof<D, T> where D: Digest + Clone, T: Into<Vec<u8>> + Clone {
impl <D, T> Proof<D, T> {
/// Constructs a new `Proof`
pub fn new(digest: D, root_hash: Vec<u8>, lemma: Lemma) -> Self {
@ -29,15 +37,15 @@ impl <D, T> Proof<D, T> where D: Digest + Clone, T: Into<Vec<u8>> + Clone {
/// Checks whether this inclusion proof is well-formed,
/// and whether its root hash matches the given `root_hash`.
pub fn validate(&self, root_hash: &Vec<u8>) -> bool {
if self.root_hash != *root_hash || self.lemma.node_hash != *root_hash {
pub fn validate(&self, root_hash: &[u8]) -> bool where D: Digest + Clone {
if self.root_hash != root_hash || self.lemma.node_hash != root_hash {
return false
}
self.validate_lemma(&self.lemma, &mut self.digest.clone())
}
fn validate_lemma(&self, lemma: &Lemma, digest: &mut D) -> bool {
fn validate_lemma(&self, lemma: &Lemma, digest: &mut D) -> bool where D: Digest {
match lemma.sub_lemma {
None =>
@ -49,12 +57,12 @@ impl <D, T> Proof<D, T> where D: Digest + Clone, T: Into<Vec<u8>> + Clone {
false,
Some(Positioned::Left(ref hash)) => {
let hashes_match = digest.combine_hashes(&hash, &sub.node_hash) == lemma.node_hash;
let hashes_match = digest.combine_hashes(hash, &sub.node_hash) == lemma.node_hash;
hashes_match && self.validate_lemma(sub, digest)
}
Some(Positioned::Right(ref hash)) => {
let hashes_match = digest.combine_hashes(&sub.node_hash, &hash) == lemma.node_hash;
let hashes_match = digest.combine_hashes(&sub.node_hash, hash) == lemma.node_hash;
hashes_match && self.validate_lemma(sub, digest)
}
@ -62,27 +70,23 @@ impl <D, T> Proof<D, T> where D: Digest + Clone, T: Into<Vec<u8>> + Clone {
}
}
#[cfg(test)]
pub fn lemma_mut(&mut self) -> &mut Lemma {
&mut self.lemma
}
}
/// A `Lemma` holds the hash of a node, the hash of its sibling node,
/// and a sub lemma, whose `node_hash`, when combined with this `sibling_hash`
/// must be equal to this `node_hash`.
#[derive(Debug)]
pub struct Lemma {
node_hash: Vec<u8>,
sibling_hash: Option<Positioned<Vec<u8>>>,
sub_lemma: Option<Box<Lemma>>
pub node_hash: Vec<u8>,
pub sibling_hash: Option<Positioned<Vec<u8>>>,
pub sub_lemma: Option<Box<Lemma>>
}
impl Lemma {
/// Attempts to generate a proof that the a value with hash `needle` is a member of the given `tree`.
pub fn new<T>(tree: &Tree<T>, needle: &Vec<u8>) -> Option<Lemma> where T: Into<Vec<u8>> + Clone {
pub fn new<T>(tree: &Tree<T>, needle: &[u8]) -> Option<Lemma> where T: Into<Vec<u8>> + Clone {
match *tree {
Tree::Leaf { ref hash, .. } =>
Lemma::new_leaf_proof(hash, needle),
@ -92,10 +96,10 @@ impl Lemma {
}
}
fn new_leaf_proof(hash: &Vec<u8>, needle: &Vec<u8>) -> Option<Lemma> {
fn new_leaf_proof(hash: &[u8], needle: &[u8]) -> Option<Lemma> {
if *hash == *needle {
Some(Lemma {
node_hash: hash.clone(),
node_hash: hash.into(),
sibling_hash: None,
sub_lemma: None
})
@ -104,9 +108,7 @@ impl Lemma {
}
}
fn new_tree_proof<T>(hash: &Vec<u8>, needle: &Vec<u8>, left: &Tree<T>, right: &Tree<T>) -> Option<Lemma>
where T: Into<Vec<u8>> + Clone
{
fn new_tree_proof<T>(hash: &[u8], needle: &[u8], left: &Tree<T>, right: &Tree<T>) -> Option<Lemma> where T: Into<Vec<u8>> + Clone {
Lemma::new(left, needle)
.map(|lemma| {
let right_hash = right.hash().clone();
@ -123,32 +125,17 @@ impl Lemma {
})
.map(|(sub_lemma, sibling_hash)| {
Lemma {
node_hash: hash.clone(),
node_hash: hash.into(),
sibling_hash: sibling_hash,
sub_lemma: Some(Box::new(sub_lemma))
}
})
}
#[cfg(test)]
pub fn node_hash_mut(&mut self) -> &mut Vec<u8> {
&mut self.node_hash
}
#[cfg(test)]
pub fn sibling_hash_mut(&mut self) -> &mut Option<Positioned<Vec<u8>>> {
&mut self.sibling_hash
}
#[cfg(test)]
pub fn sub_lemma_mut(&mut self) -> &mut Option<Box<Lemma>> {
&mut self.sub_lemma
}
}
/// Tags a value so that we know from which branch of a `Tree` (if any) it was found.
#[derive(PartialEq)]
#[derive(Debug, PartialEq)]
pub enum Positioned<T> {
/// The value was found in the left branch

137
src/proto/mod.rs Normal file
View File

@ -0,0 +1,137 @@
mod proof;
use proof::{ Proof, Lemma, Positioned };
pub use self::proof::{ ProofProto, LemmaProto };
use protobuf::Message;
use protobuf::error::ProtobufResult;
use protobuf::core::parse_from_bytes;
impl <D, T> Proof<D, T> {
/// Constructs a `Proof` struct from its Protobuf representation.
pub fn from_protobuf(digest: D, proto: ProofProto) -> Option<Self> {
proto.into_proof(digest)
}
/// Encode this `Proof` to its Protobuf representation.
pub fn into_protobuf(self) -> ProofProto {
ProofProto::from_proof(self)
}
/// Parse a `Proof` from its Protobuf binary representation.
pub fn parse_from_bytes(bytes: &[u8], digest: D) -> ProtobufResult<Option<Proof<D, T>>> {
parse_from_bytes::<ProofProto>(bytes).map(|proto| proto.into_proof(digest))
}
/// Serialize this `Proof` with Protobuf.
pub fn write_to_bytes(self) -> ProtobufResult<Vec<u8>> {
self.into_protobuf().write_to_bytes()
}
}
impl ProofProto {
pub fn from_proof<D, T>(proof: Proof<D, T>) -> Self {
let mut proto = Self::new();
match proof {
Proof { root_hash, lemma, .. } => {
proto.set_root_hash(root_hash);
proto.set_lemma(LemmaProto::from_lemma(lemma));
}
}
proto
}
pub fn into_proof<D, T>(mut self, digest: D) -> Option<Proof<D, T>> {
if !self.has_root_hash() || !self.has_lemma() {
return None;
}
self.take_lemma().into_lemma().map(|lemma| {
Proof::new(
digest,
self.take_root_hash(),
lemma
)
})
}
}
impl LemmaProto {
pub fn from_lemma(lemma: Lemma) -> Self {
let mut proto = Self::new();
match lemma {
Lemma { node_hash, sibling_hash, sub_lemma } => {
proto.set_node_hash(node_hash);
if let Some(sub_proto) = sub_lemma.map(|l| Self::from_lemma(*l)) {
proto.set_sub_lemma(sub_proto);
}
match sibling_hash {
Some(Positioned::Left(hash)) =>
proto.set_left_sibling_hash(hash),
Some(Positioned::Right(hash)) =>
proto.set_right_sibling_hash(hash),
None => {}
}
}
}
proto
}
pub fn into_lemma(mut self) -> Option<Lemma> {
if !self.has_node_hash() {
return None;
}
let node_hash = self.take_node_hash();
let sibling_hash =
if self.has_left_sibling_hash() {
Some(Positioned::Left(self.take_left_sibling_hash()))
}
else if self.has_right_sibling_hash() {
Some(Positioned::Left(self.take_right_sibling_hash()))
}
else {
None
};
if self.has_sub_lemma() {
// If a `sub_lemma` is present is the Protobuf,
// then we expect it to unserialize to a valid `Lemma`,
// otherwise we return `None`
self.take_sub_lemma().into_lemma().map(|sub_lemma| {
Lemma {
node_hash: node_hash,
sibling_hash: sibling_hash,
sub_lemma: Some(Box::new(sub_lemma))
}
})
}
else {
// We might very well not have a sub_lemma,
// in which case we just set it to `None`,
// but still return a potentially valid `Lemma`.
Some(Lemma {
node_hash: node_hash,
sibling_hash: sibling_hash,
sub_lemma: None
})
}
}
}

719
src/proto/proof.rs Normal file
View File

@ -0,0 +1,719 @@
// This file is generated. Do not edit
// @generated
// https://github.com/Manishearth/rust-clippy/issues/702
#![allow(unknown_lints)]
#![allow(clippy)]
#![cfg_attr(rustfmt, rustfmt_skip)]
#![allow(box_pointers)]
#![allow(dead_code)]
#![allow(non_camel_case_types)]
#![allow(non_snake_case)]
#![allow(non_upper_case_globals)]
#![allow(trivial_casts)]
#![allow(unsafe_code)]
#![allow(unused_imports)]
#![allow(unused_results)]
use protobuf::Message as Message_imported_for_functions;
use protobuf::ProtobufEnum as ProtobufEnum_imported_for_functions;
#[derive(Clone,Default)]
pub struct ProofProto {
// message fields
root_hash: ::protobuf::SingularField<::std::vec::Vec<u8>>,
lemma: ::protobuf::SingularPtrField<LemmaProto>,
// special fields
unknown_fields: ::protobuf::UnknownFields,
cached_size: ::std::cell::Cell<u32>,
}
// see codegen.rs for the explanation why impl Sync explicitly
unsafe impl ::std::marker::Sync for ProofProto {}
impl ProofProto {
pub fn new() -> ProofProto {
::std::default::Default::default()
}
pub fn default_instance() -> &'static ProofProto {
static mut instance: ::protobuf::lazy::Lazy<ProofProto> = ::protobuf::lazy::Lazy {
lock: ::protobuf::lazy::ONCE_INIT,
ptr: 0 as *const ProofProto,
};
unsafe {
instance.get(|| {
ProofProto {
root_hash: ::protobuf::SingularField::none(),
lemma: ::protobuf::SingularPtrField::none(),
unknown_fields: ::protobuf::UnknownFields::new(),
cached_size: ::std::cell::Cell::new(0),
}
})
}
}
// optional bytes root_hash = 1;
pub fn clear_root_hash(&mut self) {
self.root_hash.clear();
}
pub fn has_root_hash(&self) -> bool {
self.root_hash.is_some()
}
// Param is passed by value, moved
pub fn set_root_hash(&mut self, v: ::std::vec::Vec<u8>) {
self.root_hash = ::protobuf::SingularField::some(v);
}
// Mutable pointer to the field.
// If field is not initialized, it is initialized with default value first.
pub fn mut_root_hash(&mut self) -> &mut ::std::vec::Vec<u8> {
if self.root_hash.is_none() {
self.root_hash.set_default();
};
self.root_hash.as_mut().unwrap()
}
// Take field
pub fn take_root_hash(&mut self) -> ::std::vec::Vec<u8> {
self.root_hash.take().unwrap_or_else(|| ::std::vec::Vec::new())
}
pub fn get_root_hash(&self) -> &[u8] {
match self.root_hash.as_ref() {
Some(v) => &v,
None => &[],
}
}
// optional .LemmaProto lemma = 2;
pub fn clear_lemma(&mut self) {
self.lemma.clear();
}
pub fn has_lemma(&self) -> bool {
self.lemma.is_some()
}
// Param is passed by value, moved
pub fn set_lemma(&mut self, v: LemmaProto) {
self.lemma = ::protobuf::SingularPtrField::some(v);
}
// Mutable pointer to the field.
// If field is not initialized, it is initialized with default value first.
pub fn mut_lemma(&mut self) -> &mut LemmaProto {
if self.lemma.is_none() {
self.lemma.set_default();
};
self.lemma.as_mut().unwrap()
}
// Take field
pub fn take_lemma(&mut self) -> LemmaProto {
self.lemma.take().unwrap_or_else(|| LemmaProto::new())
}
pub fn get_lemma(&self) -> &LemmaProto {
self.lemma.as_ref().unwrap_or_else(|| LemmaProto::default_instance())
}
}
impl ::protobuf::Message for ProofProto {
fn is_initialized(&self) -> bool {
true
}
fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream) -> ::protobuf::ProtobufResult<()> {
while !try!(is.eof()) {
let (field_number, wire_type) = try!(is.read_tag_unpack());
match field_number {
1 => {
try!(::protobuf::rt::read_singular_bytes_into(wire_type, is, &mut self.root_hash));
},
2 => {
try!(::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.lemma));
},
_ => {
try!(::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields()));
},
};
}
::std::result::Result::Ok(())
}
// Compute sizes of nested messages
#[allow(unused_variables)]
fn compute_size(&self) -> u32 {
let mut my_size = 0;
for value in &self.root_hash {
my_size += ::protobuf::rt::bytes_size(1, &value);
};
for value in &self.lemma {
let len = value.compute_size();
my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
};
my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
self.cached_size.set(my_size);
my_size
}
fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream) -> ::protobuf::ProtobufResult<()> {
if let Some(v) = self.root_hash.as_ref() {
try!(os.write_bytes(1, &v));
};
if let Some(v) = self.lemma.as_ref() {
try!(os.write_tag(2, ::protobuf::wire_format::WireTypeLengthDelimited));
try!(os.write_raw_varint32(v.get_cached_size()));
try!(v.write_to_with_cached_sizes(os));
};
try!(os.write_unknown_fields(self.get_unknown_fields()));
::std::result::Result::Ok(())
}
fn get_cached_size(&self) -> u32 {
self.cached_size.get()
}
fn get_unknown_fields(&self) -> &::protobuf::UnknownFields {
&self.unknown_fields
}
fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields {
&mut self.unknown_fields
}
fn type_id(&self) -> ::std::any::TypeId {
::std::any::TypeId::of::<ProofProto>()
}
fn as_any(&self) -> &::std::any::Any {
self as &::std::any::Any
}
fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor {
::protobuf::MessageStatic::descriptor_static(None::<Self>)
}
}
impl ::protobuf::MessageStatic for ProofProto {
fn new() -> ProofProto {
ProofProto::new()
}
fn descriptor_static(_: ::std::option::Option<ProofProto>) -> &'static ::protobuf::reflect::MessageDescriptor {
static mut descriptor: ::protobuf::lazy::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::lazy::Lazy {
lock: ::protobuf::lazy::ONCE_INIT,
ptr: 0 as *const ::protobuf::reflect::MessageDescriptor,
};
unsafe {
descriptor.get(|| {
let mut fields = ::std::vec::Vec::new();
fields.push(::protobuf::reflect::accessor::make_singular_bytes_accessor(
"root_hash",
ProofProto::has_root_hash,
ProofProto::get_root_hash,
));
fields.push(::protobuf::reflect::accessor::make_singular_message_accessor(
"lemma",
ProofProto::has_lemma,
ProofProto::get_lemma,
));
::protobuf::reflect::MessageDescriptor::new::<ProofProto>(
"ProofProto",
fields,
file_descriptor_proto()
)
})
}
}
}
impl ::protobuf::Clear for ProofProto {
fn clear(&mut self) {
self.clear_root_hash();
self.clear_lemma();
self.unknown_fields.clear();
}
}
impl ::std::cmp::PartialEq for ProofProto {
fn eq(&self, other: &ProofProto) -> bool {
self.root_hash == other.root_hash &&
self.lemma == other.lemma &&
self.unknown_fields == other.unknown_fields
}
}
impl ::std::fmt::Debug for ProofProto {
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
::protobuf::text_format::fmt(self, f)
}
}
#[derive(Clone,Default)]
pub struct LemmaProto {
// message fields
node_hash: ::protobuf::SingularField<::std::vec::Vec<u8>>,
sub_lemma: ::protobuf::SingularPtrField<LemmaProto>,
// message oneof groups
sibling_hash: ::std::option::Option<LemmaProto_oneof_sibling_hash>,
// special fields
unknown_fields: ::protobuf::UnknownFields,
cached_size: ::std::cell::Cell<u32>,
}
// see codegen.rs for the explanation why impl Sync explicitly
unsafe impl ::std::marker::Sync for LemmaProto {}
#[derive(Clone,PartialEq)]
pub enum LemmaProto_oneof_sibling_hash {
left_sibling_hash(::std::vec::Vec<u8>),
right_sibling_hash(::std::vec::Vec<u8>),
}
impl LemmaProto {
pub fn new() -> LemmaProto {
::std::default::Default::default()
}
pub fn default_instance() -> &'static LemmaProto {
static mut instance: ::protobuf::lazy::Lazy<LemmaProto> = ::protobuf::lazy::Lazy {
lock: ::protobuf::lazy::ONCE_INIT,
ptr: 0 as *const LemmaProto,
};
unsafe {
instance.get(|| {
LemmaProto {
node_hash: ::protobuf::SingularField::none(),
sub_lemma: ::protobuf::SingularPtrField::none(),
sibling_hash: ::std::option::Option::None,
unknown_fields: ::protobuf::UnknownFields::new(),
cached_size: ::std::cell::Cell::new(0),
}
})
}
}
// optional bytes node_hash = 1;
pub fn clear_node_hash(&mut self) {
self.node_hash.clear();
}
pub fn has_node_hash(&self) -> bool {
self.node_hash.is_some()
}
// Param is passed by value, moved
pub fn set_node_hash(&mut self, v: ::std::vec::Vec<u8>) {
self.node_hash = ::protobuf::SingularField::some(v);
}
// Mutable pointer to the field.
// If field is not initialized, it is initialized with default value first.
pub fn mut_node_hash(&mut self) -> &mut ::std::vec::Vec<u8> {
if self.node_hash.is_none() {
self.node_hash.set_default();
};
self.node_hash.as_mut().unwrap()
}
// Take field
pub fn take_node_hash(&mut self) -> ::std::vec::Vec<u8> {
self.node_hash.take().unwrap_or_else(|| ::std::vec::Vec::new())
}
pub fn get_node_hash(&self) -> &[u8] {
match self.node_hash.as_ref() {
Some(v) => &v,
None => &[],
}
}
// optional .LemmaProto sub_lemma = 2;
pub fn clear_sub_lemma(&mut self) {
self.sub_lemma.clear();
}
pub fn has_sub_lemma(&self) -> bool {
self.sub_lemma.is_some()
}
// Param is passed by value, moved
pub fn set_sub_lemma(&mut self, v: LemmaProto) {
self.sub_lemma = ::protobuf::SingularPtrField::some(v);
}
// Mutable pointer to the field.
// If field is not initialized, it is initialized with default value first.
pub fn mut_sub_lemma(&mut self) -> &mut LemmaProto {
if self.sub_lemma.is_none() {
self.sub_lemma.set_default();
};
self.sub_lemma.as_mut().unwrap()
}
// Take field
pub fn take_sub_lemma(&mut self) -> LemmaProto {
self.sub_lemma.take().unwrap_or_else(|| LemmaProto::new())
}
pub fn get_sub_lemma(&self) -> &LemmaProto {
self.sub_lemma.as_ref().unwrap_or_else(|| LemmaProto::default_instance())
}
// optional bytes left_sibling_hash = 3;
pub fn clear_left_sibling_hash(&mut self) {
self.sibling_hash = ::std::option::Option::None;
}
pub fn has_left_sibling_hash(&self) -> bool {
match self.sibling_hash {
::std::option::Option::Some(LemmaProto_oneof_sibling_hash::left_sibling_hash(..)) => true,
_ => false,
}
}
// Param is passed by value, moved
pub fn set_left_sibling_hash(&mut self, v: ::std::vec::Vec<u8>) {
self.sibling_hash = ::std::option::Option::Some(LemmaProto_oneof_sibling_hash::left_sibling_hash(v))
}
// Mutable pointer to the field.
// If field is not initialized, it is initialized with default value first.
pub fn mut_left_sibling_hash(&mut self) -> &mut ::std::vec::Vec<u8> {
if let ::std::option::Option::Some(LemmaProto_oneof_sibling_hash::left_sibling_hash(_)) = self.sibling_hash {
} else {
self.sibling_hash = ::std::option::Option::Some(LemmaProto_oneof_sibling_hash::left_sibling_hash(::std::vec::Vec::new()));
}
match self.sibling_hash {
::std::option::Option::Some(LemmaProto_oneof_sibling_hash::left_sibling_hash(ref mut v)) => v,
_ => panic!(),
}
}
// Take field
pub fn take_left_sibling_hash(&mut self) -> ::std::vec::Vec<u8> {
if self.has_left_sibling_hash() {
match self.sibling_hash.take() {
::std::option::Option::Some(LemmaProto_oneof_sibling_hash::left_sibling_hash(v)) => v,
_ => panic!(),
}
} else {
::std::vec::Vec::new()
}
}
pub fn get_left_sibling_hash(&self) -> &[u8] {
match self.sibling_hash {
::std::option::Option::Some(LemmaProto_oneof_sibling_hash::left_sibling_hash(ref v)) => v,
_ => &[],
}
}
// optional bytes right_sibling_hash = 4;
pub fn clear_right_sibling_hash(&mut self) {
self.sibling_hash = ::std::option::Option::None;
}
pub fn has_right_sibling_hash(&self) -> bool {
match self.sibling_hash {
::std::option::Option::Some(LemmaProto_oneof_sibling_hash::right_sibling_hash(..)) => true,
_ => false,
}
}
// Param is passed by value, moved
pub fn set_right_sibling_hash(&mut self, v: ::std::vec::Vec<u8>) {
self.sibling_hash = ::std::option::Option::Some(LemmaProto_oneof_sibling_hash::right_sibling_hash(v))
}
// Mutable pointer to the field.
// If field is not initialized, it is initialized with default value first.
pub fn mut_right_sibling_hash(&mut self) -> &mut ::std::vec::Vec<u8> {
if let ::std::option::Option::Some(LemmaProto_oneof_sibling_hash::right_sibling_hash(_)) = self.sibling_hash {
} else {
self.sibling_hash = ::std::option::Option::Some(LemmaProto_oneof_sibling_hash::right_sibling_hash(::std::vec::Vec::new()));
}
match self.sibling_hash {
::std::option::Option::Some(LemmaProto_oneof_sibling_hash::right_sibling_hash(ref mut v)) => v,
_ => panic!(),
}
}
// Take field
pub fn take_right_sibling_hash(&mut self) -> ::std::vec::Vec<u8> {
if self.has_right_sibling_hash() {
match self.sibling_hash.take() {
::std::option::Option::Some(LemmaProto_oneof_sibling_hash::right_sibling_hash(v)) => v,
_ => panic!(),
}
} else {
::std::vec::Vec::new()
}
}
pub fn get_right_sibling_hash(&self) -> &[u8] {
match self.sibling_hash {
::std::option::Option::Some(LemmaProto_oneof_sibling_hash::right_sibling_hash(ref v)) => v,
_ => &[],
}
}
}
impl ::protobuf::Message for LemmaProto {
fn is_initialized(&self) -> bool {
true
}
fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream) -> ::protobuf::ProtobufResult<()> {
while !try!(is.eof()) {
let (field_number, wire_type) = try!(is.read_tag_unpack());
match field_number {
1 => {
try!(::protobuf::rt::read_singular_bytes_into(wire_type, is, &mut self.node_hash));
},
2 => {
try!(::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.sub_lemma));
},
3 => {
if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited {
return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));
};
self.sibling_hash = ::std::option::Option::Some(LemmaProto_oneof_sibling_hash::left_sibling_hash(try!(is.read_bytes())));
},
4 => {
if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited {
return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));
};
self.sibling_hash = ::std::option::Option::Some(LemmaProto_oneof_sibling_hash::right_sibling_hash(try!(is.read_bytes())));
},
_ => {
try!(::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields()));
},
};
}
::std::result::Result::Ok(())
}
// Compute sizes of nested messages
#[allow(unused_variables)]
fn compute_size(&self) -> u32 {
let mut my_size = 0;
for value in &self.node_hash {
my_size += ::protobuf::rt::bytes_size(1, &value);
};
for value in &self.sub_lemma {
let len = value.compute_size();
my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
};
if let ::std::option::Option::Some(ref v) = self.sibling_hash {
match v {
&LemmaProto_oneof_sibling_hash::left_sibling_hash(ref v) => {
my_size += ::protobuf::rt::bytes_size(3, &v);
},
&LemmaProto_oneof_sibling_hash::right_sibling_hash(ref v) => {
my_size += ::protobuf::rt::bytes_size(4, &v);
},
};
};
my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
self.cached_size.set(my_size);
my_size
}
fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream) -> ::protobuf::ProtobufResult<()> {
if let Some(v) = self.node_hash.as_ref() {
try!(os.write_bytes(1, &v));
};
if let Some(v) = self.sub_lemma.as_ref() {
try!(os.write_tag(2, ::protobuf::wire_format::WireTypeLengthDelimited));
try!(os.write_raw_varint32(v.get_cached_size()));
try!(v.write_to_with_cached_sizes(os));
};
if let ::std::option::Option::Some(ref v) = self.sibling_hash {
match v {
&LemmaProto_oneof_sibling_hash::left_sibling_hash(ref v) => {
try!(os.write_bytes(3, v));
},
&LemmaProto_oneof_sibling_hash::right_sibling_hash(ref v) => {
try!(os.write_bytes(4, v));
},
};
};
try!(os.write_unknown_fields(self.get_unknown_fields()));
::std::result::Result::Ok(())
}
fn get_cached_size(&self) -> u32 {
self.cached_size.get()
}
fn get_unknown_fields(&self) -> &::protobuf::UnknownFields {
&self.unknown_fields
}
fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields {
&mut self.unknown_fields
}
fn type_id(&self) -> ::std::any::TypeId {
::std::any::TypeId::of::<LemmaProto>()
}
fn as_any(&self) -> &::std::any::Any {
self as &::std::any::Any
}
fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor {
::protobuf::MessageStatic::descriptor_static(None::<Self>)
}
}
impl ::protobuf::MessageStatic for LemmaProto {
fn new() -> LemmaProto {
LemmaProto::new()
}
fn descriptor_static(_: ::std::option::Option<LemmaProto>) -> &'static ::protobuf::reflect::MessageDescriptor {
static mut descriptor: ::protobuf::lazy::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::lazy::Lazy {
lock: ::protobuf::lazy::ONCE_INIT,
ptr: 0 as *const ::protobuf::reflect::MessageDescriptor,
};
unsafe {
descriptor.get(|| {
let mut fields = ::std::vec::Vec::new();
fields.push(::protobuf::reflect::accessor::make_singular_bytes_accessor(
"node_hash",
LemmaProto::has_node_hash,
LemmaProto::get_node_hash,
));
fields.push(::protobuf::reflect::accessor::make_singular_message_accessor(
"sub_lemma",
LemmaProto::has_sub_lemma,
LemmaProto::get_sub_lemma,
));
fields.push(::protobuf::reflect::accessor::make_singular_bytes_accessor(
"left_sibling_hash",
LemmaProto::has_left_sibling_hash,
LemmaProto::get_left_sibling_hash,
));
fields.push(::protobuf::reflect::accessor::make_singular_bytes_accessor(
"right_sibling_hash",
LemmaProto::has_right_sibling_hash,
LemmaProto::get_right_sibling_hash,
));
::protobuf::reflect::MessageDescriptor::new::<LemmaProto>(
"LemmaProto",
fields,
file_descriptor_proto()
)
})
}
}
}
impl ::protobuf::Clear for LemmaProto {
fn clear(&mut self) {
self.clear_node_hash();
self.clear_sub_lemma();
self.clear_left_sibling_hash();
self.clear_right_sibling_hash();
self.unknown_fields.clear();
}
}
impl ::std::cmp::PartialEq for LemmaProto {
fn eq(&self, other: &LemmaProto) -> bool {
self.node_hash == other.node_hash &&
self.sub_lemma == other.sub_lemma &&
self.sibling_hash == other.sibling_hash &&
self.unknown_fields == other.unknown_fields
}
}
impl ::std::fmt::Debug for LemmaProto {
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
::protobuf::text_format::fmt(self, f)
}
}
static file_descriptor_proto_data: &'static [u8] = &[
0x0a, 0x14, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x70, 0x72, 0x6f, 0x6f, 0x66,
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x4c, 0x0a, 0x0a, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x50,
0x72, 0x6f, 0x74, 0x6f, 0x12, 0x1b, 0x0a, 0x09, 0x72, 0x6f, 0x6f, 0x74, 0x5f, 0x68, 0x61, 0x73,
0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x72, 0x6f, 0x6f, 0x74, 0x48, 0x61, 0x73,
0x68, 0x12, 0x21, 0x0a, 0x05, 0x6c, 0x65, 0x6d, 0x6d, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b,
0x32, 0x0b, 0x2e, 0x4c, 0x65, 0x6d, 0x6d, 0x61, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x52, 0x05, 0x6c,
0x65, 0x6d, 0x6d, 0x61, 0x22, 0xc1, 0x01, 0x0a, 0x0a, 0x4c, 0x65, 0x6d, 0x6d, 0x61, 0x50, 0x72,
0x6f, 0x74, 0x6f, 0x12, 0x1b, 0x0a, 0x09, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x68, 0x61, 0x73, 0x68,
0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x6e, 0x6f, 0x64, 0x65, 0x48, 0x61, 0x73, 0x68,
0x12, 0x28, 0x0a, 0x09, 0x73, 0x75, 0x62, 0x5f, 0x6c, 0x65, 0x6d, 0x6d, 0x61, 0x18, 0x02, 0x20,
0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x4c, 0x65, 0x6d, 0x6d, 0x61, 0x50, 0x72, 0x6f, 0x74, 0x6f,
0x52, 0x08, 0x73, 0x75, 0x62, 0x4c, 0x65, 0x6d, 0x6d, 0x61, 0x12, 0x2c, 0x0a, 0x11, 0x6c, 0x65,
0x66, 0x74, 0x5f, 0x73, 0x69, 0x62, 0x6c, 0x69, 0x6e, 0x67, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18,
0x03, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x0f, 0x6c, 0x65, 0x66, 0x74, 0x53, 0x69, 0x62,
0x6c, 0x69, 0x6e, 0x67, 0x48, 0x61, 0x73, 0x68, 0x12, 0x2e, 0x0a, 0x12, 0x72, 0x69, 0x67, 0x68,
0x74, 0x5f, 0x73, 0x69, 0x62, 0x6c, 0x69, 0x6e, 0x67, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x04,
0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x10, 0x72, 0x69, 0x67, 0x68, 0x74, 0x53, 0x69, 0x62,
0x6c, 0x69, 0x6e, 0x67, 0x48, 0x61, 0x73, 0x68, 0x42, 0x0e, 0x0a, 0x0c, 0x73, 0x69, 0x62, 0x6c,
0x69, 0x6e, 0x67, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x4a, 0xe4, 0x03, 0x0a, 0x06, 0x12, 0x04, 0x01,
0x00, 0x11, 0x01, 0x0a, 0x08, 0x0a, 0x01, 0x0c, 0x12, 0x03, 0x01, 0x00, 0x12, 0x0a, 0x0a, 0x0a,
0x02, 0x04, 0x00, 0x12, 0x04, 0x03, 0x00, 0x06, 0x01, 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x00, 0x01,
0x12, 0x03, 0x03, 0x08, 0x12, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x00, 0x02, 0x00, 0x12, 0x03, 0x04,
0x02, 0x16, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, 0x04, 0x12, 0x04, 0x04, 0x02, 0x03,
0x14, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, 0x05, 0x12, 0x03, 0x04, 0x02, 0x07, 0x0a,
0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, 0x01, 0x12, 0x03, 0x04, 0x08, 0x11, 0x0a, 0x0c, 0x0a,
0x05, 0x04, 0x00, 0x02, 0x00, 0x03, 0x12, 0x03, 0x04, 0x14, 0x15, 0x0a, 0x0b, 0x0a, 0x04, 0x04,
0x00, 0x02, 0x01, 0x12, 0x03, 0x05, 0x02, 0x17, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x01,
0x04, 0x12, 0x04, 0x05, 0x02, 0x04, 0x16, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x01, 0x06,
0x12, 0x03, 0x05, 0x02, 0x0c, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x01, 0x01, 0x12, 0x03,
0x05, 0x0d, 0x12, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x01, 0x03, 0x12, 0x03, 0x05, 0x15,
0x16, 0x0a, 0x0a, 0x0a, 0x02, 0x04, 0x01, 0x12, 0x04, 0x08, 0x00, 0x11, 0x01, 0x0a, 0x0a, 0x0a,
0x03, 0x04, 0x01, 0x01, 0x12, 0x03, 0x08, 0x08, 0x12, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x01, 0x02,
0x00, 0x12, 0x03, 0x09, 0x02, 0x16, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x00, 0x04, 0x12,
0x04, 0x09, 0x02, 0x08, 0x14, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x00, 0x05, 0x12, 0x03,
0x09, 0x02, 0x07, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x00, 0x01, 0x12, 0x03, 0x09, 0x08,
0x11, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x00, 0x03, 0x12, 0x03, 0x09, 0x14, 0x15, 0x0a,
0x0b, 0x0a, 0x04, 0x04, 0x01, 0x02, 0x01, 0x12, 0x03, 0x0a, 0x02, 0x1b, 0x0a, 0x0d, 0x0a, 0x05,
0x04, 0x01, 0x02, 0x01, 0x04, 0x12, 0x04, 0x0a, 0x02, 0x09, 0x16, 0x0a, 0x0c, 0x0a, 0x05, 0x04,
0x01, 0x02, 0x01, 0x06, 0x12, 0x03, 0x0a, 0x02, 0x0c, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02,
0x01, 0x01, 0x12, 0x03, 0x0a, 0x0d, 0x16, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x01, 0x03,
0x12, 0x03, 0x0a, 0x19, 0x1a, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x01, 0x08, 0x00, 0x12, 0x04, 0x0c,
0x02, 0x0f, 0x03, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x08, 0x00, 0x01, 0x12, 0x03, 0x0c, 0x08,
0x14, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x01, 0x02, 0x02, 0x12, 0x03, 0x0d, 0x04, 0x20, 0x0a, 0x0c,
0x0a, 0x05, 0x04, 0x01, 0x02, 0x02, 0x05, 0x12, 0x03, 0x0d, 0x04, 0x09, 0x0a, 0x0c, 0x0a, 0x05,
0x04, 0x01, 0x02, 0x02, 0x01, 0x12, 0x03, 0x0d, 0x0a, 0x1b, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01,
0x02, 0x02, 0x03, 0x12, 0x03, 0x0d, 0x1e, 0x1f, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x01, 0x02, 0x03,
0x12, 0x03, 0x0e, 0x04, 0x21, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x03, 0x05, 0x12, 0x03,
0x0e, 0x04, 0x09, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x03, 0x01, 0x12, 0x03, 0x0e, 0x0a,
0x1c, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x03, 0x03, 0x12, 0x03, 0x0e, 0x1f, 0x20, 0x62,
0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
];
static mut file_descriptor_proto_lazy: ::protobuf::lazy::Lazy<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::lazy::Lazy {
lock: ::protobuf::lazy::ONCE_INIT,
ptr: 0 as *const ::protobuf::descriptor::FileDescriptorProto,
};
fn parse_descriptor_proto() -> ::protobuf::descriptor::FileDescriptorProto {
::protobuf::parse_from_bytes(file_descriptor_proto_data).unwrap()
}
pub fn file_descriptor_proto() -> &'static ::protobuf::descriptor::FileDescriptorProto {
unsafe {
file_descriptor_proto_lazy.get(|| {
parse_descriptor_proto()
})
}
}

View File

@ -3,21 +3,21 @@
use crypto::sha3::Sha3;
use merkletree::{ MerkleTree };
use merkledigest::{ MerkleDigest };
use proof::{ Positioned };
use merkletree::MerkleTree;
use merkledigest::MerkleDigest;
use proof::Positioned;
#[test]
fn test_from_str_vec() {
let mut digest = Sha3::sha3_256();
let values = vec![ "one", "two", "three", "four" ];
let values = vec!["one", "two", "three", "four"];
let hashes = vec![
digest.hash_bytes(&values[0].into()),
digest.hash_bytes(&values[1].into()),
digest.hash_bytes(&values[2].into()),
digest.hash_bytes(&values[3].into())
digest.hash_bytes(&values[0].as_bytes()),
digest.hash_bytes(&values[1].as_bytes()),
digest.hash_bytes(&values[2].as_bytes()),
digest.hash_bytes(&values[3].as_bytes())
];
let count = values.len();
@ -30,7 +30,7 @@ fn test_from_str_vec() {
assert_eq!(tree.count(), count);
assert_eq!(tree.height(), 2);
assert_eq!(tree.root_hash().as_slice(), root_hash.as_slice());
assert_eq!(tree.root_hash(), &root_hash);
}
@ -47,7 +47,7 @@ fn test_from_vec1() {
let tree = MerkleTree::from_vec_unsafe(Sha3::sha3_256(), values);
let mut d = Sha3::sha3_256();
let root_hash = &d.hash_bytes(&"hello, world".to_string().into());
let root_hash = &d.hash_bytes(&"hello, world".as_bytes());
assert_eq!(tree.count(), 1);
assert_eq!(tree.height(), 0);
@ -63,9 +63,9 @@ fn test_from_vec3() {
let mut d = Sha3::sha3_256();
let hashes = vec![
d.hash_bytes(&vec![1].into()),
d.hash_bytes(&vec![2].into()),
d.hash_bytes(&vec![3].into())
d.hash_bytes(&vec![1]),
d.hash_bytes(&vec![2]),
d.hash_bytes(&vec![3])
];
let h01 = &d.combine_hashes(&hashes[0], &hashes[1]);
@ -84,7 +84,7 @@ fn test_from_vec9() {
let mut d = Sha3::sha3_256();
let hashes = values.iter().map(|v| d.hash_bytes(v.into())).collect::<Vec<_>>();
let hashes = values.iter().map(|v| d.hash_bytes(v)).collect::<Vec<_>>();
let h01 = &d.combine_hashes(&hashes[0], &hashes[1]);
let h23 = &d.combine_hashes(&hashes[2], &hashes[3]);
@ -161,16 +161,13 @@ fn test_mutate_proof_first_lemma() {
match i % 3 {
0 => {
let sibling_hash = proof.lemma_mut().node_hash_mut();
*sibling_hash = vec![1,2,3];
proof.lemma.node_hash = vec![1, 2, 3];
},
1 => {
let sibling_hash = proof.lemma_mut().sibling_hash_mut();
*sibling_hash = Some(Positioned::Left(vec![1, 2, 3]));
proof.lemma.sibling_hash = Some(Positioned::Left(vec![1, 2, 3]));
},
_ => {
let sibling_hash = proof.lemma_mut().sibling_hash_mut();
*sibling_hash = Some(Positioned::Right(vec![1, 2, 3]));
proof.lemma.sibling_hash = Some(Positioned::Right(vec![1, 2, 3]));
}
}

View File

@ -1,6 +1,6 @@
use crypto::digest::Digest;
use merkledigest::{ MerkleDigest };
use merkledigest::MerkleDigest;
pub use proof::{
Proof,
@ -9,6 +9,7 @@ pub use proof::{
};
/// Binary Tree where leaves hold a stand-alone value.
#[derive(Debug)]
pub enum Tree<T> {
Leaf {
hash: Vec<u8>,
@ -41,8 +42,8 @@ impl <T> Tree<T> where T: Into<Vec<u8>> + Clone {
/// Returns a hash from the tree.
pub fn hash(&self) -> &Vec<u8> {
match *self {
Tree::Leaf { ref hash, .. } => hash,
Tree::Node { ref hash, .. } => hash
Tree::Leaf { ref hash, .. } | Tree::Node { ref hash, .. } =>
hash
}
}