Result<T> to mt.add() function, applied rustfmt

This commit is contained in:
arnaucube
2019-07-15 20:35:05 +02:00
parent cb178359ca
commit 57fc963ef4
5 changed files with 696 additions and 485 deletions

View File

@@ -2,4 +2,4 @@ pub const TYPENODEEMPTY: u8 = 0;
pub const TYPENODENORMAL: u8 = 1;
pub const TYPENODEFINAL: u8 = 2;
pub const TYPENODEVALUE: u8 = 3;
pub const EMPTYNODEVALUE: [u8;32] = [0;32];
pub const EMPTYNODEVALUE: [u8; 32] = [0; 32];

View File

@@ -1,11 +1,11 @@
extern crate rusty_leveldb;
use self::rusty_leveldb::{DB};
use self::rusty_leveldb::DB;
use constants;
pub struct Db {
storage: DB
storage: DB,
}
impl Db {
@@ -17,9 +17,7 @@ impl Db {
opt = Default::default();
}
let database = DB::open(path, opt).unwrap();
Db {
storage: database,
}
Db { storage: database }
}
pub fn insert(&mut self, k: [u8; 32], t: u8, il: u32, b: Vec<u8>) {
let mut v: Vec<u8>;
@@ -29,7 +27,7 @@ impl Db {
v.extend(&b);
self.storage.put(&k[..], &v[..]).unwrap();
}
pub fn get(&mut self, k: &[u8;32]) -> (u8, u32, Vec<u8>) {
pub fn get(&mut self, k: &[u8; 32]) -> (u8, u32, Vec<u8>) {
if k.to_vec() == constants::EMPTYNODEVALUE.to_vec() {
return (0, 0, constants::EMPTYNODEVALUE.to_vec());
}
@@ -40,8 +38,12 @@ impl Db {
let il = u32::from_le_bytes(il_bytes);
let b = &x[5..];
(t, il, b.to_vec())
},
None => (constants::TYPENODEEMPTY, 0, constants::EMPTYNODEVALUE.to_vec()),
}
None => (
constants::TYPENODEEMPTY,
0,
constants::EMPTYNODEVALUE.to_vec(),
),
}
}
}

View File

@@ -1,15 +1,17 @@
#[macro_use]
extern crate arrayref;
extern crate tiny_keccak;
extern crate rustc_hex;
extern crate hex;
extern crate rustc_hex;
extern crate tiny_keccak;
use rustc_hex::ToHex;
mod utils;
mod node;
mod db;
mod constants;
mod db;
mod node;
mod utils;
type Result<T> = std::result::Result<T, String>;
pub struct TestValue {
bytes: Vec<u8>,
@@ -18,8 +20,8 @@ pub struct TestValue {
pub trait Value {
fn bytes(&self) -> &Vec<u8>;
fn index_length(&self) -> u32;
fn hi(&self) -> [u8;32];
fn ht(&self) -> [u8;32];
fn hi(&self) -> [u8; 32];
fn ht(&self) -> [u8; 32];
}
impl Value for TestValue {
fn bytes(&self) -> &Vec<u8> {
@@ -28,10 +30,16 @@ impl Value for TestValue {
fn index_length(&self) -> u32 {
self.index_length
}
fn hi(&self) -> [u8;32] {
utils::hash_vec(self.bytes().to_vec().split_at(self.index_length() as usize).0.to_vec())
fn hi(&self) -> [u8; 32] {
utils::hash_vec(
self.bytes()
.to_vec()
.split_at(self.index_length() as usize)
.0
.to_vec(),
)
}
fn ht(&self) -> [u8;32] {
fn ht(&self) -> [u8; 32] {
utils::hash_vec(self.bytes().to_vec())
}
}
@@ -43,40 +51,58 @@ pub struct MerkleTree<'a> {
}
impl<'a> MerkleTree<'a> {
pub fn new(database: &'a mut db::Db, num_levels: u32) -> MerkleTree<'a> {
MerkleTree{
MerkleTree {
root: constants::EMPTYNODEVALUE,
num_levels,
sto: database,
}
}
pub fn add(&mut self, v: &TestValue) {
pub fn add(&mut self, v: &TestValue) -> Result<()> {
// add the leaf that we are adding
self.sto.insert(v.ht(), constants::TYPENODEVALUE, v.index_length(), v.bytes().to_vec());
self.sto.insert(
v.ht(),
constants::TYPENODEVALUE,
v.index_length(),
v.bytes().to_vec(),
);
let hi = v.hi();
let path = utils::get_path(self.num_levels, hi);
let mut siblings: Vec<[u8;32]> = Vec::new();
let mut siblings: Vec<[u8; 32]> = Vec::new();
let mut node_hash = self.root;
for i in (0..=self.num_levels-2).rev() {
for i in (0..=self.num_levels - 2).rev() {
// get node
let (t, il, node_bytes) = self.sto.get(&node_hash);
if t == constants::TYPENODEFINAL {
let hi_child = utils::hash_vec(node_bytes.to_vec().split_at(il as usize).0.to_vec());
let hi_child =
utils::hash_vec(node_bytes.to_vec().split_at(il as usize).0.to_vec());
let path_child = utils::get_path(self.num_levels, hi_child);
let pos_diff = utils::compare_paths(&path_child, &path);
if pos_diff == 999 { // TODO use a match here, and instead of 999 return something better
println!("node already exists");
println!("compare paths err");
return;
if pos_diff == -1 {
return Err("node already exists".to_owned());
}
let final_node_1_hash = utils::calc_hash_from_leaf_and_level(pos_diff, &path_child, utils::hash_vec(node_bytes.to_vec()));
self.sto.insert(final_node_1_hash, constants::TYPENODEFINAL, il, node_bytes.to_vec());
let final_node_2_hash = utils::calc_hash_from_leaf_and_level(pos_diff, &path, v.ht());
self.sto.insert(final_node_2_hash, constants::TYPENODEFINAL, v.index_length(), v.bytes().to_vec());
let final_node_1_hash = utils::calc_hash_from_leaf_and_level(
pos_diff as u32,
&path_child,
utils::hash_vec(node_bytes.to_vec()),
);
self.sto.insert(
final_node_1_hash,
constants::TYPENODEFINAL,
il,
node_bytes.to_vec(),
);
let final_node_2_hash =
utils::calc_hash_from_leaf_and_level(pos_diff as u32, &path, v.ht());
self.sto.insert(
final_node_2_hash,
constants::TYPENODEFINAL,
v.index_length(),
v.bytes().to_vec(),
);
// parent node
let parent_node: node::TreeNode;
@@ -84,25 +110,34 @@ impl<'a> MerkleTree<'a> {
parent_node = node::TreeNode {
child_l: final_node_1_hash,
child_r: final_node_2_hash,
}} else {
}
} else {
parent_node = node::TreeNode {
child_l: final_node_2_hash,
child_r: final_node_1_hash,
}}
let empties = utils::get_empties_between_i_and_pos(i, pos_diff+1);
}
}
let empties = utils::get_empties_between_i_and_pos(i, pos_diff as u32 + 1);
for empty in &empties {
siblings.push(*empty);
}
let path_from_pos_diff = utils::cut_path(&path, (pos_diff + 1) as usize);
self.root = self.replace_leaf(path_from_pos_diff, &siblings, parent_node.ht(), constants::TYPENODENORMAL, 0, parent_node.bytes().to_vec());
return;
self.root = self.replace_leaf(
path_from_pos_diff,
&siblings,
parent_node.ht(),
constants::TYPENODENORMAL,
0,
parent_node.bytes().to_vec(),
);
return Ok(());
}
let node = node::parse_node_bytes(node_bytes);
let sibling: [u8;32];
let sibling: [u8; 32];
if !path[i as usize] {
node_hash = node.child_l;
sibling = node.child_r;
@@ -112,55 +147,89 @@ impl<'a> MerkleTree<'a> {
}
siblings.push(*array_ref!(sibling, 0, 32));
if node_hash == constants::EMPTYNODEVALUE {
if i==self.num_levels-2 && siblings[siblings.len()-1]==constants::EMPTYNODEVALUE {
let final_node_hash = utils::calc_hash_from_leaf_and_level(i+1, &path, v.ht());
self.sto.insert(final_node_hash, constants::TYPENODEFINAL, v.index_length(), v.bytes().to_vec());
if i == self.num_levels - 2
&& siblings[siblings.len() - 1] == constants::EMPTYNODEVALUE
{
let final_node_hash =
utils::calc_hash_from_leaf_and_level(i + 1, &path, v.ht());
self.sto.insert(
final_node_hash,
constants::TYPENODEFINAL,
v.index_length(),
v.bytes().to_vec(),
);
self.root = final_node_hash;
return;
return Ok(());
}
let final_node_hash = utils::calc_hash_from_leaf_and_level(i, &path, v.ht());
let path_from_i = utils::cut_path(&path, i as usize);
self.root = self.replace_leaf(path_from_i, &siblings, final_node_hash, constants::TYPENODEFINAL, v.index_length(), v.bytes().to_vec());
return;
self.root = self.replace_leaf(
path_from_i,
&siblings,
final_node_hash,
constants::TYPENODEFINAL,
v.index_length(),
v.bytes().to_vec(),
);
return Ok(());
}
}
self.root = self.replace_leaf(path, &siblings, v.ht(), constants::TYPENODEVALUE, v.index_length(), v.bytes().to_vec());
self.root = self.replace_leaf(
path,
&siblings,
v.ht(),
constants::TYPENODEVALUE,
v.index_length(),
v.bytes().to_vec(),
);
return Ok(());
}
pub fn replace_leaf(&mut self, path: Vec<bool>, siblings: &Vec<[u8;32]>, leaf_hash: [u8;32], node_type: u8, index_length: u32, leaf_value: Vec<u8>) -> [u8;32] {
self.sto.insert(leaf_hash, node_type, index_length, leaf_value);
pub fn replace_leaf(
&mut self,
path: Vec<bool>,
siblings: &Vec<[u8; 32]>,
leaf_hash: [u8; 32],
node_type: u8,
index_length: u32,
leaf_value: Vec<u8>,
) -> [u8; 32] {
self.sto
.insert(leaf_hash, node_type, index_length, leaf_value);
let mut curr_node = leaf_hash;
for i in 0..siblings.len() {
if !path[i as usize] {
let node = node::TreeNode {
child_l: curr_node,
child_r: siblings[siblings.len()-1-i],
child_r: siblings[siblings.len() - 1 - i],
};
self.sto.insert(node.ht(), constants::TYPENODENORMAL, 0, node.bytes());
self.sto
.insert(node.ht(), constants::TYPENODENORMAL, 0, node.bytes());
curr_node = node.ht();
} else {
let node = node::TreeNode {
child_l: siblings[siblings.len()-1-i],
child_l: siblings[siblings.len() - 1 - i],
child_r: curr_node,
};
self.sto.insert(node.ht(), constants::TYPENODENORMAL, 0, node.bytes());
self.sto
.insert(node.ht(), constants::TYPENODENORMAL, 0, node.bytes());
curr_node = node.ht();
}
}
curr_node
}
pub fn get_value_in_pos(&mut self, hi: [u8;32]) -> Vec<u8> {
pub fn get_value_in_pos(&mut self, hi: [u8; 32]) -> Vec<u8> {
let path = utils::get_path(self.num_levels, hi);
let mut node_hash = self.root;
for i in (0..=self.num_levels-2).rev() {
for i in (0..=self.num_levels - 2).rev() {
let (t, il, node_bytes) = self.sto.get(&node_hash);
if t == constants::TYPENODEFINAL {
let hi_node = utils::hash_vec(node_bytes.to_vec().split_at(il as usize).0.to_vec());
let path_node = utils::get_path(self.num_levels, hi_node);
let pos_diff = utils::compare_paths(&path_node, &path);
if pos_diff != 999 {
if pos_diff != -1 {
return constants::EMPTYNODEVALUE.to_vec();
}
return node_bytes;
@@ -176,13 +245,13 @@ impl<'a> MerkleTree<'a> {
node_bytes
}
pub fn generate_proof(&mut self, hi: [u8;32]) -> Vec<u8> {
pub fn generate_proof(&mut self, hi: [u8; 32]) -> Vec<u8> {
let mut mp: Vec<u8> = Vec::new();
let mut empties: [u8;32] = [0;32];
let mut empties: [u8; 32] = [0; 32];
let path = utils::get_path(self.num_levels, hi);
let mut siblings: Vec<[u8;32]> = Vec::new();
let mut siblings: Vec<[u8; 32]> = Vec::new();
let mut node_hash = self.root;
for i in 0..self.num_levels {
@@ -190,28 +259,34 @@ impl<'a> MerkleTree<'a> {
if t == constants::TYPENODEFINAL {
let real_value_in_pos = self.get_value_in_pos(hi);
if real_value_in_pos == constants::EMPTYNODEVALUE {
let leaf_hi = utils::hash_vec(node_bytes.to_vec().split_at(il as usize).0.to_vec());
let leaf_hi =
utils::hash_vec(node_bytes.to_vec().split_at(il as usize).0.to_vec());
let path_child = utils::get_path(self.num_levels, leaf_hi);
let pos_diff = utils::compare_paths(&path_child, &path);
if pos_diff == self.num_levels { // TODO
if pos_diff as u32 == self.num_levels {
return mp;
}
if pos_diff != self.num_levels-1-i {
let sibling = utils::calc_hash_from_leaf_and_level(pos_diff, &path_child, utils::hash_vec(node_bytes.to_vec()));
let mut new_siblings: Vec<[u8;32]> = Vec::new();
if pos_diff as u32 != self.num_levels - 1 - i {
let sibling = utils::calc_hash_from_leaf_and_level(
pos_diff as u32,
&path_child,
utils::hash_vec(node_bytes.to_vec()),
);
let mut new_siblings: Vec<[u8; 32]> = Vec::new();
new_siblings.push(sibling);
new_siblings.extend(siblings);
siblings = new_siblings;
// set empties bit
let bit_pos = self.num_levels-2-pos_diff;
empties[(empties.len() as isize + (bit_pos as isize/8-1) as isize) as usize] |= 1 << (bit_pos%8);
let bit_pos = self.num_levels - 2 - pos_diff as u32;
empties[(empties.len() as isize + (bit_pos as isize / 8 - 1) as isize)
as usize] |= 1 << (bit_pos % 8);
}
}
break
break;
}
let node = node::parse_node_bytes(node_bytes);
let sibling: [u8;32];
if !path[self.num_levels as usize -i as usize -2] {
let sibling: [u8; 32];
if !path[self.num_levels as usize - i as usize - 2] {
node_hash = node.child_l;
sibling = node.child_r;
} else {
@@ -220,8 +295,9 @@ impl<'a> MerkleTree<'a> {
}
if sibling != constants::EMPTYNODEVALUE {
// set empties bit
empties[(empties.len() as isize + (i as isize/8-1) as isize) as usize] |= 1 << (i%8);
let mut new_siblings: Vec<[u8;32]> = Vec::new();
empties[(empties.len() as isize + (i as isize / 8 - 1) as isize) as usize] |=
1 << (i % 8);
let mut new_siblings: Vec<[u8; 32]> = Vec::new();
new_siblings.push(sibling);
new_siblings.extend(siblings);
siblings = new_siblings;
@@ -234,7 +310,7 @@ impl<'a> MerkleTree<'a> {
mp
}
pub fn print_level(&mut self, parent: [u8;32], mut lvl: u32, max_level: u32) {
pub fn print_level(&mut self, parent: [u8; 32], mut lvl: u32, max_level: u32) {
let mut line: String = "".to_string();
for _ in 0..lvl {
line += &format!(" ");
@@ -246,7 +322,7 @@ impl<'a> MerkleTree<'a> {
child_l: constants::EMPTYNODEVALUE,
child_r: constants::EMPTYNODEVALUE,
};
if t==constants::TYPENODENORMAL {
if t == constants::TYPENODENORMAL {
node = node::parse_node_bytes(node_bytes);
line += &format!("'{}' - '{}'", node.child_l.to_hex(), node.child_r.to_hex());
} else if t == constants::TYPENODEVALUE {
@@ -265,7 +341,11 @@ impl<'a> MerkleTree<'a> {
}
println!("{}", line);
lvl += 1;
if node.child_r.len()>0 && lvl<max_level && t != constants::TYPENODEEMPTY && t != constants::TYPENODEFINAL {
if node.child_r.len() > 0
&& lvl < max_level
&& t != constants::TYPENODEEMPTY
&& t != constants::TYPENODEFINAL
{
self.print_level(node.child_l, lvl, max_level);
self.print_level(node.child_r, lvl, max_level);
}
@@ -282,16 +362,22 @@ impl<'a> MerkleTree<'a> {
self.print_level(root, 0, num_levels - 1 - max_level);
println!("root {:?}", self.root.to_hex());
}
}
}
pub fn verify_proof(root: [u8;32], mp: Vec<u8>, hi: [u8;32], ht: [u8;32], num_levels: u32) -> bool {
pub fn verify_proof(
root: [u8; 32],
mp: Vec<u8>,
hi: [u8; 32],
ht: [u8; 32],
num_levels: u32,
) -> bool {
let empties: Vec<u8>;
empties = mp.split_at(32).0.to_vec();
let mut siblings: Vec<[u8;32]> = Vec::new();
let mut siblings: Vec<[u8; 32]> = Vec::new();
for i in (empties.len()..mp.len()).step_by(constants::EMPTYNODEVALUE.len()) {
let mut sibling: [u8;32] = [0;32];
sibling.copy_from_slice(&mp[i..i+constants::EMPTYNODEVALUE.len()]);
let mut sibling: [u8; 32] = [0; 32];
sibling.copy_from_slice(&mp[i..i + constants::EMPTYNODEVALUE.len()]);
siblings.push(sibling);
}
@@ -299,9 +385,9 @@ impl<'a> MerkleTree<'a> {
let mut node_hash = ht;
let mut sibling_used_pos = 0;
for i in (0..=num_levels-2).rev() {
let sibling: [u8;32];
if (empties[empties.len()-i as usize/8-1] & (1 << (i%8))) > 0 {
for i in (0..=num_levels - 2).rev() {
let sibling: [u8; 32];
if (empties[empties.len() - i as usize / 8 - 1] & (1 << (i % 8))) > 0 {
sibling = siblings[sibling_used_pos];
sibling_used_pos += 1;
} else {
@@ -309,30 +395,31 @@ impl<'a> MerkleTree<'a> {
}
let n: node::TreeNode;
if path[num_levels as usize - i as usize-2] {
if path[num_levels as usize - i as usize - 2] {
n = node::TreeNode {
child_l: sibling,
child_r: node_hash,
}} else {
}
} else {
n = node::TreeNode {
child_l: node_hash,
child_r: sibling,
}}
}
}
if node_hash == constants::EMPTYNODEVALUE && sibling == constants::EMPTYNODEVALUE {
node_hash = constants::EMPTYNODEVALUE;
} else {
node_hash = n.ht();
}
}
if node_hash==root {
if node_hash == root {
return true;
}
false
}
}
#[cfg(test)]
mod tests {
mod tests {
use super::*;
use rustc_hex::ToHex;
@@ -340,7 +427,10 @@ impl<'a> MerkleTree<'a> {
fn test_hash_vec() {
let a: Vec<u8> = From::from("test".to_string());
let h = utils::hash_vec(a);
assert_eq!("9c22ff5f21f0b81b113e63f7db6da94fedef11b2119b4088b89664fb9a3cb658", h.to_hex());
assert_eq!(
"9c22ff5f21f0b81b113e63f7db6da94fedef11b2119b4088b89664fb9a3cb658",
h.to_hex()
);
}
#[test]
@@ -348,35 +438,47 @@ impl<'a> MerkleTree<'a> {
let mut sto = db::Db::new("test".to_string(), true);
let mt = MerkleTree::new(&mut sto, 140);
assert_eq!(140, mt.num_levels);
assert_eq!("0000000000000000000000000000000000000000000000000000000000000000", mt.root.to_hex());
let (_t, _il, b) = mt.sto.get(&[0;32]);
assert_eq!(
"0000000000000000000000000000000000000000000000000000000000000000",
mt.root.to_hex()
);
let (_t, _il, b) = mt.sto.get(&[0; 32]);
assert_eq!(mt.root.to_vec(), b);
}
#[test]
fn test_tree_node() {
let n = node::TreeNode {
child_l: [1;32],
child_r: [2;32],
child_l: [1; 32],
child_r: [2; 32],
};
assert_eq!("01010101010101010101010101010101010101010101010101010101010101010202020202020202020202020202020202020202020202020202020202020202",
n.bytes().to_hex());
assert_eq!("346d8c96a2454213fcc0daff3c96ad0398148181b9fa6488f7ae2c0af5b20aa0", n.ht().to_hex());
assert_eq!(
"346d8c96a2454213fcc0daff3c96ad0398148181b9fa6488f7ae2c0af5b20aa0",
n.ht().to_hex()
);
}
#[test]
fn test_add() {
let mut sto = db::Db::new("test".to_string(), true);
let mut mt = MerkleTree::new(&mut sto, 140);
assert_eq!("0000000000000000000000000000000000000000000000000000000000000000", mt.root.to_hex());
assert_eq!(
"0000000000000000000000000000000000000000000000000000000000000000",
mt.root.to_hex()
);
let val = TestValue {
bytes: vec![1,2,3,4,5],
bytes: vec![1, 2, 3, 4, 5],
index_length: 3,
};
mt.add(&val);
mt.add(&val).unwrap();
let (_t, _il, b) = mt.sto.get(&val.ht());
assert_eq!(*val.bytes(), b);
assert_eq!("a0e72cc948119fcb71b413cf5ada12b2b825d5133299b20a6d9325ffc3e2fbf1", mt.root.to_hex());
assert_eq!(
"a0e72cc948119fcb71b413cf5ada12b2b825d5133299b20a6d9325ffc3e2fbf1",
mt.root.to_hex()
);
}
#[test]
@@ -387,19 +489,28 @@ impl<'a> MerkleTree<'a> {
bytes: "this is a test leaf".as_bytes().to_vec(),
index_length: 15,
};
assert_eq!("0000000000000000000000000000000000000000000000000000000000000000", mt.root.to_hex());
mt.add(&val);
assert_eq!(
"0000000000000000000000000000000000000000000000000000000000000000",
mt.root.to_hex()
);
mt.add(&val).unwrap();
let (_t, _il, b) = mt.sto.get(&val.ht());
assert_eq!(*val.bytes(), b);
assert_eq!("b4fdf8a653198f0e179ccb3af7e4fc09d76247f479d6cfc95cd92d6fda589f27", mt.root.to_hex());
assert_eq!(
"b4fdf8a653198f0e179ccb3af7e4fc09d76247f479d6cfc95cd92d6fda589f27",
mt.root.to_hex()
);
let val2 = TestValue {
bytes: "this is a second test leaf".as_bytes().to_vec(),
index_length: 15,
};
mt.add(&val2);
mt.add(&val2).unwrap();
let (_t, _il, b) = mt.sto.get(&val2.ht());
assert_eq!(*val2.bytes(), b);
assert_eq!("8ac95e9c8a6fbd40bb21de7895ee35f9c8f30ca029dbb0972c02344f49462e82", mt.root.to_hex());
assert_eq!(
"8ac95e9c8a6fbd40bb21de7895ee35f9c8f30ca029dbb0972c02344f49462e82",
mt.root.to_hex()
);
}
#[test]
@@ -410,19 +521,28 @@ impl<'a> MerkleTree<'a> {
bytes: "this is a test leaf".as_bytes().to_vec(),
index_length: 15,
};
assert_eq!("0000000000000000000000000000000000000000000000000000000000000000", mt.root.to_hex());
mt.add(&val);
assert_eq!(
"0000000000000000000000000000000000000000000000000000000000000000",
mt.root.to_hex()
);
mt.add(&val).unwrap();
let (_t, _il, b) = mt.sto.get(&val.ht());
assert_eq!(*val.bytes(), b);
assert_eq!("b4fdf8a653198f0e179ccb3af7e4fc09d76247f479d6cfc95cd92d6fda589f27", mt.root.to_hex());
assert_eq!(
"b4fdf8a653198f0e179ccb3af7e4fc09d76247f479d6cfc95cd92d6fda589f27",
mt.root.to_hex()
);
let val2 = TestValue {
bytes: "this is a second test leaf".as_bytes().to_vec(),
index_length: 15,
};
mt.add(&val2);
mt.add(&val2).unwrap();
let (_t, _il, b) = mt.sto.get(&val2.ht());
assert_eq!(*val2.bytes(), b);
assert_eq!("8ac95e9c8a6fbd40bb21de7895ee35f9c8f30ca029dbb0972c02344f49462e82", mt.root.to_hex());
assert_eq!(
"8ac95e9c8a6fbd40bb21de7895ee35f9c8f30ca029dbb0972c02344f49462e82",
mt.root.to_hex()
);
let mp = mt.generate_proof(val2.hi());
assert_eq!("0000000000000000000000000000000000000000000000000000000000000001fd8e1a60cdb23c0c7b2cf8462c99fafd905054dccb0ed75e7c8a7d6806749b6b", mp.to_hex());
@@ -440,13 +560,16 @@ impl<'a> MerkleTree<'a> {
bytes: "this is a test leaf".as_bytes().to_vec(),
index_length: 15,
};
mt.add(&val);
mt.add(&val).unwrap();
let val2 = TestValue {
bytes: "this is a second test leaf".as_bytes().to_vec(),
index_length: 15,
};
mt.add(&val2);
assert_eq!("8ac95e9c8a6fbd40bb21de7895ee35f9c8f30ca029dbb0972c02344f49462e82", mt.root.to_hex());
mt.add(&val2).unwrap();
assert_eq!(
"8ac95e9c8a6fbd40bb21de7895ee35f9c8f30ca029dbb0972c02344f49462e82",
mt.root.to_hex()
);
// proof of empty leaf
let val3 = TestValue {
@@ -457,20 +580,35 @@ impl<'a> MerkleTree<'a> {
assert_eq!("000000000000000000000000000000000000000000000000000000000000000389741fa23da77c259781ad8f4331a5a7d793eef1db7e5200ddfc8e5f5ca7ce2bfd8e1a60cdb23c0c7b2cf8462c99fafd905054dccb0ed75e7c8a7d6806749b6b", mp.to_hex());
// verify that is a proof of an empty leaf (constants::EMPTYNODEVALUE)
let v = verify_proof(mt.root, mp, val3.hi(), constants::EMPTYNODEVALUE, mt.num_levels);
let v = verify_proof(
mt.root,
mp,
val3.hi(),
constants::EMPTYNODEVALUE,
mt.num_levels,
);
assert_eq!(true, v);
}
#[test]
fn test_harcoded_proofs_of_existing_leaf() {
// check proof of value in leaf
let mut root: [u8;32] = [0;32];
root.copy_from_slice(&hex::decode("7d7c5e8f4b3bf434f3d9d223359c4415e2764dd38de2e025fbf986e976a7ed3d").unwrap());
let mut root: [u8; 32] = [0; 32];
root.copy_from_slice(
&hex::decode("7d7c5e8f4b3bf434f3d9d223359c4415e2764dd38de2e025fbf986e976a7ed3d")
.unwrap(),
);
let mp = hex::decode("0000000000000000000000000000000000000000000000000000000000000002d45aada6eec346222eaa6b5d3a9260e08c9b62fcf63c72bc05df284de07e6a52").unwrap();
let mut hi: [u8;32] = [0;32];
hi.copy_from_slice(&hex::decode("786677808ba77bdd9090a969f1ef2cbd1ac5aecd9e654f340500159219106878").unwrap());
let mut ht: [u8;32] = [0;32];
ht.copy_from_slice(&hex::decode("786677808ba77bdd9090a969f1ef2cbd1ac5aecd9e654f340500159219106878").unwrap());
let mut hi: [u8; 32] = [0; 32];
hi.copy_from_slice(
&hex::decode("786677808ba77bdd9090a969f1ef2cbd1ac5aecd9e654f340500159219106878")
.unwrap(),
);
let mut ht: [u8; 32] = [0; 32];
ht.copy_from_slice(
&hex::decode("786677808ba77bdd9090a969f1ef2cbd1ac5aecd9e654f340500159219106878")
.unwrap(),
);
let v = verify_proof(root, mp, hi, ht, 140);
assert_eq!(true, v);
}
@@ -478,11 +616,17 @@ impl<'a> MerkleTree<'a> {
#[test]
fn test_harcoded_proofs_of_empty_leaf() {
// check proof of value in leaf
let mut root: [u8;32] = [0;32];
root.copy_from_slice(&hex::decode("8f021d00c39dcd768974ddfe0d21f5d13f7215bea28db1f1cb29842b111332e7").unwrap());
let mut root: [u8; 32] = [0; 32];
root.copy_from_slice(
&hex::decode("8f021d00c39dcd768974ddfe0d21f5d13f7215bea28db1f1cb29842b111332e7")
.unwrap(),
);
let mp = hex::decode("0000000000000000000000000000000000000000000000000000000000000004bf8e980d2ed328ae97f65c30c25520aeb53ff837579e392ea1464934c7c1feb9").unwrap();
let mut hi: [u8;32] = [0;32];
hi.copy_from_slice(&hex::decode("a69792a4cff51f40b7a1f7ae596c6ded4aba241646a47538898f17f2a8dff647").unwrap());
let mut hi: [u8; 32] = [0; 32];
hi.copy_from_slice(
&hex::decode("a69792a4cff51f40b7a1f7ae596c6ded4aba241646a47538898f17f2a8dff647")
.unwrap(),
);
let v = verify_proof(root, mp, hi, constants::EMPTYNODEVALUE, 140);
assert_eq!(true, v);
}
@@ -491,27 +635,77 @@ impl<'a> MerkleTree<'a> {
fn test_add_leafs_different_order() {
let mut sto1 = db::Db::new("test".to_string(), true);
let mut mt1 = MerkleTree::new(&mut sto1, 140);
mt1.add(&TestValue {bytes: "0 this is a test leaf".as_bytes().to_vec(), index_length: 15,});
mt1.add(&TestValue {bytes: "1 this is a test leaf".as_bytes().to_vec(), index_length: 15,});
mt1.add(&TestValue {bytes: "2 this is a test leaf".as_bytes().to_vec(), index_length: 15,});
mt1.add(&TestValue {bytes: "3 this is a test leaf".as_bytes().to_vec(), index_length: 15,});
mt1.add(&TestValue {bytes: "4 this is a test leaf".as_bytes().to_vec(), index_length: 15,});
mt1.add(&TestValue {bytes: "5 this is a test leaf".as_bytes().to_vec(), index_length: 15,});
mt1.add(&TestValue {
bytes: "0 this is a test leaf".as_bytes().to_vec(),
index_length: 15,
})
.unwrap();
mt1.add(&TestValue {
bytes: "1 this is a test leaf".as_bytes().to_vec(),
index_length: 15,
})
.unwrap();
mt1.add(&TestValue {
bytes: "2 this is a test leaf".as_bytes().to_vec(),
index_length: 15,
})
.unwrap();
mt1.add(&TestValue {
bytes: "3 this is a test leaf".as_bytes().to_vec(),
index_length: 15,
})
.unwrap();
mt1.add(&TestValue {
bytes: "4 this is a test leaf".as_bytes().to_vec(),
index_length: 15,
})
.unwrap();
mt1.add(&TestValue {
bytes: "5 this is a test leaf".as_bytes().to_vec(),
index_length: 15,
})
.unwrap();
// mt1.print_full_tree();
let mut sto2 = db::Db::new("test".to_string(), true);
let mut mt2 = MerkleTree::new(&mut sto2, 140);
mt2.add(&TestValue {bytes: "2 this is a test leaf".as_bytes().to_vec(), index_length: 15,});
mt2.add(&TestValue {bytes: "1 this is a test leaf".as_bytes().to_vec(), index_length: 15,});
mt2.add(&TestValue {bytes: "0 this is a test leaf".as_bytes().to_vec(), index_length: 15,});
mt2.add(&TestValue {bytes: "5 this is a test leaf".as_bytes().to_vec(), index_length: 15,});
mt2.add(&TestValue {bytes: "3 this is a test leaf".as_bytes().to_vec(), index_length: 15,});
mt2.add(&TestValue {bytes: "4 this is a test leaf".as_bytes().to_vec(), index_length: 15,});
mt2.add(&TestValue {
bytes: "2 this is a test leaf".as_bytes().to_vec(),
index_length: 15,
})
.unwrap();
mt2.add(&TestValue {
bytes: "1 this is a test leaf".as_bytes().to_vec(),
index_length: 15,
})
.unwrap();
mt2.add(&TestValue {
bytes: "0 this is a test leaf".as_bytes().to_vec(),
index_length: 15,
})
.unwrap();
mt2.add(&TestValue {
bytes: "5 this is a test leaf".as_bytes().to_vec(),
index_length: 15,
})
.unwrap();
mt2.add(&TestValue {
bytes: "3 this is a test leaf".as_bytes().to_vec(),
index_length: 15,
})
.unwrap();
mt2.add(&TestValue {
bytes: "4 this is a test leaf".as_bytes().to_vec(),
index_length: 15,
})
.unwrap();
// mt2.print_full_tree();
assert_eq!(mt1.root, mt2.root);
assert_eq!(&mt1.root.to_hex(), "264397f84da141b3134dcde1d7540d27a2bf0d787bbe8365d9ad5c9c18d3c621");
assert_eq!(
&mt1.root.to_hex(),
"264397f84da141b3134dcde1d7540d27a2bf0d787bbe8365d9ad5c9c18d3c621"
);
}
#[test]
@@ -519,8 +713,15 @@ impl<'a> MerkleTree<'a> {
let mut sto = db::Db::new("test".to_string(), true);
let mut mt = MerkleTree::new(&mut sto, 140);
for i in 0..1000 {
mt.add(&TestValue {bytes: (i.to_string()+" this is a test leaf").as_bytes().to_vec(), index_length: 15,});
}
assert_eq!(mt.root.to_hex(), "6e2da580b2920cd78ed8d4e4bf41e209dfc99ef28bc19560042f0ac803e0d6f7");
mt.add(&TestValue {
bytes: (i.to_string() + " this is a test leaf").as_bytes().to_vec(),
index_length: 15,
})
.unwrap();
}
assert_eq!(
mt.root.to_hex(),
"6e2da580b2920cd78ed8d4e4bf41e209dfc99ef28bc19560042f0ac803e0d6f7"
);
}
}

View File

@@ -1,17 +1,16 @@
use utils;
use constants;
use utils;
pub struct TreeNode {
pub child_l: [u8;32],
pub child_r: [u8;32],
pub child_l: [u8; 32],
pub child_r: [u8; 32],
}
impl TreeNode {
pub fn bytes(&self) -> Vec<u8> {
concatenate_arrays(&self.child_l, &self.child_r)
}
pub fn ht(&self) -> [u8;32] {
pub fn ht(&self) -> [u8; 32] {
utils::hash_vec(self.bytes())
}
}
@@ -24,7 +23,7 @@ fn concatenate_arrays<T: Clone>(x: &[T], y: &[T]) -> Vec<T> {
}
pub fn parse_node_bytes(b: Vec<u8>) -> TreeNode {
if b==constants::EMPTYNODEVALUE {
if b == constants::EMPTYNODEVALUE {
let n = TreeNode {
child_l: constants::EMPTYNODEVALUE,
child_r: constants::EMPTYNODEVALUE,
@@ -39,7 +38,6 @@ pub fn parse_node_bytes(b: Vec<u8>) -> TreeNode {
}
}
#[cfg(test)]
mod tests {
use super::*;
@@ -51,6 +49,9 @@ mod tests {
child_l: constants::EMPTYNODEVALUE,
child_r: constants::EMPTYNODEVALUE,
};
assert_eq!("ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5", n.ht().to_hex())
assert_eq!(
"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5",
n.ht().to_hex()
)
}
}

View File

@@ -1,6 +1,6 @@
use constants;
use node;
use tiny_keccak::Keccak;
use constants;
pub fn hash_vec(b: Vec<u8>) -> [u8; 32] {
let mut sha3 = Keccak::new_keccak256();
@@ -10,15 +10,19 @@ pub fn hash_vec(b: Vec<u8>) -> [u8; 32] {
res
}
pub fn get_path(num_levels: u32, hi: [u8;32]) -> Vec<bool> {
pub fn get_path(num_levels: u32, hi: [u8; 32]) -> Vec<bool> {
let mut path = Vec::new();
for i in (0..=num_levels as usize-2).rev() {
path.push((hi[hi.len()-i/8-1] & (1 << (i%8))) > 0);
for i in (0..=num_levels as usize - 2).rev() {
path.push((hi[hi.len() - i / 8 - 1] & (1 << (i % 8))) > 0);
}
path
}
pub fn calc_hash_from_leaf_and_level(until_level: u32, path: &[bool], leaf_hash: [u8;32]) -> [u8;32] {
pub fn calc_hash_from_leaf_and_level(
until_level: u32,
path: &[bool],
leaf_hash: [u8; 32],
) -> [u8; 32] {
let mut node_curr_lvl = leaf_hash;
for i in 0..until_level {
if path[i as usize] {
@@ -41,24 +45,24 @@ pub fn calc_hash_from_leaf_and_level(until_level: u32, path: &[bool], leaf_hash:
pub fn cut_path(path: &[bool], i: usize) -> Vec<bool> {
let mut path_res: Vec<bool> = Vec::new();
for j in 0..path.len() {
if j>=i {
if j >= i {
path_res.push(path[j]);
}
}
path_res
}
pub fn compare_paths(a: &[bool], b: &[bool]) -> u32 {
pub fn compare_paths(a: &[bool], b: &[bool]) -> i32 {
for i in (0..a.len()).rev() {
if a[i] != b[i] {
return i as u32;
return i as i32;
}
}
999
-1
}
pub fn get_empties_between_i_and_pos(i: u32, pos: u32) -> Vec<[u8;32]> {
let mut sibl: Vec<[u8;32]> = Vec::new();
pub fn get_empties_between_i_and_pos(i: u32, pos: u32) -> Vec<[u8; 32]> {
let mut sibl: Vec<[u8; 32]> = Vec::new();
for _ in (pos..=i).rev() {
sibl.push(constants::EMPTYNODEVALUE);
}
@@ -75,6 +79,9 @@ mod tests {
let a: Vec<u8> = From::from("test");
assert_eq!("74657374", a.to_hex());
let h = hash_vec(a);
assert_eq!("9c22ff5f21f0b81b113e63f7db6da94fedef11b2119b4088b89664fb9a3cb658", h.to_hex());
assert_eq!(
"9c22ff5f21f0b81b113e63f7db6da94fedef11b2119b4088b89664fb9a3cb658",
h.to_hex()
);
}
}