Skip to content

Commit

Permalink
more tests
Browse files Browse the repository at this point in the history
  • Loading branch information
QuantumExplorer committed Aug 21, 2024
1 parent 24bf7da commit b6b047c
Show file tree
Hide file tree
Showing 5 changed files with 1,302 additions and 104 deletions.
123 changes: 121 additions & 2 deletions grovedb/src/operations/proof/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,20 @@ use std::{collections::BTreeMap, fmt};

use bincode::{Decode, Encode};
use derive_more::From;
use grovedb_merk::proofs::{query::Key, Decoder, Node, Op};
use grovedb_merk::{
proofs::{
query::{Key, VerifyOptions},
Decoder, Node, Op,
},
CryptoHash,
};
use grovedb_version::version::GroveVersion;

use crate::operations::proof::util::{element_hex_to_ascii, hex_to_ascii};
use crate::{
operations::proof::util::{element_hex_to_ascii, hex_to_ascii, ProvedPathKeyValues},
query_result_type::PathKeyOptionalElementTrio,
Error, GroveDb, PathQuery,
};

#[derive(Debug, Clone, Copy, Encode, Decode)]
pub struct ProveOptions {
Expand Down Expand Up @@ -58,6 +69,114 @@ pub enum GroveDBProof {
V0(GroveDBProofV0),
}

impl GroveDBProof {
/// Verifies a query with options using the proof and returns the root hash
/// and the query result.
pub fn verify_with_options(
&self,
query: &PathQuery,
options: VerifyOptions,
grove_version: &GroveVersion,
) -> Result<(CryptoHash, Vec<PathKeyOptionalElementTrio>), Error> {
GroveDb::verify_proof_internal(self, query, options, grove_version)
}

/// Verifies a raw query using the proof and returns the root hash and the
/// query result.
pub fn verify_raw(
&self,
query: &PathQuery,
grove_version: &GroveVersion,
) -> Result<(CryptoHash, ProvedPathKeyValues), Error> {
GroveDb::verify_proof_raw_internal(
self,
query,
VerifyOptions {
absence_proofs_for_non_existing_searched_keys: false,
verify_proof_succinctness: false,
include_empty_trees_in_result: true,
},
grove_version,
)
}

/// Verifies a query using the proof and returns the root hash and the query
/// result.
pub fn verify(
&self,
query: &PathQuery,
grove_version: &GroveVersion,
) -> Result<(CryptoHash, Vec<PathKeyOptionalElementTrio>), Error> {
GroveDb::verify_proof_internal(
self,
query,
VerifyOptions {
absence_proofs_for_non_existing_searched_keys: false,
verify_proof_succinctness: true,
include_empty_trees_in_result: false,
},
grove_version,
)
}

/// Verifies a query with an absence proof and returns the root hash and the
/// query result.
pub fn verify_with_absence_proof(
&self,
query: &PathQuery,
grove_version: &GroveVersion,
) -> Result<(CryptoHash, Vec<PathKeyOptionalElementTrio>), Error> {
GroveDb::verify_proof_internal(
self,
query,
VerifyOptions {
absence_proofs_for_non_existing_searched_keys: true,
verify_proof_succinctness: true,
include_empty_trees_in_result: false,
},
grove_version,
)
}

/// Verifies a subset query using the proof and returns the root hash and
/// the query result.
pub fn verify_subset(
&self,
query: &PathQuery,
grove_version: &GroveVersion,
) -> Result<(CryptoHash, Vec<PathKeyOptionalElementTrio>), Error> {
GroveDb::verify_proof_internal(
self,
query,
VerifyOptions {
absence_proofs_for_non_existing_searched_keys: false,
verify_proof_succinctness: false,
include_empty_trees_in_result: false,
},
grove_version,
)
}

/// Verifies a subset query with an absence proof using the proof and
/// returns the root hash and the query result.
pub fn verify_subset_with_absence_proof(
&self,
query: &PathQuery,
grove_version: &GroveVersion,
) -> Result<(CryptoHash, Vec<PathKeyOptionalElementTrio>), Error> {
GroveDb::verify_proof_internal(
self,
query,
VerifyOptions {
absence_proofs_for_non_existing_searched_keys: true,
verify_proof_succinctness: false,
include_empty_trees_in_result: false,
},
grove_version,
)
}
}

#[derive(Encode, Decode)]
pub struct GroveDBProofV0 {
pub root_layer: LayerProof,
Expand Down
36 changes: 31 additions & 5 deletions grovedb/src/operations/proof/verify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ impl GroveDb {
Ok((root_hash, result))
}

fn verify_proof_internal(
pub(crate) fn verify_proof_internal(
proof: &GroveDBProof,
query: &PathQuery,
options: VerifyOptions,
Expand Down Expand Up @@ -192,7 +192,7 @@ impl GroveDb {
Ok((root_hash, result))
}

fn verify_proof_raw_internal(
pub(crate) fn verify_proof_raw_internal(
proof: &GroveDBProof,
query: &PathQuery,
options: VerifyOptions,
Expand Down Expand Up @@ -511,23 +511,49 @@ impl GroveDb {
Self::verify_subset_query(proof, first_query, grove_version)?;
results.push(elements);

// we should iterate over each chained path queries
// Process the chained path queries
Self::process_chained_path_queries(
proof,
last_root_hash,
chained_path_queries,
grove_version,
&mut results,
)?;

Ok((last_root_hash, results))
}

/// Processes each chained path query and verifies it.
pub(in crate::operations::proof) fn process_chained_path_queries<C>(
proof: &[u8],
last_root_hash: CryptoHash,
chained_path_queries: Vec<C>,
grove_version: &GroveVersion,
results: &mut Vec<Vec<PathKeyOptionalElementTrio>>,
) -> Result<(), Error>
where
C: Fn(Vec<PathKeyOptionalElementTrio>) -> Option<PathQuery>,
{
for path_query_generator in chained_path_queries {
let new_path_query = path_query_generator(results[results.len() - 1].clone()).ok_or(
Error::InvalidInput("one of the path query generators returns no path query"),
)?;

let (new_root_hash, new_elements) =
Self::verify_subset_query(proof, &new_path_query, grove_version)?;

if new_root_hash != last_root_hash {
return Err(Error::InvalidProof(format!(
"root hash for different path queries do no match, first is {}, this one is {}",
"root hash for different path queries do not match, first is {}, this one is \
{}",
hex::encode(last_root_hash),
hex::encode(new_root_hash)
)));
}

results.push(new_elements);
}

Ok((last_root_hash, results))
Ok(())
}
}
2 changes: 0 additions & 2 deletions grovedb/src/query/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -599,8 +599,6 @@ mod tests {
tests::{common::compare_result_tuples, make_deep_tree, TEST_LEAF},
Element, GroveDb, PathQuery, SizedQuery,
};
use crate::batch::GroveDbOp;
use crate::tests::{make_empty_grovedb, TempGroveDb};

#[test]
fn test_same_path_different_query_merge() {
Expand Down
Loading

0 comments on commit b6b047c

Please sign in to comment.