Skip to content

fix: accept PCPS trees in path validation#743

Open
thepastaclaw wants to merge 1 commit into
dashpay:developfrom
thepastaclaw:fix-check-subtree-pcps
Open

fix: accept PCPS trees in path validation#743
thepastaclaw wants to merge 1 commit into
dashpay:developfrom
thepastaclaw:fix-check-subtree-pcps

Conversation

@thepastaclaw

@thepastaclaw thepastaclaw commented May 23, 2026

Copy link
Copy Markdown
Contributor

Fix PCPS subtree path validation

Summary

  • Fix subtree path validation so check_subtree_exists accepts all
    centralized Element::is_any_tree() variants after unwrapping
    NonCounted wrappers.
  • Add regression coverage for ProvableCountProvableSumTree paths through
    is_empty_tree.
  • Add delete traversal coverage for
    DeleteOptions::validate_tree_at_path_exists on PCPS subtrees.

Closes #710.

Validation

cargo fmt
cargo test -p grovedb \
  test_is_empty_tree_on_provable_count_provable_sum_subtree \
  --all-features
cargo test -p grovedb \
  delete_with_validate_tree_at_path_exists_success_on_pcps_path \
  --all-features
cargo test -p grovedb \
  check_subtree_exists_through_non_counted_wrapper \
  --all-features
code-review dashpay/grovedb upstream/develop review/fix-check-subtree-pcps

Summary by CodeRabbit

  • Tests

    • Added test coverage for tree emptiness validation on specific tree types.
    • Added test coverage for delete operations with tree validation enabled.
  • Refactor

    • Simplified internal tree-type validation logic for improved code maintainability.

Review Change Stack

@coderabbitai

coderabbitai Bot commented May 23, 2026

Copy link
Copy Markdown
Contributor

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 810d5d59-a413-4ef6-ad09-2b5b7d0939ee

📥 Commits

Reviewing files that changed from the base of the PR and between 9f67e8c and 0dbebe9.

📒 Files selected for processing (3)
  • grovedb/src/operations/get/mod.rs
  • grovedb/src/tests/is_empty_tree_tests.rs
  • grovedb/src/tests/operations_coverage_tests.rs

📝 Walkthrough

Walkthrough

The PR addresses an audit finding by refactoring subtree-existence validation in the get operation. Instead of explicitly matching individual tree variants, check_subtree_exists now uses a polymorphic is_any_tree() check. Two test cases verify that the previously-unsupported ProvableCountProvableSumTree is now handled correctly during tree traversal and deletion.

Changes

SubTree Existence Validation

Layer / File(s) Summary
Refactor check_subtree_exists to use is_any_tree()
grovedb/src/operations/get/mod.rs
Replaced exhaustive variant matching of tree types with a single is_any_tree() check, reducing code duplication and eliminating the risk of missing new tree variants.
Test coverage for ProvableCountProvableSumTree traversal
grovedb/src/tests/is_empty_tree_tests.rs, grovedb/src/tests/operations_coverage_tests.rs
Added two tests: one verifying is_empty_tree correctly reports empty and non-empty states for a ProvableCountProvableSumTree, and one confirming delete with path validation works under that tree type.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

Poem

🐰 A rabbit found trees both tall and grand,
but one was lost in validation's land,
Now is_any_tree() sees them all at last,
no enumeration needed—the die is cast!
With tests that prove the provable sum tree shines,
the audit's fix now neatly aligns. 🌲

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: fixing path validation to accept PCPS (ProvableCountProvableSumTree) trees, which aligns with the PR's core objective of resolving issue #710.
Linked Issues check ✅ Passed The PR successfully addresses all coding requirements from issue #710: refactoring check_subtree_exists to accept all tree variants via is_any_tree() [#710], adding is_empty_tree regression test for PCPS [#710], and adding delete validation coverage for PCPS paths [#710].
Out of Scope Changes check ✅ Passed All changes are directly scoped to resolving issue #710: the get/mod.rs refactoring addresses path validation, while both new tests specifically validate PCPS tree handling in is_empty_tree and delete operations.
Docstring Coverage ✅ Passed Docstring coverage is 85.71% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@thepastaclaw

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented May 23, 2026

Copy link
Copy Markdown
Contributor
✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@codecov

codecov Bot commented May 23, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 91.43%. Comparing base (9f67e8c) to head (0dbebe9).
⚠️ Report is 10 commits behind head on develop.

Additional details and impacted files
@@           Coverage Diff            @@
##           develop     #743   +/-   ##
========================================
  Coverage    91.43%   91.43%           
========================================
  Files          236      236           
  Lines        67111    67111           
========================================
  Hits         61364    61364           
  Misses        5747     5747           
Components Coverage Δ
grovedb-core 88.94% <100.00%> (ø)
merk 92.26% <ø> (ø)
storage 86.36% <ø> (ø)
commitment-tree 96.43% <ø> (ø)
mmr 96.79% <ø> (ø)
bulk-append-tree 89.39% <ø> (ø)
element 97.38% <ø> (ø)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@thepastaclaw

thepastaclaw commented Jun 15, 2026

Copy link
Copy Markdown
Contributor Author

✅ Review complete (commit 0dbebe9)

@thepastaclaw thepastaclaw left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

Small, focused fix that swaps the hand-rolled tree-variant match in check_subtree_exists for the centralized Element::is_any_tree() helper, closing the gap where ProvableCountProvableSumTree paths were rejected. Two regression tests cover the realistic entry points. One nitpick: the explicit into_underlying() before is_any_tree() is redundant since is_any_tree() already unwraps via underlying().

💬 1 nitpick(s)

Comment on lines 404 to 408
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),
}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💬 Nitpick: Redundant into_underlying() before is_any_tree()

Element::is_any_tree() already invokes self.underlying() internally to look through NonCounted / NotSummed / NotCountedOrSummed wrappers (see grovedb-element/src/element/helpers.rs:323 and :56-63). Calling into_underlying() first re-does that unwrap, and for wrapped variants it performs an owned *inner boxed-element move on every successful subtree check. Since the subsequent arms no longer pattern-match against a specific unwrapped variant, you can pass the element straight to is_any_tree() and let the helper handle wrapper transparency. The comment about looking through NonCounted remains accurate either way.

Suggested change
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),
}
match element {
Ok(ref 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),
}

source: ['claude']

@thepastaclaw thepastaclaw marked this pull request as ready for review June 16, 2026 07:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[audit][medium] check_subtree_exists omits ProvableCountProvableSumTree

1 participant