diff --git a/Cargo.lock b/Cargo.lock index cbfcf8d387..5099f60180 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -393,13 +393,13 @@ version = "0.5.0-pre" dependencies = [ "bincode 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "bit-vec 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ckb-merkle-tree 0.5.0-pre", "ckb-util 0.5.0-pre", "crossbeam-channel 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "crypto 0.5.0-pre", "faster-hex 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "hash 0.5.0-pre", - "merkle-root 0.5.0-pre", "numext-fixed-hash 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "numext-fixed-uint 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.85 (registry+https://github.com/rust-lang/crates.io-index)", @@ -428,6 +428,13 @@ dependencies = [ "serde_json 1.0.36 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "ckb-merkle-tree" +version = "0.5.0-pre" +dependencies = [ + "merkle-cbt 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "ckb-miner" version = "0.5.0-pre" @@ -541,11 +548,10 @@ version = "0.5.0-pre" dependencies = [ "byteorder 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "ckb-core 0.5.0-pre", + "ckb-merkle-tree 0.5.0-pre", "ckb-util 0.5.0-pre", "flatbuffers 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "hash 0.5.0-pre", - "merkle-root 0.5.0-pre", - "merkle-tree 0.5.0-pre", "numext-fixed-hash 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "numext-fixed-uint 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -667,6 +673,7 @@ dependencies = [ "ckb-chain-spec 0.5.0-pre", "ckb-core 0.5.0-pre", "ckb-db 0.5.0-pre", + "ckb-merkle-tree 0.5.0-pre", "ckb-notify 0.5.0-pre", "ckb-pow 0.5.0-pre", "ckb-script 0.5.0-pre", @@ -674,7 +681,6 @@ dependencies = [ "faketime 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "hash 0.5.0-pre", - "merkle-root 0.5.0-pre", "numext-fixed-hash 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "numext-fixed-uint 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "rayon 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1852,19 +1858,15 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] -name = "merkle-root" -version = "0.5.0-pre" +name = "merkle-cbt" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "hash 0.5.0-pre", - "merkle-tree 0.5.0-pre", + "blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", "numext-fixed-hash 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "merkle-tree" -version = "0.5.0-pre" -dependencies = [ - "proptest 0.8.7 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.85 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.85 (registry+https://github.com/rust-lang/crates.io-index)", + "tiny-keccak 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3451,7 +3453,7 @@ name = "yaml-rust" version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "linked-hash-map 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "linked-hash-map 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3616,6 +3618,7 @@ dependencies = [ "checksum memchr 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "148fab2e51b4f1cfc66da2a7c32981d1d3c083a803978268bb11fe4b86925e7a" "checksum memchr 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "db4c41318937f6e76648f42826b1d9ade5c09cafb5aef7e351240a70f39206e9" "checksum memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0f9dc261e2b62d7a622bf416ea3c5245cdd5d9a7fcc428c0d06804dfce1775b3" +"checksum merkle-cbt 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0b88b4e4a20a2099bd5dccb0039dc3ee3c781410a952fb5bb8d61977a77a0a8e" "checksum mime 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ba626b8a6de5da682e1caa06bdb42a335aee5a84db8e5046a3e8ab17ba0a3ae0" "checksum mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)" = "71646331f2619b1026cc302f87a2b8b648d5c6dd6937846a16cc8ce0f347f432" "checksum mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)" = "966257a94e196b11bb43aca423754d87429960a768de9414f3691d6957abf125" diff --git a/Cargo.toml b/Cargo.toml index f0990e3c2a..5cd16f7956 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -49,7 +49,6 @@ members = [ "util/logger", "util/hash", "util/merkle-tree", - "util/merkle-root", "util/jsonrpc-types", "util/crypto", "util/dir", diff --git a/core/Cargo.toml b/core/Cargo.toml index 6ad31a293e..b61ae4ca74 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -17,5 +17,5 @@ bit-vec = "0.5.0" crossbeam-channel = "0.3" ckb-util = { path = "../util" } fnv = "1.0.3" -merkle-root = {path = "../util/merkle-root"} +ckb-merkle-tree = {path = "../util/merkle-tree"} faster-hex = "0.3" diff --git a/core/src/block.rs b/core/src/block.rs index 55b8dd9910..52cf42a454 100644 --- a/core/src/block.rs +++ b/core/src/block.rs @@ -1,8 +1,8 @@ use crate::header::{Header, HeaderBuilder}; use crate::transaction::{ProposalShortId, Transaction}; use crate::uncle::{uncles_hash, UncleBlock}; +use ckb_merkle_tree::merkle_root; use fnv::FnvHashSet; -use merkle_root::merkle_root; use numext_fixed_hash::H256; use serde_derive::{Deserialize, Serialize}; diff --git a/protocol/Cargo.toml b/protocol/Cargo.toml index bd1a8f936a..d3b35470fe 100644 --- a/protocol/Cargo.toml +++ b/protocol/Cargo.toml @@ -14,5 +14,4 @@ hash = { path = "../util/hash"} siphasher = "0.3.0" rand = "0.6" ckb-util = { path = "../util" } -merkle-tree = { path = "../util/merkle-tree"} -merkle-root = { path = "../util/merkle-root"} +ckb-merkle-tree = { path = "../util/merkle-tree"} diff --git a/protocol/src/builder.rs b/protocol/src/builder.rs index 2b835858ee..ae2366000a 100644 --- a/protocol/src/builder.rs +++ b/protocol/src/builder.rs @@ -17,9 +17,8 @@ use ckb_core::header::{BlockNumber, Header}; use ckb_core::script::Script; use ckb_core::transaction::{CellInput, CellOutput, OutPoint, ProposalShortId, Transaction}; use ckb_core::uncle::UncleBlock; +use ckb_merkle_tree::build_merkle_proof; use flatbuffers::{FlatBufferBuilder, WIPOffset}; -use merkle_root::H256Sha3; -use merkle_tree::Tree; use numext_fixed_hash::H256; use numext_fixed_uint::U256; use rand::{thread_rng, Rng}; @@ -385,16 +384,16 @@ impl<'a> FilteredBlock<'a> { }) .collect::>(); - let tree = Tree::::new( + let proof = build_merkle_proof( &block .commit_transactions() .iter() .map(|tx| tx.hash()) .collect::>(), + transactions_index, ); - let lemmas = tree - .get_proof(transactions_index) - .map(|proof| proof.lemmas) + let lemmas = proof + .map(|proof| proof.lemmas().to_vec()) .unwrap_or_else(Vec::new); let header = FbsHeader::build(fbb, &block.header()); diff --git a/util/merkle-root/Cargo.toml b/util/merkle-root/Cargo.toml deleted file mode 100644 index 83f88f374e..0000000000 --- a/util/merkle-root/Cargo.toml +++ /dev/null @@ -1,11 +0,0 @@ -[package] -name = "merkle-root" -version = "0.5.0-pre" -license = "MIT" -authors = ["Nervos Core Dev "] -edition = "2018" - -[dependencies] -numext-fixed-hash = { version = "0.1", features = ["support_rand", "support_heapsize", "support_serde"] } -hash = {path = "../hash"} -merkle-tree = {path = "../merkle-tree"} diff --git a/util/merkle-root/src/lib.rs b/util/merkle-root/src/lib.rs deleted file mode 100644 index aa34faa2b1..0000000000 --- a/util/merkle-root/src/lib.rs +++ /dev/null @@ -1,22 +0,0 @@ -use hash::Sha3; -use merkle_tree::{Merge, Tree}; -use numext_fixed_hash::H256; - -pub struct H256Sha3; - -impl Merge for H256Sha3 { - type Item = H256; - - fn merge(left: &Self::Item, right: &Self::Item) -> Self::Item { - let mut hash = [0u8; 32]; - let mut sha3 = Sha3::new_sha3_256(); - sha3.update(left.as_bytes()); - sha3.update(right.as_bytes()); - sha3.finalize(&mut hash); - hash.into() - } -} - -pub fn merkle_root(input: &[H256]) -> H256 { - Tree::::build_root(input).unwrap_or_else(H256::zero) -} diff --git a/util/merkle-tree/Cargo.toml b/util/merkle-tree/Cargo.toml index ecac3f9dd8..113afa5d9d 100644 --- a/util/merkle-tree/Cargo.toml +++ b/util/merkle-tree/Cargo.toml @@ -1,9 +1,9 @@ [package] -name = "merkle-tree" +name = "ckb-merkle-tree" version = "0.5.0-pre" license = "MIT" authors = ["Nervos Core Dev "] edition = "2018" -[dev-dependencies] -proptest = "0.8" +[dependencies] +merkle-cbt = { version="0.1", features = ["sha3"] } diff --git a/util/merkle-tree/src/hash.rs b/util/merkle-tree/src/hash.rs deleted file mode 100644 index 629e41bfd4..0000000000 --- a/util/merkle-tree/src/hash.rs +++ /dev/null @@ -1,6 +0,0 @@ -/// A trait for creating parent node. -pub trait Merge { - type Item; - /// Returns parent node of two nodes - fn merge(left: &Self::Item, right: &Self::Item) -> Self::Item; -} diff --git a/util/merkle-tree/src/lib.rs b/util/merkle-tree/src/lib.rs index 233b67e51a..6354be7f77 100644 --- a/util/merkle-tree/src/lib.rs +++ b/util/merkle-tree/src/lib.rs @@ -1,7 +1,13 @@ -mod hash; -mod proof; -mod tree; +use merkle_cbt::{MerkleProof, MerkleTree, CBMT, H256}; -pub use crate::hash::Merge; -pub use crate::proof::Proof; -pub use crate::tree::Tree; +pub fn merkle_root(leaves: &[H256]) -> H256 { + CBMT::build_merkle_root(leaves) +} + +pub fn build_merkle_tree(leaves: Vec) -> MerkleTree { + CBMT::build_merkle_tree(leaves) +} + +pub fn build_merkle_proof(leaves: &[H256], indices: &[usize]) -> Option> { + CBMT::build_merkle_proof(leaves, indices) +} diff --git a/util/merkle-tree/src/proof.rs b/util/merkle-tree/src/proof.rs deleted file mode 100644 index 461120eb86..0000000000 --- a/util/merkle-tree/src/proof.rs +++ /dev/null @@ -1,255 +0,0 @@ -use crate::hash::Merge; -use crate::tree::Tree; -use std::collections::VecDeque; - -/// Merkle Proof can provide a proof for existence of one or more items. -/// Only sibling of the nodes along the path that form leaves to root, -/// excluding the nodes already in the path, should be included in the proof. -/// For example, if we want to show that [T0, T5] is in the list of 6 items, -/// only nodes [T4, T1, B3] should be included in the proof. -/// -/// `tree nodes`: [B0, B1, B2, B3, B4, T0, T1, T2, T3, T4, T5] -/// `leaves`: [(0, T0), (5, T5)] -/// `lemmas`: [T4, T1, B3] -/// `leaves_count`: 6 -pub struct Proof -where - M: Merge, -{ - /// a partial leaves collection keeps the items sorted based on index - pub leaves: Vec<(usize, M::Item)>, - /// non-calculable nodes, stored in descending order - pub lemmas: Vec, - /// total leaves count - pub leaves_count: usize, -} - -impl Proof -where - M: Merge, - ::Item: Clone + Default, -{ - /// Returns the root of the proof, or None if it is empty or lemmas are invalid - pub fn root(&self) -> Option { - if self.leaves_count == 0 { - return None; - } - - let mut queue = self - .leaves - .iter() - .rev() - .map(|(index, leaf)| (self.leaves_count + index - 1, leaf.clone())) - .collect::>(); - - let mut lemmas_iter = self.lemmas.iter(); - - while let Some((index, node)) = queue.pop_front() { - if index == 0 { - // ensure that all lemmas and leaves are consumed - if lemmas_iter.next().is_none() && queue.is_empty() { - return Some(node); - } else { - return None; - } - } - - if let Some(sibling) = match queue.front() { - Some((front, _)) if *front == index.sibling() => { - queue.pop_front().map(|i| i.1.clone()) - } - _ => lemmas_iter.next().cloned(), - } { - let parent_node = if index.is_left() { - M::merge(&node, &sibling) - } else { - M::merge(&sibling, &node) - }; - queue.push_back((index.parent(), parent_node)); - } - } - - None - } -} - -impl Tree -where - M: Merge, - ::Item: Clone + Default, -{ - /// Returns the proof of the tree, or None if it is empty. - /// Assumes that the `leaf_indexes` is sorted. - pub fn get_proof(&self, leaf_indexes: &[usize]) -> Option> { - let leaves_count = (self.nodes.len() >> 1) + 1; - - if self.nodes.is_empty() - || leaf_indexes.is_empty() - || *leaf_indexes.last().unwrap() >= leaves_count - { - return None; - } - - let leaves = leaf_indexes - .iter() - .map(|&index| (index, self.nodes[leaves_count + index - 1].clone())) - .collect::>(); - - let mut lemmas = Vec::new(); - let mut queue = leaf_indexes - .iter() - .rev() - .map(|index| leaves_count + index - 1) - .collect::>(); - while let Some(index) = queue.pop_front() { - if index == 0 { - break; - } - if Some(&index.sibling()) == queue.front() { - queue.pop_front(); - } else { - lemmas.push(self.nodes[index.sibling()].clone()); - } - - queue.push_back(index.parent()); - } - - Some(Proof { - leaves, - lemmas, - leaves_count, - }) - } -} - -/// A helper trait for node index -trait NodeIndex { - fn sibling(&self) -> usize; - fn parent(&self) -> usize; - fn is_left(&self) -> bool; -} - -impl NodeIndex for usize { - #[inline] - fn sibling(&self) -> usize { - debug_assert!(*self > 0); - ((self + 1) ^ 1) - 1 - } - - #[inline] - fn parent(&self) -> usize { - debug_assert!(*self > 0); - (self - 1) >> 1 - } - - #[inline] - fn is_left(&self) -> bool { - self & 1 == 1 - } -} - -#[cfg(test)] -mod tests { - use super::*; - use crate::tree::Tree; - use proptest::collection::vec; - use proptest::num::i32; - use proptest::prelude::*; - use proptest::sample::subsequence; - use proptest::{proptest, proptest_helper}; - struct DummyHash; - - impl Merge for DummyHash { - type Item = i32; - - fn merge(left: &Self::Item, right: &Self::Item) -> Self::Item { - right.wrapping_sub(*left) - } - } - - #[test] - fn empty() { - let proof: Proof = Proof { - leaves: vec![], - lemmas: vec![], - leaves_count: 0, - }; - - assert_eq!(None, proof.root()); - } - - #[test] - fn one() { - let proof: Proof = Proof { - leaves: vec![(0, 1)], - lemmas: vec![], - leaves_count: 1, - }; - - assert_eq!(Some(1), proof.root()); - } - - #[test] - fn extra_lemma() { - let proof: Proof = Proof { - leaves: vec![(0, 1)], - lemmas: vec![1], - leaves_count: 1, - }; - - assert_eq!(None, proof.root()); - } - - #[test] - fn missing_leaves() { - let proof: Proof = Proof { - leaves: vec![(1, 1)], - lemmas: vec![], - leaves_count: 2, - }; - - assert_eq!(None, proof.root()); - } - - #[test] - // [ 1, 0, 1, 2, 2, 2, 3, 5, 7, 11, 13] - // [B0, B1, B2, B3, B4, T0, T1, T2, T3, T4, T5] - // [(0, 2), (5, 13)] - // [ T0, T5] - // [11, 3, 2] - // [T4, T1, B3] - fn two_of_six() { - let proof: Proof = Proof { - leaves: vec![(0, 2), (5, 13)], - lemmas: vec![11, 3, 2], - leaves_count: 6, - }; - - assert_eq!(Some(1), proof.root()); - } - - #[test] - fn build_proof() { - let leaves = vec![2, 3, 5, 7, 11, 13]; - let tree = Tree::::new(&leaves); - let proof = tree.get_proof(&[0, 5]).unwrap(); - assert_eq!(vec![(0, 2), (5, 13)], proof.leaves); - assert_eq!(vec![11, 3, 2], proof.lemmas); - assert_eq!(Some(1), proof.root()); - } - - fn _tree_root_is_same_as_proof_root(leaves: &[i32], indexes: &[usize]) { - let tree = Tree::::new(leaves); - let proof = tree.get_proof(indexes).unwrap(); - assert_eq!(Tree::::build_root(leaves), proof.root()); - } - - proptest! { - #[test] - fn tree_root_is_same_as_proof_root(input in vec(i32::ANY, 2..1000) - .prop_flat_map(|leaves| (Just(leaves.clone()), subsequence((0..leaves.len()).collect::>(), 1..leaves.len()))) - ) { - _tree_root_is_same_as_proof_root(&input.0, &input.1); - } - } -} diff --git a/util/merkle-tree/src/tree.rs b/util/merkle-tree/src/tree.rs deleted file mode 100644 index 902c4fcbf6..0000000000 --- a/util/merkle-tree/src/tree.rs +++ /dev/null @@ -1,177 +0,0 @@ -use crate::hash::Merge; -use std::collections::VecDeque; - -/// Merkle tree is a tree in which every leaf node is labelled with the hash of a data block and -/// every non-leaf node is labelled with the cryptographic hash of the labels of its child nodes. -/// -/// [Article on Wikipedia](https://en.wikipedia.org/wiki/Merkle_tree) -/// -/// This implementation use `Full and Complete Binary Tree` to store the data. -/// -/// ```text -/// with 6 leaves with 7 leaves -/// -/// B0 B0 -/// / \ / \ -/// / \ / \ -/// / \ / \ -/// / \ / \ -/// B1 B2 B1 B2 -/// / \ / \ / \ / \ -/// / \ / \ / \ / \ -/// / \ / \ / \ / \ -/// B3 B4 TO T1 B3 B4 B5 T0 -/// / \ / \ / \ / \ / \ -/// T2 T3 T4 T5 T1 T2 T3 T4 T5 T6 -/// ``` -/// -/// the two trees above can be represented as: -/// [B0, B1, B2, B3, B4, T0, T1, T2, T3, T4, T5] -/// [B0, B1, B2, B3, B4, B5, T0, T1, T2, T3, T4, T5, T6] -pub struct Tree -where - M: Merge, -{ - pub(crate) nodes: Vec, -} - -impl Tree -where - M: Merge, - ::Item: Clone + Default, -{ - /// Create a merkle tree with leaves - /// # Examples - /// ``` - /// use merkle_tree::{Merge, Tree}; - /// struct DummyHash; - /// - /// impl Merge for DummyHash { - /// type Item = i32; - /// - /// fn merge(left: &Self::Item, right: &Self::Item) -> Self::Item { - /// right.wrapping_sub(*left) - /// } - /// } - /// - /// let leaves = vec![2, 3, 5, 7, 11, 13]; - /// let tree = Tree::::new(&leaves); - /// assert_eq!(vec![1, 0, 1, 2, 2, 2, 3, 5, 7, 11, 13], tree.nodes()); - /// assert_eq!(Some(1), tree.root()); - /// ``` - pub fn new(leaves: &[M::Item]) -> Self { - let len = leaves.len(); - if len > 0 { - let mut vec = vec![M::Item::default(); len - 1]; - vec.extend(leaves.to_vec()); - - (0..len - 1) - .rev() - .for_each(|i| vec[i] = M::merge(&vec[(i << 1) + 1], &vec[(i << 1) + 2])); - - Self { nodes: vec } - } else { - Self { nodes: vec![] } - } - } - - /// Returns all nodes of the tree - pub fn nodes(&self) -> &[M::Item] { - &self.nodes - } - - /// Returns the root of the tree, or None if it is empty. - pub fn root(&self) -> Option { - self.nodes.first().cloned() - } - - /// Build merkle root directly without tree initialization - pub fn build_root(leaves: &[M::Item]) -> Option { - if leaves.is_empty() { - return None; - } - - let mut queue = VecDeque::with_capacity((leaves.len() + 1) >> 1); - - let mut iter = leaves.rchunks_exact(2); - while let Some([leaf1, leaf2]) = iter.next() { - queue.push_back(M::merge(leaf1, leaf2)) - } - if let [leaf] = iter.remainder() { - queue.push_front(leaf.clone()) - } - - while queue.len() > 1 { - let right = queue.pop_front().unwrap(); - let left = queue.pop_front().unwrap(); - queue.push_back(M::merge(&left, &right)); - } - - queue.pop_front() - } -} - -#[cfg(test)] -mod tests { - use super::*; - use proptest::collection::vec; - use proptest::num::i32; - use proptest::{proptest, proptest_helper}; - - struct DummyHash; - - impl Merge for DummyHash { - type Item = i32; - - fn merge(left: &Self::Item, right: &Self::Item) -> Self::Item { - right.wrapping_sub(*left) - } - } - - #[test] - fn build_empty() { - let leaves = vec![]; - let tree = Tree::::new(&leaves); - assert!(tree.nodes().is_empty()); - assert!(tree.root().is_none()); - } - - #[test] - fn build_one() { - let leaves = vec![1]; - let tree = Tree::::new(&leaves); - assert_eq!(vec![1], tree.nodes()); - } - - #[test] - fn build_two() { - let leaves = vec![1, 2]; - let tree = Tree::::new(&leaves); - assert_eq!(vec![1, 1, 2], tree.nodes()); - } - - #[test] - fn build_five() { - let leaves = vec![2, 3, 5, 7, 11]; - let tree = Tree::::new(&leaves); - assert_eq!(vec![4, -2, 2, 4, 2, 3, 5, 7, 11], tree.nodes()); - } - - #[test] - fn build_root_directly() { - let leaves = vec![2, 3, 5, 7, 11]; - assert_eq!(Some(4), Tree::::build_root(&leaves)); - } - - fn _build_root_is_same_as_tree_root(leaves: &[i32]) { - let tree = Tree::::new(leaves); - assert_eq!(Tree::::build_root(leaves), tree.root()); - } - - proptest! { - #[test] - fn build_root_is_same_as_tree_root(ref leaves in vec(i32::ANY, 0..1000)) { - _build_root_is_same_as_tree_root(leaves); - } - } -} diff --git a/verification/Cargo.toml b/verification/Cargo.toml index 70b47f8130..4e6be78da0 100644 --- a/verification/Cargo.toml +++ b/verification/Cargo.toml @@ -11,7 +11,7 @@ ckb-shared = { path = "../shared" } ckb-script = { path = "../script" } ckb-pow = { path = "../pow" } faketime = "0.2.0" -merkle-root = {path = "../util/merkle-root"} +ckb-merkle-tree = {path = "../util/merkle-tree"} numext-fixed-hash = { version = "0.1", features = ["support_rand", "support_heapsize", "support_serde"] } numext-fixed-uint = { version = "0.1", features = ["support_rand", "support_heapsize", "support_serde"] } rayon = "1.0" diff --git a/verification/src/block_verifier.rs b/verification/src/block_verifier.rs index 7ec448b04b..181c544efe 100644 --- a/verification/src/block_verifier.rs +++ b/verification/src/block_verifier.rs @@ -6,9 +6,9 @@ use ckb_core::cell::{CellProvider, CellStatus}; use ckb_core::header::Header; use ckb_core::transaction::{Capacity, CellInput, OutPoint}; use ckb_core::Cycle; +use ckb_merkle_tree::merkle_root; use ckb_shared::shared::ChainProvider; use fnv::{FnvHashMap, FnvHashSet}; -use merkle_root::merkle_root; use numext_fixed_hash::H256; use numext_fixed_uint::U256; use rayon::iter::{IndexedParallelIterator, IntoParallelRefIterator, ParallelIterator};