Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make structures Send #28

Merged
merged 3 commits into from
Feb 17, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ documentation = "https://docs.rs/merkle-tree-stream"
authors = ["Yoshua Wuyts <[email protected]>"]
license = "MIT OR Apache-2.0"
readme = "README.md"
edition = "2018"

[dependencies]
flat-tree = "4.0.1"
Expand All @@ -15,3 +16,4 @@ flat-tree = "4.0.1"
hex = "0.4.0"
quickcheck = "0.9.0"
crypto-hash = "0.3.1"
async-std = "1.5.0"
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,14 @@ extern crate rust_sodium;
use merkle_tree_stream::{HashMethods, DefaultNode, MerkleTreeStream, Node,
PartialNode};
use rust_sodium::crypto::hash::sha256;
use std::rc::Rc;
use std::sync::Arc;

struct H;
impl HashMethods for H {
type Node = DefaultNode;
type Hash = Vec<u8>;

fn leaf(&self, leaf: &PartialNode, _roots: &[Rc<Self::Node>]) -> Self::Hash {
fn leaf(&self, leaf: &PartialNode, _roots: &[Arc<Self::Node>]) -> Self::Hash {
let data = leaf.as_ref().unwrap();
sha256::hash(&data).0.to_vec()
}
Expand Down
49 changes: 49 additions & 0 deletions examples/async.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
use async_std::task;
use merkle_tree_stream::{
DefaultNode, HashMethods, MerkleTreeStream, Node, NodeKind, PartialNode,
};
use std::sync::Arc;
use std::vec::Vec;

struct XorHashMethods;
impl HashMethods for XorHashMethods {
type Node = DefaultNode;
type Hash = Vec<u8>;

fn leaf(&self, leaf: &PartialNode, _roots: &[Arc<Self::Node>]) -> Self::Hash {
// bitwise XOR the data into u8
let hash = match leaf.data() {
NodeKind::Parent => 0,
NodeKind::Leaf(data) => data.iter().fold(0, |acc, x| acc ^ x),
};
vec![hash]
}

fn parent(&self, a: &Self::Node, b: &Self::Node) -> Self::Hash {
let hash = Node::hash(a)
.iter()
.chain(Node::hash(b).iter())
.fold(0, |acc, x| acc ^ x);
vec![hash]
}
}

async fn append<H: HashMethods>(
mts: &mut MerkleTreeStream<H>,
content: &[u8],
nodes: &mut Vec<Arc<H::Node>>,
) {
mts.next(content, nodes);
}

fn main() {
task::block_on(task::spawn(async {
let mut mts = MerkleTreeStream::new(XorHashMethods, Vec::new());
let mut nodes = Vec::new();
append(&mut mts, b"hello", &mut nodes).await;
append(&mut mts, b"hashed", &mut nodes).await;
mts.next(b"world", &mut nodes);

println!("{:?}", nodes);
}));
}
4 changes: 2 additions & 2 deletions examples/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@ extern crate merkle_tree_stream;
use merkle_tree_stream::{
DefaultNode, HashMethods, MerkleTreeStream, Node, NodeKind, PartialNode,
};
use std::rc::Rc;
use std::sync::Arc;
use std::vec::Vec;

struct XorHashMethods;
impl HashMethods for XorHashMethods {
type Node = DefaultNode;
type Hash = Vec<u8>;

fn leaf(&self, leaf: &PartialNode, _roots: &[Rc<Self::Node>]) -> Self::Hash {
fn leaf(&self, leaf: &PartialNode, _roots: &[Arc<Self::Node>]) -> Self::Hash {
// bitwise XOR the data into u8
let hash = match leaf.data() {
NodeKind::Parent => 0,
Expand Down
36 changes: 18 additions & 18 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@
//! ## Example
//! ```rust
//! use merkle_tree_stream::{DefaultNode, HashMethods, MerkleTreeStream, Node, PartialNode, NodeKind};
//! use std::rc::Rc;
//! use std::sync::Arc;
//! use std::vec::Vec;
//!
//! struct XorHashMethods;
//! impl HashMethods for XorHashMethods {
//! type Node = DefaultNode;
//! type Hash = Vec<u8>;
//!
//! fn leaf(&self, leaf: &PartialNode, _roots: &[Rc<Self::Node>]) -> Self::Hash {
//! fn leaf(&self, leaf: &PartialNode, _roots: &[Arc<Self::Node>]) -> Self::Hash {
//! // bitwise XOR the data into u8
//! let hash = match leaf.data() {
//! NodeKind::Parent => 0,
Expand All @@ -39,10 +39,10 @@ extern crate flat_tree as flat;
mod default_node;
mod partial_node;

pub use default_node::DefaultNode;
pub use partial_node::{NodeKind, PartialNode};
pub use crate::default_node::DefaultNode;
pub use crate::partial_node::{NodeKind, PartialNode};

use std::rc::Rc;
use std::sync::Arc;

/// The parts that make up a full Node from a PartialNode
#[derive(Debug)]
Expand Down Expand Up @@ -80,7 +80,7 @@ pub trait HashMethods {
/// The type of hash returned from the hashing functions.
type Hash;
/// Pass data through a hash function.
fn leaf(&self, leaf: &PartialNode, roots: &[Rc<Self::Node>]) -> Self::Hash;
fn leaf(&self, leaf: &PartialNode, roots: &[Arc<Self::Node>]) -> Self::Hash;
/// Pass hashes through a hash function.
fn parent(&self, a: &Self::Node, b: &Self::Node) -> Self::Hash;
}
Expand All @@ -105,15 +105,15 @@ pub trait Node {
/// ## Example
/// ```rust
/// use merkle_tree_stream::{DefaultNode, HashMethods, MerkleTreeStream, Node, PartialNode, NodeKind};
/// use std::rc::Rc;
/// use std::sync::Arc;
/// use std::vec::Vec;
///
/// struct XorHashMethods;
/// impl HashMethods for XorHashMethods {
/// type Node = DefaultNode;
/// type Hash = Vec<u8>;
///
/// fn leaf(&self, leaf: &PartialNode, _roots: &[Rc<Self::Node>]) -> Self::Hash {
/// fn leaf(&self, leaf: &PartialNode, _roots: &[Arc<Self::Node>]) -> Self::Hash {
/// // bitwise XOR the data into u8
/// let hash = match leaf.data() {
/// NodeKind::Parent => 0,
Expand Down Expand Up @@ -177,13 +177,13 @@ pub trait Node {
#[derive(Debug)]
pub struct MerkleTreeStream<T: HashMethods> {
handler: T,
roots: Vec<Rc<T::Node>>,
roots: Vec<Arc<T::Node>>,
blocks: usize,
}

impl<H: HashMethods> MerkleTreeStream<H> {
/// Create a new MerkleTreeStream instance.
pub fn new(handler: H, roots: Vec<Rc<H::Node>>) -> MerkleTreeStream<H> {
pub fn new(handler: H, roots: Vec<Arc<H::Node>>) -> MerkleTreeStream<H> {
MerkleTreeStream {
handler,
roots,
Expand All @@ -193,7 +193,7 @@ impl<H: HashMethods> MerkleTreeStream<H> {

/// Pass a string buffer through the flat-tree hash functions, and write the
/// result back out to "nodes".
pub fn next<'a>(&mut self, data: &[u8], nodes: &'a mut Vec<Rc<H::Node>>) {
pub fn next<'a>(&mut self, data: &[u8], nodes: &'a mut Vec<Arc<H::Node>>) {
let index: usize = 2 * self.blocks;
self.blocks += 1;

Expand All @@ -206,10 +206,10 @@ impl<H: HashMethods> MerkleTreeStream<H> {

let hash = self.handler.leaf(&leaf, &self.roots);
let parts = NodeParts { node: leaf, hash };
let node = Rc::new(H::Node::from(parts));
let node = Arc::new(H::Node::from(parts));

self.roots.push(Rc::clone(&node));
nodes.push(Rc::clone(&node));
self.roots.push(Arc::clone(&node));
nodes.push(Arc::clone(&node));

while self.roots.len() > 1 {
let leaf = {
Expand Down Expand Up @@ -238,14 +238,14 @@ impl<H: HashMethods> MerkleTreeStream<H> {
self.roots.pop();
}

let leaf = Rc::new(leaf);
self.roots.push(Rc::clone(&leaf));
nodes.push(Rc::clone(&leaf));
let leaf = Arc::new(leaf);
self.roots.push(Arc::clone(&leaf));
nodes.push(Arc::clone(&leaf));
}
}

/// Get the roots vector.
pub fn roots(&self) -> &Vec<Rc<H::Node>> {
pub fn roots(&self) -> &Vec<Arc<H::Node>> {
&self.roots
}
}
18 changes: 9 additions & 9 deletions tests/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@ use merkle_tree_stream::{
use quickcheck::quickcheck;
use std::collections::HashSet;
use std::iter;
use std::rc::Rc;
use std::sync::Arc;

struct H;
impl HashMethods for H {
type Node = DefaultNode;
type Hash = Vec<u8>;

fn leaf(&self, leaf: &PartialNode, _roots: &[Rc<Self::Node>]) -> Self::Hash {
fn leaf(&self, leaf: &PartialNode, _roots: &[Arc<Self::Node>]) -> Self::Hash {
match leaf.data() {
NodeKind::Leaf(data) => {
hex_digest(Algorithm::SHA256, &data).as_bytes().to_vec()
Expand All @@ -39,7 +39,7 @@ impl HashMethods for H {
fn mts_one_node() {
let roots = Vec::new();
let mut mts = MerkleTreeStream::new(H, roots);
let mut nodes: Vec<Rc<DefaultNode>> = Vec::new();
let mut nodes: Vec<Arc<DefaultNode>> = Vec::new();
mts.next(b"hello", &mut nodes);
assert_eq!(1, nodes.len());

Expand All @@ -57,7 +57,7 @@ fn mts_one_node() {
fn mts_more_nodes() {
let roots = Vec::new();
let mut mts = MerkleTreeStream::new(H, roots);
let mut nodes: Vec<Rc<DefaultNode>> = Vec::new();
let mut nodes: Vec<Arc<DefaultNode>> = Vec::new();
mts.next(b"a", &mut nodes);
mts.next(b"b", &mut nodes);

Expand Down Expand Up @@ -115,7 +115,7 @@ fn mts_more_nodes() {
}
}

fn build_mts(data: &[Vec<u8>]) -> (MerkleTreeStream<H>, Vec<Rc<DefaultNode>>) {
fn build_mts(data: &[Vec<u8>]) -> (MerkleTreeStream<H>, Vec<Arc<DefaultNode>>) {
let roots = vec![];
let mut mts = MerkleTreeStream::new(H, roots);
let mut nodes = vec![];
Expand All @@ -124,7 +124,7 @@ fn build_mts(data: &[Vec<u8>]) -> (MerkleTreeStream<H>, Vec<Rc<DefaultNode>>) {
(mts, nodes)
}

fn all_children(index: usize) -> Box<Iterator<Item = usize>> {
fn all_children(index: usize) -> Box<dyn Iterator<Item = usize>> {
let self_ = iter::once(index);
match flat_tree::children(index) {
None => Box::new(self_),
Expand Down Expand Up @@ -218,7 +218,7 @@ fn all_leaves_contain_data() {
#[test]
fn hashes_change_when_data_is_changed() {
/// Finds the parent indices (in-tree IDs) of the nth data block
fn parent_indices(nodes: &[Rc<DefaultNode>], n: usize) -> HashSet<usize> {
fn parent_indices(nodes: &[Arc<DefaultNode>], n: usize) -> HashSet<usize> {
let modified_node_index = nodes
.iter()
.filter(|node| node.data.is_some())
Expand All @@ -240,9 +240,9 @@ fn hashes_change_when_data_is_changed() {
}

fn partition(
nodes: Vec<Rc<DefaultNode>>,
nodes: Vec<Arc<DefaultNode>>,
indices: &HashSet<usize>,
) -> (Vec<Rc<DefaultNode>>, Vec<Rc<DefaultNode>>) {
) -> (Vec<Arc<DefaultNode>>, Vec<Arc<DefaultNode>>) {
nodes
.into_iter()
.partition(|node| indices.contains(&node.index()))
Expand Down