From ff3ef11df5bb81f2e0c68401bae369f91090a7ad Mon Sep 17 00:00:00 2001 From: Joii Date: Tue, 31 Aug 2021 16:13:54 +0800 Subject: [PATCH 01/16] Replace H256 with the one in rust-numext --- Cargo.toml | 1 + src/h256.rs | 47 ++++++++-------- src/lib.rs | 2 +- src/merge.rs | 10 ++-- src/merkle_proof.rs | 10 ++-- src/tests/tree.rs | 128 ++++++++++++++++++++++---------------------- src/traits.rs | 4 +- src/tree.rs | 10 ++-- 8 files changed, 106 insertions(+), 106 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index a994d73..3143765 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,6 +18,7 @@ blake2b = ["blake2b-rs"] [dependencies] cfg-if = "0.1" blake2b-rs = { version = "0.1", optional = true } +numext-fixed-hash = "0.1.6" [dev-dependencies] proptest = "0.9" diff --git a/src/h256.rs b/src/h256.rs index b76143b..1827e7c 100644 --- a/src/h256.rs +++ b/src/h256.rs @@ -1,41 +1,37 @@ +use numext_fixed_hash; + use core::cmp::Ordering; /// Represent 256 bits -#[derive(Eq, PartialEq, Debug, Default, Hash, Clone, Copy)] -pub struct H256([u8; 32]); +#[derive(Eq, PartialEq, Debug, Default, Hash, Clone)] +pub struct H256 { + inner: numext_fixed_hash::H256, +} -const ZERO: H256 = H256([0u8; 32]); const BYTE_SIZE: u8 = 8; impl H256 { - pub const fn zero() -> Self { - ZERO + pub const fn empty() -> Self { + H256 { inner: numext_fixed_hash::H256::empty() } } pub fn is_zero(&self) -> bool { - self == &ZERO + self.inner.is_empty() } #[inline] pub fn get_bit(&self, i: u8) -> bool { - let byte_pos = i / BYTE_SIZE; - let bit_pos = i % BYTE_SIZE; - let bit = self.0[byte_pos as usize] >> bit_pos & 1; - bit != 0 + self.inner.bit(i.into()).unwrap_or(false) } #[inline] pub fn set_bit(&mut self, i: u8) { - let byte_pos = i / BYTE_SIZE; - let bit_pos = i % BYTE_SIZE; - self.0[byte_pos as usize] |= 1 << bit_pos as u8; + self.inner.set_bit(i.into(), true); } #[inline] pub fn clear_bit(&mut self, i: u8) { - let byte_pos = i / BYTE_SIZE; - let bit_pos = i % BYTE_SIZE; - self.0[byte_pos as usize] &= !((1 << bit_pos) as u8); + self.inner.set_bit(i.into(), false); } #[inline] @@ -44,7 +40,7 @@ impl H256 { } pub fn as_slice(&self) -> &[u8] { - &self.0[..] + self.inner.as_bytes() } /// Treat H256 as a path in a tree @@ -62,7 +58,7 @@ impl H256 { /// return parent_path of self pub fn parent_path(&self, height: u8) -> Self { if height == core::u8::MAX { - H256::zero() + H256::empty() } else { self.copy_bits(height + 1) } @@ -70,16 +66,17 @@ impl H256 { /// Copy bits and return a new H256 pub fn copy_bits(&self, start: u8) -> Self { - let mut target = H256::zero(); + // It can also be implemented with And, but the performance is not as good as this + let mut target = H256::empty(); let start_byte = (start / BYTE_SIZE) as usize; // copy bytes - target.0[start_byte..].copy_from_slice(&self.0[start_byte..]); + target.inner.0[start_byte..].copy_from_slice(&self.inner.0[start_byte..]); // reset remain bytes let remain = start % BYTE_SIZE; if remain > 0 { - target.0[start_byte] &= 0b11111111 << remain + target.inner.0[start_byte] &= 0b11111111 << remain } target @@ -95,18 +92,20 @@ impl PartialOrd for H256 { impl Ord for H256 { fn cmp(&self, other: &Self) -> Ordering { // Compare bits from heigher to lower (255..0) - self.0.iter().rev().cmp(other.0.iter().rev()) + self.inner.0.iter().rev().cmp(other.inner.0.iter().rev()) } } impl From<[u8; 32]> for H256 { fn from(v: [u8; 32]) -> H256 { - H256(v) + H256{ + inner: numext_fixed_hash::H256::from(v), + } } } impl Into<[u8; 32]> for H256 { fn into(self: H256) -> [u8; 32] { - self.0 + self.inner.0 } } diff --git a/src/lib.rs b/src/lib.rs index b33f77e..a076e98 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -19,7 +19,7 @@ //! impl Value for Word { //! fn to_h256(&self) -> H256 { //! if self.0.is_empty() { -//! return H256::zero(); +//! return H256::empty(); //! } //! let mut buf = [0u8; 32]; //! let mut hasher = new_blake2b(); diff --git a/src/merge.rs b/src/merge.rs index c42cedb..291944d 100644 --- a/src/merge.rs +++ b/src/merge.rs @@ -20,7 +20,7 @@ impl MergeValue { } pub fn zero() -> Self { - MergeValue::Value(H256::zero()) + MergeValue::Value(H256::empty()) } pub fn is_zero(&self) -> bool { @@ -32,7 +32,7 @@ impl MergeValue { pub fn hash(&self) -> H256 { match self { - MergeValue::Value(v) => *v, + MergeValue::Value(v) => v.clone(), MergeValue::MergeWithZero { base_node, zero_bits, @@ -97,7 +97,7 @@ fn merge_with_zero( ) -> MergeValue { match value { MergeValue::Value(v) => { - let mut zero_bits = H256::zero(); + let mut zero_bits = H256::empty(); if set_bit { zero_bits.set_bit(height); } @@ -113,12 +113,12 @@ fn merge_with_zero( zero_bits, zero_count, } => { - let mut zero_bits = *zero_bits; + let mut zero_bits = zero_bits.clone(); if set_bit { zero_bits.set_bit(height); } MergeValue::MergeWithZero { - base_node: *base_node, + base_node: base_node.clone(), zero_bits, zero_count: zero_count.wrapping_add(1), } diff --git a/src/merkle_proof.rs b/src/merkle_proof.rs index ba102f7..91b2d47 100644 --- a/src/merkle_proof.rs +++ b/src/merkle_proof.rs @@ -59,7 +59,7 @@ impl MerkleProof { }); } // sort leaves - leaves.sort_unstable_by_key(|(k, _v)| *k); + leaves.sort_unstable_by_key(|(k, _v)| k.clone()); let (leaves_bitmap, merkle_path) = self.take(); @@ -69,7 +69,7 @@ impl MerkleProof { let mut leaf_index = 0; let mut merkle_path_index = 0; while leaf_index < leaves.len() { - let (leaf_key, _value) = leaves[leaf_index]; + let (leaf_key, _value) = leaves[leaf_index].clone(); let fork_height = if leaf_index + 1 < leaves.len() { leaf_key.fork_height(&leaves[leaf_index + 1].0) } else { @@ -184,7 +184,7 @@ pub struct CompiledMerkleProof(pub Vec); impl CompiledMerkleProof { pub fn compute_root(&self, mut leaves: Vec<(H256, H256)>) -> Result { - leaves.sort_unstable_by_key(|(k, _v)| *k); + leaves.sort_unstable_by_key(|(k, _v)| k.clone()); let mut program_index = 0; let mut leaf_index = 0; let mut stack: Vec<(u16, H256, MergeValue)> = Vec::new(); @@ -197,7 +197,7 @@ impl CompiledMerkleProof { if leaf_index >= leaves.len() { return Err(Error::CorruptedStack); } - let (k, v) = leaves[leaf_index]; + let (k, v) = leaves[leaf_index].clone(); stack.push((0, k, MergeValue::from_h256(v))); leaf_index += 1; } @@ -308,7 +308,7 @@ impl CompiledMerkleProof { if base_height > 255 { return Err(Error::CorruptedProof); } - let mut parent_key = key; + let mut parent_key = key.clone(); let mut height_u16 = base_height; for idx in 0..zero_count { if base_height + idx > 255 { diff --git a/src/tests/tree.rs b/src/tests/tree.rs index ce72fc5..0d26745 100644 --- a/src/tests/tree.rs +++ b/src/tests/tree.rs @@ -13,33 +13,33 @@ fn test_default_root() { let mut tree = SMT::default(); assert_eq!(tree.store().branches_map().len(), 0); assert_eq!(tree.store().leaves_map().len(), 0); - assert_eq!(tree.root(), &H256::zero()); + assert_eq!(tree.root(), &H256::empty()); // insert a key-value - tree.update(H256::zero(), [42u8; 32].into()) + tree.update(H256::empty(), [42u8; 32].into()) .expect("update"); - assert_ne!(tree.root(), &H256::zero()); + assert_ne!(tree.root(), &H256::empty()); assert_ne!(tree.store().branches_map().len(), 0); assert_ne!(tree.store().leaves_map().len(), 0); - assert_eq!(tree.get(&H256::zero()).expect("get"), [42u8; 32].into()); + assert_eq!(tree.get(&H256::empty()).expect("get"), [42u8; 32].into()); // update zero is to delete the key - tree.update(H256::zero(), H256::zero()).expect("update"); - assert_eq!(tree.root(), &H256::zero()); - assert_eq!(tree.get(&H256::zero()).expect("get"), H256::zero()); + tree.update(H256::empty(), H256::empty()).expect("update"); + assert_eq!(tree.root(), &H256::empty()); + assert_eq!(tree.get(&H256::empty()).expect("get"), H256::empty()); } #[test] fn test_default_tree() { let tree = SMT::default(); - assert_eq!(tree.get(&H256::zero()).expect("get"), H256::zero()); - let proof = tree.merkle_proof(vec![H256::zero()]).expect("merkle proof"); + assert_eq!(tree.get(&H256::empty()).expect("get"), H256::empty()); + let proof = tree.merkle_proof(vec![H256::empty()]).expect("merkle proof"); let root = proof - .compute_root::(vec![(H256::zero(), H256::zero())]) + .compute_root::(vec![(H256::empty(), H256::empty())]) .expect("root"); assert_eq!(&root, tree.root()); - let proof = tree.merkle_proof(vec![H256::zero()]).expect("merkle proof"); + let proof = tree.merkle_proof(vec![H256::empty()]).expect("merkle proof"); let root2 = proof - .compute_root::(vec![(H256::zero(), [42u8; 32].into())]) + .compute_root::(vec![(H256::empty(), [42u8; 32].into())]) .expect("root"); assert_ne!(&root2, tree.root()); } @@ -61,7 +61,7 @@ fn test_default_merkle_proof() { // let root = proof // .compute_root::(vec![([42u8; 32].into(), [42u8; 32].into())]) // .expect("compute root"); - // assert_ne!(root, H256::zero()); + // assert_ne!(root, H256::empty()); } #[test] @@ -109,9 +109,9 @@ fn test_zero_value_donot_change_root() { 0, 1, ] .into(); - let value = H256::zero(); + let value = H256::empty(); tree.update(key, value).unwrap(); - assert_eq!(tree.root(), &H256::zero()); + assert_eq!(tree.root(), &H256::empty()); assert_eq!(tree.store().leaves_map().len(), 0); assert_eq!(tree.store().branches_map().len(), 0); } @@ -130,8 +130,8 @@ fn test_zero_value_donot_change_store() { ] .into(); tree.update(key, value).unwrap(); - assert_ne!(tree.root(), &H256::zero()); - let root = *tree.root(); + assert_ne!(tree.root(), &H256::empty()); + let root = tree.root().clone(); let store = tree.store().clone(); // insert a zero value leaf @@ -165,12 +165,12 @@ fn test_delete_a_leaf() { ] .into(); tree.update(key, value).unwrap(); - assert_ne!(tree.root(), &H256::zero()); - let root = *tree.root(); + assert_ne!(tree.root(), &H256::empty()); + let root = tree.root().clone(); let store = tree.store().clone(); // insert a leaf - let key = [ + let key: H256 = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, ] @@ -180,11 +180,11 @@ fn test_delete_a_leaf() { 0, 1, ] .into(); - tree.update(key, value).unwrap(); + tree.update(key.clone(), value).unwrap(); assert_ne!(tree.root(), &root); // delete a leaf - tree.update(key, H256::zero()).unwrap(); + tree.update(key, H256::empty()).unwrap(); assert_eq!(tree.root(), &root); assert_eq!(tree.store().leaves_map(), store.leaves_map()); assert_eq!(tree.store().branches_map(), store.branches_map()); @@ -206,7 +206,7 @@ fn test_sibling_key_get() { 0, 0, 0, ]); // get non exists sibling key should return zero value; - assert_eq!(H256::zero(), tree.get(&sibling_key).unwrap()); + assert_eq!(H256::empty(), tree.get(&sibling_key).unwrap()); } { @@ -216,14 +216,14 @@ fn test_sibling_key_get() { 0, 0, 0, ]); let value = H256::from([1u8; 32]); - tree.update(key, value).expect("update"); + tree.update(key.clone(), value.clone()).expect("update"); let sibling_key = H256::from([ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ]); let sibling_value = H256::from([2u8; 32]); - tree.update(sibling_key, sibling_value).expect("update"); + tree.update(sibling_key.clone(), sibling_value.clone()).expect("update"); // get sibling key should return corresponding value assert_eq!(value, tree.get(&key).unwrap()); assert_eq!(sibling_value, tree.get(&sibling_key).unwrap()); @@ -234,7 +234,7 @@ fn test_construct(key: H256, value: H256) { // insert same value to sibling key will construct a different root let mut tree = SMT::default(); - tree.update(key, value).expect("update"); + tree.update(key.clone(), value.clone()).expect("update"); let mut sibling_key = key; if sibling_key.get_bit(0) { @@ -249,7 +249,7 @@ fn test_construct(key: H256, value: H256) { fn test_update(key: H256, value: H256) { let mut tree = SMT::default(); - tree.update(key, value).expect("update"); + tree.update(key.clone(), value.clone()).expect("update"); assert_eq!(tree.get(&key), Ok(value)); } @@ -257,10 +257,10 @@ fn test_update_tree_store(key: H256, value: H256, value2: H256) { const EXPECTED_LEAVES_LEN: usize = 1; let mut tree = SMT::default(); - tree.update(key, value).expect("update"); + tree.update(key.clone(), value).expect("update"); assert_eq!(tree.store().branches_map().len(), 256); assert_eq!(tree.store().leaves_map().len(), EXPECTED_LEAVES_LEN); - tree.update(key, value2).expect("update"); + tree.update(key.clone(), value2.clone()).expect("update"); assert_eq!(tree.store().branches_map().len(), 256); assert_eq!(tree.store().leaves_map().len(), EXPECTED_LEAVES_LEN); assert_eq!(tree.get(&key), Ok(value2)); @@ -270,16 +270,16 @@ fn test_merkle_proof(key: H256, value: H256) { const EXPECTED_MERKLE_PATH_SIZE: usize = 1; let mut tree = SMT::default(); - tree.update(key, value).expect("update"); + tree.update(key.clone(), value.clone()).expect("update"); if !tree.is_empty() { - let proof = tree.merkle_proof(vec![key]).expect("proof"); + let proof = tree.merkle_proof(vec![key.clone()]).expect("proof"); let compiled_proof = proof .clone() - .compile(vec![(key, value)]) + .compile(vec![(key.clone(), value.clone())]) .expect("compile proof"); assert!(proof.merkle_path().len() < EXPECTED_MERKLE_PATH_SIZE); assert!(proof - .verify::(tree.root(), vec![(key, value)]) + .verify::(tree.root(), vec![(key.clone(), value.clone())]) .expect("verify")); assert!(compiled_proof .verify::(tree.root(), vec![(key, value)]) @@ -341,7 +341,7 @@ proptest! { let mut list1: Vec = vec![key.into() , key2.into()]; let mut list2 = list1.clone(); // sort H256 - list1.sort_unstable_by_key(|k| *k); + list1.sort_unstable_by_key(|k| k.clone()); // sort by high bits to lower bits list2.sort_unstable_by(|k1, k2| { for i in (0u8..=255).rev() { @@ -393,9 +393,9 @@ proptest! { fn test_smt_single_leaf_small((pairs, _n) in leaves(1, 50)){ let smt = new_smt(pairs.clone()); for (k, v) in pairs { - let proof = smt.merkle_proof(vec![k]).expect("gen proof"); - let compiled_proof = proof.clone().compile(vec![(k, v)]).expect("compile proof"); - assert!(proof.verify::(smt.root(), vec![(k, v)]).expect("verify proof")); + let proof = smt.merkle_proof(vec![k.clone()]).expect("gen proof"); + let compiled_proof = proof.clone().compile(vec![(k.clone(), v.clone())]).expect("compile proof"); + assert!(proof.verify::(smt.root(), vec![(k.clone(), v.clone())]).expect("verify proof")); assert!(compiled_proof.verify::(smt.root(), vec![(k, v)]).expect("verify compiled proof")); } } @@ -404,9 +404,9 @@ proptest! { fn test_smt_single_leaf_large((pairs, _n) in leaves(50, 100)){ let smt = new_smt(pairs.clone()); for (k, v) in pairs { - let proof = smt.merkle_proof(vec![k]).expect("gen proof"); - let compiled_proof = proof.clone().compile(vec![(k, v)]).expect("compile proof"); - assert!(proof.verify::(smt.root(), vec![(k, v)]).expect("verify proof")); + let proof = smt.merkle_proof(vec![k.clone()]).expect("gen proof"); + let compiled_proof = proof.clone().compile(vec![(k.clone(), v.clone())]).expect("compile proof"); + assert!(proof.verify::(smt.root(), vec![(k.clone(), v.clone())]).expect("verify proof")); assert!(compiled_proof.verify::(smt.root(), vec![(k, v)]).expect("verify compiled proof")); } } @@ -414,7 +414,7 @@ proptest! { #[test] fn test_smt_multi_leaves_small((pairs, n) in leaves(1, 50)){ let smt = new_smt(pairs.clone()); - let proof = smt.merkle_proof(pairs.iter().take(n).map(|(k, _v)| *k).collect()).expect("gen proof"); + let proof = smt.merkle_proof(pairs.iter().take(n).map(|(k, _v)| k.clone()).collect()).expect("gen proof"); let data: Vec<(H256, H256)> = pairs.into_iter().take(n).collect(); let compiled_proof = proof.clone().compile(data.clone()).expect("compile proof"); assert!(proof.verify::(smt.root(), data.clone()).expect("verify proof")); @@ -425,7 +425,7 @@ proptest! { fn test_smt_multi_leaves_large((pairs, _n) in leaves(50, 100)){ let n = 20; let smt = new_smt(pairs.clone()); - let proof = smt.merkle_proof(pairs.iter().take(n).map(|(k, _v)| *k).collect()).expect("gen proof"); + let proof = smt.merkle_proof(pairs.iter().take(n).map(|(k, _v)| k.clone()).collect()).expect("gen proof"); let data: Vec<(H256, H256)> = pairs.into_iter().take(n).collect(); let compiled_proof = proof.clone().compile(data.clone()).expect("compile proof"); assert!(proof.verify::(smt.root(), data.clone()).expect("verify proof")); @@ -437,7 +437,7 @@ proptest! { let smt = new_smt(pairs); let non_exists_keys: Vec<_> = pairs2.into_iter().map(|(k, _v)|k).collect(); let proof = smt.merkle_proof(non_exists_keys.clone()).expect("gen proof"); - let data: Vec<(H256, H256)> = non_exists_keys.into_iter().map(|k|(k, H256::zero())).collect(); + let data: Vec<(H256, H256)> = non_exists_keys.into_iter().map(|k|(k, H256::empty())).collect(); let compiled_proof = proof.clone().compile(data.clone()).expect("compile proof"); assert!(proof.verify::(smt.root(), data.clone()).expect("verify proof")); assert!(compiled_proof.verify::(smt.root(), data).expect("verify compiled proof")); @@ -453,7 +453,7 @@ proptest! { let mut keys: Vec<_> = exists_keys.into_iter().take(exists_keys_len).chain(non_exists_keys.into_iter().take(non_exists_keys_len)).collect(); keys.dedup(); let proof = smt.merkle_proof(keys.clone()).expect("gen proof"); - let data: Vec<(H256, H256)> = keys.into_iter().map(|k|(k, smt.get(&k).expect("get"))).collect(); + let data: Vec<(H256, H256)> = keys.into_iter().map(|k|(k.clone(), smt.get(&k).expect("get"))).collect(); let compiled_proof = proof.clone().compile(data.clone()).expect("compile proof"); assert!(proof.verify::(smt.root(), data.clone()).expect("verify proof")); assert!(compiled_proof.verify::(smt.root(), data).expect("verify compiled proof")); @@ -470,7 +470,7 @@ proptest! { #[test] fn test_smt_random_insert_order((pairs, _n) in leaves(5, 50)){ let smt = new_smt(pairs.clone()); - let root = *smt.root(); + let root = smt.root().clone(); let mut pairs = pairs; let mut rng = rand::thread_rng(); @@ -486,11 +486,11 @@ proptest! { for (k, v) in &pairs { assert_eq!(&smt2.get(k).unwrap(), v, "key value must be consisted"); - let origin_proof = smt.merkle_proof(vec![*k]).unwrap(); - let proof = smt2.merkle_proof(vec![*k]).unwrap(); + let origin_proof = smt.merkle_proof(vec![k.clone()]).unwrap(); + let proof = smt2.merkle_proof(vec![k.clone()]).unwrap(); assert_eq!(origin_proof, proof, "merkle proof must be consisted"); - let calculated_root = proof.compute_root::(vec![(*k, *v)]).unwrap(); + let calculated_root = proof.compute_root::(vec![(k.clone(), v.clone())]).unwrap(); assert_eq!(root, calculated_root, "root must be consisted"); } } @@ -501,14 +501,14 @@ proptest! { let mut rng = rand::thread_rng(); let len = rng.gen_range(0, pairs.len()); let mut smt = new_smt(pairs[..len].to_vec()); - let root = *smt.root(); + let root = smt.root().clone(); // insert zero values for (k, _v) in pairs[len..].iter() { - smt.update(*k, H256::zero()).unwrap(); + smt.update(k.clone(), H256::empty()).unwrap(); } // check root - let current_root = *smt.root(); + let current_root = smt.root().clone(); assert_eq!(root, current_root); // check inserted pairs for (k, v) in pairs[..len].iter() { @@ -598,14 +598,14 @@ fn test_v0_2_broken_sample() { .collect::>(); let mut pairs = keys.into_iter().zip(values.into_iter()).collect::>(); let smt = new_smt(pairs.clone()); - let base_root = *smt.root(); + let base_root = smt.root().clone(); // insert in random order let mut rng = rand::thread_rng(); for _i in 0..10 { pairs.shuffle(&mut rng); let smt = new_smt(pairs.clone()); - let current_root = *smt.root(); + let current_root = smt.root().clone(); assert_eq!(base_root, current_root); } } @@ -687,14 +687,14 @@ fn test_replay_to_pass_proof() { ] .into(); let pairs = vec![ - (key1, existing), - (key2, non_existing), - (key3, non_existing), - (key4, non_existing), + (key1.clone(), existing), + (key2, non_existing.clone()), + (key3.clone(), non_existing.clone()), + (key4, non_existing.clone()), ]; let smt = new_smt(pairs); - let leaf_a_bl = vec![(key1, H256::zero())]; - let leaf_c = vec![(key3, non_existing)]; + let leaf_a_bl = vec![(key1, H256::empty())]; + let leaf_c = vec![(key3.clone(), non_existing)]; let leaf_other = vec![(key3, other_value)]; let proofc = smt .merkle_proof(leaf_c.clone().into_iter().map(|(k, _)| k).collect()) @@ -734,13 +734,13 @@ fn test_sibling_leaf() { H256::from(rand_data) } let rand_key = gen_rand_h256(); - let mut sibling_key = rand_key; + let mut sibling_key = rand_key.clone(); if rand_key.is_right(0) { sibling_key.clear_bit(0); } else { sibling_key.set_bit(0); } - let pairs = vec![(rand_key, gen_rand_h256()), (sibling_key, gen_rand_h256())]; + let pairs = vec![(rand_key.clone(), gen_rand_h256()), (sibling_key.clone(), gen_rand_h256())]; let keys = vec![rand_key, sibling_key]; let smt = new_smt(pairs.clone()); let proof = smt.merkle_proof(keys).expect("gen proof"); @@ -753,7 +753,7 @@ fn test_sibling_leaf() { fn test_max_stack_size() { fn gen_h256(height: u8) -> H256 { // The key path is first go right `256 - height` times then go left `height` times. - let mut key = H256::zero(); + let mut key = H256::empty(); for h in height..=255 { key.set_bit(h); } @@ -763,10 +763,10 @@ fn test_max_stack_size() { .map(|height| (gen_h256(height), gen_h256(1))) .collect(); // Most left key - pairs.push((H256::zero(), gen_h256(1))); + pairs.push((H256::empty(), gen_h256(1))); { // A pair of sibling keys in between - let mut left_key = H256::zero(); + let mut left_key = H256::empty(); for h in 12..56 { left_key.set_bit(h); } diff --git a/src/traits.rs b/src/traits.rs index a7b617e..73cd6c4 100644 --- a/src/traits.rs +++ b/src/traits.rs @@ -19,10 +19,10 @@ pub trait Value { impl Value for H256 { fn to_h256(&self) -> H256 { - *self + self.clone() } fn zero() -> Self { - H256::zero() + H256::empty() } } diff --git a/src/tree.rs b/src/tree.rs index 7304d25..26ed50f 100644 --- a/src/tree.rs +++ b/src/tree.rs @@ -93,7 +93,7 @@ impl> SparseMerkleTree { let node = MergeValue::from_h256(value.to_h256()); // notice when value is zero the leaf is deleted, so we do not need to store it if !node.is_zero() { - self.store.insert_leaf(key, value)?; + self.store.insert_leaf(key.clone(), value)?; } else { self.store.remove_leaf(&key)?; } @@ -103,7 +103,7 @@ impl> SparseMerkleTree { let mut current_node = node; for height in 0..=core::u8::MAX { let parent_key = current_key.parent_path(height); - let parent_branch_key = BranchKey::new(height, parent_key); + let parent_branch_key = BranchKey::new(height, parent_key.clone()); let (left, right) = if let Some(parent_branch) = self.store.get_branch(&parent_branch_key)? { if current_key.is_right(height) { @@ -131,7 +131,7 @@ impl> SparseMerkleTree { self.store.remove_branch(&parent_branch_key)?; } // prepare for next round - current_key = parent_key; + current_key = parent_key.clone(); current_node = merge::(height, &parent_key, &left, &right); } @@ -160,7 +160,7 @@ impl> SparseMerkleTree { // Collect leaf bitmaps let mut leaves_bitmap: Vec = Default::default(); for current_key in &keys { - let mut bitmap = H256::zero(); + let mut bitmap = H256::empty(); for height in 0..=core::u8::MAX { let parent_key = current_key.parent_path(height); let parent_branch_key = BranchKey::new(height, parent_key); @@ -185,7 +185,7 @@ impl> SparseMerkleTree { let mut stack_top = 0; let mut leaf_index = 0; while leaf_index < keys.len() { - let leaf_key = keys[leaf_index]; + let leaf_key = keys[leaf_index].clone(); let fork_height = if leaf_index + 1 < keys.len() { leaf_key.fork_height(&keys[leaf_index + 1]) } else { From d3e48c3604e846705a5ec127e44e884c58066862 Mon Sep 17 00:00:00 2001 From: Joii Date: Wed, 1 Sep 2021 11:03:59 +0800 Subject: [PATCH 02/16] Delete class H256 completely, use numext H256 instead. --- benches/smt_benchmark.rs | 7 ++- src/blake2b.rs | 2 +- src/h256.rs | 120 +++++++++------------------------------ src/merge.rs | 6 +- src/merkle_proof.rs | 88 +++++++++++++++++----------- src/tests/tree.rs | 91 ++++++++++++++++++++++------- src/tree.rs | 66 ++++++++++++--------- 7 files changed, 199 insertions(+), 181 deletions(-) diff --git a/benches/smt_benchmark.rs b/benches/smt_benchmark.rs index d067942..692a036 100644 --- a/benches/smt_benchmark.rs +++ b/benches/smt_benchmark.rs @@ -4,8 +4,9 @@ extern crate criterion; use criterion::Criterion; use rand::{thread_rng, Rng}; use sparse_merkle_tree::{ - blake2b::Blake2bHasher, default_store::DefaultStore, tree::SparseMerkleTree, H256, + blake2b::Blake2bHasher, default_store::DefaultStore, tree::SparseMerkleTree, H256 }; +use core::cmp::Ordering; const TARGET_LEAVES_COUNT: usize = 20; @@ -23,7 +24,7 @@ fn random_smt(update_count: usize, rng: &mut impl Rng) -> (SMT, Vec) { for _ in 0..update_count { let key = random_h256(rng); let value = random_h256(rng); - smt.update(key, value).unwrap(); + smt.update(key.clone(), value.clone()).unwrap(); keys.push(key); } (smt, keys) @@ -71,7 +72,7 @@ fn bench(c: &mut Criterion) { let leaves: Vec<_> = keys .iter() .take(TARGET_LEAVES_COUNT) - .map(|k| (*k, smt.get(k).unwrap())) + .map(|k| (k.clone(), smt.get(&k).unwrap())) .collect(); let proof = smt .merkle_proof(keys.into_iter().take(TARGET_LEAVES_COUNT).collect()) diff --git a/src/blake2b.rs b/src/blake2b.rs index 47f50e7..a264619 100644 --- a/src/blake2b.rs +++ b/src/blake2b.rs @@ -19,7 +19,7 @@ impl Default for Blake2bHasher { impl Hasher for Blake2bHasher { fn write_h256(&mut self, h: &H256) { - self.0.update(h.as_slice()); + self.0.update(h.as_bytes()); } fn write_byte(&mut self, b: u8) { self.0.update(&[b][..]); diff --git a/src/h256.rs b/src/h256.rs index 1827e7c..dc7bde3 100644 --- a/src/h256.rs +++ b/src/h256.rs @@ -1,111 +1,45 @@ use numext_fixed_hash; - use core::cmp::Ordering; -/// Represent 256 bits -#[derive(Eq, PartialEq, Debug, Default, Hash, Clone)] -pub struct H256 { - inner: numext_fixed_hash::H256, -} +pub type H256 = numext_fixed_hash::H256; const BYTE_SIZE: u8 = 8; -impl H256 { - pub const fn empty() -> Self { - H256 { inner: numext_fixed_hash::H256::empty() } - } - - pub fn is_zero(&self) -> bool { - self.inner.is_empty() - } - - #[inline] - pub fn get_bit(&self, i: u8) -> bool { - self.inner.bit(i.into()).unwrap_or(false) - } - - #[inline] - pub fn set_bit(&mut self, i: u8) { - self.inner.set_bit(i.into(), true); - } - - #[inline] - pub fn clear_bit(&mut self, i: u8) { - self.inner.set_bit(i.into(), false); - } - - #[inline] - pub fn is_right(&self, height: u8) -> bool { - self.get_bit(height) - } - - pub fn as_slice(&self) -> &[u8] { - self.inner.as_bytes() - } - - /// Treat H256 as a path in a tree - /// fork height is the number of common bits(from heigher to lower: 255..=0) of two H256 - pub fn fork_height(&self, key: &H256) -> u8 { - for h in (0..=core::u8::MAX).rev() { - if self.get_bit(h) != key.get_bit(h) { - return h; - } +pub fn fork_height(data: &H256, key: &H256) -> u8 { + for h in (0..=core::u8::MAX).rev() { + if data.bit(h.into()).unwrap_or(false) != key.bit(h.into()).unwrap_or(false) { + return h; } - 0 - } - - /// Treat H256 as a path in a tree - /// return parent_path of self - pub fn parent_path(&self, height: u8) -> Self { - if height == core::u8::MAX { - H256::empty() - } else { - self.copy_bits(height + 1) - } - } - - /// Copy bits and return a new H256 - pub fn copy_bits(&self, start: u8) -> Self { - // It can also be implemented with And, but the performance is not as good as this - let mut target = H256::empty(); - - let start_byte = (start / BYTE_SIZE) as usize; - // copy bytes - target.inner.0[start_byte..].copy_from_slice(&self.inner.0[start_byte..]); - - // reset remain bytes - let remain = start % BYTE_SIZE; - if remain > 0 { - target.inner.0[start_byte] &= 0b11111111 << remain - } - - target } + 0 } -impl PartialOrd for H256 { - fn partial_cmp(&self, other: &Self) -> Option { - Some(self.cmp(other)) +pub fn parent_path(data: &H256, height: u8) -> H256 { + if height == core::u8::MAX { + H256::empty() + } else { + copy_bits(data, height + 1) } } -impl Ord for H256 { - fn cmp(&self, other: &Self) -> Ordering { - // Compare bits from heigher to lower (255..0) - self.inner.0.iter().rev().cmp(other.inner.0.iter().rev()) - } -} +/// Copy bits and return a new H256 +pub fn copy_bits(data: &H256, start: u8) -> H256 { + // It can also be implemented with And, but the performance is not as good as this + let mut target = H256::empty(); -impl From<[u8; 32]> for H256 { - fn from(v: [u8; 32]) -> H256 { - H256{ - inner: numext_fixed_hash::H256::from(v), - } + let start_byte = (start / BYTE_SIZE) as usize; + // copy bytes + target.0[start_byte..].copy_from_slice(&data.0[start_byte..]); + + // reset remain bytes + let remain = start % BYTE_SIZE; + if remain > 0 { + target.0[start_byte] &= 0b11111111 << remain } + + target } -impl Into<[u8; 32]> for H256 { - fn into(self: H256) -> [u8; 32] { - self.inner.0 - } +pub fn h256_cmp(v1: &H256, v2: &H256) -> Ordering { + v1.0.iter().rev().cmp(v2.0.iter().rev()) } diff --git a/src/merge.rs b/src/merge.rs index 291944d..4eeb866 100644 --- a/src/merge.rs +++ b/src/merge.rs @@ -25,7 +25,7 @@ impl MergeValue { pub fn is_zero(&self) -> bool { if let MergeValue::Value(v) = self { - return v.is_zero(); + return v.is_empty(); } false } @@ -99,7 +99,7 @@ fn merge_with_zero( MergeValue::Value(v) => { let mut zero_bits = H256::empty(); if set_bit { - zero_bits.set_bit(height); + zero_bits.set_bit(height.into(), true); } let base_node = hash_base_node::(height, node_key, v); MergeValue::MergeWithZero { @@ -115,7 +115,7 @@ fn merge_with_zero( } => { let mut zero_bits = zero_bits.clone(); if set_bit { - zero_bits.set_bit(height); + zero_bits.set_bit(height.into(), true); } MergeValue::MergeWithZero { base_node: base_node.clone(), diff --git a/src/merkle_proof.rs b/src/merkle_proof.rs index 91b2d47..f303525 100644 --- a/src/merkle_proof.rs +++ b/src/merkle_proof.rs @@ -3,8 +3,28 @@ use crate::{ merge::{merge, MergeValue}, traits::Hasher, vec::Vec, - H256, MAX_STACK_SIZE, + h256, + H256, + MAX_STACK_SIZE, }; +use core::cmp::Ordering; + +#[derive(Eq, PartialEq, Debug, Default, Hash, Clone)] +struct H256Ord { + pub inner: H256, +} + +impl PartialOrd for H256Ord { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +impl Ord for H256Ord { + fn cmp(&self, other: &Self) -> Ordering { + h256::h256_cmp(&self.inner, &other.inner) + } +} #[derive(Debug, Clone, PartialEq, Eq)] pub struct MerkleProof { @@ -49,36 +69,38 @@ impl MerkleProof { &self.merkle_path } - pub fn compile(self, mut leaves: Vec<(H256, H256)>) -> Result { - if leaves.is_empty() { + pub fn compile(self, leaves: Vec<(H256, H256)>) -> Result { + let mut leaves_ord: Vec<(H256Ord, H256)> = + leaves.iter().take(leaves.len()).map(|(k, v)| (H256Ord{inner:k.clone()}, v.clone())).collect::>(); + if leaves_ord.is_empty() { return Err(Error::EmptyKeys); - } else if leaves.len() != self.leaves_count() { + } else if leaves_ord.len() != self.leaves_count() { return Err(Error::IncorrectNumberOfLeaves { expected: self.leaves_count(), - actual: leaves.len(), + actual: leaves_ord.len(), }); } // sort leaves - leaves.sort_unstable_by_key(|(k, _v)| k.clone()); + leaves_ord.sort_unstable_by_key(|(k, _v)| k.clone()); let (leaves_bitmap, merkle_path) = self.take(); - let mut proof: Vec = Vec::with_capacity(merkle_path.len() * 33 + leaves.len()); + let mut proof: Vec = Vec::with_capacity(merkle_path.len() * 33 + leaves_ord.len()); let mut stack_fork_height = [0u8; MAX_STACK_SIZE]; // store fork height let mut stack_top = 0; let mut leaf_index = 0; let mut merkle_path_index = 0; - while leaf_index < leaves.len() { - let (leaf_key, _value) = leaves[leaf_index].clone(); - let fork_height = if leaf_index + 1 < leaves.len() { - leaf_key.fork_height(&leaves[leaf_index + 1].0) + while leaf_index < leaves_ord.len() { + let (leaf_key, _value) = leaves_ord[leaf_index].clone(); + let fork_height = if leaf_index + 1 < leaves_ord.len() { + h256::fork_height(&leaf_key.inner, &leaves_ord[leaf_index + 1].0.inner) } else { core::u8::MAX }; proof.push(0x4C); let mut zero_count = 0u16; for height in 0..=fork_height { - if height == fork_height && leaf_index + 1 < leaves.len() { + if height == fork_height && leaf_index + 1 < leaves_ord.len() { // If it's not final round, we don't need to merge to root (height=255) break; } @@ -86,14 +108,14 @@ impl MerkleProof { if stack_top > 0 && stack_fork_height[stack_top - 1] == height { stack_top -= 1; (Some(0x48), None) - } else if leaves_bitmap[leaf_index].get_bit(height) { + } else if leaves_bitmap[leaf_index].bit(height.into()).unwrap_or(false) { if merkle_path_index >= merkle_path.len() { return Err(Error::CorruptedProof); } let node = &merkle_path[merkle_path_index]; merkle_path_index += 1; match node { - MergeValue::Value(v) => (Some(0x50), Some(v.as_slice().to_vec())), + MergeValue::Value(v) => (Some(0x50), Some(v.as_bytes().to_vec())), MergeValue::MergeWithZero { base_node, zero_bits, @@ -101,8 +123,8 @@ impl MerkleProof { } => { let mut buffer = Vec::new(); buffer.push(*zero_count); - buffer.extend_from_slice(base_node.as_slice()); - buffer.extend_from_slice(zero_bits.as_slice()); + buffer.extend_from_slice(base_node.as_bytes()); + buffer.extend_from_slice(zero_bits.as_bytes()); (Some(0x51), Some(buffer)) } } @@ -148,7 +170,7 @@ impl MerkleProof { if stack_top != 1 { return Err(Error::CorruptedProof); } - if leaf_index != leaves.len() { + if leaf_index != leaves_ord.len() { return Err(Error::CorruptedProof); } if merkle_path_index != merkle_path.len() { @@ -183,8 +205,10 @@ impl MerkleProof { pub struct CompiledMerkleProof(pub Vec); impl CompiledMerkleProof { - pub fn compute_root(&self, mut leaves: Vec<(H256, H256)>) -> Result { - leaves.sort_unstable_by_key(|(k, _v)| k.clone()); + pub fn compute_root(&self, leaves: Vec<(H256, H256)>) -> Result { + let mut leaves_ord: Vec<(H256Ord, H256)> = + leaves.iter().take(leaves.len()).map(|(k, v)| (H256Ord{inner:k.clone()}, v.clone())).collect(); + leaves_ord.sort_unstable_by_key(|(k, _v)| k.clone()); let mut program_index = 0; let mut leaf_index = 0; let mut stack: Vec<(u16, H256, MergeValue)> = Vec::new(); @@ -194,11 +218,11 @@ impl CompiledMerkleProof { match code { // L : push leaf value 0x4C => { - if leaf_index >= leaves.len() { + if leaf_index >= leaves_ord.len() { return Err(Error::CorruptedStack); } - let (k, v) = leaves[leaf_index].clone(); - stack.push((0, k, MergeValue::from_h256(v))); + let (k, v) = leaves_ord[leaf_index].clone(); + stack.push((0, k.inner, MergeValue::from_h256(v))); leaf_index += 1; } // P : hash stack top item with sibling node in proof @@ -218,8 +242,8 @@ impl CompiledMerkleProof { return Err(Error::CorruptedProof); } let height = height_u16 as u8; - let parent_key = key.parent_path(height); - let parent = if key.get_bit(height) { + let parent_key = h256::parent_path(&key, height); + let parent = if key.bit(height.into()).unwrap_or(false) { merge::(height, &parent_key, &sibling_node, &value) } else { merge::(height, &parent_key, &value, &sibling_node) @@ -258,8 +282,8 @@ impl CompiledMerkleProof { return Err(Error::CorruptedProof); } let height = height_u16 as u8; - let parent_key = key.parent_path(height); - let parent = if key.get_bit(height) { + let parent_key = h256::parent_path(&key, height); + let parent = if key.bit(height.into()).unwrap_or(false) { merge::(height, &parent_key, &sibling_node, &value) } else { merge::(height, &parent_key, &value, &sibling_node) @@ -281,12 +305,12 @@ impl CompiledMerkleProof { } let height_u16 = height_a; let height = height_u16 as u8; - let parent_key_a = key_a.parent_path(height); - let parent_key_b = key_b.parent_path(height); + let parent_key_a = h256::parent_path(&key_a, height); + let parent_key_b = h256::parent_path(&key_b, height); if parent_key_a != parent_key_b { return Err(Error::CorruptedProof); } - let parent = if key_a.get_bit(height) { + let parent = if key_a.bit(height.into()).unwrap_or(false) { merge::(height, &parent_key_a, &value_b, &value_a) } else { merge::(height, &parent_key_a, &value_a, &value_b) @@ -316,8 +340,8 @@ impl CompiledMerkleProof { } height_u16 = base_height + idx; let height = height_u16 as u8; - parent_key = key.parent_path(height); - value = if key.get_bit(height) { + parent_key = h256::parent_path(&key, height); + value = if key.bit(height.into()).unwrap_or(false) { merge::(height, &parent_key, &MergeValue::zero(), &value) } else { merge::(height, &parent_key, &value, &MergeValue::zero()) @@ -335,7 +359,7 @@ impl CompiledMerkleProof { if stack[0].0 != 256 { return Err(Error::CorruptedProof); } - if leaf_index != leaves.len() { + if leaf_index != leaves_ord.len() { return Err(Error::CorruptedProof); } Ok(stack[0].2.hash::()) diff --git a/src/tests/tree.rs b/src/tests/tree.rs index 0d26745..be7ea22 100644 --- a/src/tests/tree.rs +++ b/src/tests/tree.rs @@ -1,13 +1,57 @@ use crate::*; use crate::{ blake2b::Blake2bHasher, default_store::DefaultStore, error::Error, merge::MergeValue, - MerkleProof, SparseMerkleTree, + MerkleProof, SparseMerkleTree }; use proptest::prelude::*; use rand::prelude::{Rng, SliceRandom}; +use core::cmp::Ordering; type SMT = SparseMerkleTree>; +#[derive(Eq, PartialEq, Debug, Default, Hash, Clone)] +pub struct H256OrdTest { + pub inner: H256, +} + +impl H256OrdTest { + pub fn empty() -> H256OrdTest { + H256OrdTest::from(H256::empty()) + } +} + +impl From<[u8; 32]> for H256OrdTest { + fn from(v: [u8; 32]) -> H256OrdTest { + H256OrdTest { inner: H256::from(v)} + } +} + +impl From for H256OrdTest { + fn from(v: H256) -> H256OrdTest { + H256OrdTest { inner: v } + } +} + +impl From<&H256> for H256OrdTest { + fn from(v: &H256) -> H256OrdTest { + H256OrdTest { inner: v.clone() } + } +} + +impl PartialOrd for H256OrdTest { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +impl Ord for H256OrdTest { + fn cmp(&self, other: &Self) -> Ordering { + // Compare bits from heigher to lower (255..0) + self.inner.0.iter().rev().cmp(other.inner.0.iter().rev()) + } +} + + #[test] fn test_default_root() { let mut tree = SMT::default(); @@ -237,10 +281,10 @@ fn test_construct(key: H256, value: H256) { tree.update(key.clone(), value.clone()).expect("update"); let mut sibling_key = key; - if sibling_key.get_bit(0) { - sibling_key.clear_bit(0); + if sibling_key.bit(0).unwrap_or(false) { + sibling_key.set_bit(0, false); } else { - sibling_key.set_bit(0); + sibling_key.set_bit(0, true); } let mut tree2 = SMT::default(); tree2.update(sibling_key, value).expect("update"); @@ -338,15 +382,15 @@ fn merkle_proof(max_proof: usize) -> impl Strategy> { proptest! { #[test] fn test_h256(key: [u8; 32], key2: [u8; 32]) { - let mut list1: Vec = vec![key.into() , key2.into()]; + let mut list1: Vec = vec![H256OrdTest::from(key) , H256OrdTest::from(key2)]; let mut list2 = list1.clone(); // sort H256 list1.sort_unstable_by_key(|k| k.clone()); // sort by high bits to lower bits list2.sort_unstable_by(|k1, k2| { for i in (0u8..=255).rev() { - let b1 = if k1.get_bit(i) { 1 } else { 0 }; - let b2 = if k2.get_bit(i) { 1 } else { 0 }; + let b1 = if k1.inner.bit(i.into()).unwrap_or(false) { 1 } else { 0 }; + let b2 = if k2.inner.bit(i.into()).unwrap_or(false) { 1 } else { 0 }; let o = b1.cmp(&b2); if o != std::cmp::Ordering::Equal { return o; @@ -360,12 +404,12 @@ proptest! { #[test] fn test_h256_copy_bits(start: u8) { let one: H256 = [255u8; 32].into(); - let target = one.copy_bits(start); + let target = h256::copy_bits(&one, start); for i in start..=core::u8::MAX { - assert_eq!(one.get_bit(i), target.get_bit(i)); + assert_eq!(one.bit(i.into()).unwrap_or(false), target.bit(i.into()).unwrap_or(false)); } for i in 0..start { - assert!(!target.get_bit(i)); + assert!(!target.bit(i.into()).unwrap_or(false)); } } @@ -484,7 +528,7 @@ proptest! { // check leaves for (k, v) in &pairs { - assert_eq!(&smt2.get(k).unwrap(), v, "key value must be consisted"); + assert_eq!(&smt2.get(&k).unwrap(), v, "key value must be consisted"); let origin_proof = smt.merkle_proof(vec![k.clone()]).unwrap(); let proof = smt2.merkle_proof(vec![k.clone()]).unwrap(); @@ -512,7 +556,7 @@ proptest! { assert_eq!(root, current_root); // check inserted pairs for (k, v) in pairs[..len].iter() { - let value = smt.get(k).unwrap(); + let value = smt.get(&k).unwrap(); assert_eq!(v, &value); } } @@ -596,7 +640,8 @@ fn test_v0_2_broken_sample() { .into_iter() .map(parse_h256) .collect::>(); - let mut pairs = keys.into_iter().zip(values.into_iter()).collect::>(); + let mut pairs = + keys.iter().take(keys.len()).map(|k| k.clone()).into_iter().zip(values.into_iter()).collect::>(); let smt = new_smt(pairs.clone()); let base_root = smt.root().clone(); @@ -688,9 +733,9 @@ fn test_replay_to_pass_proof() { .into(); let pairs = vec![ (key1.clone(), existing), - (key2, non_existing.clone()), + (key2.clone(), non_existing.clone()), (key3.clone(), non_existing.clone()), - (key4, non_existing.clone()), + (key4.clone(), non_existing.clone()), ]; let smt = new_smt(pairs); let leaf_a_bl = vec![(key1, H256::empty())]; @@ -735,12 +780,14 @@ fn test_sibling_leaf() { } let rand_key = gen_rand_h256(); let mut sibling_key = rand_key.clone(); - if rand_key.is_right(0) { - sibling_key.clear_bit(0); + if rand_key.bit(0).unwrap_or(false) { + sibling_key.set_bit(0, false); } else { - sibling_key.set_bit(0); + sibling_key.set_bit(0, true); } - let pairs = vec![(rand_key.clone(), gen_rand_h256()), (sibling_key.clone(), gen_rand_h256())]; + let pairs = vec![ + (rand_key.clone(), gen_rand_h256()), + (sibling_key.clone(), gen_rand_h256())]; let keys = vec![rand_key, sibling_key]; let smt = new_smt(pairs.clone()); let proof = smt.merkle_proof(keys).expect("gen proof"); @@ -755,7 +802,7 @@ fn test_max_stack_size() { // The key path is first go right `256 - height` times then go left `height` times. let mut key = H256::empty(); for h in height..=255 { - key.set_bit(h); + key.set_bit(h.into(), true); } key } @@ -768,10 +815,10 @@ fn test_max_stack_size() { // A pair of sibling keys in between let mut left_key = H256::empty(); for h in 12..56 { - left_key.set_bit(h); + left_key.set_bit(h, true); } let mut right_key = left_key.clone(); - right_key.set_bit(0); + right_key.set_bit(0, true); pairs.push((left_key, gen_h256(1))); pairs.push((right_key, gen_h256(1))); } diff --git a/src/tree.rs b/src/tree.rs index 26ed50f..c5ecf93 100644 --- a/src/tree.rs +++ b/src/tree.rs @@ -1,11 +1,4 @@ -use crate::{ - error::{Error, Result}, - merge::{merge, MergeValue}, - merkle_proof::MerkleProof, - traits::{Hasher, Store, Value}, - vec::Vec, - H256, MAX_STACK_SIZE, -}; +use crate::{H256, MAX_STACK_SIZE, error::{Error, Result}, h256, merge::{merge, MergeValue}, merkle_proof::MerkleProof, traits::{Hasher, Store, Value}, vec::Vec}; use core::cmp::Ordering; use core::marker::PhantomData; @@ -51,6 +44,23 @@ pub struct SparseMerkleTree { phantom: PhantomData<(H, V)>, } +#[derive(Eq, PartialEq, Debug, Default, Hash, Clone)] +struct H256OrdTree { + pub inner: H256, +} + +impl PartialOrd for H256OrdTree { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +impl Ord for H256OrdTree { + fn cmp(&self, other: &Self) -> Ordering { + h256::h256_cmp(&self.inner, &other.inner) + } +} + impl> SparseMerkleTree { /// Build a merkle tree from root and store pub fn new(root: H256, store: S) -> SparseMerkleTree { @@ -68,7 +78,7 @@ impl> SparseMerkleTree { /// Check empty of the tree pub fn is_empty(&self) -> bool { - self.root.is_zero() + self.root.is_empty() } /// Destroy current tree and retake store @@ -102,16 +112,16 @@ impl> SparseMerkleTree { let mut current_key = key; let mut current_node = node; for height in 0..=core::u8::MAX { - let parent_key = current_key.parent_path(height); + let parent_key = h256::parent_path(¤t_key, height); let parent_branch_key = BranchKey::new(height, parent_key.clone()); let (left, right) = if let Some(parent_branch) = self.store.get_branch(&parent_branch_key)? { - if current_key.is_right(height) { + if current_key.bit(height.into()).unwrap_or(false) { (parent_branch.left, current_node) } else { (current_node, parent_branch.right) } - } else if current_key.is_right(height) { + } else if current_key.bit(height.into()).unwrap_or(false) { (MergeValue::zero(), current_node) } else { (current_node, MergeValue::zero()) @@ -149,29 +159,31 @@ impl> SparseMerkleTree { } /// Generate merkle proof - pub fn merkle_proof(&self, mut keys: Vec) -> Result { - if keys.is_empty() { + pub fn merkle_proof(&self, keys: Vec) -> Result { + let mut keys_ord = + keys.iter().take(keys.len()).map(|k| H256OrdTree{inner:k.clone()}).collect::>(); + if keys_ord.is_empty() { return Err(Error::EmptyKeys); } // sort keys - keys.sort_unstable(); + keys_ord.sort_unstable(); // Collect leaf bitmaps let mut leaves_bitmap: Vec = Default::default(); - for current_key in &keys { + for current_key in &keys_ord { let mut bitmap = H256::empty(); for height in 0..=core::u8::MAX { - let parent_key = current_key.parent_path(height); + let parent_key = h256::parent_path(¤t_key.inner, height); let parent_branch_key = BranchKey::new(height, parent_key); if let Some(parent_branch) = self.store.get_branch(&parent_branch_key)? { - let sibling = if current_key.is_right(height) { + let sibling = if current_key.inner.bit(height.into()).unwrap_or(false) { parent_branch.left } else { parent_branch.right }; if !sibling.is_zero() { - bitmap.set_bit(height); + bitmap.set_bit(height.into(), true); } } else { // The key is not in the tree (support non-inclusion proof) @@ -184,25 +196,25 @@ impl> SparseMerkleTree { let mut stack_fork_height = [0u8; MAX_STACK_SIZE]; // store fork height let mut stack_top = 0; let mut leaf_index = 0; - while leaf_index < keys.len() { - let leaf_key = keys[leaf_index].clone(); - let fork_height = if leaf_index + 1 < keys.len() { - leaf_key.fork_height(&keys[leaf_index + 1]) + while leaf_index < keys_ord.len() { + let leaf_key = keys_ord[leaf_index].inner.clone(); + let fork_height = if leaf_index + 1 < keys_ord.len() { + h256::fork_height(&leaf_key, &keys_ord[leaf_index + 1].inner) } else { core::u8::MAX }; for height in 0..=fork_height { - if height == fork_height && leaf_index + 1 < keys.len() { + if height == fork_height && leaf_index + 1 < keys_ord.len() { // If it's not final round, we don't need to merge to root (height=255) break; } - let parent_key = leaf_key.parent_path(height); - let is_right = leaf_key.is_right(height); + let parent_key = h256::parent_path(&leaf_key, height); + let is_right = leaf_key.bit(height.into()).unwrap_or(false); // has non-zero sibling if stack_top > 0 && stack_fork_height[stack_top - 1] == height { stack_top -= 1; - } else if leaves_bitmap[leaf_index].get_bit(height) { + } else if leaves_bitmap[leaf_index].bit(height.into()).unwrap_or(false) { let parent_branch_key = BranchKey::new(height, parent_key); if let Some(parent_branch) = self.store.get_branch(&parent_branch_key)? { let sibling = if is_right { From 70c2fd2b8e4c042d2ce0e4ef9465114cf9d23768 Mon Sep 17 00:00:00 2001 From: Joii Date: Wed, 1 Sep 2021 11:18:03 +0800 Subject: [PATCH 03/16] Repair warning, delete two unused codes --- benches/smt_benchmark.rs | 2 -- src/tests/tree.rs | 6 ------ 2 files changed, 8 deletions(-) diff --git a/benches/smt_benchmark.rs b/benches/smt_benchmark.rs index 692a036..eb8a3b1 100644 --- a/benches/smt_benchmark.rs +++ b/benches/smt_benchmark.rs @@ -6,8 +6,6 @@ use rand::{thread_rng, Rng}; use sparse_merkle_tree::{ blake2b::Blake2bHasher, default_store::DefaultStore, tree::SparseMerkleTree, H256 }; -use core::cmp::Ordering; - const TARGET_LEAVES_COUNT: usize = 20; type SMT = SparseMerkleTree>; diff --git a/src/tests/tree.rs b/src/tests/tree.rs index be7ea22..a603aea 100644 --- a/src/tests/tree.rs +++ b/src/tests/tree.rs @@ -14,12 +14,6 @@ pub struct H256OrdTest { pub inner: H256, } -impl H256OrdTest { - pub fn empty() -> H256OrdTest { - H256OrdTest::from(H256::empty()) - } -} - impl From<[u8; 32]> for H256OrdTest { fn from(v: [u8; 32]) -> H256OrdTest { H256OrdTest { inner: H256::from(v)} From fcb8ac44eb7dc68592df57b6490bc951b6553e5f Mon Sep 17 00:00:00 2001 From: Joii Date: Wed, 1 Sep 2021 11:34:50 +0800 Subject: [PATCH 04/16] The last time the format was changed, the CI problem has been resolved --- benches/smt_benchmark.rs | 2 +- src/h256.rs | 4 ++-- src/merkle_proof.rs | 24 ++++++++++++++++-------- src/tests/tree.rs | 32 ++++++++++++++++++++++---------- src/tree.rs | 22 ++++++++++++++++++---- 5 files changed, 59 insertions(+), 25 deletions(-) diff --git a/benches/smt_benchmark.rs b/benches/smt_benchmark.rs index eb8a3b1..eb73bcb 100644 --- a/benches/smt_benchmark.rs +++ b/benches/smt_benchmark.rs @@ -4,7 +4,7 @@ extern crate criterion; use criterion::Criterion; use rand::{thread_rng, Rng}; use sparse_merkle_tree::{ - blake2b::Blake2bHasher, default_store::DefaultStore, tree::SparseMerkleTree, H256 + blake2b::Blake2bHasher, default_store::DefaultStore, tree::SparseMerkleTree, H256, }; const TARGET_LEAVES_COUNT: usize = 20; diff --git a/src/h256.rs b/src/h256.rs index dc7bde3..219bc46 100644 --- a/src/h256.rs +++ b/src/h256.rs @@ -1,5 +1,5 @@ -use numext_fixed_hash; use core::cmp::Ordering; +use numext_fixed_hash; pub type H256 = numext_fixed_hash::H256; @@ -24,7 +24,7 @@ pub fn parent_path(data: &H256, height: u8) -> H256 { /// Copy bits and return a new H256 pub fn copy_bits(data: &H256, start: u8) -> H256 { - // It can also be implemented with And, but the performance is not as good as this + // It can also be implemented with And, but the performance is not as good as this let mut target = H256::empty(); let start_byte = (start / BYTE_SIZE) as usize; diff --git a/src/merkle_proof.rs b/src/merkle_proof.rs index f303525..8f5b24d 100644 --- a/src/merkle_proof.rs +++ b/src/merkle_proof.rs @@ -1,11 +1,10 @@ use crate::{ error::{Error, Result}, + h256, merge::{merge, MergeValue}, traits::Hasher, vec::Vec, - h256, - H256, - MAX_STACK_SIZE, + H256, MAX_STACK_SIZE, }; use core::cmp::Ordering; @@ -70,8 +69,11 @@ impl MerkleProof { } pub fn compile(self, leaves: Vec<(H256, H256)>) -> Result { - let mut leaves_ord: Vec<(H256Ord, H256)> = - leaves.iter().take(leaves.len()).map(|(k, v)| (H256Ord{inner:k.clone()}, v.clone())).collect::>(); + let mut leaves_ord: Vec<(H256Ord, H256)> = leaves + .iter() + .take(leaves.len()) + .map(|(k, v)| (H256Ord { inner: k.clone() }, v.clone())) + .collect::>(); if leaves_ord.is_empty() { return Err(Error::EmptyKeys); } else if leaves_ord.len() != self.leaves_count() { @@ -108,7 +110,10 @@ impl MerkleProof { if stack_top > 0 && stack_fork_height[stack_top - 1] == height { stack_top -= 1; (Some(0x48), None) - } else if leaves_bitmap[leaf_index].bit(height.into()).unwrap_or(false) { + } else if leaves_bitmap[leaf_index] + .bit(height.into()) + .unwrap_or(false) + { if merkle_path_index >= merkle_path.len() { return Err(Error::CorruptedProof); } @@ -206,8 +211,11 @@ pub struct CompiledMerkleProof(pub Vec); impl CompiledMerkleProof { pub fn compute_root(&self, leaves: Vec<(H256, H256)>) -> Result { - let mut leaves_ord: Vec<(H256Ord, H256)> = - leaves.iter().take(leaves.len()).map(|(k, v)| (H256Ord{inner:k.clone()}, v.clone())).collect(); + let mut leaves_ord: Vec<(H256Ord, H256)> = leaves + .iter() + .take(leaves.len()) + .map(|(k, v)| (H256Ord { inner: k.clone() }, v.clone())) + .collect(); leaves_ord.sort_unstable_by_key(|(k, _v)| k.clone()); let mut program_index = 0; let mut leaf_index = 0; diff --git a/src/tests/tree.rs b/src/tests/tree.rs index a603aea..1ef1506 100644 --- a/src/tests/tree.rs +++ b/src/tests/tree.rs @@ -1,11 +1,11 @@ use crate::*; use crate::{ blake2b::Blake2bHasher, default_store::DefaultStore, error::Error, merge::MergeValue, - MerkleProof, SparseMerkleTree + MerkleProof, SparseMerkleTree, }; +use core::cmp::Ordering; use proptest::prelude::*; use rand::prelude::{Rng, SliceRandom}; -use core::cmp::Ordering; type SMT = SparseMerkleTree>; @@ -16,7 +16,9 @@ pub struct H256OrdTest { impl From<[u8; 32]> for H256OrdTest { fn from(v: [u8; 32]) -> H256OrdTest { - H256OrdTest { inner: H256::from(v)} + H256OrdTest { + inner: H256::from(v), + } } } @@ -45,7 +47,6 @@ impl Ord for H256OrdTest { } } - #[test] fn test_default_root() { let mut tree = SMT::default(); @@ -70,12 +71,16 @@ fn test_default_root() { fn test_default_tree() { let tree = SMT::default(); assert_eq!(tree.get(&H256::empty()).expect("get"), H256::empty()); - let proof = tree.merkle_proof(vec![H256::empty()]).expect("merkle proof"); + let proof = tree + .merkle_proof(vec![H256::empty()]) + .expect("merkle proof"); let root = proof .compute_root::(vec![(H256::empty(), H256::empty())]) .expect("root"); assert_eq!(&root, tree.root()); - let proof = tree.merkle_proof(vec![H256::empty()]).expect("merkle proof"); + let proof = tree + .merkle_proof(vec![H256::empty()]) + .expect("merkle proof"); let root2 = proof .compute_root::(vec![(H256::empty(), [42u8; 32].into())]) .expect("root"); @@ -261,7 +266,8 @@ fn test_sibling_key_get() { 0, 0, 0, ]); let sibling_value = H256::from([2u8; 32]); - tree.update(sibling_key.clone(), sibling_value.clone()).expect("update"); + tree.update(sibling_key.clone(), sibling_value.clone()) + .expect("update"); // get sibling key should return corresponding value assert_eq!(value, tree.get(&key).unwrap()); assert_eq!(sibling_value, tree.get(&sibling_key).unwrap()); @@ -634,8 +640,13 @@ fn test_v0_2_broken_sample() { .into_iter() .map(parse_h256) .collect::>(); - let mut pairs = - keys.iter().take(keys.len()).map(|k| k.clone()).into_iter().zip(values.into_iter()).collect::>(); + let mut pairs = keys + .iter() + .take(keys.len()) + .map(|k| k.clone()) + .into_iter() + .zip(values.into_iter()) + .collect::>(); let smt = new_smt(pairs.clone()); let base_root = smt.root().clone(); @@ -781,7 +792,8 @@ fn test_sibling_leaf() { } let pairs = vec![ (rand_key.clone(), gen_rand_h256()), - (sibling_key.clone(), gen_rand_h256())]; + (sibling_key.clone(), gen_rand_h256()), + ]; let keys = vec![rand_key, sibling_key]; let smt = new_smt(pairs.clone()); let proof = smt.merkle_proof(keys).expect("gen proof"); diff --git a/src/tree.rs b/src/tree.rs index c5ecf93..18faff9 100644 --- a/src/tree.rs +++ b/src/tree.rs @@ -1,4 +1,12 @@ -use crate::{H256, MAX_STACK_SIZE, error::{Error, Result}, h256, merge::{merge, MergeValue}, merkle_proof::MerkleProof, traits::{Hasher, Store, Value}, vec::Vec}; +use crate::{ + error::{Error, Result}, + h256, + merge::{merge, MergeValue}, + merkle_proof::MerkleProof, + traits::{Hasher, Store, Value}, + vec::Vec, + H256, MAX_STACK_SIZE, +}; use core::cmp::Ordering; use core::marker::PhantomData; @@ -160,8 +168,11 @@ impl> SparseMerkleTree { /// Generate merkle proof pub fn merkle_proof(&self, keys: Vec) -> Result { - let mut keys_ord = - keys.iter().take(keys.len()).map(|k| H256OrdTree{inner:k.clone()}).collect::>(); + let mut keys_ord = keys + .iter() + .take(keys.len()) + .map(|k| H256OrdTree { inner: k.clone() }) + .collect::>(); if keys_ord.is_empty() { return Err(Error::EmptyKeys); } @@ -214,7 +225,10 @@ impl> SparseMerkleTree { // has non-zero sibling if stack_top > 0 && stack_fork_height[stack_top - 1] == height { stack_top -= 1; - } else if leaves_bitmap[leaf_index].bit(height.into()).unwrap_or(false) { + } else if leaves_bitmap[leaf_index] + .bit(height.into()) + .unwrap_or(false) + { let parent_branch_key = BranchKey::new(height, parent_key); if let Some(parent_branch) = self.store.get_branch(&parent_branch_key)? { let sibling = if is_right { From dff1e56e8f9d60bca47119defa9d1d1140367056 Mon Sep 17 00:00:00 2001 From: Joii Date: Wed, 1 Sep 2021 15:06:10 +0800 Subject: [PATCH 05/16] Remove H256 from lib.rs and change it to SmtH256 to avoid confusion; merge H256Ord to avoid code duplication. --- benches/smt_benchmark.rs | 8 +- c/rust-tests/src/tests/smt.rs | 37 ++++---- src/blake2b.rs | 6 +- src/default_store.rs | 12 +-- src/error.rs | 6 +- src/h256.rs | 54 +++++++++-- src/lib.rs | 9 +- src/merge.rs | 28 +++--- src/merkle_proof.rs | 66 ++++++------- src/tests/fixtures.rs | 8 +- src/tests/tree.rs | 168 +++++++++++++--------------------- src/traits.rs | 20 ++-- src/tree.rs | 43 +++------ 13 files changed, 219 insertions(+), 246 deletions(-) diff --git a/benches/smt_benchmark.rs b/benches/smt_benchmark.rs index eb73bcb..77afb8c 100644 --- a/benches/smt_benchmark.rs +++ b/benches/smt_benchmark.rs @@ -4,19 +4,19 @@ extern crate criterion; use criterion::Criterion; use rand::{thread_rng, Rng}; use sparse_merkle_tree::{ - blake2b::Blake2bHasher, default_store::DefaultStore, tree::SparseMerkleTree, H256, + blake2b::Blake2bHasher, default_store::DefaultStore, h256::SmtH256, tree::SparseMerkleTree, }; const TARGET_LEAVES_COUNT: usize = 20; -type SMT = SparseMerkleTree>; +type SMT = SparseMerkleTree>; -fn random_h256(rng: &mut impl Rng) -> H256 { +fn random_h256(rng: &mut impl Rng) -> SmtH256 { let mut buf = [0u8; 32]; rng.fill(&mut buf); buf.into() } -fn random_smt(update_count: usize, rng: &mut impl Rng) -> (SMT, Vec) { +fn random_smt(update_count: usize, rng: &mut impl Rng) -> (SMT, Vec) { let mut smt = SparseMerkleTree::default(); let mut keys = Vec::with_capacity(update_count); for _ in 0..update_count { diff --git a/c/rust-tests/src/tests/smt.rs b/c/rust-tests/src/tests/smt.rs index e0419a5..87a374d 100644 --- a/c/rust-tests/src/tests/smt.rs +++ b/c/rust-tests/src/tests/smt.rs @@ -6,9 +6,8 @@ use proptest::prelude::*; use rand::prelude::Rng; use serde::{Deserialize, Serialize}; use sparse_merkle_tree::traits::Hasher; -use sparse_merkle_tree::{default_store::DefaultStore, SparseMerkleTree, H256}; +use sparse_merkle_tree::{default_store::DefaultStore, h256::SmtH256, SparseMerkleTree}; use std::collections::HashMap; -use std::fs; #[link(name = "dl-c-impl", kind = "static")] extern "C" { @@ -144,19 +143,19 @@ impl Hasher for CkbBlake2bHasher { fn write_byte(&mut self, b: u8) { self.0.update(&[b][..]); } - fn write_h256(&mut self, h: &H256) { - self.0.update(h.as_slice()); + fn write_h256(&mut self, h: &SmtH256) { + self.0.update(h.as_bytes()); } - fn finish(self) -> H256 { + fn finish(self) -> SmtH256 { let mut hash = [0u8; 32]; self.0.finalize(&mut hash); hash.into() } } -pub type CkbSMT = SparseMerkleTree>; +pub type CkbSMT = SparseMerkleTree>; -pub fn new_ckb_smt(pairs: Vec<(H256, H256)>) -> CkbSMT { +pub fn _new_ckb_smt(pairs: Vec<(SmtH256, SmtH256)>) -> CkbSMT { let mut smt = CkbSMT::default(); for (key, value) in pairs { smt.update(key, value).unwrap(); @@ -228,10 +227,10 @@ fn test_normalize_random() { } } -fn run_test_case(case: Case) -> AnyResult<()> { +fn _run_test_case(case: Case) -> AnyResult<()> { let Case { leaves, proofs, .. } = case; - let ckb_smt = new_ckb_smt( + let ckb_smt = _new_ckb_smt( leaves .iter() .map(|(k, v)| ((*k).into(), (*v).into())) @@ -273,7 +272,7 @@ fn run_test_case(case: Case) -> AnyResult<()> { assert_eq!(smt_state.len(), leaves.len() as u32); smt_state - .verify(ckb_smt.root().as_slice(), &ckb_actual_compiled_proof_bin) + .verify(ckb_smt.root().as_bytes(), &ckb_actual_compiled_proof_bin) .unwrap(); } Ok(()) @@ -295,32 +294,32 @@ fn run_test_case(case: Case) -> AnyResult<()> { proptest! { #[test] fn test_random_merkle_proof(key: [u8; 32], value: [u8;32]) { - let key = H256::from(key); - let value = H256::from(value); + let key = SmtH256::from(key); + let value = SmtH256::from(value); const EXPECTED_PROOF_SIZE: usize = 16; let mut tree = CkbSMT::default(); - tree.update(key, value).expect("update"); + tree.update(key.clone(), value.clone()).expect("update"); if !tree.is_empty() { - let proof = tree.merkle_proof(vec![key]).expect("proof"); + let proof = tree.merkle_proof(vec![key.clone()]).expect("proof"); let compiled_proof = proof .clone() - .compile(vec![(key, value)]) + .compile(vec![(key.clone(), value.clone())]) .expect("compile proof"); assert!(proof.merkle_path().len() < EXPECTED_PROOF_SIZE); assert!(proof - .verify::(tree.root(), vec![(key, value)]) + .verify::(tree.root(), vec![(key.clone(), value.clone())]) .expect("verify")); assert!(compiled_proof - .verify::(tree.root(), vec![(key, value)]) + .verify::(tree.root(), vec![(key.clone(), value.clone())]) .expect("compiled verify")); let compiled_proof_bin: Vec = compiled_proof.into(); let mut smt_state = SmtCImpl::new(8); - smt_state.insert(key.as_slice(), value.as_slice()).unwrap(); + smt_state.insert(key.as_bytes(), value.as_bytes()).unwrap(); smt_state.normalize(); smt_state - .verify(tree.root().as_slice(), &compiled_proof_bin) + .verify(tree.root().as_bytes(), &compiled_proof_bin) .expect("verify with c"); } } diff --git a/src/blake2b.rs b/src/blake2b.rs index a264619..4aa34ce 100644 --- a/src/blake2b.rs +++ b/src/blake2b.rs @@ -1,4 +1,4 @@ -use crate::{traits::Hasher, H256}; +use crate::{h256::SmtH256, traits::Hasher}; use blake2b_rs::{Blake2b, Blake2bBuilder}; const BLAKE2B_KEY: &[u8] = &[]; @@ -18,13 +18,13 @@ impl Default for Blake2bHasher { } impl Hasher for Blake2bHasher { - fn write_h256(&mut self, h: &H256) { + fn write_h256(&mut self, h: &SmtH256) { self.0.update(h.as_bytes()); } fn write_byte(&mut self, b: u8) { self.0.update(&[b][..]); } - fn finish(self) -> H256 { + fn finish(self) -> SmtH256 { let mut hash = [0u8; 32]; self.0.finalize(&mut hash); hash.into() diff --git a/src/default_store.rs b/src/default_store.rs index fda98b1..abba33a 100644 --- a/src/default_store.rs +++ b/src/default_store.rs @@ -1,22 +1,22 @@ use crate::{ collections, error::Error, + h256::SmtH256, traits::Store, tree::{BranchKey, BranchNode}, - H256, }; #[derive(Debug, Clone, Default)] pub struct DefaultStore { branches_map: Map, - leaves_map: Map, + leaves_map: Map, } impl DefaultStore { pub fn branches_map(&self) -> &Map { &self.branches_map } - pub fn leaves_map(&self) -> &Map { + pub fn leaves_map(&self) -> &Map { &self.leaves_map } pub fn clear(&mut self) { @@ -29,14 +29,14 @@ impl Store for DefaultStore { fn get_branch(&self, branch_key: &BranchKey) -> Result, Error> { Ok(self.branches_map.get(branch_key).map(Clone::clone)) } - fn get_leaf(&self, leaf_key: &H256) -> Result, Error> { + fn get_leaf(&self, leaf_key: &SmtH256) -> Result, Error> { Ok(self.leaves_map.get(leaf_key).map(Clone::clone)) } fn insert_branch(&mut self, branch_key: BranchKey, branch: BranchNode) -> Result<(), Error> { self.branches_map.insert(branch_key, branch); Ok(()) } - fn insert_leaf(&mut self, leaf_key: H256, leaf: V) -> Result<(), Error> { + fn insert_leaf(&mut self, leaf_key: SmtH256, leaf: V) -> Result<(), Error> { self.leaves_map.insert(leaf_key, leaf); Ok(()) } @@ -44,7 +44,7 @@ impl Store for DefaultStore { self.branches_map.remove(branch_key); Ok(()) } - fn remove_leaf(&mut self, leaf_key: &H256) -> Result<(), Error> { + fn remove_leaf(&mut self, leaf_key: &SmtH256) -> Result<(), Error> { self.leaves_map.remove(leaf_key); Ok(()) } diff --git a/src/error.rs b/src/error.rs index 3f4f79f..a2abf57 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,11 +1,11 @@ -use crate::{string, H256}; +use crate::{h256::SmtH256, string}; pub type Result = ::core::result::Result; #[derive(Debug, Clone, PartialEq, Eq)] pub enum Error { - MissingBranch(u8, H256), - MissingLeaf(H256), + MissingBranch(u8, SmtH256), + MissingLeaf(SmtH256), CorruptedProof, EmptyProof, EmptyKeys, diff --git a/src/h256.rs b/src/h256.rs index 219bc46..3d936dc 100644 --- a/src/h256.rs +++ b/src/h256.rs @@ -1,11 +1,11 @@ use core::cmp::Ordering; use numext_fixed_hash; -pub type H256 = numext_fixed_hash::H256; +pub type SmtH256 = numext_fixed_hash::H256; const BYTE_SIZE: u8 = 8; -pub fn fork_height(data: &H256, key: &H256) -> u8 { +pub fn fork_height(data: &SmtH256, key: &SmtH256) -> u8 { for h in (0..=core::u8::MAX).rev() { if data.bit(h.into()).unwrap_or(false) != key.bit(h.into()).unwrap_or(false) { return h; @@ -14,18 +14,18 @@ pub fn fork_height(data: &H256, key: &H256) -> u8 { 0 } -pub fn parent_path(data: &H256, height: u8) -> H256 { +pub fn parent_path(data: &SmtH256, height: u8) -> SmtH256 { if height == core::u8::MAX { - H256::empty() + SmtH256::empty() } else { copy_bits(data, height + 1) } } -/// Copy bits and return a new H256 -pub fn copy_bits(data: &H256, start: u8) -> H256 { +/// Copy bits and return a new SmtH256 +pub fn copy_bits(data: &SmtH256, start: u8) -> SmtH256 { // It can also be implemented with And, but the performance is not as good as this - let mut target = H256::empty(); + let mut target = SmtH256::empty(); let start_byte = (start / BYTE_SIZE) as usize; // copy bytes @@ -40,6 +40,44 @@ pub fn copy_bits(data: &H256, start: u8) -> H256 { target } -pub fn h256_cmp(v1: &H256, v2: &H256) -> Ordering { +#[derive(Debug, Clone, Eq, PartialEq, Hash)] +pub struct SmtH256Ord { + pub inner: SmtH256, +} + +impl From<[u8; 32]> for SmtH256Ord { + fn from(v: [u8; 32]) -> SmtH256Ord { + SmtH256Ord { + inner: SmtH256::from(v), + } + } +} + +impl From for SmtH256Ord { + fn from(v: SmtH256) -> SmtH256Ord { + SmtH256Ord { inner: v } + } +} + +impl From<&SmtH256> for SmtH256Ord { + fn from(v: &SmtH256) -> SmtH256Ord { + SmtH256Ord { inner: v.clone() } + } +} + +impl PartialOrd for SmtH256Ord { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +impl Ord for SmtH256Ord { + fn cmp(&self, other: &Self) -> Ordering { + // Compare bits from heigher to lower (255..0) + self.inner.0.iter().rev().cmp(other.inner.0.iter().rev()) + } +} + +pub fn h256_cmp(v1: &SmtH256, v2: &SmtH256) -> Ordering { v1.0.iter().rev().cmp(v2.0.iter().rev()) } diff --git a/src/lib.rs b/src/lib.rs index a076e98..b3cdda0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -6,7 +6,7 @@ //! use sparse_merkle_tree::{ //! blake2b::Blake2bHasher, default_store::DefaultStore, //! error::Error, MerkleProof, -//! SparseMerkleTree, traits::Value, H256 +//! SparseMerkleTree, traits::Value, h256::SmtH256 //! }; //! use blake2b_rs::{Blake2b, Blake2bBuilder}; //! @@ -17,9 +17,9 @@ //! #[derive(Default, Clone)] //! pub struct Word(String); //! impl Value for Word { -//! fn to_h256(&self) -> H256 { +//! fn to_h256(&self) -> SmtH256 { //! if self.0.is_empty() { -//! return H256::empty(); +//! return SmtH256::empty(); //! } //! let mut buf = [0u8; 32]; //! let mut hasher = new_blake2b(); @@ -43,7 +43,7 @@ //! .split_whitespace() //! .enumerate() //! { -//! let key: H256 = { +//! let key: SmtH256 = { //! let mut buf = [0u8; 32]; //! let mut hasher = new_blake2b(); //! hasher.update(&(i as u32).to_le_bytes()); @@ -73,7 +73,6 @@ mod tests; pub mod traits; pub mod tree; -pub use h256::H256; pub use merkle_proof::{CompiledMerkleProof, MerkleProof}; pub use tree::SparseMerkleTree; diff --git a/src/merge.rs b/src/merge.rs index 4eeb866..ce67ddc 100644 --- a/src/merge.rs +++ b/src/merge.rs @@ -1,4 +1,4 @@ -use crate::h256::H256; +use crate::h256::SmtH256; use crate::traits::Hasher; const MERGE_NORMAL: u8 = 1; @@ -6,21 +6,21 @@ const MERGE_ZEROS: u8 = 2; #[derive(Debug, Eq, PartialEq, Clone)] pub enum MergeValue { - Value(H256), + Value(SmtH256), MergeWithZero { - base_node: H256, - zero_bits: H256, + base_node: SmtH256, + zero_bits: SmtH256, zero_count: u8, }, } impl MergeValue { - pub fn from_h256(v: H256) -> Self { + pub fn from_h256(v: SmtH256) -> Self { MergeValue::Value(v) } pub fn zero() -> Self { - MergeValue::Value(H256::empty()) + MergeValue::Value(SmtH256::empty()) } pub fn is_zero(&self) -> bool { @@ -30,7 +30,7 @@ impl MergeValue { false } - pub fn hash(&self) -> H256 { + pub fn hash(&self) -> SmtH256 { match self { MergeValue::Value(v) => v.clone(), MergeValue::MergeWithZero { @@ -49,12 +49,12 @@ impl MergeValue { } } -/// Hash base node into a H256 +/// Hash base node into a SmtH256 pub fn hash_base_node( base_height: u8, - base_key: &H256, - base_value: &H256, -) -> H256 { + base_key: &SmtH256, + base_value: &SmtH256, +) -> SmtH256 { let mut hasher = H::default(); hasher.write_byte(base_height); hasher.write_h256(base_key); @@ -67,7 +67,7 @@ pub fn hash_base_node( /// if lhs and rhs both are ZERO_HASH return ZERO_HASH, otherwise hash all info. pub fn merge( height: u8, - node_key: &H256, + node_key: &SmtH256, lhs: &MergeValue, rhs: &MergeValue, ) -> MergeValue { @@ -91,13 +91,13 @@ pub fn merge( fn merge_with_zero( height: u8, - node_key: &H256, + node_key: &SmtH256, value: &MergeValue, set_bit: bool, ) -> MergeValue { match value { MergeValue::Value(v) => { - let mut zero_bits = H256::empty(); + let mut zero_bits = SmtH256::empty(); if set_bit { zero_bits.set_bit(height.into(), true); } diff --git a/src/merkle_proof.rs b/src/merkle_proof.rs index 8f5b24d..55162e0 100644 --- a/src/merkle_proof.rs +++ b/src/merkle_proof.rs @@ -1,34 +1,18 @@ use crate::{ error::{Error, Result}, h256, + h256::SmtH256Ord, + h256::SmtH256, merge::{merge, MergeValue}, traits::Hasher, vec::Vec, - H256, MAX_STACK_SIZE, + MAX_STACK_SIZE, }; -use core::cmp::Ordering; - -#[derive(Eq, PartialEq, Debug, Default, Hash, Clone)] -struct H256Ord { - pub inner: H256, -} - -impl PartialOrd for H256Ord { - fn partial_cmp(&self, other: &Self) -> Option { - Some(self.cmp(other)) - } -} - -impl Ord for H256Ord { - fn cmp(&self, other: &Self) -> Ordering { - h256::h256_cmp(&self.inner, &other.inner) - } -} #[derive(Debug, Clone, PartialEq, Eq)] pub struct MerkleProof { // leaf bitmap, bitmap.get_bit(height) is true means there need a non zero sibling in this height - leaves_bitmap: Vec, + leaves_bitmap: Vec, // needed sibling node hash merkle_path: Vec, } @@ -37,7 +21,7 @@ impl MerkleProof { /// Create MerkleProof /// leaves_bitmap: leaf bitmap, bitmap.get_bit(height) is true means there need a non zero sibling in this height /// proof: needed sibling node hash - pub fn new(leaves_bitmap: Vec, merkle_path: Vec) -> Self { + pub fn new(leaves_bitmap: Vec, merkle_path: Vec) -> Self { MerkleProof { leaves_bitmap, merkle_path, @@ -45,7 +29,7 @@ impl MerkleProof { } /// Destruct the structure, useful for serialization - pub fn take(self) -> (Vec, Vec) { + pub fn take(self) -> (Vec, Vec) { let MerkleProof { leaves_bitmap, merkle_path, @@ -59,7 +43,7 @@ impl MerkleProof { } /// return the inner leaves_bitmap vector - pub fn leaves_bitmap(&self) -> &Vec { + pub fn leaves_bitmap(&self) -> &Vec { &self.leaves_bitmap } @@ -68,11 +52,11 @@ impl MerkleProof { &self.merkle_path } - pub fn compile(self, leaves: Vec<(H256, H256)>) -> Result { - let mut leaves_ord: Vec<(H256Ord, H256)> = leaves + pub fn compile(self, leaves: Vec<(SmtH256, SmtH256)>) -> Result { + let mut leaves_ord: Vec<(SmtH256Ord, SmtH256)> = leaves .iter() .take(leaves.len()) - .map(|(k, v)| (H256Ord { inner: k.clone() }, v.clone())) + .map(|(k, v)| (SmtH256Ord { inner: k.clone() }, v.clone())) .collect::>(); if leaves_ord.is_empty() { return Err(Error::EmptyKeys); @@ -189,7 +173,10 @@ impl MerkleProof { /// /// return EmptyProof error when proof is empty /// return CorruptedProof error when proof is invalid - pub fn compute_root(self, leaves: Vec<(H256, H256)>) -> Result { + pub fn compute_root( + self, + leaves: Vec<(SmtH256, SmtH256)>, + ) -> Result { self.compile(leaves.clone())?.compute_root::(leaves) } @@ -197,8 +184,8 @@ impl MerkleProof { /// see compute_root_from_proof pub fn verify( self, - root: &H256, - leaves: Vec<(H256, H256)>, + root: &SmtH256, + leaves: Vec<(SmtH256, SmtH256)>, ) -> Result { let calculated_root = self.compute_root::(leaves)?; Ok(&calculated_root == root) @@ -210,16 +197,19 @@ impl MerkleProof { pub struct CompiledMerkleProof(pub Vec); impl CompiledMerkleProof { - pub fn compute_root(&self, leaves: Vec<(H256, H256)>) -> Result { - let mut leaves_ord: Vec<(H256Ord, H256)> = leaves + pub fn compute_root( + &self, + leaves: Vec<(SmtH256, SmtH256)>, + ) -> Result { + let mut leaves_ord: Vec<(SmtH256Ord, SmtH256)> = leaves .iter() .take(leaves.len()) - .map(|(k, v)| (H256Ord { inner: k.clone() }, v.clone())) + .map(|(k, v)| (SmtH256Ord { inner: k.clone() }, v.clone())) .collect(); leaves_ord.sort_unstable_by_key(|(k, _v)| k.clone()); let mut program_index = 0; let mut leaf_index = 0; - let mut stack: Vec<(u16, H256, MergeValue)> = Vec::new(); + let mut stack: Vec<(u16, SmtH256, MergeValue)> = Vec::new(); while program_index < self.0.len() { let code = self.0[program_index]; program_index += 1; @@ -244,7 +234,7 @@ impl CompiledMerkleProof { let mut data = [0u8; 32]; data.copy_from_slice(&self.0[program_index..program_index + 32]); program_index += 32; - let sibling_node = MergeValue::from_h256(H256::from(data)); + let sibling_node = MergeValue::from_h256(SmtH256::from(data)); let (height_u16, key, value) = stack.pop().unwrap(); if height_u16 > 255 { return Err(Error::CorruptedProof); @@ -272,12 +262,12 @@ impl CompiledMerkleProof { let base_node = { let mut data = [0u8; 32]; data.copy_from_slice(&self.0[program_index + 1..program_index + 33]); - H256::from(data) + SmtH256::from(data) }; let zero_bits = { let mut data = [0u8; 32]; data.copy_from_slice(&self.0[program_index + 33..program_index + 65]); - H256::from(data) + SmtH256::from(data) }; program_index += 65; let sibling_node = MergeValue::MergeWithZero { @@ -375,8 +365,8 @@ impl CompiledMerkleProof { pub fn verify( &self, - root: &H256, - leaves: Vec<(H256, H256)>, + root: &SmtH256, + leaves: Vec<(SmtH256, SmtH256)>, ) -> Result { let calculated_root = self.compute_root::(leaves)?; Ok(&calculated_root == root) diff --git a/src/tests/fixtures.rs b/src/tests/fixtures.rs index a385a0e..2032478 100644 --- a/src/tests/fixtures.rs +++ b/src/tests/fixtures.rs @@ -1,6 +1,6 @@ use std::fs; -use crate::{blake2b::Blake2bHasher, default_store::DefaultStore, SparseMerkleTree, H256}; +use crate::{blake2b::Blake2bHasher, default_store::DefaultStore, SparseMerkleTree, SmtH256}; use anyhow::Result; use serde::{Deserialize, Serialize}; // use rand::{prelude::SliceRandom, thread_rng, Rng}; @@ -22,9 +22,9 @@ struct Case { proofs: Vec, } -type SMT = SparseMerkleTree>; +type SMT = SparseMerkleTree>; -fn new_smt(pairs: Vec<(H256, H256)>) -> SMT { +fn new_smt(pairs: Vec<(SmtH256, SmtH256)>) -> SMT { let mut smt = SMT::default(); for (key, value) in pairs { smt.update(key, value).unwrap(); @@ -33,7 +33,7 @@ fn new_smt(pairs: Vec<(H256, H256)>) -> SMT { } /// Generate random leaves -// fn leaves(min_leaves: usize, max_leaves: usize) -> Vec<(H256, H256)> { +// fn leaves(min_leaves: usize, max_leaves: usize) -> Vec<(SmtH256, SmtH256)> { // let mut rng = thread_rng(); // let size = rng.gen_range(min_leaves, max_leaves); // let mut pairs: Vec<_> = (0..size) diff --git a/src/tests/tree.rs b/src/tests/tree.rs index 1ef1506..f0fe26c 100644 --- a/src/tests/tree.rs +++ b/src/tests/tree.rs @@ -1,88 +1,50 @@ use crate::*; use crate::{ - blake2b::Blake2bHasher, default_store::DefaultStore, error::Error, merge::MergeValue, - MerkleProof, SparseMerkleTree, + blake2b::Blake2bHasher, default_store::DefaultStore, error::Error, h256::SmtH256Ord, + h256::SmtH256, merge::MergeValue, MerkleProof, SparseMerkleTree, }; -use core::cmp::Ordering; use proptest::prelude::*; use rand::prelude::{Rng, SliceRandom}; -type SMT = SparseMerkleTree>; - -#[derive(Eq, PartialEq, Debug, Default, Hash, Clone)] -pub struct H256OrdTest { - pub inner: H256, -} - -impl From<[u8; 32]> for H256OrdTest { - fn from(v: [u8; 32]) -> H256OrdTest { - H256OrdTest { - inner: H256::from(v), - } - } -} - -impl From for H256OrdTest { - fn from(v: H256) -> H256OrdTest { - H256OrdTest { inner: v } - } -} - -impl From<&H256> for H256OrdTest { - fn from(v: &H256) -> H256OrdTest { - H256OrdTest { inner: v.clone() } - } -} - -impl PartialOrd for H256OrdTest { - fn partial_cmp(&self, other: &Self) -> Option { - Some(self.cmp(other)) - } -} - -impl Ord for H256OrdTest { - fn cmp(&self, other: &Self) -> Ordering { - // Compare bits from heigher to lower (255..0) - self.inner.0.iter().rev().cmp(other.inner.0.iter().rev()) - } -} +type SMT = SparseMerkleTree>; #[test] fn test_default_root() { let mut tree = SMT::default(); assert_eq!(tree.store().branches_map().len(), 0); assert_eq!(tree.store().leaves_map().len(), 0); - assert_eq!(tree.root(), &H256::empty()); + assert_eq!(tree.root(), &SmtH256::empty()); // insert a key-value - tree.update(H256::empty(), [42u8; 32].into()) + tree.update(SmtH256::empty(), [42u8; 32].into()) .expect("update"); - assert_ne!(tree.root(), &H256::empty()); + assert_ne!(tree.root(), &SmtH256::empty()); assert_ne!(tree.store().branches_map().len(), 0); assert_ne!(tree.store().leaves_map().len(), 0); - assert_eq!(tree.get(&H256::empty()).expect("get"), [42u8; 32].into()); + assert_eq!(tree.get(&SmtH256::empty()).expect("get"), [42u8; 32].into()); // update zero is to delete the key - tree.update(H256::empty(), H256::empty()).expect("update"); - assert_eq!(tree.root(), &H256::empty()); - assert_eq!(tree.get(&H256::empty()).expect("get"), H256::empty()); + tree.update(SmtH256::empty(), SmtH256::empty()) + .expect("update"); + assert_eq!(tree.root(), &SmtH256::empty()); + assert_eq!(tree.get(&SmtH256::empty()).expect("get"), SmtH256::empty()); } #[test] fn test_default_tree() { let tree = SMT::default(); - assert_eq!(tree.get(&H256::empty()).expect("get"), H256::empty()); + assert_eq!(tree.get(&SmtH256::empty()).expect("get"), SmtH256::empty()); let proof = tree - .merkle_proof(vec![H256::empty()]) + .merkle_proof(vec![SmtH256::empty()]) .expect("merkle proof"); let root = proof - .compute_root::(vec![(H256::empty(), H256::empty())]) + .compute_root::(vec![(SmtH256::empty(), SmtH256::empty())]) .expect("root"); assert_eq!(&root, tree.root()); let proof = tree - .merkle_proof(vec![H256::empty()]) + .merkle_proof(vec![SmtH256::empty()]) .expect("merkle proof"); let root2 = proof - .compute_root::(vec![(H256::empty(), [42u8; 32].into())]) + .compute_root::(vec![(SmtH256::empty(), [42u8; 32].into())]) .expect("root"); assert_ne!(&root2, tree.root()); } @@ -104,7 +66,7 @@ fn test_default_merkle_proof() { // let root = proof // .compute_root::(vec![([42u8; 32].into(), [42u8; 32].into())]) // .expect("compute root"); - // assert_ne!(root, H256::empty()); + // assert_ne!(root, SmtH256::empty()); } #[test] @@ -118,14 +80,14 @@ fn test_merkle_root() { .split_whitespace() .enumerate() { - let key: H256 = { + let key: SmtH256 = { let mut buf = [0u8; 32]; let mut hasher = new_blake2b(); hasher.update(&(i as u32).to_le_bytes()); hasher.finalize(&mut buf); buf.into() }; - let value: H256 = { + let value: SmtH256 = { let mut buf = [0u8; 32]; let mut hasher = new_blake2b(); hasher.update(&word.as_bytes()); @@ -135,7 +97,7 @@ fn test_merkle_root() { tree.update(key, value).expect("update"); } - let expected_root: H256 = [ + let expected_root: SmtH256 = [ 209, 214, 1, 128, 166, 207, 49, 89, 206, 78, 169, 88, 18, 243, 130, 61, 150, 45, 43, 54, 208, 20, 237, 20, 98, 69, 130, 120, 241, 169, 248, 211, ] @@ -152,9 +114,9 @@ fn test_zero_value_donot_change_root() { 0, 1, ] .into(); - let value = H256::empty(); + let value = SmtH256::empty(); tree.update(key, value).unwrap(); - assert_eq!(tree.root(), &H256::empty()); + assert_eq!(tree.root(), &SmtH256::empty()); assert_eq!(tree.store().leaves_map().len(), 0); assert_eq!(tree.store().branches_map().len(), 0); } @@ -173,7 +135,7 @@ fn test_zero_value_donot_change_store() { ] .into(); tree.update(key, value).unwrap(); - assert_ne!(tree.root(), &H256::empty()); + assert_ne!(tree.root(), &SmtH256::empty()); let root = tree.root().clone(); let store = tree.store().clone(); @@ -208,12 +170,12 @@ fn test_delete_a_leaf() { ] .into(); tree.update(key, value).unwrap(); - assert_ne!(tree.root(), &H256::empty()); + assert_ne!(tree.root(), &SmtH256::empty()); let root = tree.root().clone(); let store = tree.store().clone(); // insert a leaf - let key: H256 = [ + let key: SmtH256 = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, ] @@ -227,7 +189,7 @@ fn test_delete_a_leaf() { assert_ne!(tree.root(), &root); // delete a leaf - tree.update(key, H256::empty()).unwrap(); + tree.update(key, SmtH256::empty()).unwrap(); assert_eq!(tree.root(), &root); assert_eq!(tree.store().leaves_map(), store.leaves_map()); assert_eq!(tree.store().branches_map(), store.branches_map()); @@ -237,35 +199,35 @@ fn test_delete_a_leaf() { fn test_sibling_key_get() { { let mut tree = SMT::default(); - let key = H256::from([ + let key = SmtH256::from([ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ]); - let value = H256::from([1u8; 32]); + let value = SmtH256::from([1u8; 32]); tree.update(key, value).expect("update"); - let sibling_key = H256::from([ + let sibling_key = SmtH256::from([ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ]); // get non exists sibling key should return zero value; - assert_eq!(H256::empty(), tree.get(&sibling_key).unwrap()); + assert_eq!(SmtH256::empty(), tree.get(&sibling_key).unwrap()); } { let mut tree = SMT::default(); - let key = H256::from([ + let key = SmtH256::from([ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ]); - let value = H256::from([1u8; 32]); + let value = SmtH256::from([1u8; 32]); tree.update(key.clone(), value.clone()).expect("update"); - let sibling_key = H256::from([ + let sibling_key = SmtH256::from([ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ]); - let sibling_value = H256::from([2u8; 32]); + let sibling_value = SmtH256::from([2u8; 32]); tree.update(sibling_key.clone(), sibling_value.clone()) .expect("update"); // get sibling key should return corresponding value @@ -274,7 +236,7 @@ fn test_sibling_key_get() { } } -fn test_construct(key: H256, value: H256) { +fn test_construct(key: SmtH256, value: SmtH256) { // insert same value to sibling key will construct a different root let mut tree = SMT::default(); @@ -291,13 +253,13 @@ fn test_construct(key: H256, value: H256) { assert_ne!(tree.root(), tree2.root()); } -fn test_update(key: H256, value: H256) { +fn test_update(key: SmtH256, value: SmtH256) { let mut tree = SMT::default(); tree.update(key.clone(), value.clone()).expect("update"); assert_eq!(tree.get(&key), Ok(value)); } -fn test_update_tree_store(key: H256, value: H256, value2: H256) { +fn test_update_tree_store(key: SmtH256, value: SmtH256, value2: SmtH256) { const EXPECTED_LEAVES_LEN: usize = 1; let mut tree = SMT::default(); @@ -310,7 +272,7 @@ fn test_update_tree_store(key: H256, value: H256, value2: H256) { assert_eq!(tree.get(&key), Ok(value2)); } -fn test_merkle_proof(key: H256, value: H256) { +fn test_merkle_proof(key: SmtH256, value: SmtH256) { const EXPECTED_MERKLE_PATH_SIZE: usize = 1; let mut tree = SMT::default(); @@ -331,7 +293,7 @@ fn test_merkle_proof(key: H256, value: H256) { } } -fn new_smt(pairs: Vec<(H256, H256)>) -> SMT { +fn new_smt(pairs: Vec<(SmtH256, SmtH256)>) -> SMT { let mut smt = SMT::default(); for (key, value) in pairs { smt.update(key, value).unwrap(); @@ -342,7 +304,7 @@ fn new_smt(pairs: Vec<(H256, H256)>) -> SMT { fn leaves( min_leaves: usize, max_leaves: usize, -) -> impl Strategy, usize)> { +) -> impl Strategy, usize)> { prop::collection::vec( prop::array::uniform2(prop::array::uniform32(0u8..)), min_leaves..=max_leaves, @@ -362,7 +324,7 @@ fn leaves( }) } -fn leaves_bitmap(max_leaves_bitmap: usize) -> impl Strategy> { +fn leaves_bitmap(max_leaves_bitmap: usize) -> impl Strategy> { prop::collection::vec(prop::array::uniform32(0u8..), max_leaves_bitmap).prop_flat_map( |leaves_bitmap| Just(leaves_bitmap.into_iter().map(|item| item.into()).collect()), ) @@ -382,9 +344,9 @@ fn merkle_proof(max_proof: usize) -> impl Strategy> { proptest! { #[test] fn test_h256(key: [u8; 32], key2: [u8; 32]) { - let mut list1: Vec = vec![H256OrdTest::from(key) , H256OrdTest::from(key2)]; + let mut list1: Vec = vec![SmtH256Ord::from(key) , SmtH256Ord::from(key2)]; let mut list2 = list1.clone(); - // sort H256 + // sort SmtH256 list1.sort_unstable_by_key(|k| k.clone()); // sort by high bits to lower bits list2.sort_unstable_by(|k1, k2| { @@ -403,7 +365,7 @@ proptest! { #[test] fn test_h256_copy_bits(start: u8) { - let one: H256 = [255u8; 32].into(); + let one: SmtH256 = [255u8; 32].into(); let target = h256::copy_bits(&one, start); for i in start..=core::u8::MAX { assert_eq!(one.bit(i.into()).unwrap_or(false), target.bit(i.into()).unwrap_or(false)); @@ -459,7 +421,7 @@ proptest! { fn test_smt_multi_leaves_small((pairs, n) in leaves(1, 50)){ let smt = new_smt(pairs.clone()); let proof = smt.merkle_proof(pairs.iter().take(n).map(|(k, _v)| k.clone()).collect()).expect("gen proof"); - let data: Vec<(H256, H256)> = pairs.into_iter().take(n).collect(); + let data: Vec<(SmtH256, SmtH256)> = pairs.into_iter().take(n).collect(); let compiled_proof = proof.clone().compile(data.clone()).expect("compile proof"); assert!(proof.verify::(smt.root(), data.clone()).expect("verify proof")); assert!(compiled_proof.verify::(smt.root(), data).expect("verify compiled proof")); @@ -470,7 +432,7 @@ proptest! { let n = 20; let smt = new_smt(pairs.clone()); let proof = smt.merkle_proof(pairs.iter().take(n).map(|(k, _v)| k.clone()).collect()).expect("gen proof"); - let data: Vec<(H256, H256)> = pairs.into_iter().take(n).collect(); + let data: Vec<(SmtH256, SmtH256)> = pairs.into_iter().take(n).collect(); let compiled_proof = proof.clone().compile(data.clone()).expect("compile proof"); assert!(proof.verify::(smt.root(), data.clone()).expect("verify proof")); assert!(compiled_proof.verify::(smt.root(), data).expect("verify compiled proof")); @@ -481,7 +443,7 @@ proptest! { let smt = new_smt(pairs); let non_exists_keys: Vec<_> = pairs2.into_iter().map(|(k, _v)|k).collect(); let proof = smt.merkle_proof(non_exists_keys.clone()).expect("gen proof"); - let data: Vec<(H256, H256)> = non_exists_keys.into_iter().map(|k|(k, H256::empty())).collect(); + let data: Vec<(SmtH256, SmtH256)> = non_exists_keys.into_iter().map(|k|(k, SmtH256::empty())).collect(); let compiled_proof = proof.clone().compile(data.clone()).expect("compile proof"); assert!(proof.verify::(smt.root(), data.clone()).expect("verify proof")); assert!(compiled_proof.verify::(smt.root(), data).expect("verify compiled proof")); @@ -497,7 +459,7 @@ proptest! { let mut keys: Vec<_> = exists_keys.into_iter().take(exists_keys_len).chain(non_exists_keys.into_iter().take(non_exists_keys_len)).collect(); keys.dedup(); let proof = smt.merkle_proof(keys.clone()).expect("gen proof"); - let data: Vec<(H256, H256)> = keys.into_iter().map(|k|(k.clone(), smt.get(&k).expect("get"))).collect(); + let data: Vec<(SmtH256, SmtH256)> = keys.into_iter().map(|k|(k.clone(), smt.get(&k).expect("get"))).collect(); let compiled_proof = proof.clone().compile(data.clone()).expect("compile proof"); assert!(proof.verify::(smt.root(), data.clone()).expect("verify proof")); assert!(compiled_proof.verify::(smt.root(), data).expect("verify compiled proof")); @@ -549,7 +511,7 @@ proptest! { // insert zero values for (k, _v) in pairs[len..].iter() { - smt.update(k.clone(), H256::empty()).unwrap(); + smt.update(k.clone(), SmtH256::empty()).unwrap(); } // check root let current_root = smt.root().clone(); @@ -599,11 +561,11 @@ proptest! { } } -fn parse_h256(s: &str) -> H256 { +fn parse_h256(s: &str) -> SmtH256 { let data = hex::decode(s).unwrap(); let mut inner = [0u8; 32]; inner.copy_from_slice(&data); - H256::from(inner) + SmtH256::from(inner) } #[test] @@ -700,38 +662,38 @@ fn test_v0_3_broken_sample() { #[test] fn test_replay_to_pass_proof() { - let key1: H256 = [ + let key1: SmtH256 = [ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ] .into(); - let key2: H256 = [ + let key2: SmtH256 = [ 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ] .into(); - let key3: H256 = [ + let key3: SmtH256 = [ 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ] .into(); - let key4: H256 = [ + let key4: SmtH256 = [ 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ] .into(); - let existing: H256 = [ + let existing: SmtH256 = [ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ] .into(); - let non_existing: H256 = [ + let non_existing: SmtH256 = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ] .into(); - let other_value: H256 = [ + let other_value: SmtH256 = [ 0, 0, 0xff, 0, 0, 0, 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, ] @@ -743,7 +705,7 @@ fn test_replay_to_pass_proof() { (key4.clone(), non_existing.clone()), ]; let smt = new_smt(pairs); - let leaf_a_bl = vec![(key1, H256::empty())]; + let leaf_a_bl = vec![(key1, SmtH256::empty())]; let leaf_c = vec![(key3.clone(), non_existing)]; let leaf_other = vec![(key3, other_value)]; let proofc = smt @@ -778,10 +740,10 @@ fn test_replay_to_pass_proof() { #[test] fn test_sibling_leaf() { - fn gen_rand_h256() -> H256 { + fn gen_rand_h256() -> SmtH256 { let mut rng = rand::thread_rng(); let rand_data: [u8; 32] = rng.gen(); - H256::from(rand_data) + SmtH256::from(rand_data) } let rand_key = gen_rand_h256(); let mut sibling_key = rand_key.clone(); @@ -804,9 +766,9 @@ fn test_sibling_leaf() { #[test] fn test_max_stack_size() { - fn gen_h256(height: u8) -> H256 { + fn gen_h256(height: u8) -> SmtH256 { // The key path is first go right `256 - height` times then go left `height` times. - let mut key = H256::empty(); + let mut key = SmtH256::empty(); for h in height..=255 { key.set_bit(h.into(), true); } @@ -816,10 +778,10 @@ fn test_max_stack_size() { .map(|height| (gen_h256(height), gen_h256(1))) .collect(); // Most left key - pairs.push((H256::empty(), gen_h256(1))); + pairs.push((SmtH256::empty(), gen_h256(1))); { // A pair of sibling keys in between - let mut left_key = H256::empty(); + let mut left_key = SmtH256::empty(); for h in 12..56 { left_key.set_bit(h, true); } diff --git a/src/traits.rs b/src/traits.rs index 73cd6c4..cdb7f6e 100644 --- a/src/traits.rs +++ b/src/traits.rs @@ -1,37 +1,37 @@ use crate::{ error::Error, + h256::SmtH256, tree::{BranchKey, BranchNode}, - H256, }; /// Trait for customize hash function pub trait Hasher { - fn write_h256(&mut self, h: &H256); + fn write_h256(&mut self, h: &SmtH256); fn write_byte(&mut self, b: u8); - fn finish(self) -> H256; + fn finish(self) -> SmtH256; } /// Trait for define value structures pub trait Value { - fn to_h256(&self) -> H256; + fn to_h256(&self) -> SmtH256; fn zero() -> Self; } -impl Value for H256 { - fn to_h256(&self) -> H256 { +impl Value for SmtH256 { + fn to_h256(&self) -> SmtH256 { self.clone() } fn zero() -> Self { - H256::empty() + SmtH256::empty() } } /// Trait for customize backend storage pub trait Store { fn get_branch(&self, branch_key: &BranchKey) -> Result, Error>; - fn get_leaf(&self, leaf_key: &H256) -> Result, Error>; + fn get_leaf(&self, leaf_key: &SmtH256) -> Result, Error>; fn insert_branch(&mut self, node_key: BranchKey, branch: BranchNode) -> Result<(), Error>; - fn insert_leaf(&mut self, leaf_key: H256, leaf: V) -> Result<(), Error>; + fn insert_leaf(&mut self, leaf_key: SmtH256, leaf: V) -> Result<(), Error>; fn remove_branch(&mut self, node_key: &BranchKey) -> Result<(), Error>; - fn remove_leaf(&mut self, leaf_key: &H256) -> Result<(), Error>; + fn remove_leaf(&mut self, leaf_key: &SmtH256) -> Result<(), Error>; } diff --git a/src/tree.rs b/src/tree.rs index 18faff9..d703414 100644 --- a/src/tree.rs +++ b/src/tree.rs @@ -1,11 +1,13 @@ use crate::{ error::{Error, Result}, h256, + h256::SmtH256Ord, + h256::SmtH256, merge::{merge, MergeValue}, merkle_proof::MerkleProof, traits::{Hasher, Store, Value}, vec::Vec, - H256, MAX_STACK_SIZE, + MAX_STACK_SIZE, }; use core::cmp::Ordering; use core::marker::PhantomData; @@ -14,11 +16,11 @@ use core::marker::PhantomData; #[derive(Debug, Clone, Eq, PartialEq, Hash)] pub struct BranchKey { pub height: u8, - pub node_key: H256, + pub node_key: SmtH256, } impl BranchKey { - pub fn new(height: u8, node_key: H256) -> BranchKey { + pub fn new(height: u8, node_key: SmtH256) -> BranchKey { BranchKey { height, node_key } } } @@ -48,30 +50,13 @@ pub struct BranchNode { #[derive(Default, Debug)] pub struct SparseMerkleTree { store: S, - root: H256, + root: SmtH256, phantom: PhantomData<(H, V)>, } -#[derive(Eq, PartialEq, Debug, Default, Hash, Clone)] -struct H256OrdTree { - pub inner: H256, -} - -impl PartialOrd for H256OrdTree { - fn partial_cmp(&self, other: &Self) -> Option { - Some(self.cmp(other)) - } -} - -impl Ord for H256OrdTree { - fn cmp(&self, other: &Self) -> Ordering { - h256::h256_cmp(&self.inner, &other.inner) - } -} - impl> SparseMerkleTree { /// Build a merkle tree from root and store - pub fn new(root: H256, store: S) -> SparseMerkleTree { + pub fn new(root: SmtH256, store: S) -> SparseMerkleTree { SparseMerkleTree { root, store, @@ -80,7 +65,7 @@ impl> SparseMerkleTree { } /// Merkle root - pub fn root(&self) -> &H256 { + pub fn root(&self) -> &SmtH256 { &self.root } @@ -106,7 +91,7 @@ impl> SparseMerkleTree { /// Update a leaf, return new merkle root /// set to zero value to delete a key - pub fn update(&mut self, key: H256, value: V) -> Result<&H256> { + pub fn update(&mut self, key: SmtH256, value: V) -> Result<&SmtH256> { // compute and store new leaf let node = MergeValue::from_h256(value.to_h256()); // notice when value is zero the leaf is deleted, so we do not need to store it @@ -159,7 +144,7 @@ impl> SparseMerkleTree { /// Get value of a leaf /// return zero value if leaf not exists - pub fn get(&self, key: &H256) -> Result { + pub fn get(&self, key: &SmtH256) -> Result { if self.is_empty() { return Ok(V::zero()); } @@ -167,11 +152,11 @@ impl> SparseMerkleTree { } /// Generate merkle proof - pub fn merkle_proof(&self, keys: Vec) -> Result { + pub fn merkle_proof(&self, keys: Vec) -> Result { let mut keys_ord = keys .iter() .take(keys.len()) - .map(|k| H256OrdTree { inner: k.clone() }) + .map(|k| SmtH256Ord { inner: k.clone() }) .collect::>(); if keys_ord.is_empty() { return Err(Error::EmptyKeys); @@ -181,9 +166,9 @@ impl> SparseMerkleTree { keys_ord.sort_unstable(); // Collect leaf bitmaps - let mut leaves_bitmap: Vec = Default::default(); + let mut leaves_bitmap: Vec = Default::default(); for current_key in &keys_ord { - let mut bitmap = H256::empty(); + let mut bitmap = SmtH256::empty(); for height in 0..=core::u8::MAX { let parent_key = h256::parent_path(¤t_key.inner, height); let parent_branch_key = BranchKey::new(height, parent_key); From fc0a843f6160dee40ca315c359c329592f0697af Mon Sep 17 00:00:00 2001 From: Joii Date: Wed, 1 Sep 2021 16:34:30 +0800 Subject: [PATCH 06/16] Revert "Remove H256 from lib.rs and change it to SmtH256 to avoid confusion; merge H256Ord to avoid code duplication." This reverts commit dff1e56e8f9d60bca47119defa9d1d1140367056. --- benches/smt_benchmark.rs | 8 +- c/rust-tests/src/tests/smt.rs | 37 ++++---- src/blake2b.rs | 6 +- src/default_store.rs | 12 +-- src/error.rs | 6 +- src/h256.rs | 54 ++--------- src/lib.rs | 9 +- src/merge.rs | 28 +++--- src/merkle_proof.rs | 66 +++++++------ src/tests/fixtures.rs | 8 +- src/tests/tree.rs | 168 +++++++++++++++++++++------------- src/traits.rs | 20 ++-- src/tree.rs | 43 ++++++--- 13 files changed, 246 insertions(+), 219 deletions(-) diff --git a/benches/smt_benchmark.rs b/benches/smt_benchmark.rs index 77afb8c..eb73bcb 100644 --- a/benches/smt_benchmark.rs +++ b/benches/smt_benchmark.rs @@ -4,19 +4,19 @@ extern crate criterion; use criterion::Criterion; use rand::{thread_rng, Rng}; use sparse_merkle_tree::{ - blake2b::Blake2bHasher, default_store::DefaultStore, h256::SmtH256, tree::SparseMerkleTree, + blake2b::Blake2bHasher, default_store::DefaultStore, tree::SparseMerkleTree, H256, }; const TARGET_LEAVES_COUNT: usize = 20; -type SMT = SparseMerkleTree>; +type SMT = SparseMerkleTree>; -fn random_h256(rng: &mut impl Rng) -> SmtH256 { +fn random_h256(rng: &mut impl Rng) -> H256 { let mut buf = [0u8; 32]; rng.fill(&mut buf); buf.into() } -fn random_smt(update_count: usize, rng: &mut impl Rng) -> (SMT, Vec) { +fn random_smt(update_count: usize, rng: &mut impl Rng) -> (SMT, Vec) { let mut smt = SparseMerkleTree::default(); let mut keys = Vec::with_capacity(update_count); for _ in 0..update_count { diff --git a/c/rust-tests/src/tests/smt.rs b/c/rust-tests/src/tests/smt.rs index 87a374d..e0419a5 100644 --- a/c/rust-tests/src/tests/smt.rs +++ b/c/rust-tests/src/tests/smt.rs @@ -6,8 +6,9 @@ use proptest::prelude::*; use rand::prelude::Rng; use serde::{Deserialize, Serialize}; use sparse_merkle_tree::traits::Hasher; -use sparse_merkle_tree::{default_store::DefaultStore, h256::SmtH256, SparseMerkleTree}; +use sparse_merkle_tree::{default_store::DefaultStore, SparseMerkleTree, H256}; use std::collections::HashMap; +use std::fs; #[link(name = "dl-c-impl", kind = "static")] extern "C" { @@ -143,19 +144,19 @@ impl Hasher for CkbBlake2bHasher { fn write_byte(&mut self, b: u8) { self.0.update(&[b][..]); } - fn write_h256(&mut self, h: &SmtH256) { - self.0.update(h.as_bytes()); + fn write_h256(&mut self, h: &H256) { + self.0.update(h.as_slice()); } - fn finish(self) -> SmtH256 { + fn finish(self) -> H256 { let mut hash = [0u8; 32]; self.0.finalize(&mut hash); hash.into() } } -pub type CkbSMT = SparseMerkleTree>; +pub type CkbSMT = SparseMerkleTree>; -pub fn _new_ckb_smt(pairs: Vec<(SmtH256, SmtH256)>) -> CkbSMT { +pub fn new_ckb_smt(pairs: Vec<(H256, H256)>) -> CkbSMT { let mut smt = CkbSMT::default(); for (key, value) in pairs { smt.update(key, value).unwrap(); @@ -227,10 +228,10 @@ fn test_normalize_random() { } } -fn _run_test_case(case: Case) -> AnyResult<()> { +fn run_test_case(case: Case) -> AnyResult<()> { let Case { leaves, proofs, .. } = case; - let ckb_smt = _new_ckb_smt( + let ckb_smt = new_ckb_smt( leaves .iter() .map(|(k, v)| ((*k).into(), (*v).into())) @@ -272,7 +273,7 @@ fn _run_test_case(case: Case) -> AnyResult<()> { assert_eq!(smt_state.len(), leaves.len() as u32); smt_state - .verify(ckb_smt.root().as_bytes(), &ckb_actual_compiled_proof_bin) + .verify(ckb_smt.root().as_slice(), &ckb_actual_compiled_proof_bin) .unwrap(); } Ok(()) @@ -294,32 +295,32 @@ fn _run_test_case(case: Case) -> AnyResult<()> { proptest! { #[test] fn test_random_merkle_proof(key: [u8; 32], value: [u8;32]) { - let key = SmtH256::from(key); - let value = SmtH256::from(value); + let key = H256::from(key); + let value = H256::from(value); const EXPECTED_PROOF_SIZE: usize = 16; let mut tree = CkbSMT::default(); - tree.update(key.clone(), value.clone()).expect("update"); + tree.update(key, value).expect("update"); if !tree.is_empty() { - let proof = tree.merkle_proof(vec![key.clone()]).expect("proof"); + let proof = tree.merkle_proof(vec![key]).expect("proof"); let compiled_proof = proof .clone() - .compile(vec![(key.clone(), value.clone())]) + .compile(vec![(key, value)]) .expect("compile proof"); assert!(proof.merkle_path().len() < EXPECTED_PROOF_SIZE); assert!(proof - .verify::(tree.root(), vec![(key.clone(), value.clone())]) + .verify::(tree.root(), vec![(key, value)]) .expect("verify")); assert!(compiled_proof - .verify::(tree.root(), vec![(key.clone(), value.clone())]) + .verify::(tree.root(), vec![(key, value)]) .expect("compiled verify")); let compiled_proof_bin: Vec = compiled_proof.into(); let mut smt_state = SmtCImpl::new(8); - smt_state.insert(key.as_bytes(), value.as_bytes()).unwrap(); + smt_state.insert(key.as_slice(), value.as_slice()).unwrap(); smt_state.normalize(); smt_state - .verify(tree.root().as_bytes(), &compiled_proof_bin) + .verify(tree.root().as_slice(), &compiled_proof_bin) .expect("verify with c"); } } diff --git a/src/blake2b.rs b/src/blake2b.rs index 4aa34ce..a264619 100644 --- a/src/blake2b.rs +++ b/src/blake2b.rs @@ -1,4 +1,4 @@ -use crate::{h256::SmtH256, traits::Hasher}; +use crate::{traits::Hasher, H256}; use blake2b_rs::{Blake2b, Blake2bBuilder}; const BLAKE2B_KEY: &[u8] = &[]; @@ -18,13 +18,13 @@ impl Default for Blake2bHasher { } impl Hasher for Blake2bHasher { - fn write_h256(&mut self, h: &SmtH256) { + fn write_h256(&mut self, h: &H256) { self.0.update(h.as_bytes()); } fn write_byte(&mut self, b: u8) { self.0.update(&[b][..]); } - fn finish(self) -> SmtH256 { + fn finish(self) -> H256 { let mut hash = [0u8; 32]; self.0.finalize(&mut hash); hash.into() diff --git a/src/default_store.rs b/src/default_store.rs index abba33a..fda98b1 100644 --- a/src/default_store.rs +++ b/src/default_store.rs @@ -1,22 +1,22 @@ use crate::{ collections, error::Error, - h256::SmtH256, traits::Store, tree::{BranchKey, BranchNode}, + H256, }; #[derive(Debug, Clone, Default)] pub struct DefaultStore { branches_map: Map, - leaves_map: Map, + leaves_map: Map, } impl DefaultStore { pub fn branches_map(&self) -> &Map { &self.branches_map } - pub fn leaves_map(&self) -> &Map { + pub fn leaves_map(&self) -> &Map { &self.leaves_map } pub fn clear(&mut self) { @@ -29,14 +29,14 @@ impl Store for DefaultStore { fn get_branch(&self, branch_key: &BranchKey) -> Result, Error> { Ok(self.branches_map.get(branch_key).map(Clone::clone)) } - fn get_leaf(&self, leaf_key: &SmtH256) -> Result, Error> { + fn get_leaf(&self, leaf_key: &H256) -> Result, Error> { Ok(self.leaves_map.get(leaf_key).map(Clone::clone)) } fn insert_branch(&mut self, branch_key: BranchKey, branch: BranchNode) -> Result<(), Error> { self.branches_map.insert(branch_key, branch); Ok(()) } - fn insert_leaf(&mut self, leaf_key: SmtH256, leaf: V) -> Result<(), Error> { + fn insert_leaf(&mut self, leaf_key: H256, leaf: V) -> Result<(), Error> { self.leaves_map.insert(leaf_key, leaf); Ok(()) } @@ -44,7 +44,7 @@ impl Store for DefaultStore { self.branches_map.remove(branch_key); Ok(()) } - fn remove_leaf(&mut self, leaf_key: &SmtH256) -> Result<(), Error> { + fn remove_leaf(&mut self, leaf_key: &H256) -> Result<(), Error> { self.leaves_map.remove(leaf_key); Ok(()) } diff --git a/src/error.rs b/src/error.rs index a2abf57..3f4f79f 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,11 +1,11 @@ -use crate::{h256::SmtH256, string}; +use crate::{string, H256}; pub type Result = ::core::result::Result; #[derive(Debug, Clone, PartialEq, Eq)] pub enum Error { - MissingBranch(u8, SmtH256), - MissingLeaf(SmtH256), + MissingBranch(u8, H256), + MissingLeaf(H256), CorruptedProof, EmptyProof, EmptyKeys, diff --git a/src/h256.rs b/src/h256.rs index 3d936dc..219bc46 100644 --- a/src/h256.rs +++ b/src/h256.rs @@ -1,11 +1,11 @@ use core::cmp::Ordering; use numext_fixed_hash; -pub type SmtH256 = numext_fixed_hash::H256; +pub type H256 = numext_fixed_hash::H256; const BYTE_SIZE: u8 = 8; -pub fn fork_height(data: &SmtH256, key: &SmtH256) -> u8 { +pub fn fork_height(data: &H256, key: &H256) -> u8 { for h in (0..=core::u8::MAX).rev() { if data.bit(h.into()).unwrap_or(false) != key.bit(h.into()).unwrap_or(false) { return h; @@ -14,18 +14,18 @@ pub fn fork_height(data: &SmtH256, key: &SmtH256) -> u8 { 0 } -pub fn parent_path(data: &SmtH256, height: u8) -> SmtH256 { +pub fn parent_path(data: &H256, height: u8) -> H256 { if height == core::u8::MAX { - SmtH256::empty() + H256::empty() } else { copy_bits(data, height + 1) } } -/// Copy bits and return a new SmtH256 -pub fn copy_bits(data: &SmtH256, start: u8) -> SmtH256 { +/// Copy bits and return a new H256 +pub fn copy_bits(data: &H256, start: u8) -> H256 { // It can also be implemented with And, but the performance is not as good as this - let mut target = SmtH256::empty(); + let mut target = H256::empty(); let start_byte = (start / BYTE_SIZE) as usize; // copy bytes @@ -40,44 +40,6 @@ pub fn copy_bits(data: &SmtH256, start: u8) -> SmtH256 { target } -#[derive(Debug, Clone, Eq, PartialEq, Hash)] -pub struct SmtH256Ord { - pub inner: SmtH256, -} - -impl From<[u8; 32]> for SmtH256Ord { - fn from(v: [u8; 32]) -> SmtH256Ord { - SmtH256Ord { - inner: SmtH256::from(v), - } - } -} - -impl From for SmtH256Ord { - fn from(v: SmtH256) -> SmtH256Ord { - SmtH256Ord { inner: v } - } -} - -impl From<&SmtH256> for SmtH256Ord { - fn from(v: &SmtH256) -> SmtH256Ord { - SmtH256Ord { inner: v.clone() } - } -} - -impl PartialOrd for SmtH256Ord { - fn partial_cmp(&self, other: &Self) -> Option { - Some(self.cmp(other)) - } -} - -impl Ord for SmtH256Ord { - fn cmp(&self, other: &Self) -> Ordering { - // Compare bits from heigher to lower (255..0) - self.inner.0.iter().rev().cmp(other.inner.0.iter().rev()) - } -} - -pub fn h256_cmp(v1: &SmtH256, v2: &SmtH256) -> Ordering { +pub fn h256_cmp(v1: &H256, v2: &H256) -> Ordering { v1.0.iter().rev().cmp(v2.0.iter().rev()) } diff --git a/src/lib.rs b/src/lib.rs index b3cdda0..a076e98 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -6,7 +6,7 @@ //! use sparse_merkle_tree::{ //! blake2b::Blake2bHasher, default_store::DefaultStore, //! error::Error, MerkleProof, -//! SparseMerkleTree, traits::Value, h256::SmtH256 +//! SparseMerkleTree, traits::Value, H256 //! }; //! use blake2b_rs::{Blake2b, Blake2bBuilder}; //! @@ -17,9 +17,9 @@ //! #[derive(Default, Clone)] //! pub struct Word(String); //! impl Value for Word { -//! fn to_h256(&self) -> SmtH256 { +//! fn to_h256(&self) -> H256 { //! if self.0.is_empty() { -//! return SmtH256::empty(); +//! return H256::empty(); //! } //! let mut buf = [0u8; 32]; //! let mut hasher = new_blake2b(); @@ -43,7 +43,7 @@ //! .split_whitespace() //! .enumerate() //! { -//! let key: SmtH256 = { +//! let key: H256 = { //! let mut buf = [0u8; 32]; //! let mut hasher = new_blake2b(); //! hasher.update(&(i as u32).to_le_bytes()); @@ -73,6 +73,7 @@ mod tests; pub mod traits; pub mod tree; +pub use h256::H256; pub use merkle_proof::{CompiledMerkleProof, MerkleProof}; pub use tree::SparseMerkleTree; diff --git a/src/merge.rs b/src/merge.rs index ce67ddc..4eeb866 100644 --- a/src/merge.rs +++ b/src/merge.rs @@ -1,4 +1,4 @@ -use crate::h256::SmtH256; +use crate::h256::H256; use crate::traits::Hasher; const MERGE_NORMAL: u8 = 1; @@ -6,21 +6,21 @@ const MERGE_ZEROS: u8 = 2; #[derive(Debug, Eq, PartialEq, Clone)] pub enum MergeValue { - Value(SmtH256), + Value(H256), MergeWithZero { - base_node: SmtH256, - zero_bits: SmtH256, + base_node: H256, + zero_bits: H256, zero_count: u8, }, } impl MergeValue { - pub fn from_h256(v: SmtH256) -> Self { + pub fn from_h256(v: H256) -> Self { MergeValue::Value(v) } pub fn zero() -> Self { - MergeValue::Value(SmtH256::empty()) + MergeValue::Value(H256::empty()) } pub fn is_zero(&self) -> bool { @@ -30,7 +30,7 @@ impl MergeValue { false } - pub fn hash(&self) -> SmtH256 { + pub fn hash(&self) -> H256 { match self { MergeValue::Value(v) => v.clone(), MergeValue::MergeWithZero { @@ -49,12 +49,12 @@ impl MergeValue { } } -/// Hash base node into a SmtH256 +/// Hash base node into a H256 pub fn hash_base_node( base_height: u8, - base_key: &SmtH256, - base_value: &SmtH256, -) -> SmtH256 { + base_key: &H256, + base_value: &H256, +) -> H256 { let mut hasher = H::default(); hasher.write_byte(base_height); hasher.write_h256(base_key); @@ -67,7 +67,7 @@ pub fn hash_base_node( /// if lhs and rhs both are ZERO_HASH return ZERO_HASH, otherwise hash all info. pub fn merge( height: u8, - node_key: &SmtH256, + node_key: &H256, lhs: &MergeValue, rhs: &MergeValue, ) -> MergeValue { @@ -91,13 +91,13 @@ pub fn merge( fn merge_with_zero( height: u8, - node_key: &SmtH256, + node_key: &H256, value: &MergeValue, set_bit: bool, ) -> MergeValue { match value { MergeValue::Value(v) => { - let mut zero_bits = SmtH256::empty(); + let mut zero_bits = H256::empty(); if set_bit { zero_bits.set_bit(height.into(), true); } diff --git a/src/merkle_proof.rs b/src/merkle_proof.rs index 55162e0..8f5b24d 100644 --- a/src/merkle_proof.rs +++ b/src/merkle_proof.rs @@ -1,18 +1,34 @@ use crate::{ error::{Error, Result}, h256, - h256::SmtH256Ord, - h256::SmtH256, merge::{merge, MergeValue}, traits::Hasher, vec::Vec, - MAX_STACK_SIZE, + H256, MAX_STACK_SIZE, }; +use core::cmp::Ordering; + +#[derive(Eq, PartialEq, Debug, Default, Hash, Clone)] +struct H256Ord { + pub inner: H256, +} + +impl PartialOrd for H256Ord { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +impl Ord for H256Ord { + fn cmp(&self, other: &Self) -> Ordering { + h256::h256_cmp(&self.inner, &other.inner) + } +} #[derive(Debug, Clone, PartialEq, Eq)] pub struct MerkleProof { // leaf bitmap, bitmap.get_bit(height) is true means there need a non zero sibling in this height - leaves_bitmap: Vec, + leaves_bitmap: Vec, // needed sibling node hash merkle_path: Vec, } @@ -21,7 +37,7 @@ impl MerkleProof { /// Create MerkleProof /// leaves_bitmap: leaf bitmap, bitmap.get_bit(height) is true means there need a non zero sibling in this height /// proof: needed sibling node hash - pub fn new(leaves_bitmap: Vec, merkle_path: Vec) -> Self { + pub fn new(leaves_bitmap: Vec, merkle_path: Vec) -> Self { MerkleProof { leaves_bitmap, merkle_path, @@ -29,7 +45,7 @@ impl MerkleProof { } /// Destruct the structure, useful for serialization - pub fn take(self) -> (Vec, Vec) { + pub fn take(self) -> (Vec, Vec) { let MerkleProof { leaves_bitmap, merkle_path, @@ -43,7 +59,7 @@ impl MerkleProof { } /// return the inner leaves_bitmap vector - pub fn leaves_bitmap(&self) -> &Vec { + pub fn leaves_bitmap(&self) -> &Vec { &self.leaves_bitmap } @@ -52,11 +68,11 @@ impl MerkleProof { &self.merkle_path } - pub fn compile(self, leaves: Vec<(SmtH256, SmtH256)>) -> Result { - let mut leaves_ord: Vec<(SmtH256Ord, SmtH256)> = leaves + pub fn compile(self, leaves: Vec<(H256, H256)>) -> Result { + let mut leaves_ord: Vec<(H256Ord, H256)> = leaves .iter() .take(leaves.len()) - .map(|(k, v)| (SmtH256Ord { inner: k.clone() }, v.clone())) + .map(|(k, v)| (H256Ord { inner: k.clone() }, v.clone())) .collect::>(); if leaves_ord.is_empty() { return Err(Error::EmptyKeys); @@ -173,10 +189,7 @@ impl MerkleProof { /// /// return EmptyProof error when proof is empty /// return CorruptedProof error when proof is invalid - pub fn compute_root( - self, - leaves: Vec<(SmtH256, SmtH256)>, - ) -> Result { + pub fn compute_root(self, leaves: Vec<(H256, H256)>) -> Result { self.compile(leaves.clone())?.compute_root::(leaves) } @@ -184,8 +197,8 @@ impl MerkleProof { /// see compute_root_from_proof pub fn verify( self, - root: &SmtH256, - leaves: Vec<(SmtH256, SmtH256)>, + root: &H256, + leaves: Vec<(H256, H256)>, ) -> Result { let calculated_root = self.compute_root::(leaves)?; Ok(&calculated_root == root) @@ -197,19 +210,16 @@ impl MerkleProof { pub struct CompiledMerkleProof(pub Vec); impl CompiledMerkleProof { - pub fn compute_root( - &self, - leaves: Vec<(SmtH256, SmtH256)>, - ) -> Result { - let mut leaves_ord: Vec<(SmtH256Ord, SmtH256)> = leaves + pub fn compute_root(&self, leaves: Vec<(H256, H256)>) -> Result { + let mut leaves_ord: Vec<(H256Ord, H256)> = leaves .iter() .take(leaves.len()) - .map(|(k, v)| (SmtH256Ord { inner: k.clone() }, v.clone())) + .map(|(k, v)| (H256Ord { inner: k.clone() }, v.clone())) .collect(); leaves_ord.sort_unstable_by_key(|(k, _v)| k.clone()); let mut program_index = 0; let mut leaf_index = 0; - let mut stack: Vec<(u16, SmtH256, MergeValue)> = Vec::new(); + let mut stack: Vec<(u16, H256, MergeValue)> = Vec::new(); while program_index < self.0.len() { let code = self.0[program_index]; program_index += 1; @@ -234,7 +244,7 @@ impl CompiledMerkleProof { let mut data = [0u8; 32]; data.copy_from_slice(&self.0[program_index..program_index + 32]); program_index += 32; - let sibling_node = MergeValue::from_h256(SmtH256::from(data)); + let sibling_node = MergeValue::from_h256(H256::from(data)); let (height_u16, key, value) = stack.pop().unwrap(); if height_u16 > 255 { return Err(Error::CorruptedProof); @@ -262,12 +272,12 @@ impl CompiledMerkleProof { let base_node = { let mut data = [0u8; 32]; data.copy_from_slice(&self.0[program_index + 1..program_index + 33]); - SmtH256::from(data) + H256::from(data) }; let zero_bits = { let mut data = [0u8; 32]; data.copy_from_slice(&self.0[program_index + 33..program_index + 65]); - SmtH256::from(data) + H256::from(data) }; program_index += 65; let sibling_node = MergeValue::MergeWithZero { @@ -365,8 +375,8 @@ impl CompiledMerkleProof { pub fn verify( &self, - root: &SmtH256, - leaves: Vec<(SmtH256, SmtH256)>, + root: &H256, + leaves: Vec<(H256, H256)>, ) -> Result { let calculated_root = self.compute_root::(leaves)?; Ok(&calculated_root == root) diff --git a/src/tests/fixtures.rs b/src/tests/fixtures.rs index 2032478..a385a0e 100644 --- a/src/tests/fixtures.rs +++ b/src/tests/fixtures.rs @@ -1,6 +1,6 @@ use std::fs; -use crate::{blake2b::Blake2bHasher, default_store::DefaultStore, SparseMerkleTree, SmtH256}; +use crate::{blake2b::Blake2bHasher, default_store::DefaultStore, SparseMerkleTree, H256}; use anyhow::Result; use serde::{Deserialize, Serialize}; // use rand::{prelude::SliceRandom, thread_rng, Rng}; @@ -22,9 +22,9 @@ struct Case { proofs: Vec, } -type SMT = SparseMerkleTree>; +type SMT = SparseMerkleTree>; -fn new_smt(pairs: Vec<(SmtH256, SmtH256)>) -> SMT { +fn new_smt(pairs: Vec<(H256, H256)>) -> SMT { let mut smt = SMT::default(); for (key, value) in pairs { smt.update(key, value).unwrap(); @@ -33,7 +33,7 @@ fn new_smt(pairs: Vec<(SmtH256, SmtH256)>) -> SMT { } /// Generate random leaves -// fn leaves(min_leaves: usize, max_leaves: usize) -> Vec<(SmtH256, SmtH256)> { +// fn leaves(min_leaves: usize, max_leaves: usize) -> Vec<(H256, H256)> { // let mut rng = thread_rng(); // let size = rng.gen_range(min_leaves, max_leaves); // let mut pairs: Vec<_> = (0..size) diff --git a/src/tests/tree.rs b/src/tests/tree.rs index f0fe26c..1ef1506 100644 --- a/src/tests/tree.rs +++ b/src/tests/tree.rs @@ -1,50 +1,88 @@ use crate::*; use crate::{ - blake2b::Blake2bHasher, default_store::DefaultStore, error::Error, h256::SmtH256Ord, - h256::SmtH256, merge::MergeValue, MerkleProof, SparseMerkleTree, + blake2b::Blake2bHasher, default_store::DefaultStore, error::Error, merge::MergeValue, + MerkleProof, SparseMerkleTree, }; +use core::cmp::Ordering; use proptest::prelude::*; use rand::prelude::{Rng, SliceRandom}; -type SMT = SparseMerkleTree>; +type SMT = SparseMerkleTree>; + +#[derive(Eq, PartialEq, Debug, Default, Hash, Clone)] +pub struct H256OrdTest { + pub inner: H256, +} + +impl From<[u8; 32]> for H256OrdTest { + fn from(v: [u8; 32]) -> H256OrdTest { + H256OrdTest { + inner: H256::from(v), + } + } +} + +impl From for H256OrdTest { + fn from(v: H256) -> H256OrdTest { + H256OrdTest { inner: v } + } +} + +impl From<&H256> for H256OrdTest { + fn from(v: &H256) -> H256OrdTest { + H256OrdTest { inner: v.clone() } + } +} + +impl PartialOrd for H256OrdTest { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +impl Ord for H256OrdTest { + fn cmp(&self, other: &Self) -> Ordering { + // Compare bits from heigher to lower (255..0) + self.inner.0.iter().rev().cmp(other.inner.0.iter().rev()) + } +} #[test] fn test_default_root() { let mut tree = SMT::default(); assert_eq!(tree.store().branches_map().len(), 0); assert_eq!(tree.store().leaves_map().len(), 0); - assert_eq!(tree.root(), &SmtH256::empty()); + assert_eq!(tree.root(), &H256::empty()); // insert a key-value - tree.update(SmtH256::empty(), [42u8; 32].into()) + tree.update(H256::empty(), [42u8; 32].into()) .expect("update"); - assert_ne!(tree.root(), &SmtH256::empty()); + assert_ne!(tree.root(), &H256::empty()); assert_ne!(tree.store().branches_map().len(), 0); assert_ne!(tree.store().leaves_map().len(), 0); - assert_eq!(tree.get(&SmtH256::empty()).expect("get"), [42u8; 32].into()); + assert_eq!(tree.get(&H256::empty()).expect("get"), [42u8; 32].into()); // update zero is to delete the key - tree.update(SmtH256::empty(), SmtH256::empty()) - .expect("update"); - assert_eq!(tree.root(), &SmtH256::empty()); - assert_eq!(tree.get(&SmtH256::empty()).expect("get"), SmtH256::empty()); + tree.update(H256::empty(), H256::empty()).expect("update"); + assert_eq!(tree.root(), &H256::empty()); + assert_eq!(tree.get(&H256::empty()).expect("get"), H256::empty()); } #[test] fn test_default_tree() { let tree = SMT::default(); - assert_eq!(tree.get(&SmtH256::empty()).expect("get"), SmtH256::empty()); + assert_eq!(tree.get(&H256::empty()).expect("get"), H256::empty()); let proof = tree - .merkle_proof(vec![SmtH256::empty()]) + .merkle_proof(vec![H256::empty()]) .expect("merkle proof"); let root = proof - .compute_root::(vec![(SmtH256::empty(), SmtH256::empty())]) + .compute_root::(vec![(H256::empty(), H256::empty())]) .expect("root"); assert_eq!(&root, tree.root()); let proof = tree - .merkle_proof(vec![SmtH256::empty()]) + .merkle_proof(vec![H256::empty()]) .expect("merkle proof"); let root2 = proof - .compute_root::(vec![(SmtH256::empty(), [42u8; 32].into())]) + .compute_root::(vec![(H256::empty(), [42u8; 32].into())]) .expect("root"); assert_ne!(&root2, tree.root()); } @@ -66,7 +104,7 @@ fn test_default_merkle_proof() { // let root = proof // .compute_root::(vec![([42u8; 32].into(), [42u8; 32].into())]) // .expect("compute root"); - // assert_ne!(root, SmtH256::empty()); + // assert_ne!(root, H256::empty()); } #[test] @@ -80,14 +118,14 @@ fn test_merkle_root() { .split_whitespace() .enumerate() { - let key: SmtH256 = { + let key: H256 = { let mut buf = [0u8; 32]; let mut hasher = new_blake2b(); hasher.update(&(i as u32).to_le_bytes()); hasher.finalize(&mut buf); buf.into() }; - let value: SmtH256 = { + let value: H256 = { let mut buf = [0u8; 32]; let mut hasher = new_blake2b(); hasher.update(&word.as_bytes()); @@ -97,7 +135,7 @@ fn test_merkle_root() { tree.update(key, value).expect("update"); } - let expected_root: SmtH256 = [ + let expected_root: H256 = [ 209, 214, 1, 128, 166, 207, 49, 89, 206, 78, 169, 88, 18, 243, 130, 61, 150, 45, 43, 54, 208, 20, 237, 20, 98, 69, 130, 120, 241, 169, 248, 211, ] @@ -114,9 +152,9 @@ fn test_zero_value_donot_change_root() { 0, 1, ] .into(); - let value = SmtH256::empty(); + let value = H256::empty(); tree.update(key, value).unwrap(); - assert_eq!(tree.root(), &SmtH256::empty()); + assert_eq!(tree.root(), &H256::empty()); assert_eq!(tree.store().leaves_map().len(), 0); assert_eq!(tree.store().branches_map().len(), 0); } @@ -135,7 +173,7 @@ fn test_zero_value_donot_change_store() { ] .into(); tree.update(key, value).unwrap(); - assert_ne!(tree.root(), &SmtH256::empty()); + assert_ne!(tree.root(), &H256::empty()); let root = tree.root().clone(); let store = tree.store().clone(); @@ -170,12 +208,12 @@ fn test_delete_a_leaf() { ] .into(); tree.update(key, value).unwrap(); - assert_ne!(tree.root(), &SmtH256::empty()); + assert_ne!(tree.root(), &H256::empty()); let root = tree.root().clone(); let store = tree.store().clone(); // insert a leaf - let key: SmtH256 = [ + let key: H256 = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, ] @@ -189,7 +227,7 @@ fn test_delete_a_leaf() { assert_ne!(tree.root(), &root); // delete a leaf - tree.update(key, SmtH256::empty()).unwrap(); + tree.update(key, H256::empty()).unwrap(); assert_eq!(tree.root(), &root); assert_eq!(tree.store().leaves_map(), store.leaves_map()); assert_eq!(tree.store().branches_map(), store.branches_map()); @@ -199,35 +237,35 @@ fn test_delete_a_leaf() { fn test_sibling_key_get() { { let mut tree = SMT::default(); - let key = SmtH256::from([ + let key = H256::from([ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ]); - let value = SmtH256::from([1u8; 32]); + let value = H256::from([1u8; 32]); tree.update(key, value).expect("update"); - let sibling_key = SmtH256::from([ + let sibling_key = H256::from([ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ]); // get non exists sibling key should return zero value; - assert_eq!(SmtH256::empty(), tree.get(&sibling_key).unwrap()); + assert_eq!(H256::empty(), tree.get(&sibling_key).unwrap()); } { let mut tree = SMT::default(); - let key = SmtH256::from([ + let key = H256::from([ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ]); - let value = SmtH256::from([1u8; 32]); + let value = H256::from([1u8; 32]); tree.update(key.clone(), value.clone()).expect("update"); - let sibling_key = SmtH256::from([ + let sibling_key = H256::from([ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ]); - let sibling_value = SmtH256::from([2u8; 32]); + let sibling_value = H256::from([2u8; 32]); tree.update(sibling_key.clone(), sibling_value.clone()) .expect("update"); // get sibling key should return corresponding value @@ -236,7 +274,7 @@ fn test_sibling_key_get() { } } -fn test_construct(key: SmtH256, value: SmtH256) { +fn test_construct(key: H256, value: H256) { // insert same value to sibling key will construct a different root let mut tree = SMT::default(); @@ -253,13 +291,13 @@ fn test_construct(key: SmtH256, value: SmtH256) { assert_ne!(tree.root(), tree2.root()); } -fn test_update(key: SmtH256, value: SmtH256) { +fn test_update(key: H256, value: H256) { let mut tree = SMT::default(); tree.update(key.clone(), value.clone()).expect("update"); assert_eq!(tree.get(&key), Ok(value)); } -fn test_update_tree_store(key: SmtH256, value: SmtH256, value2: SmtH256) { +fn test_update_tree_store(key: H256, value: H256, value2: H256) { const EXPECTED_LEAVES_LEN: usize = 1; let mut tree = SMT::default(); @@ -272,7 +310,7 @@ fn test_update_tree_store(key: SmtH256, value: SmtH256, value2: SmtH256) { assert_eq!(tree.get(&key), Ok(value2)); } -fn test_merkle_proof(key: SmtH256, value: SmtH256) { +fn test_merkle_proof(key: H256, value: H256) { const EXPECTED_MERKLE_PATH_SIZE: usize = 1; let mut tree = SMT::default(); @@ -293,7 +331,7 @@ fn test_merkle_proof(key: SmtH256, value: SmtH256) { } } -fn new_smt(pairs: Vec<(SmtH256, SmtH256)>) -> SMT { +fn new_smt(pairs: Vec<(H256, H256)>) -> SMT { let mut smt = SMT::default(); for (key, value) in pairs { smt.update(key, value).unwrap(); @@ -304,7 +342,7 @@ fn new_smt(pairs: Vec<(SmtH256, SmtH256)>) -> SMT { fn leaves( min_leaves: usize, max_leaves: usize, -) -> impl Strategy, usize)> { +) -> impl Strategy, usize)> { prop::collection::vec( prop::array::uniform2(prop::array::uniform32(0u8..)), min_leaves..=max_leaves, @@ -324,7 +362,7 @@ fn leaves( }) } -fn leaves_bitmap(max_leaves_bitmap: usize) -> impl Strategy> { +fn leaves_bitmap(max_leaves_bitmap: usize) -> impl Strategy> { prop::collection::vec(prop::array::uniform32(0u8..), max_leaves_bitmap).prop_flat_map( |leaves_bitmap| Just(leaves_bitmap.into_iter().map(|item| item.into()).collect()), ) @@ -344,9 +382,9 @@ fn merkle_proof(max_proof: usize) -> impl Strategy> { proptest! { #[test] fn test_h256(key: [u8; 32], key2: [u8; 32]) { - let mut list1: Vec = vec![SmtH256Ord::from(key) , SmtH256Ord::from(key2)]; + let mut list1: Vec = vec![H256OrdTest::from(key) , H256OrdTest::from(key2)]; let mut list2 = list1.clone(); - // sort SmtH256 + // sort H256 list1.sort_unstable_by_key(|k| k.clone()); // sort by high bits to lower bits list2.sort_unstable_by(|k1, k2| { @@ -365,7 +403,7 @@ proptest! { #[test] fn test_h256_copy_bits(start: u8) { - let one: SmtH256 = [255u8; 32].into(); + let one: H256 = [255u8; 32].into(); let target = h256::copy_bits(&one, start); for i in start..=core::u8::MAX { assert_eq!(one.bit(i.into()).unwrap_or(false), target.bit(i.into()).unwrap_or(false)); @@ -421,7 +459,7 @@ proptest! { fn test_smt_multi_leaves_small((pairs, n) in leaves(1, 50)){ let smt = new_smt(pairs.clone()); let proof = smt.merkle_proof(pairs.iter().take(n).map(|(k, _v)| k.clone()).collect()).expect("gen proof"); - let data: Vec<(SmtH256, SmtH256)> = pairs.into_iter().take(n).collect(); + let data: Vec<(H256, H256)> = pairs.into_iter().take(n).collect(); let compiled_proof = proof.clone().compile(data.clone()).expect("compile proof"); assert!(proof.verify::(smt.root(), data.clone()).expect("verify proof")); assert!(compiled_proof.verify::(smt.root(), data).expect("verify compiled proof")); @@ -432,7 +470,7 @@ proptest! { let n = 20; let smt = new_smt(pairs.clone()); let proof = smt.merkle_proof(pairs.iter().take(n).map(|(k, _v)| k.clone()).collect()).expect("gen proof"); - let data: Vec<(SmtH256, SmtH256)> = pairs.into_iter().take(n).collect(); + let data: Vec<(H256, H256)> = pairs.into_iter().take(n).collect(); let compiled_proof = proof.clone().compile(data.clone()).expect("compile proof"); assert!(proof.verify::(smt.root(), data.clone()).expect("verify proof")); assert!(compiled_proof.verify::(smt.root(), data).expect("verify compiled proof")); @@ -443,7 +481,7 @@ proptest! { let smt = new_smt(pairs); let non_exists_keys: Vec<_> = pairs2.into_iter().map(|(k, _v)|k).collect(); let proof = smt.merkle_proof(non_exists_keys.clone()).expect("gen proof"); - let data: Vec<(SmtH256, SmtH256)> = non_exists_keys.into_iter().map(|k|(k, SmtH256::empty())).collect(); + let data: Vec<(H256, H256)> = non_exists_keys.into_iter().map(|k|(k, H256::empty())).collect(); let compiled_proof = proof.clone().compile(data.clone()).expect("compile proof"); assert!(proof.verify::(smt.root(), data.clone()).expect("verify proof")); assert!(compiled_proof.verify::(smt.root(), data).expect("verify compiled proof")); @@ -459,7 +497,7 @@ proptest! { let mut keys: Vec<_> = exists_keys.into_iter().take(exists_keys_len).chain(non_exists_keys.into_iter().take(non_exists_keys_len)).collect(); keys.dedup(); let proof = smt.merkle_proof(keys.clone()).expect("gen proof"); - let data: Vec<(SmtH256, SmtH256)> = keys.into_iter().map(|k|(k.clone(), smt.get(&k).expect("get"))).collect(); + let data: Vec<(H256, H256)> = keys.into_iter().map(|k|(k.clone(), smt.get(&k).expect("get"))).collect(); let compiled_proof = proof.clone().compile(data.clone()).expect("compile proof"); assert!(proof.verify::(smt.root(), data.clone()).expect("verify proof")); assert!(compiled_proof.verify::(smt.root(), data).expect("verify compiled proof")); @@ -511,7 +549,7 @@ proptest! { // insert zero values for (k, _v) in pairs[len..].iter() { - smt.update(k.clone(), SmtH256::empty()).unwrap(); + smt.update(k.clone(), H256::empty()).unwrap(); } // check root let current_root = smt.root().clone(); @@ -561,11 +599,11 @@ proptest! { } } -fn parse_h256(s: &str) -> SmtH256 { +fn parse_h256(s: &str) -> H256 { let data = hex::decode(s).unwrap(); let mut inner = [0u8; 32]; inner.copy_from_slice(&data); - SmtH256::from(inner) + H256::from(inner) } #[test] @@ -662,38 +700,38 @@ fn test_v0_3_broken_sample() { #[test] fn test_replay_to_pass_proof() { - let key1: SmtH256 = [ + let key1: H256 = [ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ] .into(); - let key2: SmtH256 = [ + let key2: H256 = [ 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ] .into(); - let key3: SmtH256 = [ + let key3: H256 = [ 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ] .into(); - let key4: SmtH256 = [ + let key4: H256 = [ 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ] .into(); - let existing: SmtH256 = [ + let existing: H256 = [ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ] .into(); - let non_existing: SmtH256 = [ + let non_existing: H256 = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ] .into(); - let other_value: SmtH256 = [ + let other_value: H256 = [ 0, 0, 0xff, 0, 0, 0, 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, ] @@ -705,7 +743,7 @@ fn test_replay_to_pass_proof() { (key4.clone(), non_existing.clone()), ]; let smt = new_smt(pairs); - let leaf_a_bl = vec![(key1, SmtH256::empty())]; + let leaf_a_bl = vec![(key1, H256::empty())]; let leaf_c = vec![(key3.clone(), non_existing)]; let leaf_other = vec![(key3, other_value)]; let proofc = smt @@ -740,10 +778,10 @@ fn test_replay_to_pass_proof() { #[test] fn test_sibling_leaf() { - fn gen_rand_h256() -> SmtH256 { + fn gen_rand_h256() -> H256 { let mut rng = rand::thread_rng(); let rand_data: [u8; 32] = rng.gen(); - SmtH256::from(rand_data) + H256::from(rand_data) } let rand_key = gen_rand_h256(); let mut sibling_key = rand_key.clone(); @@ -766,9 +804,9 @@ fn test_sibling_leaf() { #[test] fn test_max_stack_size() { - fn gen_h256(height: u8) -> SmtH256 { + fn gen_h256(height: u8) -> H256 { // The key path is first go right `256 - height` times then go left `height` times. - let mut key = SmtH256::empty(); + let mut key = H256::empty(); for h in height..=255 { key.set_bit(h.into(), true); } @@ -778,10 +816,10 @@ fn test_max_stack_size() { .map(|height| (gen_h256(height), gen_h256(1))) .collect(); // Most left key - pairs.push((SmtH256::empty(), gen_h256(1))); + pairs.push((H256::empty(), gen_h256(1))); { // A pair of sibling keys in between - let mut left_key = SmtH256::empty(); + let mut left_key = H256::empty(); for h in 12..56 { left_key.set_bit(h, true); } diff --git a/src/traits.rs b/src/traits.rs index cdb7f6e..73cd6c4 100644 --- a/src/traits.rs +++ b/src/traits.rs @@ -1,37 +1,37 @@ use crate::{ error::Error, - h256::SmtH256, tree::{BranchKey, BranchNode}, + H256, }; /// Trait for customize hash function pub trait Hasher { - fn write_h256(&mut self, h: &SmtH256); + fn write_h256(&mut self, h: &H256); fn write_byte(&mut self, b: u8); - fn finish(self) -> SmtH256; + fn finish(self) -> H256; } /// Trait for define value structures pub trait Value { - fn to_h256(&self) -> SmtH256; + fn to_h256(&self) -> H256; fn zero() -> Self; } -impl Value for SmtH256 { - fn to_h256(&self) -> SmtH256 { +impl Value for H256 { + fn to_h256(&self) -> H256 { self.clone() } fn zero() -> Self { - SmtH256::empty() + H256::empty() } } /// Trait for customize backend storage pub trait Store { fn get_branch(&self, branch_key: &BranchKey) -> Result, Error>; - fn get_leaf(&self, leaf_key: &SmtH256) -> Result, Error>; + fn get_leaf(&self, leaf_key: &H256) -> Result, Error>; fn insert_branch(&mut self, node_key: BranchKey, branch: BranchNode) -> Result<(), Error>; - fn insert_leaf(&mut self, leaf_key: SmtH256, leaf: V) -> Result<(), Error>; + fn insert_leaf(&mut self, leaf_key: H256, leaf: V) -> Result<(), Error>; fn remove_branch(&mut self, node_key: &BranchKey) -> Result<(), Error>; - fn remove_leaf(&mut self, leaf_key: &SmtH256) -> Result<(), Error>; + fn remove_leaf(&mut self, leaf_key: &H256) -> Result<(), Error>; } diff --git a/src/tree.rs b/src/tree.rs index d703414..18faff9 100644 --- a/src/tree.rs +++ b/src/tree.rs @@ -1,13 +1,11 @@ use crate::{ error::{Error, Result}, h256, - h256::SmtH256Ord, - h256::SmtH256, merge::{merge, MergeValue}, merkle_proof::MerkleProof, traits::{Hasher, Store, Value}, vec::Vec, - MAX_STACK_SIZE, + H256, MAX_STACK_SIZE, }; use core::cmp::Ordering; use core::marker::PhantomData; @@ -16,11 +14,11 @@ use core::marker::PhantomData; #[derive(Debug, Clone, Eq, PartialEq, Hash)] pub struct BranchKey { pub height: u8, - pub node_key: SmtH256, + pub node_key: H256, } impl BranchKey { - pub fn new(height: u8, node_key: SmtH256) -> BranchKey { + pub fn new(height: u8, node_key: H256) -> BranchKey { BranchKey { height, node_key } } } @@ -50,13 +48,30 @@ pub struct BranchNode { #[derive(Default, Debug)] pub struct SparseMerkleTree { store: S, - root: SmtH256, + root: H256, phantom: PhantomData<(H, V)>, } +#[derive(Eq, PartialEq, Debug, Default, Hash, Clone)] +struct H256OrdTree { + pub inner: H256, +} + +impl PartialOrd for H256OrdTree { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +impl Ord for H256OrdTree { + fn cmp(&self, other: &Self) -> Ordering { + h256::h256_cmp(&self.inner, &other.inner) + } +} + impl> SparseMerkleTree { /// Build a merkle tree from root and store - pub fn new(root: SmtH256, store: S) -> SparseMerkleTree { + pub fn new(root: H256, store: S) -> SparseMerkleTree { SparseMerkleTree { root, store, @@ -65,7 +80,7 @@ impl> SparseMerkleTree { } /// Merkle root - pub fn root(&self) -> &SmtH256 { + pub fn root(&self) -> &H256 { &self.root } @@ -91,7 +106,7 @@ impl> SparseMerkleTree { /// Update a leaf, return new merkle root /// set to zero value to delete a key - pub fn update(&mut self, key: SmtH256, value: V) -> Result<&SmtH256> { + pub fn update(&mut self, key: H256, value: V) -> Result<&H256> { // compute and store new leaf let node = MergeValue::from_h256(value.to_h256()); // notice when value is zero the leaf is deleted, so we do not need to store it @@ -144,7 +159,7 @@ impl> SparseMerkleTree { /// Get value of a leaf /// return zero value if leaf not exists - pub fn get(&self, key: &SmtH256) -> Result { + pub fn get(&self, key: &H256) -> Result { if self.is_empty() { return Ok(V::zero()); } @@ -152,11 +167,11 @@ impl> SparseMerkleTree { } /// Generate merkle proof - pub fn merkle_proof(&self, keys: Vec) -> Result { + pub fn merkle_proof(&self, keys: Vec) -> Result { let mut keys_ord = keys .iter() .take(keys.len()) - .map(|k| SmtH256Ord { inner: k.clone() }) + .map(|k| H256OrdTree { inner: k.clone() }) .collect::>(); if keys_ord.is_empty() { return Err(Error::EmptyKeys); @@ -166,9 +181,9 @@ impl> SparseMerkleTree { keys_ord.sort_unstable(); // Collect leaf bitmaps - let mut leaves_bitmap: Vec = Default::default(); + let mut leaves_bitmap: Vec = Default::default(); for current_key in &keys_ord { - let mut bitmap = SmtH256::empty(); + let mut bitmap = H256::empty(); for height in 0..=core::u8::MAX { let parent_key = h256::parent_path(¤t_key.inner, height); let parent_branch_key = BranchKey::new(height, parent_key); From fbf439ba0974541bde189f9ea2462683f06c36ce Mon Sep 17 00:00:00 2001 From: Joii Date: Wed, 1 Sep 2021 17:06:57 +0800 Subject: [PATCH 07/16] The struce H256 is marked as pub(crate) and fix CI --- benches/smt_benchmark.rs | 6 +++++- c/rust-tests/Cargo.toml | 1 + c/rust-tests/src/tests/smt.rs | 29 +++++++++++++++-------------- src/h256.rs | 2 +- src/lib.rs | 5 +++-- 5 files changed, 25 insertions(+), 18 deletions(-) diff --git a/benches/smt_benchmark.rs b/benches/smt_benchmark.rs index eb73bcb..800bda8 100644 --- a/benches/smt_benchmark.rs +++ b/benches/smt_benchmark.rs @@ -2,10 +2,14 @@ extern crate criterion; use criterion::Criterion; +use numext_fixed_hash; use rand::{thread_rng, Rng}; use sparse_merkle_tree::{ - blake2b::Blake2bHasher, default_store::DefaultStore, tree::SparseMerkleTree, H256, + blake2b::Blake2bHasher, default_store::DefaultStore, tree::SparseMerkleTree, }; + +// Because the direct 'use numext_fixed_hash::H256' may cause part of the IDE errors. (may be about macro expansion) +type H256 = numext_fixed_hash::H256; const TARGET_LEAVES_COUNT: usize = 20; type SMT = SparseMerkleTree>; diff --git a/c/rust-tests/Cargo.toml b/c/rust-tests/Cargo.toml index a31add7..0dbd47c 100644 --- a/c/rust-tests/Cargo.toml +++ b/c/rust-tests/Cargo.toml @@ -17,6 +17,7 @@ hex = "0.4" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" anyhow = "1.0" +numext-fixed-hash = "0.1.6" [build-dependencies] cc = "1.0" \ No newline at end of file diff --git a/c/rust-tests/src/tests/smt.rs b/c/rust-tests/src/tests/smt.rs index e0419a5..400f0c8 100644 --- a/c/rust-tests/src/tests/smt.rs +++ b/c/rust-tests/src/tests/smt.rs @@ -6,9 +6,10 @@ use proptest::prelude::*; use rand::prelude::Rng; use serde::{Deserialize, Serialize}; use sparse_merkle_tree::traits::Hasher; -use sparse_merkle_tree::{default_store::DefaultStore, SparseMerkleTree, H256}; +use sparse_merkle_tree::{default_store::DefaultStore, SparseMerkleTree}; use std::collections::HashMap; -use std::fs; +//use std::fs; +use numext_fixed_hash::H256; #[link(name = "dl-c-impl", kind = "static")] extern "C" { @@ -145,7 +146,7 @@ impl Hasher for CkbBlake2bHasher { self.0.update(&[b][..]); } fn write_h256(&mut self, h: &H256) { - self.0.update(h.as_slice()); + self.0.update(h.as_bytes()); } fn finish(self) -> H256 { let mut hash = [0u8; 32]; @@ -156,7 +157,7 @@ impl Hasher for CkbBlake2bHasher { pub type CkbSMT = SparseMerkleTree>; -pub fn new_ckb_smt(pairs: Vec<(H256, H256)>) -> CkbSMT { +pub fn _new_ckb_smt(pairs: Vec<(H256, H256)>) -> CkbSMT { let mut smt = CkbSMT::default(); for (key, value) in pairs { smt.update(key, value).unwrap(); @@ -228,10 +229,10 @@ fn test_normalize_random() { } } -fn run_test_case(case: Case) -> AnyResult<()> { +fn _run_test_case(case: Case) -> AnyResult<()> { let Case { leaves, proofs, .. } = case; - let ckb_smt = new_ckb_smt( + let ckb_smt = _new_ckb_smt( leaves .iter() .map(|(k, v)| ((*k).into(), (*v).into())) @@ -273,7 +274,7 @@ fn run_test_case(case: Case) -> AnyResult<()> { assert_eq!(smt_state.len(), leaves.len() as u32); smt_state - .verify(ckb_smt.root().as_slice(), &ckb_actual_compiled_proof_bin) + .verify(ckb_smt.root().as_bytes(), &ckb_actual_compiled_proof_bin) .unwrap(); } Ok(()) @@ -300,27 +301,27 @@ proptest! { const EXPECTED_PROOF_SIZE: usize = 16; let mut tree = CkbSMT::default(); - tree.update(key, value).expect("update"); + tree.update(key.clone(), value.clone()).expect("update"); if !tree.is_empty() { - let proof = tree.merkle_proof(vec![key]).expect("proof"); + let proof = tree.merkle_proof(vec![key.clone()]).expect("proof"); let compiled_proof = proof .clone() - .compile(vec![(key, value)]) + .compile(vec![(key.clone(), value.clone())]) .expect("compile proof"); assert!(proof.merkle_path().len() < EXPECTED_PROOF_SIZE); assert!(proof - .verify::(tree.root(), vec![(key, value)]) + .verify::(tree.root(), vec![(key.clone(), value.clone())]) .expect("verify")); assert!(compiled_proof - .verify::(tree.root(), vec![(key, value)]) + .verify::(tree.root(), vec![(key.clone(), value.clone())]) .expect("compiled verify")); let compiled_proof_bin: Vec = compiled_proof.into(); let mut smt_state = SmtCImpl::new(8); - smt_state.insert(key.as_slice(), value.as_slice()).unwrap(); + smt_state.insert(key.as_bytes(), value.as_bytes()).unwrap(); smt_state.normalize(); smt_state - .verify(tree.root().as_slice(), &compiled_proof_bin) + .verify(tree.root().as_bytes(), &compiled_proof_bin) .expect("verify with c"); } } diff --git a/src/h256.rs b/src/h256.rs index 219bc46..1d649b7 100644 --- a/src/h256.rs +++ b/src/h256.rs @@ -1,7 +1,7 @@ use core::cmp::Ordering; use numext_fixed_hash; -pub type H256 = numext_fixed_hash::H256; +pub(crate) type H256 = numext_fixed_hash::H256; const BYTE_SIZE: u8 = 8; diff --git a/src/lib.rs b/src/lib.rs index a076e98..6868773 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -6,9 +6,10 @@ //! use sparse_merkle_tree::{ //! blake2b::Blake2bHasher, default_store::DefaultStore, //! error::Error, MerkleProof, -//! SparseMerkleTree, traits::Value, H256 +//! SparseMerkleTree, traits::Value //! }; //! use blake2b_rs::{Blake2b, Blake2bBuilder}; +//! use numext_fixed_hash::H256; //! //! // define SMT //! type SMT = SparseMerkleTree>; @@ -73,7 +74,7 @@ mod tests; pub mod traits; pub mod tree; -pub use h256::H256; +pub(crate) use h256::H256; pub use merkle_proof::{CompiledMerkleProof, MerkleProof}; pub use tree::SparseMerkleTree; From 79a677f094f3daf6750ecada870eb99a25ed159b Mon Sep 17 00:00:00 2001 From: Joii Date: Wed, 1 Sep 2021 17:14:51 +0800 Subject: [PATCH 08/16] merge H256Ord to h256.rs to avoid code duplication --- src/h256.rs | 38 ++++++++++++++++++++++++++++++++++++-- src/merkle_proof.rs | 19 +------------------ src/tests/tree.rs | 45 +++------------------------------------------ src/tree.rs | 20 ++------------------ 4 files changed, 42 insertions(+), 80 deletions(-) diff --git a/src/h256.rs b/src/h256.rs index 1d649b7..da68fe6 100644 --- a/src/h256.rs +++ b/src/h256.rs @@ -40,6 +40,40 @@ pub fn copy_bits(data: &H256, start: u8) -> H256 { target } -pub fn h256_cmp(v1: &H256, v2: &H256) -> Ordering { - v1.0.iter().rev().cmp(v2.0.iter().rev()) +#[derive(Eq, PartialEq, Debug, Default, Hash, Clone)] +pub(crate) struct H256Ord { + pub inner: H256, +} + +impl From<[u8; 32]> for H256Ord { + fn from(v: [u8; 32]) -> H256Ord { + H256Ord { + inner: H256::from(v), + } + } +} + +impl From for H256Ord { + fn from(v: H256) -> H256Ord { + H256Ord { inner: v } + } +} + +impl From<&H256> for H256Ord { + fn from(v: &H256) -> H256Ord { + H256Ord { inner: v.clone() } + } +} + +impl PartialOrd for H256Ord { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +impl Ord for H256Ord { + fn cmp(&self, other: &Self) -> Ordering { + // Compare bits from heigher to lower (255..0) + self.inner.0.iter().rev().cmp(other.inner.0.iter().rev()) + } } diff --git a/src/merkle_proof.rs b/src/merkle_proof.rs index 8f5b24d..156740f 100644 --- a/src/merkle_proof.rs +++ b/src/merkle_proof.rs @@ -1,29 +1,12 @@ use crate::{ error::{Error, Result}, h256, + h256::H256Ord, merge::{merge, MergeValue}, traits::Hasher, vec::Vec, H256, MAX_STACK_SIZE, }; -use core::cmp::Ordering; - -#[derive(Eq, PartialEq, Debug, Default, Hash, Clone)] -struct H256Ord { - pub inner: H256, -} - -impl PartialOrd for H256Ord { - fn partial_cmp(&self, other: &Self) -> Option { - Some(self.cmp(other)) - } -} - -impl Ord for H256Ord { - fn cmp(&self, other: &Self) -> Ordering { - h256::h256_cmp(&self.inner, &other.inner) - } -} #[derive(Debug, Clone, PartialEq, Eq)] pub struct MerkleProof { diff --git a/src/tests/tree.rs b/src/tests/tree.rs index 1ef1506..49036ae 100644 --- a/src/tests/tree.rs +++ b/src/tests/tree.rs @@ -1,52 +1,13 @@ use crate::*; use crate::{ - blake2b::Blake2bHasher, default_store::DefaultStore, error::Error, merge::MergeValue, - MerkleProof, SparseMerkleTree, + blake2b::Blake2bHasher, default_store::DefaultStore, error::Error, h256::H256Ord, + merge::MergeValue, MerkleProof, SparseMerkleTree, }; -use core::cmp::Ordering; use proptest::prelude::*; use rand::prelude::{Rng, SliceRandom}; type SMT = SparseMerkleTree>; -#[derive(Eq, PartialEq, Debug, Default, Hash, Clone)] -pub struct H256OrdTest { - pub inner: H256, -} - -impl From<[u8; 32]> for H256OrdTest { - fn from(v: [u8; 32]) -> H256OrdTest { - H256OrdTest { - inner: H256::from(v), - } - } -} - -impl From for H256OrdTest { - fn from(v: H256) -> H256OrdTest { - H256OrdTest { inner: v } - } -} - -impl From<&H256> for H256OrdTest { - fn from(v: &H256) -> H256OrdTest { - H256OrdTest { inner: v.clone() } - } -} - -impl PartialOrd for H256OrdTest { - fn partial_cmp(&self, other: &Self) -> Option { - Some(self.cmp(other)) - } -} - -impl Ord for H256OrdTest { - fn cmp(&self, other: &Self) -> Ordering { - // Compare bits from heigher to lower (255..0) - self.inner.0.iter().rev().cmp(other.inner.0.iter().rev()) - } -} - #[test] fn test_default_root() { let mut tree = SMT::default(); @@ -382,7 +343,7 @@ fn merkle_proof(max_proof: usize) -> impl Strategy> { proptest! { #[test] fn test_h256(key: [u8; 32], key2: [u8; 32]) { - let mut list1: Vec = vec![H256OrdTest::from(key) , H256OrdTest::from(key2)]; + let mut list1: Vec = vec![H256Ord::from(key) , H256Ord::from(key2)]; let mut list2 = list1.clone(); // sort H256 list1.sort_unstable_by_key(|k| k.clone()); diff --git a/src/tree.rs b/src/tree.rs index 18faff9..85708b1 100644 --- a/src/tree.rs +++ b/src/tree.rs @@ -1,6 +1,7 @@ use crate::{ error::{Error, Result}, h256, + h256::H256Ord, merge::{merge, MergeValue}, merkle_proof::MerkleProof, traits::{Hasher, Store, Value}, @@ -52,23 +53,6 @@ pub struct SparseMerkleTree { phantom: PhantomData<(H, V)>, } -#[derive(Eq, PartialEq, Debug, Default, Hash, Clone)] -struct H256OrdTree { - pub inner: H256, -} - -impl PartialOrd for H256OrdTree { - fn partial_cmp(&self, other: &Self) -> Option { - Some(self.cmp(other)) - } -} - -impl Ord for H256OrdTree { - fn cmp(&self, other: &Self) -> Ordering { - h256::h256_cmp(&self.inner, &other.inner) - } -} - impl> SparseMerkleTree { /// Build a merkle tree from root and store pub fn new(root: H256, store: S) -> SparseMerkleTree { @@ -171,7 +155,7 @@ impl> SparseMerkleTree { let mut keys_ord = keys .iter() .take(keys.len()) - .map(|k| H256OrdTree { inner: k.clone() }) + .map(|k| H256Ord { inner: k.clone() }) .collect::>(); if keys_ord.is_empty() { return Err(Error::EmptyKeys); From 02985a2e30de6aba85cd57eedd460d69d8309493 Mon Sep 17 00:00:00 2001 From: Joii Date: Thu, 2 Sep 2021 12:10:34 +0800 Subject: [PATCH 09/16] Replace several iter with into_iter, --- src/merkle_proof.rs | 8 +++----- src/tests/tree.rs | 7 +++---- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/src/merkle_proof.rs b/src/merkle_proof.rs index 156740f..fd764ff 100644 --- a/src/merkle_proof.rs +++ b/src/merkle_proof.rs @@ -53,8 +53,7 @@ impl MerkleProof { pub fn compile(self, leaves: Vec<(H256, H256)>) -> Result { let mut leaves_ord: Vec<(H256Ord, H256)> = leaves - .iter() - .take(leaves.len()) + .into_iter() .map(|(k, v)| (H256Ord { inner: k.clone() }, v.clone())) .collect::>(); if leaves_ord.is_empty() { @@ -195,9 +194,8 @@ pub struct CompiledMerkleProof(pub Vec); impl CompiledMerkleProof { pub fn compute_root(&self, leaves: Vec<(H256, H256)>) -> Result { let mut leaves_ord: Vec<(H256Ord, H256)> = leaves - .iter() - .take(leaves.len()) - .map(|(k, v)| (H256Ord { inner: k.clone() }, v.clone())) + .into_iter() + .map(|(k, v)| (H256Ord::from(k), v)) .collect(); leaves_ord.sort_unstable_by_key(|(k, _v)| k.clone()); let mut program_index = 0; diff --git a/src/tests/tree.rs b/src/tests/tree.rs index 49036ae..ed28a47 100644 --- a/src/tests/tree.rs +++ b/src/tests/tree.rs @@ -419,8 +419,8 @@ proptest! { #[test] fn test_smt_multi_leaves_small((pairs, n) in leaves(1, 50)){ let smt = new_smt(pairs.clone()); - let proof = smt.merkle_proof(pairs.iter().take(n).map(|(k, _v)| k.clone()).collect()).expect("gen proof"); - let data: Vec<(H256, H256)> = pairs.into_iter().take(n).collect(); + let proof = smt.merkle_proof(pairs.iter().map(|(k, _v)| k.clone()).collect()).expect("gen proof"); + let data: Vec<(H256, H256)> = pairs.into_iter().collect(); let compiled_proof = proof.clone().compile(data.clone()).expect("compile proof"); assert!(proof.verify::(smt.root(), data.clone()).expect("verify proof")); assert!(compiled_proof.verify::(smt.root(), data).expect("verify compiled proof")); @@ -602,8 +602,7 @@ fn test_v0_2_broken_sample() { .map(parse_h256) .collect::>(); let mut pairs = keys - .iter() - .take(keys.len()) + .into_iter() .map(|k| k.clone()) .into_iter() .zip(values.into_iter()) From 071c20192941be9ca4a47ec86dd9c9cb00eadda5 Mon Sep 17 00:00:00 2001 From: Joii Date: Thu, 2 Sep 2021 12:21:15 +0800 Subject: [PATCH 10/16] revert new_ckb_smt in smt.rs file _new_ckb_smt --- c/rust-tests/src/tests/smt.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/c/rust-tests/src/tests/smt.rs b/c/rust-tests/src/tests/smt.rs index 400f0c8..a9e0f82 100644 --- a/c/rust-tests/src/tests/smt.rs +++ b/c/rust-tests/src/tests/smt.rs @@ -157,7 +157,7 @@ impl Hasher for CkbBlake2bHasher { pub type CkbSMT = SparseMerkleTree>; -pub fn _new_ckb_smt(pairs: Vec<(H256, H256)>) -> CkbSMT { +pub fn new_ckb_smt(pairs: Vec<(H256, H256)>) -> CkbSMT { let mut smt = CkbSMT::default(); for (key, value) in pairs { smt.update(key, value).unwrap(); @@ -229,10 +229,10 @@ fn test_normalize_random() { } } -fn _run_test_case(case: Case) -> AnyResult<()> { +fn run_test_case(case: Case) -> AnyResult<()> { let Case { leaves, proofs, .. } = case; - let ckb_smt = _new_ckb_smt( + let ckb_smt = new_ckb_smt( leaves .iter() .map(|(k, v)| ((*k).into(), (*v).into())) From dd466f55ebd8738af9ef73745f2d7b63960b9a9c Mon Sep 17 00:00:00 2001 From: Joii Date: Thu, 2 Sep 2021 17:04:46 +0800 Subject: [PATCH 11/16] H256Ord use Deref to return H256 --- src/h256.rs | 10 +++++++++- src/merkle_proof.rs | 6 +++--- src/tests/tree.rs | 6 +++--- src/tree.rs | 10 +++++----- 4 files changed, 20 insertions(+), 12 deletions(-) diff --git a/src/h256.rs b/src/h256.rs index da68fe6..69a3c98 100644 --- a/src/h256.rs +++ b/src/h256.rs @@ -1,4 +1,5 @@ use core::cmp::Ordering; +use core::ops::Deref; use numext_fixed_hash; pub(crate) type H256 = numext_fixed_hash::H256; @@ -42,7 +43,14 @@ pub fn copy_bits(data: &H256, start: u8) -> H256 { #[derive(Eq, PartialEq, Debug, Default, Hash, Clone)] pub(crate) struct H256Ord { - pub inner: H256, + inner: H256, +} + +impl Deref for H256Ord { + type Target = H256; + fn deref(&self) -> &Self::Target { + &self.inner + } } impl From<[u8; 32]> for H256Ord { diff --git a/src/merkle_proof.rs b/src/merkle_proof.rs index fd764ff..7f09a83 100644 --- a/src/merkle_proof.rs +++ b/src/merkle_proof.rs @@ -54,7 +54,7 @@ impl MerkleProof { pub fn compile(self, leaves: Vec<(H256, H256)>) -> Result { let mut leaves_ord: Vec<(H256Ord, H256)> = leaves .into_iter() - .map(|(k, v)| (H256Ord { inner: k.clone() }, v.clone())) + .map(|(k, v)| (H256Ord::from(k), v.clone())) .collect::>(); if leaves_ord.is_empty() { return Err(Error::EmptyKeys); @@ -77,7 +77,7 @@ impl MerkleProof { while leaf_index < leaves_ord.len() { let (leaf_key, _value) = leaves_ord[leaf_index].clone(); let fork_height = if leaf_index + 1 < leaves_ord.len() { - h256::fork_height(&leaf_key.inner, &leaves_ord[leaf_index + 1].0.inner) + h256::fork_height(&leaf_key, &leaves_ord[leaf_index + 1].0) } else { core::u8::MAX }; @@ -211,7 +211,7 @@ impl CompiledMerkleProof { return Err(Error::CorruptedStack); } let (k, v) = leaves_ord[leaf_index].clone(); - stack.push((0, k.inner, MergeValue::from_h256(v))); + stack.push((0, (*k).clone(), MergeValue::from_h256(v))); leaf_index += 1; } // P : hash stack top item with sibling node in proof diff --git a/src/tests/tree.rs b/src/tests/tree.rs index ed28a47..c12c4c6 100644 --- a/src/tests/tree.rs +++ b/src/tests/tree.rs @@ -350,8 +350,8 @@ proptest! { // sort by high bits to lower bits list2.sort_unstable_by(|k1, k2| { for i in (0u8..=255).rev() { - let b1 = if k1.inner.bit(i.into()).unwrap_or(false) { 1 } else { 0 }; - let b2 = if k2.inner.bit(i.into()).unwrap_or(false) { 1 } else { 0 }; + let b1 = if (*k1).bit(i.into()).unwrap_or(false) { 1 } else { 0 }; + let b2 = if (*k2).bit(i.into()).unwrap_or(false) { 1 } else { 0 }; let o = b1.cmp(&b2); if o != std::cmp::Ordering::Equal { return o; @@ -417,7 +417,7 @@ proptest! { } #[test] - fn test_smt_multi_leaves_small((pairs, n) in leaves(1, 50)){ + fn test_smt_multi_leaves_small((pairs, _n) in leaves(1, 50)){ let smt = new_smt(pairs.clone()); let proof = smt.merkle_proof(pairs.iter().map(|(k, _v)| k.clone()).collect()).expect("gen proof"); let data: Vec<(H256, H256)> = pairs.into_iter().collect(); diff --git a/src/tree.rs b/src/tree.rs index 85708b1..ba1c289 100644 --- a/src/tree.rs +++ b/src/tree.rs @@ -155,7 +155,7 @@ impl> SparseMerkleTree { let mut keys_ord = keys .iter() .take(keys.len()) - .map(|k| H256Ord { inner: k.clone() }) + .map(|k| H256Ord::from(k)) .collect::>(); if keys_ord.is_empty() { return Err(Error::EmptyKeys); @@ -169,10 +169,10 @@ impl> SparseMerkleTree { for current_key in &keys_ord { let mut bitmap = H256::empty(); for height in 0..=core::u8::MAX { - let parent_key = h256::parent_path(¤t_key.inner, height); + let parent_key = h256::parent_path(¤t_key, height); let parent_branch_key = BranchKey::new(height, parent_key); if let Some(parent_branch) = self.store.get_branch(&parent_branch_key)? { - let sibling = if current_key.inner.bit(height.into()).unwrap_or(false) { + let sibling = if current_key.bit(height.into()).unwrap_or(false) { parent_branch.left } else { parent_branch.right @@ -192,9 +192,9 @@ impl> SparseMerkleTree { let mut stack_top = 0; let mut leaf_index = 0; while leaf_index < keys_ord.len() { - let leaf_key = keys_ord[leaf_index].inner.clone(); + let leaf_key = keys_ord[leaf_index].clone(); let fork_height = if leaf_index + 1 < keys_ord.len() { - h256::fork_height(&leaf_key, &keys_ord[leaf_index + 1].inner) + h256::fork_height(&leaf_key, &keys_ord[leaf_index + 1]) } else { core::u8::MAX }; From e0159647edc74f020c22c83cde6e7550b889b4f3 Mon Sep 17 00:00:00 2001 From: Joii Date: Thu, 2 Sep 2021 21:06:56 +0800 Subject: [PATCH 12/16] Use a function to implement H256 sorting instead of using a class --- src/h256.rs | 48 +++++---------------------------------------- src/merkle_proof.rs | 43 +++++++++++++++++----------------------- src/tests/tree.rs | 7 ++++--- src/tree.rs | 23 +++++++++------------- 4 files changed, 36 insertions(+), 85 deletions(-) diff --git a/src/h256.rs b/src/h256.rs index 69a3c98..2eae67f 100644 --- a/src/h256.rs +++ b/src/h256.rs @@ -1,5 +1,4 @@ -use core::cmp::Ordering; -use core::ops::Deref; +use crate::vec::Vec; use numext_fixed_hash; pub(crate) type H256 = numext_fixed_hash::H256; @@ -41,47 +40,10 @@ pub fn copy_bits(data: &H256, start: u8) -> H256 { target } -#[derive(Eq, PartialEq, Debug, Default, Hash, Clone)] -pub(crate) struct H256Ord { - inner: H256, +pub(crate) fn smt_sort_unstable(v: &mut Vec) { + (*v).sort_unstable_by(|k1, k2| k1.0.iter().rev().cmp(k2.0.iter().rev())); } -impl Deref for H256Ord { - type Target = H256; - fn deref(&self) -> &Self::Target { - &self.inner - } -} - -impl From<[u8; 32]> for H256Ord { - fn from(v: [u8; 32]) -> H256Ord { - H256Ord { - inner: H256::from(v), - } - } -} - -impl From for H256Ord { - fn from(v: H256) -> H256Ord { - H256Ord { inner: v } - } -} - -impl From<&H256> for H256Ord { - fn from(v: &H256) -> H256Ord { - H256Ord { inner: v.clone() } - } -} - -impl PartialOrd for H256Ord { - fn partial_cmp(&self, other: &Self) -> Option { - Some(self.cmp(other)) - } -} - -impl Ord for H256Ord { - fn cmp(&self, other: &Self) -> Ordering { - // Compare bits from heigher to lower (255..0) - self.inner.0.iter().rev().cmp(other.inner.0.iter().rev()) - } +pub(crate) fn smt_sort_unstable_kv(v: &mut Vec<(H256, H256)>) { + v.sort_unstable_by(|(k1, _v1), (k2, _v2)| k1.0.iter().rev().cmp(k2.0.iter().rev())); } diff --git a/src/merkle_proof.rs b/src/merkle_proof.rs index 7f09a83..57595df 100644 --- a/src/merkle_proof.rs +++ b/src/merkle_proof.rs @@ -1,7 +1,6 @@ use crate::{ error::{Error, Result}, h256, - h256::H256Ord, merge::{merge, MergeValue}, traits::Hasher, vec::Vec, @@ -52,39 +51,36 @@ impl MerkleProof { } pub fn compile(self, leaves: Vec<(H256, H256)>) -> Result { - let mut leaves_ord: Vec<(H256Ord, H256)> = leaves - .into_iter() - .map(|(k, v)| (H256Ord::from(k), v.clone())) - .collect::>(); - if leaves_ord.is_empty() { + let mut leaves = leaves; + if leaves.is_empty() { return Err(Error::EmptyKeys); - } else if leaves_ord.len() != self.leaves_count() { + } else if leaves.len() != self.leaves_count() { return Err(Error::IncorrectNumberOfLeaves { expected: self.leaves_count(), - actual: leaves_ord.len(), + actual: leaves.len(), }); } // sort leaves - leaves_ord.sort_unstable_by_key(|(k, _v)| k.clone()); + h256::smt_sort_unstable_kv(&mut leaves); let (leaves_bitmap, merkle_path) = self.take(); - let mut proof: Vec = Vec::with_capacity(merkle_path.len() * 33 + leaves_ord.len()); + let mut proof: Vec = Vec::with_capacity(merkle_path.len() * 33 + leaves.len()); let mut stack_fork_height = [0u8; MAX_STACK_SIZE]; // store fork height let mut stack_top = 0; let mut leaf_index = 0; let mut merkle_path_index = 0; - while leaf_index < leaves_ord.len() { - let (leaf_key, _value) = leaves_ord[leaf_index].clone(); - let fork_height = if leaf_index + 1 < leaves_ord.len() { - h256::fork_height(&leaf_key, &leaves_ord[leaf_index + 1].0) + while leaf_index < leaves.len() { + let (leaf_key, _value) = leaves[leaf_index].clone(); + let fork_height = if leaf_index + 1 < leaves.len() { + h256::fork_height(&leaf_key, &leaves[leaf_index + 1].0) } else { core::u8::MAX }; proof.push(0x4C); let mut zero_count = 0u16; for height in 0..=fork_height { - if height == fork_height && leaf_index + 1 < leaves_ord.len() { + if height == fork_height && leaf_index + 1 < leaves.len() { // If it's not final round, we don't need to merge to root (height=255) break; } @@ -157,7 +153,7 @@ impl MerkleProof { if stack_top != 1 { return Err(Error::CorruptedProof); } - if leaf_index != leaves_ord.len() { + if leaf_index != leaves.len() { return Err(Error::CorruptedProof); } if merkle_path_index != merkle_path.len() { @@ -193,11 +189,8 @@ pub struct CompiledMerkleProof(pub Vec); impl CompiledMerkleProof { pub fn compute_root(&self, leaves: Vec<(H256, H256)>) -> Result { - let mut leaves_ord: Vec<(H256Ord, H256)> = leaves - .into_iter() - .map(|(k, v)| (H256Ord::from(k), v)) - .collect(); - leaves_ord.sort_unstable_by_key(|(k, _v)| k.clone()); + let mut leaves = leaves; + h256::smt_sort_unstable_kv(&mut leaves); let mut program_index = 0; let mut leaf_index = 0; let mut stack: Vec<(u16, H256, MergeValue)> = Vec::new(); @@ -207,11 +200,11 @@ impl CompiledMerkleProof { match code { // L : push leaf value 0x4C => { - if leaf_index >= leaves_ord.len() { + if leaf_index >= leaves.len() { return Err(Error::CorruptedStack); } - let (k, v) = leaves_ord[leaf_index].clone(); - stack.push((0, (*k).clone(), MergeValue::from_h256(v))); + let (k, v) = leaves[leaf_index].clone(); + stack.push((0, k.clone(), MergeValue::from_h256(v))); leaf_index += 1; } // P : hash stack top item with sibling node in proof @@ -348,7 +341,7 @@ impl CompiledMerkleProof { if stack[0].0 != 256 { return Err(Error::CorruptedProof); } - if leaf_index != leaves_ord.len() { + if leaf_index != leaves.len() { return Err(Error::CorruptedProof); } Ok(stack[0].2.hash::()) diff --git a/src/tests/tree.rs b/src/tests/tree.rs index c12c4c6..bed485c 100644 --- a/src/tests/tree.rs +++ b/src/tests/tree.rs @@ -1,7 +1,7 @@ use crate::*; use crate::{ - blake2b::Blake2bHasher, default_store::DefaultStore, error::Error, h256::H256Ord, - merge::MergeValue, MerkleProof, SparseMerkleTree, + blake2b::Blake2bHasher, default_store::DefaultStore, error::Error, merge::MergeValue, + MerkleProof, SparseMerkleTree, }; use proptest::prelude::*; use rand::prelude::{Rng, SliceRandom}; @@ -343,10 +343,11 @@ fn merkle_proof(max_proof: usize) -> impl Strategy> { proptest! { #[test] fn test_h256(key: [u8; 32], key2: [u8; 32]) { - let mut list1: Vec = vec![H256Ord::from(key) , H256Ord::from(key2)]; + let mut list1: Vec = vec![H256::from(key) , H256::from(key2)]; let mut list2 = list1.clone(); // sort H256 list1.sort_unstable_by_key(|k| k.clone()); + h256::smt_sort_unstable(&mut list1); // sort by high bits to lower bits list2.sort_unstable_by(|k1, k2| { for i in (0u8..=255).rev() { diff --git a/src/tree.rs b/src/tree.rs index ba1c289..20f819d 100644 --- a/src/tree.rs +++ b/src/tree.rs @@ -1,7 +1,6 @@ use crate::{ error::{Error, Result}, h256, - h256::H256Ord, merge::{merge, MergeValue}, merkle_proof::MerkleProof, traits::{Hasher, Store, Value}, @@ -152,21 +151,17 @@ impl> SparseMerkleTree { /// Generate merkle proof pub fn merkle_proof(&self, keys: Vec) -> Result { - let mut keys_ord = keys - .iter() - .take(keys.len()) - .map(|k| H256Ord::from(k)) - .collect::>(); - if keys_ord.is_empty() { + let mut keys = keys; + if keys.is_empty() { return Err(Error::EmptyKeys); } // sort keys - keys_ord.sort_unstable(); + h256::smt_sort_unstable(&mut keys); // Collect leaf bitmaps let mut leaves_bitmap: Vec = Default::default(); - for current_key in &keys_ord { + for current_key in &keys { let mut bitmap = H256::empty(); for height in 0..=core::u8::MAX { let parent_key = h256::parent_path(¤t_key, height); @@ -191,15 +186,15 @@ impl> SparseMerkleTree { let mut stack_fork_height = [0u8; MAX_STACK_SIZE]; // store fork height let mut stack_top = 0; let mut leaf_index = 0; - while leaf_index < keys_ord.len() { - let leaf_key = keys_ord[leaf_index].clone(); - let fork_height = if leaf_index + 1 < keys_ord.len() { - h256::fork_height(&leaf_key, &keys_ord[leaf_index + 1]) + while leaf_index < keys.len() { + let leaf_key = keys[leaf_index].clone(); + let fork_height = if leaf_index + 1 < keys.len() { + h256::fork_height(&leaf_key, &keys[leaf_index + 1]) } else { core::u8::MAX }; for height in 0..=fork_height { - if height == fork_height && leaf_index + 1 < keys_ord.len() { + if height == fork_height && leaf_index + 1 < keys.len() { // If it's not final round, we don't need to merge to root (height=255) break; } From 89b7e8587c86315f540c6b9195415cec462965f0 Mon Sep 17 00:00:00 2001 From: Joii Date: Wed, 8 Sep 2021 11:31:53 +0800 Subject: [PATCH 13/16] remove std in features --- Cargo.toml | 3 +-- src/error.rs | 2 +- src/tests/tree.rs | 3 +++ 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 3143765..263d26e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,8 +11,7 @@ exclude = ["/fixtures", "/proptest-regressions"] # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [features] -default = ["std", "blake2b"] -std = [] +default = ["blake2b"] blake2b = ["blake2b-rs"] [dependencies] diff --git a/src/error.rs b/src/error.rs index 3f4f79f..c612b5a 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,4 +1,5 @@ use crate::{string, H256}; +extern crate std; pub type Result = ::core::result::Result; @@ -66,5 +67,4 @@ impl core::fmt::Display for Error { } } -#[cfg(feature = "std")] impl std::error::Error for Error {} diff --git a/src/tests/tree.rs b/src/tests/tree.rs index bed485c..7b4a2f8 100644 --- a/src/tests/tree.rs +++ b/src/tests/tree.rs @@ -6,6 +6,9 @@ use crate::{ use proptest::prelude::*; use rand::prelude::{Rng, SliceRandom}; +extern crate std; +use std::{println, vec::Vec}; + type SMT = SparseMerkleTree>; #[test] From da76840fb32dc0bf8d3033c065b2a763f6358522 Mon Sep 17 00:00:00 2001 From: Joii Date: Wed, 15 Sep 2021 10:07:17 +0800 Subject: [PATCH 14/16] Remove two unreasonable codes: lib.rs about no_std and error.rs about extern std --- src/error.rs | 1 - src/lib.rs | 2 -- 2 files changed, 3 deletions(-) diff --git a/src/error.rs b/src/error.rs index c612b5a..f18af7e 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,5 +1,4 @@ use crate::{string, H256}; -extern crate std; pub type Result = ::core::result::Result; diff --git a/src/lib.rs b/src/lib.rs index 6868773..060e048 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -60,8 +60,6 @@ //! } //! ``` -#![cfg_attr(not(feature = "std"), no_std)] - #[cfg(feature = "blake2b")] pub mod blake2b; pub mod default_store; From 103801eb03c13a2f63bee9173217ed67da8fb772 Mon Sep 17 00:00:00 2001 From: Joii Date: Wed, 15 Sep 2021 10:34:50 +0800 Subject: [PATCH 15/16] Remove the "extern crate std" in test.rs --- src/tests/tree.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/tests/tree.rs b/src/tests/tree.rs index 7b4a2f8..28f7950 100644 --- a/src/tests/tree.rs +++ b/src/tests/tree.rs @@ -6,7 +6,6 @@ use crate::{ use proptest::prelude::*; use rand::prelude::{Rng, SliceRandom}; -extern crate std; use std::{println, vec::Vec}; type SMT = SparseMerkleTree>; From 018c5f3d465ad100eeaac1265a6d992f243d6a35 Mon Sep 17 00:00:00 2001 From: Joii Date: Wed, 15 Sep 2021 10:53:47 +0800 Subject: [PATCH 16/16] Organize the code, remove some unnecessary code --- src/default_store.rs | 11 ++--------- src/h256.rs | 1 - src/lib.rs | 15 +++------------ src/merkle_proof.rs | 1 - src/tests/tree.rs | 2 -- src/tree.rs | 1 - 6 files changed, 5 insertions(+), 26 deletions(-) diff --git a/src/default_store.rs b/src/default_store.rs index fda98b1..70bc8dd 100644 --- a/src/default_store.rs +++ b/src/default_store.rs @@ -50,12 +50,5 @@ impl Store for DefaultStore { } } -cfg_if::cfg_if! { - if #[cfg(feature = "std")] { - pub type Map = collections::HashMap; - pub type Entry<'a, K, V> = collections::hash_map::Entry<'a, K, V>; - } else { - pub type Map = collections::BTreeMap; - pub type Entry<'a, K, V> = collections::btree_map::Entry<'a, K, V>; - } -} +pub type Map = collections::BTreeMap; +pub type Entry<'a, K, V> = collections::btree_map::Entry<'a, K, V>; diff --git a/src/h256.rs b/src/h256.rs index 2eae67f..f620747 100644 --- a/src/h256.rs +++ b/src/h256.rs @@ -1,4 +1,3 @@ -use crate::vec::Vec; use numext_fixed_hash; pub(crate) type H256 = numext_fixed_hash::H256; diff --git a/src/lib.rs b/src/lib.rs index 060e048..bec4d98 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -81,15 +81,6 @@ pub const EXPECTED_PATH_SIZE: usize = 16; // Max stack size can be used when verify compiled proof pub(crate) const MAX_STACK_SIZE: usize = 257; -cfg_if::cfg_if! { - if #[cfg(feature = "std")] { - use std::collections; - use std::vec; - use std::string; - } else { - extern crate alloc; - use alloc::collections; - use alloc::vec; - use alloc::string; - } -} +extern crate alloc; +use alloc::collections; +use alloc::string; diff --git a/src/merkle_proof.rs b/src/merkle_proof.rs index 57595df..710301d 100644 --- a/src/merkle_proof.rs +++ b/src/merkle_proof.rs @@ -3,7 +3,6 @@ use crate::{ h256, merge::{merge, MergeValue}, traits::Hasher, - vec::Vec, H256, MAX_STACK_SIZE, }; diff --git a/src/tests/tree.rs b/src/tests/tree.rs index 28f7950..bed485c 100644 --- a/src/tests/tree.rs +++ b/src/tests/tree.rs @@ -6,8 +6,6 @@ use crate::{ use proptest::prelude::*; use rand::prelude::{Rng, SliceRandom}; -use std::{println, vec::Vec}; - type SMT = SparseMerkleTree>; #[test] diff --git a/src/tree.rs b/src/tree.rs index 20f819d..6709433 100644 --- a/src/tree.rs +++ b/src/tree.rs @@ -4,7 +4,6 @@ use crate::{ merge::{merge, MergeValue}, merkle_proof::MerkleProof, traits::{Hasher, Store, Value}, - vec::Vec, H256, MAX_STACK_SIZE, }; use core::cmp::Ordering;