From 36979c6deabbfd3fa29794ed382dafa735b54560 Mon Sep 17 00:00:00 2001 From: Bruno Tavares Date: Mon, 3 Feb 2020 20:47:30 -0300 Subject: [PATCH 1/3] Upgrade code to rust 2018 edtion to use async await --- Cargo.toml | 2 ++ src/lib.rs | 4 ++-- tests/lib.rs | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index c611083..36287ca 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,6 +7,7 @@ documentation = "https://docs.rs/merkle-tree-stream" authors = ["Yoshua Wuyts "] license = "MIT OR Apache-2.0" readme = "README.md" +edition = "2018" [dependencies] flat-tree = "4.0.1" @@ -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" diff --git a/src/lib.rs b/src/lib.rs index bdf009c..a8d93cc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -39,8 +39,8 @@ 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; diff --git a/tests/lib.rs b/tests/lib.rs index db62571..32751f2 100644 --- a/tests/lib.rs +++ b/tests/lib.rs @@ -124,7 +124,7 @@ fn build_mts(data: &[Vec]) -> (MerkleTreeStream, Vec>) { (mts, nodes) } -fn all_children(index: usize) -> Box> { +fn all_children(index: usize) -> Box> { let self_ = iter::once(index); match flat_tree::children(index) { None => Box::new(self_), From f63f7035b78d3c7a98a7079df8484e4a583623b5 Mon Sep 17 00:00:00 2001 From: Bruno Tavares Date: Mon, 3 Feb 2020 20:53:10 -0300 Subject: [PATCH 2/3] Create test case to ensure struct is send --- examples/async.rs | 49 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 examples/async.rs diff --git a/examples/async.rs b/examples/async.rs new file mode 100644 index 0000000..f71c066 --- /dev/null +++ b/examples/async.rs @@ -0,0 +1,49 @@ +use async_std::task; +use merkle_tree_stream::{ + DefaultNode, HashMethods, MerkleTreeStream, Node, NodeKind, PartialNode, +}; +use std::rc::Rc; +use std::vec::Vec; + +struct XorHashMethods; +impl HashMethods for XorHashMethods { + type Node = DefaultNode; + type Hash = Vec; + + fn leaf(&self, leaf: &PartialNode, _roots: &[Rc]) -> 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( + mts: &mut MerkleTreeStream, + content: &[u8], + nodes: &mut Vec>, +) { + mts.next(b"hello", 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); + })); +} From f9b3399d72dd34d37ff7f9e1aba4d7a89518b1ed Mon Sep 17 00:00:00 2001 From: Bruno Tavares Date: Mon, 3 Feb 2020 20:56:42 -0300 Subject: [PATCH 3/3] Replace all references from Rc to Arc --- README.md | 4 ++-- examples/async.rs | 8 ++++---- examples/main.rs | 4 ++-- src/lib.rs | 32 ++++++++++++++++---------------- tests/lib.rs | 16 ++++++++-------- 5 files changed, 32 insertions(+), 32 deletions(-) diff --git a/README.md b/README.md index 7ba2d7f..6074241 100644 --- a/README.md +++ b/README.md @@ -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; - fn leaf(&self, leaf: &PartialNode, _roots: &[Rc]) -> Self::Hash { + fn leaf(&self, leaf: &PartialNode, _roots: &[Arc]) -> Self::Hash { let data = leaf.as_ref().unwrap(); sha256::hash(&data).0.to_vec() } diff --git a/examples/async.rs b/examples/async.rs index f71c066..0f87ea6 100644 --- a/examples/async.rs +++ b/examples/async.rs @@ -2,7 +2,7 @@ use async_std::task; use merkle_tree_stream::{ DefaultNode, HashMethods, MerkleTreeStream, Node, NodeKind, PartialNode, }; -use std::rc::Rc; +use std::sync::Arc; use std::vec::Vec; struct XorHashMethods; @@ -10,7 +10,7 @@ impl HashMethods for XorHashMethods { type Node = DefaultNode; type Hash = Vec; - fn leaf(&self, leaf: &PartialNode, _roots: &[Rc]) -> Self::Hash { + fn leaf(&self, leaf: &PartialNode, _roots: &[Arc]) -> Self::Hash { // bitwise XOR the data into u8 let hash = match leaf.data() { NodeKind::Parent => 0, @@ -31,9 +31,9 @@ impl HashMethods for XorHashMethods { async fn append( mts: &mut MerkleTreeStream, content: &[u8], - nodes: &mut Vec>, + nodes: &mut Vec>, ) { - mts.next(b"hello", nodes); + mts.next(content, nodes); } fn main() { diff --git a/examples/main.rs b/examples/main.rs index a463556..be47761 100644 --- a/examples/main.rs +++ b/examples/main.rs @@ -3,7 +3,7 @@ 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; @@ -11,7 +11,7 @@ impl HashMethods for XorHashMethods { type Node = DefaultNode; type Hash = Vec; - fn leaf(&self, leaf: &PartialNode, _roots: &[Rc]) -> Self::Hash { + fn leaf(&self, leaf: &PartialNode, _roots: &[Arc]) -> Self::Hash { // bitwise XOR the data into u8 let hash = match leaf.data() { NodeKind::Parent => 0, diff --git a/src/lib.rs b/src/lib.rs index a8d93cc..4d87219 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,7 +4,7 @@ //! ## 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; @@ -12,7 +12,7 @@ //! type Node = DefaultNode; //! type Hash = Vec; //! -//! fn leaf(&self, leaf: &PartialNode, _roots: &[Rc]) -> Self::Hash { +//! fn leaf(&self, leaf: &PartialNode, _roots: &[Arc]) -> Self::Hash { //! // bitwise XOR the data into u8 //! let hash = match leaf.data() { //! NodeKind::Parent => 0, @@ -42,7 +42,7 @@ mod partial_node; 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)] @@ -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::Hash; + fn leaf(&self, leaf: &PartialNode, roots: &[Arc]) -> Self::Hash; /// Pass hashes through a hash function. fn parent(&self, a: &Self::Node, b: &Self::Node) -> Self::Hash; } @@ -105,7 +105,7 @@ 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; @@ -113,7 +113,7 @@ pub trait Node { /// type Node = DefaultNode; /// type Hash = Vec; /// -/// fn leaf(&self, leaf: &PartialNode, _roots: &[Rc]) -> Self::Hash { +/// fn leaf(&self, leaf: &PartialNode, _roots: &[Arc]) -> Self::Hash { /// // bitwise XOR the data into u8 /// let hash = match leaf.data() { /// NodeKind::Parent => 0, @@ -177,13 +177,13 @@ pub trait Node { #[derive(Debug)] pub struct MerkleTreeStream { handler: T, - roots: Vec>, + roots: Vec>, blocks: usize, } impl MerkleTreeStream { /// Create a new MerkleTreeStream instance. - pub fn new(handler: H, roots: Vec>) -> MerkleTreeStream { + pub fn new(handler: H, roots: Vec>) -> MerkleTreeStream { MerkleTreeStream { handler, roots, @@ -193,7 +193,7 @@ impl MerkleTreeStream { /// 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>) { + pub fn next<'a>(&mut self, data: &[u8], nodes: &'a mut Vec>) { let index: usize = 2 * self.blocks; self.blocks += 1; @@ -206,10 +206,10 @@ impl MerkleTreeStream { 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 = { @@ -238,14 +238,14 @@ impl MerkleTreeStream { 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> { + pub fn roots(&self) -> &Vec> { &self.roots } } diff --git a/tests/lib.rs b/tests/lib.rs index 32751f2..db6ed1a 100644 --- a/tests/lib.rs +++ b/tests/lib.rs @@ -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; - fn leaf(&self, leaf: &PartialNode, _roots: &[Rc]) -> Self::Hash { + fn leaf(&self, leaf: &PartialNode, _roots: &[Arc]) -> Self::Hash { match leaf.data() { NodeKind::Leaf(data) => { hex_digest(Algorithm::SHA256, &data).as_bytes().to_vec() @@ -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> = Vec::new(); + let mut nodes: Vec> = Vec::new(); mts.next(b"hello", &mut nodes); assert_eq!(1, nodes.len()); @@ -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> = Vec::new(); + let mut nodes: Vec> = Vec::new(); mts.next(b"a", &mut nodes); mts.next(b"b", &mut nodes); @@ -115,7 +115,7 @@ fn mts_more_nodes() { } } -fn build_mts(data: &[Vec]) -> (MerkleTreeStream, Vec>) { +fn build_mts(data: &[Vec]) -> (MerkleTreeStream, Vec>) { let roots = vec![]; let mut mts = MerkleTreeStream::new(H, roots); let mut nodes = vec![]; @@ -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], n: usize) -> HashSet { + fn parent_indices(nodes: &[Arc], n: usize) -> HashSet { let modified_node_index = nodes .iter() .filter(|node| node.data.is_some()) @@ -240,9 +240,9 @@ fn hashes_change_when_data_is_changed() { } fn partition( - nodes: Vec>, + nodes: Vec>, indices: &HashSet, - ) -> (Vec>, Vec>) { + ) -> (Vec>, Vec>) { nodes .into_iter() .partition(|node| indices.contains(&node.index()))