Skip to content
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
05a4180
Implemented single merk path + key proof
iammadab Nov 23, 2021
08ce2d1
Recursive proofs wip
iammadab Nov 24, 2021
9901b94
Returning the root proof as an option
iammadab Nov 26, 2021
5c51797
Merge branch '1merks1rocksdb' into feat/proofs
iammadab Nov 26, 2021
a69f57b
fmt
iammadab Nov 26, 2021
ef331bc
restore a number of tests
fominok Nov 26, 2021
0052d85
returning root proof without option
iammadab Nov 29, 2021
4dbe5f1
Updated proof function signature
iammadab Nov 29, 2021
62b6a26
Implemented test for proof construction
iammadab Nov 29, 2021
8a8abd5
fmt
iammadab Nov 29, 2021
aec0713
Merge branch '2merks1rocksdb' into feat/proofs
iammadab Nov 29, 2021
0bd438e
Removed unwrap when createing tempmerk
iammadab Nov 29, 2021
9b13f96
Merge branch '2merks1rocksdb' of github.com:dashevo/grovedb into 2mer…
iammadab Nov 29, 2021
892ad83
Merge branch '2merks1rocksdb' into feat/proofs
iammadab Nov 29, 2021
8f7bba7
Ignore of grove.db folder not necessary
iammadab Nov 29, 2021
d28f457
Removed unnecessary vec!
iammadab Nov 29, 2021
b7a268a
Fixed typo
iammadab Dec 2, 2021
ecd68a6
Added support for range queries
iammadab Dec 3, 2021
37482af
fmt
iammadab Dec 3, 2021
08b52a2
Adding root key hash map to constructed proof
iammadab Dec 16, 2021
68ef9d9
Fixed comment
iammadab Dec 16, 2021
01138b7
Added more values to test merk
iammadab Dec 20, 2021
fdfb98e
Extended proof function to take a query object instead of a query item
iammadab Dec 20, 2021
c221f7c
Exposed query and query item for library client
iammadab Dec 20, 2021
4f7b5ad
Resolved conflicts
iammadab Dec 20, 2021
55691c3
fmt
iammadab Dec 20, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
/target
.idea
Cargo.lock
Cargo.lock
36 changes: 33 additions & 3 deletions grovedb/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use std::{
rc::Rc,
};

use merk::{self, rocksdb, Merk};
use merk::{self, proofs::Query, rocksdb, Merk};
use rs_merkle::{algorithms::Sha256, MerkleTree};
use subtree::Element;

Expand Down Expand Up @@ -231,8 +231,38 @@ impl GroveDb {
Err(Error::ReferenceLimit)
}

pub fn proof(&self) -> ! {
todo!()
pub fn proof(&self, path: &[&[u8]], key: &[u8]) -> Result<Vec<Vec<u8>>, Error> {
let mut split_path = Some((&key, path));
let mut proofs: Vec<Vec<u8>> = Vec::new();

while let Some((key, path_slice)) = split_path {
if path_slice.is_empty() {
// Get proof for root tree at current key
let root_key_index = self
.root_leaf_keys
.get(*key)
.ok_or(Error::InvalidPath("root key not found"))?;
proofs.push(self.root_tree.proof(&[*root_key_index]).to_bytes());
} else {
let merk = self
.subtrees
.get(&Self::compress_path(path_slice, None))
.ok_or(Error::InvalidPath("no subtree found under that path"))?;

// Generate a proof for this merk at the given key
let mut proof_query = Query::new();
proof_query.insert_key(key.to_vec());

let proof_result = merk
.prove(proof_query)
.expect("should prove both inclusion and absence");

proofs.push(proof_result);
}
split_path = path_slice.split_last();
}

Ok(proofs)
}

/// Method to propagate updated subtree root hashes up to GroveDB root
Expand Down
50 changes: 50 additions & 0 deletions grovedb/src/tests.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::ops::{Deref, DerefMut};

use merk::test_utils::TempMerk;
use tempdir::TempDir;

use super::*;
Expand Down Expand Up @@ -239,3 +240,52 @@ fn test_root_tree_leafs_are_noted() {
assert_eq!(db.root_leaf_keys, hm);
assert_eq!(db.root_tree.leaves_len(), 2);
}

#[test]
fn test_proof_construction() {
let mut temp_db = make_grovedb();
temp_db
.insert(&[TEST_LEAF], b"innertree".to_vec(), Element::empty_tree())
.expect("successful subtree insert");
temp_db
.insert(
&[TEST_LEAF, b"innertree"],
b"key1".to_vec(),
Element::Item(b"value1".to_vec()),
)
.expect("successful item insert");

// Manually build the ads structures
let mut inner_tree_merk = TempMerk::new();
let value_element = Element::Item(b"value1".to_vec());
value_element.insert(&mut inner_tree_merk, b"key1".to_vec());

let mut test_leaf_merk = TempMerk::new();
let inner_tree_root_element = Element::Tree(inner_tree_merk.root_hash());
inner_tree_root_element.insert(&mut test_leaf_merk, b"innertree".to_vec());

let another_test_leaf_merk = TempMerk::new();

let leaves = [
test_leaf_merk.root_hash(),
another_test_leaf_merk.root_hash(),
];
let root_tree = MerkleTree::<Sha256>::from_leaves(&leaves);

// Generate groove db proof
Comment thread
iammadab marked this conversation as resolved.
Outdated
let proof = temp_db
.proof(&[TEST_LEAF, b"innertree"], b"key1")
.expect("Successful proof generation");

assert_eq!(proof.len(), 3);

let mut proof_query = Query::new();
proof_query.insert_key(b"key1".to_vec());
assert_eq!(proof[0], inner_tree_merk.prove(proof_query).unwrap());

let mut proof_query = Query::new();
proof_query.insert_key(b"innertree".to_vec());
assert_eq!(proof[1], test_leaf_merk.prove(proof_query).unwrap());

assert_eq!(proof[2], root_tree.proof(&vec![0]).to_bytes());
}