Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
14 changes: 10 additions & 4 deletions grovedb/src/operations/proof/aggregate_common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,10 @@
//! thin wrapper, preserving the original error text.

use grovedb_merk::{
proofs::{query::QueryProofVerify, Query as MerkQuery},
proofs::{
query::{QueryProofVerify, PROOF_VERSION_LATEST},
Query as MerkQuery,
},
CryptoHash,
};
use grovedb_query::{Query, QueryItem};
Expand Down Expand Up @@ -97,7 +100,7 @@ pub(in crate::operations::proof) fn verify_single_key_layer_proof_v0(
};

let (root_hash, merk_result) = level_query
.execute_proof(merk_bytes, None, true, 0)
.execute_proof(merk_bytes, None, true, PROOF_VERSION_LATEST)
.unwrap()
.map_err(|e| {
Error::InvalidProof(
Expand Down Expand Up @@ -190,9 +193,12 @@ pub(in crate::operations::proof) fn execute_carrier_layer_proof(

// Walk direction must match the prover's; otherwise the merk
// walker stops at the first out-of-order boundary and only the last
// key in the proof is returned.
// key in the proof is returned. Strict mode (#863) makes that a
// hard requirement on the stream's op family, so a carrier stream
// in the wrong family cannot fill a limited outer walk from the
// wrong end of the range.
let (root_hash, merk_result) = level_query
.execute_proof(merk_bytes, outer_limit, left_to_right, 0)
.execute_proof(merk_bytes, outer_limit, left_to_right, PROOF_VERSION_LATEST)
.unwrap()
.map_err(|e| {
Error::InvalidProof(
Expand Down
6 changes: 4 additions & 2 deletions grovedb/src/operations/proof/indexed_axis/verify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ use super::{aggregate_range_out_of_domain, AxisEntries, IndexedTargetChain};
// Test-oracle-only imports (see the module doc): the standalone
// verifiers and their inner cores are `#[cfg(test)]`.
#[cfg(test)]
use grovedb_merk::proofs::query::PROOF_VERSION_LATEST;
#[cfg(test)]
use grovedb_merk::{
proofs::{
query::{
Expand Down Expand Up @@ -285,7 +287,7 @@ fn execute_single_key_proof(
let mut query = MerkQuery::new();
query.insert_item(MerkQueryItem::Key(target_key.to_vec()));
let (root_hash, result) = query
.execute_proof(proof_bytes, None, true, 0)
.execute_proof(proof_bytes, None, true, PROOF_VERSION_LATEST)
.unwrap()
.map_err(|e| {
Error::CorruptedData(format!(
Expand Down Expand Up @@ -657,7 +659,7 @@ fn verify_indexed_axis_range_inner(
&envelope.secondary_proof,
limit_for_verify,
left_to_right,
0,
PROOF_VERSION_LATEST,
)
.unwrap()
.map_err(|e| {
Expand Down
50 changes: 40 additions & 10 deletions grovedb/src/operations/proof/verify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1056,15 +1056,21 @@ impl GroveDb {
let secondary_query =
crate::query::axis_lowering::axis_bounded_merk_query(axis_query)?;
let left_to_right = secondary_query.left_to_right;
// proof_version 0 (lenient) matches the standalone
// envelope's choice and is safe HERE because the
// axis decoders consume only `proved.key` — bound
// into the recomputed secondary root — never
// `proved.value`. If a future change starts reading
// secondary VALUES, it must move to
// PROOF_VERSION_LATEST first.
// Strict mode (#863): the secondary stream must be
// encoded in the family of the direction it is
// walked in, or an upright stream handed to a
// descending axis read would fill the page from the
// wrong end of the range. The strict value checks
// that come with it are moot here — the axis
// decoders consume only `proved.key`, bound into the
// recomputed secondary root — but harmless.
let (root, res) = secondary_query
.execute_proof(&payload.secondary_proof, Some(*limit), left_to_right, 0)
.execute_proof(
&payload.secondary_proof,
Some(*limit),
left_to_right,
PROOF_VERSION_LATEST,
)
.unwrap()
.map_err(|e| {
Error::InvalidProof(
Expand Down Expand Up @@ -1424,8 +1430,21 @@ impl GroveDb {
merk_proof_bytes: &[u8],
query: &PathQuery,
) -> Result<CryptoHash, Error> {
let (root_hash, _) = Query::new()
.execute_proof(merk_proof_bytes, None, true, PROOF_VERSION_LATEST)
// The layer was emitted in the direction of the query that
// generated the proof, which this (subset) query does not know.
// No row is reported, so the direction carries no semantics
// here; it only has to match the stream's own family for the
// #863 orientation check, which still refuses a mixed stream.
let left_to_right = grovedb_merk::proofs::query::proof_stream_direction(merk_proof_bytes)
.map_err(|e| {
Error::InvalidProof(
query.clone(),
format!("Invalid V1 lower layer proof (root derivation): {}", e),
)
})?
.unwrap_or(true);
let (root_hash, _) = Query::new_with_direction(left_to_right)
.execute_proof(merk_proof_bytes, None, left_to_right, PROOF_VERSION_LATEST)
.unwrap()
.map_err(|e| {
Error::InvalidProof(
Expand Down Expand Up @@ -1555,6 +1574,17 @@ impl GroveDb {
// binds the result stays where it was: the reconstructed root
// hash still has to match what the parent layer committed, and
// `QueryItem::contains` still gates every returned key.
//
// For every other level the direction is the query's, and
// `execute_proof` itself (#863) refuses a stream that is not
// homogeneous in that direction's op family — an upright
// stream walked descending, or a mixed stream that rebuilds
// the honest tree in a non-monotonic visit order, would
// otherwise read an absence, or a page from the wrong end of
// the range, out of an authentic root hash. The same check
// runs on a synthesized level, where the direction read off
// the stream trivially matches it (`proof_stream_direction`
// already refuses a mixed stream).
let single_key_synthesized_level = internal_query.synthesized_path_component
&& matches!(
internal_query.items.as_slice(),
Expand Down
1 change: 1 addition & 0 deletions grovedb/src/tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ mod partial_batch_consistency_tests;
mod proof_advanced_tests;
mod proof_coverage_tests;
mod proof_depth_limit_tests;
mod proof_orientation_tests;
mod proof_size_measurement;
mod provable_count_indexed_tree_tests;
mod provable_count_provable_sum_indexed_tree_tests;
Expand Down
Loading
Loading