Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: bidirectional references #104

Open
wants to merge 190 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
190 commits
Select commit Hold shift + click to select a range
fd1806f
test range from proof
iammadab Mar 10, 2022
b8c30e3
add unbounded right
iammadab Mar 10, 2022
5f4581d
test for range to proof
iammadab Mar 10, 2022
bfb89ea
add left unbounded
iammadab Mar 10, 2022
239105a
add absence tuple checks to test
iammadab Mar 10, 2022
f46f93d
test range to inclusive
iammadab Mar 10, 2022
9237d11
test for range after proof
iammadab Mar 10, 2022
7270c89
test for range after proof
iammadab Mar 10, 2022
825ffbe
test for range after to inclusive
iammadab Mar 10, 2022
3dc5157
test for range full proof
iammadab Mar 10, 2022
4ad18f7
update verify proof func to account for unbounded ranges
iammadab Mar 10, 2022
9de2e73
add verification check for right non inclusive ranges
iammadab Mar 10, 2022
2a77862
refactor bounds to return options
iammadab Mar 14, 2022
82b9000
update verify function to work with range_after_* queries
iammadab Mar 15, 2022
5143009
fix range_after_proof test
iammadab Mar 15, 2022
bf06d7c
fix range_after_to_proof test
iammadab Mar 15, 2022
4294910
fix range_after_to_proof_inclusive test
iammadab Mar 15, 2022
1dbcf0e
fix range_full_proof
iammadab Mar 15, 2022
029502f
modify create_full_proof function to take optional limit and offset v…
iammadab Mar 15, 2022
7258fd5
add failing test to limit result set to 1 item
iammadab Mar 15, 2022
0c39fea
removed unnecessary comments
iammadab Mar 15, 2022
48eaca2
implement limit functionality in merk
iammadab Mar 15, 2022
f706d2e
add limit test for range from proof
iammadab Mar 16, 2022
90f7f29
feat: addition of more range types (#82)
iammadab Mar 16, 2022
33b0e54
define KVDigest node variant
iammadab Mar 16, 2022
60558a4
implement encode for kvdigest
iammadab Mar 16, 2022
ec42393
implement decode for kvdigest
iammadab Mar 16, 2022
7cb49ea
add ability to convert node to kvdigest
iammadab Mar 16, 2022
f5c6662
add test for node variant conversions
iammadab Mar 16, 2022
263c33b
add node hash computation for kvdigest node variant
iammadab Mar 16, 2022
efc4a63
feat: new node type Node::KVDigest (#89)
iammadab Mar 17, 2022
c35d7f9
extract main verify proof body into closure
iammadab Mar 17, 2022
c62281c
update verify_query to work with kvdigest node
iammadab Mar 17, 2022
b73f706
resolve conflicts
iammadab Mar 17, 2022
3b7f490
fixed absence proof tests
iammadab Mar 17, 2022
69dd987
remove marker comments
iammadab Mar 17, 2022
a226027
push KVDigest for non inclusive bound keys
iammadab Mar 17, 2022
291487f
Merge branch 'absence-proof-without-raw-value' into merk-limit
iammadab Mar 17, 2022
76713dc
add limit argument to verify_query function
iammadab Mar 17, 2022
a3ebe3c
add failing test for proof with limit verification
iammadab Mar 17, 2022
f1288d5
implement proof with limit verification
iammadab Mar 18, 2022
cf0a6df
fix range_from proof for limits
iammadab Mar 18, 2022
c7389a1
add limit test for range_to_proof
iammadab Mar 18, 2022
cffeec8
add limit test for range_to_proof_inclusive
iammadab Mar 18, 2022
01d19ba
fix bug: don't reserve limit slot for non inclusive nodes
iammadab Mar 18, 2022
2e738e6
add limit test for range_after_proof
iammadab Mar 18, 2022
8a54d20
add limit test for range_after_to_proof
iammadab Mar 18, 2022
7b3346c
add limit test for range_full_proof
iammadab Mar 18, 2022
a24ecb6
add poc failing test for offset
iammadab Mar 18, 2022
0517298
ignore limit as long as offset exists and is not zero
iammadab Mar 18, 2022
af63edb
updated create_proof to make use of offset
iammadab Mar 18, 2022
eb7c8b9
pass offset as input to verify_query function
iammadab Mar 18, 2022
b785acf
modify verify_query function to work with offset
iammadab Mar 18, 2022
9d49bfe
fix typos
iammadab Mar 18, 2022
9ac5db4
make proof_with_offset test verbose
iammadab Mar 18, 2022
1f87aa3
add offset test for range_from_proof
iammadab Mar 18, 2022
3393b63
add offset test for range_to_proof
iammadab Mar 18, 2022
8e4d863
add offset test for range_to_proof_inclusive
iammadab Mar 18, 2022
d5e3216
add offset test for range_after and range_after_to
iammadab Mar 18, 2022
b10208f
add offset test for range_after_to_inclusive and range_full
iammadab Mar 18, 2022
db64fd4
add failing offset test for range proof
iammadab Mar 18, 2022
3b0df1c
fix bug: prevent reservation of offset slot for non query keys
iammadab Mar 18, 2022
dddb03f
add offset test for range_proof_inclusive
iammadab Mar 18, 2022
2d2c3dd
add encoding for child_inverted and parent_inverted op codes
iammadab Mar 22, 2022
66ba047
add encoding for push inverted op code
iammadab Mar 22, 2022
e386fa0
modify execute function to take into account the new op codes
iammadab Mar 22, 2022
5b22696
add right_to_left logic to proof creation
iammadab Mar 22, 2022
599003a
modify create_full_proof api to take left_to_right bool
iammadab Mar 22, 2022
9bb67f4
add poc verification that right_to_left generates correct elements
iammadab Mar 22, 2022
6372413
add failing test for right_to_left proof verification
iammadab Mar 22, 2022
1f5e538
modify verify_query function to take the left_to_right bool as input
iammadab Mar 22, 2022
ab43124
modify verify_query to work with right_to_left
iammadab Mar 23, 2022
f6e991a
cleanup
iammadab Mar 23, 2022
2518f4e
add right_to_left test for range_proof, range_proof_inclusive and ran…
iammadab Mar 23, 2022
50ffd9b
add right_to_left proof test for remaning range types
iammadab Mar 23, 2022
35d8b24
add absence tests
iammadab Mar 23, 2022
d1f6e04
minor cleanup
iammadab Mar 23, 2022
3d518c6
Merge branch 'develop' into path-query-proofs
iammadab Mar 25, 2022
5cfdebc
modify verify_query function to return limit and offset
iammadab Mar 28, 2022
1a5df3a
refactor test to use new verification interface
iammadab Mar 28, 2022
63e5f3d
add test to check validity of limit and offset returned after verific…
iammadab Mar 28, 2022
3daecca
define interface for proof construction and execution
iammadab Mar 29, 2022
a59e639
wip
iammadab Mar 29, 2022
ff622bd
generate proof up to root - 1
iammadab Mar 30, 2022
126e06e
generating proof up to root
iammadab Mar 30, 2022
7e083f4
combine individual proofs into single structure
iammadab Mar 31, 2022
e127333
reading proof data from proof buffer during execution
iammadab Mar 31, 2022
6d28eaa
extract proof verification algo into execute_proof function
iammadab Mar 31, 2022
455067c
fmt
iammadab Mar 31, 2022
1ed0cb7
Merge branch 'refactor-merk-verification-interface' into path-query-p…
iammadab Mar 31, 2022
7f6725e
make proof verification field public
iammadab Mar 31, 2022
be4b1cc
verify proof up to root - 1
iammadab Mar 31, 2022
f4a7a72
fix bug where value hash gets cleared on decode
iammadab Mar 31, 2022
71bd31c
v0.5 implementation of path query proofs without subqueries
iammadab Mar 31, 2022
1bd36ff
implement read_proof function
iammadab Mar 31, 2022
60bedb3
refactor execute proof to use proof reader
iammadab Mar 31, 2022
22ffb5e
cleanup
iammadab Mar 31, 2022
291e3fc
make use of left_to_right from query
iammadab Mar 31, 2022
e30b01e
make use of limit and offset values provided by query
iammadab Mar 31, 2022
3c8a94a
add test for path_query_proofs_without_subquery
iammadab Mar 31, 2022
9ec04c4
get rid of non result errors
iammadab Mar 31, 2022
fbf26d4
journey begins
iammadab Apr 1, 2022
4f42b81
refactor prove function to return limit and offset values
iammadab Apr 4, 2022
050be41
fix test to use new proof result interface
iammadab Apr 4, 2022
d2328df
add basic test to verify the result of proof construction limit and o…
iammadab Apr 4, 2022
e8ef2ce
cleanup
iammadab Apr 4, 2022
ce24830
Merge branch 'construction-limit-offset-propagation' into path-query-…
iammadab Apr 4, 2022
ba5442b
get all elements in the subtree
iammadab Apr 5, 2022
60498d8
define interface for recursion + algo
iammadab Apr 5, 2022
c458c38
implement prove_subqueries to construct proof without subqueries
iammadab Apr 5, 2022
6f8c0dd
add temporary default subquery paths function
iammadab Apr 5, 2022
baef4bb
recursively prove tree elements based on subqueries
iammadab Apr 5, 2022
4655efc
add basic visibility test for subquery proofs
iammadab Apr 5, 2022
c727c22
propagate limit and offset values in prove_subqueries function
iammadab Apr 7, 2022
918478b
generating sized merk proofs for leaf nodes of path queries
iammadab Apr 7, 2022
8600bee
fix path_query_proof_without_subquery test
iammadab Apr 7, 2022
7da2637
refactor proof types as enums
iammadab Apr 8, 2022
c289cda
implement convertion from proof_type enum to bytes and vice versa
iammadab Apr 8, 2022
7e51540
add read_proof function to proof_reader that makes no assumption of p…
iammadab Apr 8, 2022
9804445
fix test_path_query_proof_without_subquery verification test
iammadab Apr 8, 2022
62a3aa2
it works!!
iammadab Apr 8, 2022
911a2a9
send proof of all children for non leaf subquery nodes
iammadab Apr 10, 2022
50a97fb
update test for default subquery to get result set across subtrees
iammadab Apr 10, 2022
c910bee
add range type subquery test
iammadab Apr 10, 2022
463cb97
define new schema for more convuluted tree
iammadab Apr 10, 2022
7a94f00
add variable leaf size length
iammadab Apr 10, 2022
d21a666
add test for with 3 subqueries
iammadab Apr 10, 2022
0616392
extract deep tree builder into a separate function
iammadab Apr 10, 2022
fee0db6
add test for subquery key
iammadab Apr 11, 2022
938b46d
wip
iammadab Apr 11, 2022
b26c75b
add support for subquery_key without subquery
iammadab Apr 12, 2022
21be4e2
generate proof for subquery key existence
iammadab Apr 13, 2022
334d920
verification of intermediate subquery key proof
iammadab Apr 13, 2022
1e046aa
optionally run subquery key logic
iammadab Apr 13, 2022
080fca8
switch get subquery to use conditional subquery getter
iammadab Apr 13, 2022
ca2eb1e
prevent subquery proof logic from running if no subquery
iammadab Apr 13, 2022
8fd9433
add test for conditional subqueries
iammadab Apr 13, 2022
5a0a5e5
remove old proof test
iammadab Apr 13, 2022
c443dec
add test for conditional subquery + default subquery
iammadab Apr 13, 2022
3be237f
add failing test for sized query
iammadab Apr 13, 2022
cb5356e
sized path query works
iammadab Apr 13, 2022
0f2deee
add failing test for path query proof with direction
iammadab Apr 13, 2022
7f58490
fix directional path query test
iammadab Apr 13, 2022
92b1b30
add interesting test with mixed query directions
iammadab Apr 13, 2022
1faca9f
remove unnecessary comments
iammadab Apr 13, 2022
1785fa3
extract subquery subroutines into separate functions
iammadab Apr 13, 2022
e4d2418
basic clean up
iammadab Apr 13, 2022
8dde1cd
more cleanup
iammadab Apr 14, 2022
a76cd31
don't generate or verify proof for empty path
iammadab Apr 17, 2022
5fd1e95
add more comments to execute proof routine
iammadab Apr 17, 2022
dc2017f
extract merk proof to bytes generation into separate routine
iammadab Apr 17, 2022
24fd885
extract merk proof execution into seperate routine
iammadab Apr 17, 2022
2a38b74
remove duplication from proof reader
iammadab Apr 18, 2022
dcb7d5a
clean up + more todos
iammadab Apr 18, 2022
7b51c2a
encode and decode value_hash for kv node
iammadab Apr 18, 2022
99218c0
fix test_follow_reference create reference element before creating re…
iammadab Apr 18, 2022
42d601e
on reference insert, get the referenced element and pass the value hash
iammadab Apr 18, 2022
d7a8567
refactor reference insertion to use value hash of referenced value
iammadab Apr 18, 2022
183bb17
references compute to the same hash as their referenced element
iammadab Apr 19, 2022
b34b879
add test for path query with reference elements
iammadab Apr 19, 2022
74731b4
allow merk to call grovedb methods using traits
iammadab Apr 19, 2022
20b10df
Revert "allow merk to call grovedb methods using traits"
iammadab Apr 19, 2022
1e0dd21
add new prove function that doesn't encode values
iammadab Apr 19, 2022
5f44613
created intermidiary zone for future proof value substitution
iammadab Apr 19, 2022
2cafb44
proof properly handles referencesgit add .
iammadab Apr 19, 2022
9da06d9
fixed reference test
iammadab Apr 19, 2022
d90fa74
return error from generate_and_store_merk_proof
iammadab Apr 22, 2022
8efdbcc
handle errors in proof reader
iammadab Apr 22, 2022
2353ae1
add test to show references must point to a valid item before insertion
iammadab Apr 22, 2022
0b6b89c
fix test_too_many_indirections
iammadab Apr 22, 2022
0927baa
clean insert function
iammadab Apr 22, 2022
e1c32c7
add documenatation + cleanup
iammadab Apr 22, 2022
c728576
fmt
iammadab Apr 22, 2022
b4ee191
more clean up
iammadab Apr 22, 2022
b72d80d
add fix comment
iammadab Apr 22, 2022
c634101
add reference meta data to item element type
iammadab Apr 27, 2022
b17ef83
fix build + test (ignoring serialization test for now)
iammadab Apr 27, 2022
92cbfac
handle single item reference
iammadab Apr 28, 2022
9e6ee5f
add reference meta data
iammadab Apr 28, 2022
50b8b10
fix reference limit test
iammadab Apr 28, 2022
e2b915d
cleanup
iammadab Apr 28, 2022
e723e0a
recursively delete references when you delete a base item
iammadab May 9, 2022
fc6630b
add failing test for reference deletion with bidirectional logic
iammadab May 9, 2022
a46a32c
update base item when reference is deleted to prevent dangling refere…
iammadab May 9, 2022
2dbb883
properly handle errors for bidirectional delete
iammadab May 9, 2022
23875f5
fixed byte size calculation
iammadab May 9, 2022
35e8adf
fix serialization test
iammadab May 9, 2022
3d51525
Merge branch 'develop' into feat/delete-references
iammadab May 24, 2022
a94160b
add test to verify that root hash is same for reference tree and actu…
iammadab May 24, 2022
dc17cd2
cleanup + more tests
iammadab May 24, 2022
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
34 changes: 19 additions & 15 deletions grovedb/src/batch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -475,8 +475,8 @@ mod tests {
#[test]
fn test_batch_validation_ok() {
let db = make_grovedb();
let element = Element::Item(b"ayy".to_vec());
let element2 = Element::Item(b"ayy2".to_vec());
let element = Element::new_item(b"ayy".to_vec());
let element2 = Element::new_item(b"ayy2".to_vec());
let ops = vec![
GroveDbOp::insert(vec![], b"key1".to_vec(), Element::empty_tree()),
GroveDbOp::insert(
Expand Down Expand Up @@ -530,7 +530,7 @@ mod tests {
#[test]
fn test_batch_validation_broken_chain() {
let db = make_grovedb();
let element = Element::Item(b"ayy".to_vec());
let element = Element::new_item(b"ayy".to_vec());
let ops = vec![
GroveDbOp::insert(vec![], b"key1".to_vec(), Element::empty_tree()),
GroveDbOp::insert(
Expand All @@ -551,7 +551,7 @@ mod tests {
#[test]
fn test_batch_validation_broken_chain_aborts_whole_batch() {
let db = make_grovedb();
let element = Element::Item(b"ayy".to_vec());
let element = Element::new_item(b"ayy".to_vec());
let ops = vec![
GroveDbOp::insert(
vec![TEST_LEAF.to_vec()],
Expand Down Expand Up @@ -583,7 +583,7 @@ mod tests {
#[test]
fn test_batch_validation_deletion_brokes_chain() {
let db = make_grovedb();
let element = Element::Item(b"ayy".to_vec());
let element = Element::new_item(b"ayy".to_vec());

db.insert([], b"key1", Element::empty_tree(), None)
.expect("cannot insert a subtree");
Expand All @@ -609,7 +609,7 @@ mod tests {
#[test]
fn test_batch_validation_deletion_and_insertion_restore_chain() {
let db = make_grovedb();
let element = Element::Item(b"ayy".to_vec());
let element = Element::new_item(b"ayy".to_vec());
let ops = vec![
GroveDbOp::insert(vec![], b"key1".to_vec(), Element::empty_tree()),
GroveDbOp::insert(
Expand Down Expand Up @@ -640,7 +640,7 @@ mod tests {
#[test]
fn test_batch_validation_insert_into_existing_tree() {
let db = make_grovedb();
let element = Element::Item(b"ayy".to_vec());
let element = Element::new_item(b"ayy".to_vec());

db.insert([TEST_LEAF], b"invalid", element.clone(), None)
.expect("cannot insert value");
Expand Down Expand Up @@ -672,8 +672,8 @@ mod tests {
#[test]
fn test_batch_validation_nested_subtree_overwrite() {
let db = make_grovedb();
let element = Element::Item(b"ayy".to_vec());
let element2 = Element::Item(b"ayy2".to_vec());
let element = Element::new_item(b"ayy".to_vec());
let element2 = Element::new_item(b"ayy2".to_vec());
db.insert([TEST_LEAF], b"key_subtree", Element::empty_tree(), None)
.expect("cannot insert a subtree");
db.insert([TEST_LEAF, b"key_subtree"], b"key2", element, None)
Expand Down Expand Up @@ -721,7 +721,11 @@ mod tests {
fn test_batch_validation_root_leaf_removal() {
let db = make_grovedb();
let ops = vec![
GroveDbOp::insert(vec![], TEST_LEAF.to_vec(), Element::Item(b"ayy".to_vec())),
GroveDbOp::insert(
vec![],
TEST_LEAF.to_vec(),
Element::new_item(b"ayy".to_vec()),
),
GroveDbOp::insert(
vec![TEST_LEAF.to_vec()],
b"key1".to_vec(),
Expand All @@ -734,7 +738,7 @@ mod tests {
#[test]
fn test_merk_data_is_deleted() {
let db = make_grovedb();
let element = Element::Item(b"ayy".to_vec());
let element = Element::new_item(b"ayy".to_vec());

db.insert([TEST_LEAF], b"key1", Element::empty_tree(), None)
.expect("cannot insert a subtree");
Expand All @@ -743,7 +747,7 @@ mod tests {
let ops = vec![GroveDbOp::insert(
vec![TEST_LEAF.to_vec()],
b"key1".to_vec(),
Element::Item(b"ayy2".to_vec()),
Element::new_item(b"ayy2".to_vec()),
)];

assert_eq!(
Expand All @@ -770,8 +774,8 @@ mod tests {
.ok()
.flatten()
.expect("cannot get root hash");
let element = Element::Item(b"ayy".to_vec());
let element2 = Element::Item(b"ayy2".to_vec());
let element = Element::new_item(b"ayy".to_vec());
let element2 = Element::new_item(b"ayy2".to_vec());

let ops = vec![
GroveDbOp::insert(
Expand Down Expand Up @@ -848,7 +852,7 @@ mod tests {
acc_path.push(p);
}

let element = Element::Item(b"ayy".to_vec());
let element = Element::new_item(b"ayy".to_vec());
let batch = vec![GroveDbOp::insert(
acc_path.clone(),
b"key".to_vec(),
Expand Down
5 changes: 1 addition & 4 deletions grovedb/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,7 @@ mod subtree;
mod tests;
mod util;
mod visualize;
use std::{
collections::{BTreeMap, HashMap},
path::Path,
};
use std::{collections::BTreeMap, path::Path};

pub use merk::proofs::{query::QueryItem, Query};
use merk::{self, Merk};
Expand Down
56 changes: 56 additions & 0 deletions grovedb/src/operations/delete.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,62 @@ impl GroveDb {
delete_element()?;
}
} else {
fn to_slice(x: &Vec<u8>) -> &[u8] {
x.as_slice()
}

if let Element::Reference(ref base_element_path, _) = element {
let (base_element_key, base_element_subtree_path) = base_element_path
.split_last()
.expect("reference path cannot be empty");

let base_element_subtree_path_as_slice =
base_element_subtree_path.iter().map(to_slice);
let mut base_element = self.get(
base_element_subtree_path_as_slice.clone(),
base_element_key,
transaction,
)?;

match base_element {
Element::Tree(_) => {}
Element::Item(_, ref mut references)
| Element::Reference(_, ref mut references) => {
let mut path_owned: Vec<Vec<u8>> =
path_iter.clone().map(|x| x.to_vec()).collect();
path_owned.push(key.to_vec());
let position = references.iter().position(|path| path == &path_owned);
if let Some(index) = position {
references.remove(index);
merk_optional_tx!(
self.db,
base_element_subtree_path_as_slice,
transaction,
mut subtree,
{
base_element.insert(&mut subtree, base_element_key)?;
}
);
}
}
}
}

if let Element::Item(_, references) | Element::Reference(_, references) = element {
// recursively delete all references of to be deleted element
for reference in references {
let (referenced_key, reference_subtree_path) = reference
.split_last()
.expect("reference path cannot be empty");
self.delete_internal(
reference_subtree_path.iter().map(to_slice),
referenced_key,
false,
transaction,
)?;
}
}

delete_element()?;
}
self.propagate_changes(path_iter, transaction)?;
Expand Down
14 changes: 7 additions & 7 deletions grovedb/src/operations/get.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ impl GroveDb {
<P as IntoIterator>::IntoIter: DoubleEndedIterator + ExactSizeIterator + Clone,
{
match self.get_raw(path, key, transaction)? {
Element::Reference(reference_path) => {
Element::Reference(reference_path, _) => {
self.follow_reference(reference_path, transaction)
}
other => Ok(other),
Expand Down Expand Up @@ -48,7 +48,7 @@ impl GroveDb {
}
visited.insert(path);
match current_element {
Element::Reference(reference_path) => path = reference_path,
Element::Reference(reference_path, _) => path = reference_path,
other => return Ok(other),
}
hops_left -= 1;
Expand Down Expand Up @@ -89,9 +89,9 @@ impl GroveDb {
let results = elements
.into_iter()
.map(|element| match element {
Element::Reference(reference_path) => {
Element::Reference(reference_path, _) => {
let maybe_item = self.follow_reference(reference_path, transaction)?;
if let Element::Item(item) = maybe_item {
if let Element::Item(item, _) = maybe_item {
Ok(item)
} else {
Err(Error::InvalidQuery("the reference must result in an item"))
Expand Down Expand Up @@ -127,15 +127,15 @@ impl GroveDb {
let results = elements
.into_iter()
.map(|element| match element {
Element::Reference(reference_path) => {
Element::Reference(reference_path, _) => {
let maybe_item = self.follow_reference(reference_path, transaction)?;
if let Element::Item(item) = maybe_item {
if let Element::Item(item, _) = maybe_item {
Ok(item)
} else {
Err(Error::InvalidQuery("the reference must result in an item"))
}
}
Element::Item(item) => Ok(item),
Element::Item(item, _) => Ok(item),
Element::Tree(_) => Err(Error::InvalidQuery(
"path_queries can only refer to items and references",
)),
Expand Down
50 changes: 44 additions & 6 deletions grovedb/src/operations/insert.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,26 +29,64 @@ impl GroveDb {
self.propagate_changes(path_iter, transaction)?;
}
}
Element::Reference(ref reference_path) => {
Element::Reference(ref reference_path, _) => {
if path_iter.len() == 0 {
return Err(Error::InvalidPath(
"only subtrees are allowed as root tree's leafs",
));
}

self.check_subtree_exists_invalid_path(path_iter.clone(), Some(key), transaction)?;
let referenced_element =
self.follow_reference(reference_path.to_owned(), transaction)?;

// reference path denotes the element we are directly referencing
let (referenced_key, referenced_subtree_path) = reference_path
.split_last()
.ok_or(Error::InvalidPath("invalid reference path"))?;

let mut referenced_element = self.get_raw(
referenced_subtree_path.iter().map(|x| x.as_slice()),
referenced_key,
transaction,
)?;

match referenced_element {
Element::Item(_, ref mut references)
| Element::Reference(_, ref mut references) => {
let mut path_owned: Vec<Vec<u8>> =
path_iter.clone().map(|x| x.to_vec()).collect();
path_owned.push(key.to_vec());
references.push(path_owned);
}
_ => {
return Err(Error::InvalidPath("cannot reference tree items"));
}
}

// update the reference list of the referenced item
merk_optional_tx!(
self.db,
referenced_subtree_path.iter().map(|x| x.as_slice()),
transaction,
mut subtree,
{
referenced_element.insert(&mut subtree, referenced_key.as_slice())?;
}
);
self.propagate_changes(
referenced_subtree_path.iter().map(|x| x.as_slice()),
transaction,
);

// insert the reference
let base_element = self.follow_reference(reference_path.to_owned(), transaction)?;
merk_optional_tx!(self.db, path_iter.clone(), transaction, mut subtree, {
element.insert_reference(&mut subtree, key, referenced_element.serialize()?)?;
element.insert_reference(&mut subtree, key, base_element.serialize()?)?;
});
self.propagate_changes(path_iter, transaction)?;
}
_ => {
// If path is empty that means there is an attempt to insert
// something into a root tree and this branch is for anything
// but trees
// something into a root tree and this branch is for items
if path_iter.len() == 0 {
return Err(Error::InvalidPath(
"only subtrees are allowed as root tree's leaves",
Expand Down
2 changes: 1 addition & 1 deletion grovedb/src/operations/proof/generate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ impl GroveDb {
Op::Push(node) | Op::PushInverted(node) => match node {
Node::KV(_, value) => {
let elem = Element::deserialize(value);
if let Ok(Element::Reference(reference_path)) = elem {
if let Ok(Element::Reference(reference_path, _)) = elem {
let referenced_elem = self.follow_reference(reference_path, None)?;
*value = referenced_elem.serialize().unwrap();
}
Expand Down
1 change: 0 additions & 1 deletion grovedb/src/operations/proof/verify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,6 @@ impl ProofVerifier {
continue;
}


if subquery_key.is_some() {
if subquery_value.is_none() {
self.verify_subquery_key(
Expand Down
Loading