Skip to content

fix: remove ProveOptions from V1 proofs#647

Merged
QuantumExplorer merged 1 commit into
developfrom
fix/remove-prove-options-from-v1-proof
Mar 11, 2026
Merged

fix: remove ProveOptions from V1 proofs#647
QuantumExplorer merged 1 commit into
developfrom
fix/remove-prove-options-from-v1-proof

Conversation

@QuantumExplorer
Copy link
Copy Markdown
Member

@QuantumExplorer QuantumExplorer commented Mar 10, 2026

Summary

  • Removes prove_options field from GroveDBProofV1 struct — V1 proofs no longer embed prover-controlled options
  • V1 verification now uses ProveOptions::default() instead of deserializing options from the untrusted proof
  • V0 proofs are unchanged (backwards compatible)
  • Updates debugger, depth-limit tests, and doc comments

Background

ProveOptions (specifically decrease_limit_on_empty_sub_query_result) was embedded in the serialized proof and trusted by the verifier. A malicious prover could set this flag to true to make empty subquery results consume the query limit, causing the verifier to return fewer results than actually exist. Both honest and malicious proofs verified correctly — the verifier couldn't distinguish them.

Since all Platform queries use decrease_limit_on_empty_sub_query_result = true (the default), removing it from V1 proofs has no practical impact while closing the attack vector.

Test plan

  • All 22 proof depth limit tests pass
  • All 133 proof coverage tests pass
  • All 5 trunk proof tests pass
  • cargo clippy -- -D warnings clean
  • cargo build --no-default-features --features verify builds

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Refactor
    • Simplified V1 proof structure by removing embedded configuration options.
    • V1 proof verification now uses standardized default configuration settings instead of proof-embedded options.
    • Updated documentation to clarify V1 proof behavior.

…tack

V0 proofs embed ProveOptions (including decrease_limit_on_empty_sub_query_result)
in the serialized proof bytes. Since the verifier deserializes and trusts these
options, a malicious prover can manipulate how many results the verifier returns.

V1 proofs no longer embed ProveOptions. The verifier uses ProveOptions::default()
instead, ensuring the prover cannot influence limit-counting behavior.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Mar 10, 2026

📝 Walkthrough

Walkthrough

The PR removes the prove_options field from the GroveDBProofV1 struct to address a potential attack surface. V1 proof verification now uniformly uses ProveOptions::default() instead of relying on embedded options. Related code in generation, verification, debugging, and tests has been updated accordingly, with documentation clarified.

Changes

Cohort / File(s) Summary
Proof Struct Definition
grovedb/src/operations/proof/mod.rs
Removed prove_options field from public GroveDBProofV1 struct. Documentation expanded to clarify that V1 proofs no longer embed ProveOptions and that default options are used during verification to prevent attack vectors.
Proof Generation
grovedb/src/operations/proof/generate.rs
Updated prove_query_non_serialized_v1 to construct GroveDBProofV1 with only root_layer, eliminating the prove_options field from the V1 proof payload.
Proof Verification
grovedb/src/operations/proof/verify.rs
Modified V1 verification entry points (verify_proof_v1_internal, verify_proof_v1_raw_internal) to initialize and use ProveOptions::default() instead of extracting options from the proof structure.
Debugger Integration
grovedb/src/debugger.rs
Updated proof_to_grovedbg to construct V1 proofs using ProveOptions::default() with clarifying comments about V1 proof behavior.
Test Updates
grovedb/src/tests/proof_depth_limit_tests.rs
Revised test code to construct GroveDBProofV1 literals with only root_layer field, matching the updated struct signature.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 With options removed, V1 proofs now shine,
No embedded tricks in the proof's design,
Defaults keep verifiers safe from the fray,
Simpler and stronger in every way! 🌟

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'fix: remove ProveOptions from V1 proofs' is concise, specific, and accurately summarizes the main change—removing ProveOptions from V1 proofs—making it clear to teammates scanning history.

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

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/remove-prove-options-from-v1-proof

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.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
grovedb/src/operations/proof/generate.rs (1)

820-856: ⚠️ Potential issue | 🟠 Major

Reject non-default ProveOptions for V1 proofs.

GroveDb::prove_query_non_serialized_v1 still shapes the proof with the caller-supplied prove_options, but both V1 verifier entry points now always use ProveOptions::default(). A proof generated with decrease_limit_on_empty_sub_query_result = false therefore no longer round-trips under V1. V1 generation should either ignore that knob or fail fast when it is set away from the default.

Suggested direction
     pub(crate) fn prove_query_non_serialized_v1(
         &self,
         path_query: &PathQuery,
         prove_options: Option<ProveOptions>,
         grove_version: &GroveVersion,
     ) -> CostResult<GroveDBProof, Error> {
         let mut cost = OperationCost::default();
-        let prove_options = prove_options.unwrap_or_default();
+        if matches!(
+            prove_options,
+            Some(ProveOptions {
+                decrease_limit_on_empty_sub_query_result: false,
+            })
+        ) {
+            return Err(Error::NotSupported(
+                "V1 proofs always use ProveOptions::default()".to_string(),
+            ))
+            .wrap_with_cost(cost);
+        }
+        let prove_options = ProveOptions::default();
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@grovedb/src/operations/proof/generate.rs` around lines 820 - 856, In
prove_query_non_serialized_v1, detect when the caller supplied non-default
ProveOptions (compare the unwrapped prove_options to ProveOptions::default())
and return an error (e.g., Error::InvalidQuery or a new error variant) instead
of using them; update the function to reject any ProveOptions that differ from
default before calling prove_subqueries_v1 so V1 proofs cannot be generated with
non-default knobs like decrease_limit_on_empty_sub_query_result.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@grovedb/src/operations/proof/generate.rs`:
- Around line 820-856: In prove_query_non_serialized_v1, detect when the caller
supplied non-default ProveOptions (compare the unwrapped prove_options to
ProveOptions::default()) and return an error (e.g., Error::InvalidQuery or a new
error variant) instead of using them; update the function to reject any
ProveOptions that differ from default before calling prove_subqueries_v1 so V1
proofs cannot be generated with non-default knobs like
decrease_limit_on_empty_sub_query_result.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 03ec1b91-0fdb-4d56-8bf1-cc87d550c31b

📥 Commits

Reviewing files that changed from the base of the PR and between f686a34 and c3dff72.

📒 Files selected for processing (5)
  • grovedb/src/debugger.rs
  • grovedb/src/operations/proof/generate.rs
  • grovedb/src/operations/proof/mod.rs
  • grovedb/src/operations/proof/verify.rs
  • grovedb/src/tests/proof_depth_limit_tests.rs

@codecov
Copy link
Copy Markdown

codecov Bot commented Mar 11, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 90.83%. Comparing base (f556532) to head (c3dff72).
⚠️ Report is 2 commits behind head on develop.

Additional details and impacted files
@@           Coverage Diff            @@
##           develop     #647   +/-   ##
========================================
  Coverage    90.83%   90.83%           
========================================
  Files          182      182           
  Lines        51911    51909    -2     
========================================
- Hits         47151    47150    -1     
+ Misses        4760     4759    -1     
Components Coverage Δ
grovedb-core 89.06% <100.00%> (+<0.01%) ⬆️
merk 91.93% <ø> (ø)
storage 86.36% <ø> (ø)
commitment-tree 96.43% <ø> (ø)
mmr 96.76% <ø> (ø)
bulk-append-tree 89.65% <ø> (ø)
element 97.56% <ø> (ø)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Copy Markdown
Member Author

@QuantumExplorer QuantumExplorer left a comment

Choose a reason for hiding this comment

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

Approved

@QuantumExplorer QuantumExplorer merged commit 344b957 into develop Mar 11, 2026
10 of 11 checks passed
@QuantumExplorer QuantumExplorer deleted the fix/remove-prove-options-from-v1-proof branch March 11, 2026 02:21
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.

1 participant