From 0dbebe9bd8ad87ba01ab6eeb2bd7d3fbbbf22f74 Mon Sep 17 00:00:00 2001 From: PastaClaw Date: Fri, 22 May 2026 21:38:35 -0500 Subject: [PATCH] fix: accept PCPS trees in path validation --- grovedb/src/operations/get/mod.rs | 13 +---- grovedb/src/tests/is_empty_tree_tests.rs | 46 ++++++++++++++++ .../src/tests/operations_coverage_tests.rs | 54 +++++++++++++++++++ 3 files changed, 101 insertions(+), 12 deletions(-) diff --git a/grovedb/src/operations/get/mod.rs b/grovedb/src/operations/get/mod.rs index f60893e9d..58b195e24 100644 --- a/grovedb/src/operations/get/mod.rs +++ b/grovedb/src/operations/get/mod.rs @@ -402,18 +402,7 @@ impl GroveDb { // check_subtree_exists would reject paths through wrapped // parents — breaking the wrapper-transparency contract. match element.map(|e| e.into_underlying()) { - Ok(Element::Tree(..)) - | Ok(Element::SumTree(..)) - | Ok(Element::BigSumTree(..)) - | Ok(Element::CountTree(..)) - | Ok(Element::CountSumTree(..)) - | Ok(Element::ProvableCountTree(..)) - | Ok(Element::ProvableCountSumTree(..)) - | Ok(Element::ProvableSumTree(..)) - | Ok(Element::CommitmentTree(..)) - | Ok(Element::MmrTree(..)) - | Ok(Element::BulkAppendTree(..)) - | Ok(Element::DenseAppendOnlyFixedSizeTree(..)) => Ok(()).wrap_with_cost(cost), + Ok(e) if e.is_any_tree() => Ok(()).wrap_with_cost(cost), Ok(_) | Err(Error::PathKeyNotFound(_)) => Err(error_fn()).wrap_with_cost(cost), Err(e) => Err(e).wrap_with_cost(cost), } diff --git a/grovedb/src/tests/is_empty_tree_tests.rs b/grovedb/src/tests/is_empty_tree_tests.rs index 2876e2e80..c530d0d5a 100644 --- a/grovedb/src/tests/is_empty_tree_tests.rs +++ b/grovedb/src/tests/is_empty_tree_tests.rs @@ -172,6 +172,52 @@ mod tests { assert!(inner_result, "inner tree should be empty"); } + #[test] + fn test_is_empty_tree_on_provable_count_provable_sum_subtree() { + let grove_version = GroveVersion::latest(); + let db = make_test_grovedb(grove_version); + + db.insert( + [TEST_LEAF].as_ref(), + b"pcps", + Element::empty_provable_count_provable_sum_tree(), + None, + None, + grove_version, + ) + .unwrap() + .expect("should insert ProvableCountProvableSumTree"); + + let empty_result = db + .is_empty_tree([TEST_LEAF, b"pcps"].as_ref(), None, grove_version) + .unwrap() + .expect("should succeed checking empty ProvableCountProvableSumTree"); + assert!( + empty_result, + "empty ProvableCountProvableSumTree should be empty" + ); + + db.insert( + [TEST_LEAF, b"pcps"].as_ref(), + b"item", + Element::new_item(b"value".to_vec()), + None, + None, + grove_version, + ) + .unwrap() + .expect("should insert item into ProvableCountProvableSumTree"); + + let non_empty_result = db + .is_empty_tree([TEST_LEAF, b"pcps"].as_ref(), None, grove_version) + .unwrap() + .expect("should succeed checking non-empty ProvableCountProvableSumTree"); + assert!( + !non_empty_result, + "ProvableCountProvableSumTree with items should not be empty" + ); + } + #[test] fn test_is_empty_tree_after_delete() { let grove_version = GroveVersion::latest(); diff --git a/grovedb/src/tests/operations_coverage_tests.rs b/grovedb/src/tests/operations_coverage_tests.rs index 191e59f9c..5879a18ad 100644 --- a/grovedb/src/tests/operations_coverage_tests.rs +++ b/grovedb/src/tests/operations_coverage_tests.rs @@ -2259,6 +2259,60 @@ mod tests { ); } + #[test] + fn delete_with_validate_tree_at_path_exists_success_on_pcps_path() { + let grove_version = GroveVersion::latest(); + let db = make_test_grovedb(grove_version); + + db.insert( + [TEST_LEAF].as_ref(), + b"pcps", + Element::empty_provable_count_provable_sum_tree(), + None, + None, + grove_version, + ) + .unwrap() + .expect("should insert ProvableCountProvableSumTree"); + + db.insert( + [TEST_LEAF, b"pcps"].as_ref(), + b"item_v", + Element::new_item(b"data".to_vec()), + None, + None, + grove_version, + ) + .unwrap() + .expect("should insert item into ProvableCountProvableSumTree"); + + db.delete( + [TEST_LEAF, b"pcps"].as_ref(), + b"item_v", + Some(DeleteOptions { + validate_tree_at_path_exists: true, + ..Default::default() + }), + None, + grove_version, + ) + .unwrap() + .expect("should delete with path validation through ProvableCountProvableSumTree"); + + let result = db + .get( + [TEST_LEAF, b"pcps"].as_ref(), + b"item_v", + None, + grove_version, + ) + .unwrap(); + assert!( + matches!(result, Err(Error::PathKeyNotFound(_))), + "item should be deleted from ProvableCountProvableSumTree" + ); + } + #[test] fn delete_with_sectional_storage_function_with_flags() { let grove_version = GroveVersion::latest();