Skip to content

fix(proofs): version trailing-byte proof decoding#739

Open
QuantumExplorer wants to merge 1 commit into
developfrom
codex/version-proof-trailing-bytes
Open

fix(proofs): version trailing-byte proof decoding#739
QuantumExplorer wants to merge 1 commit into
developfrom
codex/version-proof-trailing-bytes

Conversation

@QuantumExplorer

@QuantumExplorer QuantumExplorer commented May 21, 2026

Copy link
Copy Markdown
Member

Summary

  • route GroveDB proof-envelope decoding through a proof-version trailing-byte policy
  • set v3 to reject trailing proof bytes while preserving v1/v2 legacy decoding
  • add regression coverage for latest rejection and legacy acceptance

Tests

  • cargo test -p grovedb verify_query_rejects_proof_with_trailing_bytes --lib
  • cargo test -p grovedb verify_query_legacy_version_accepts_proof_with_trailing_bytes --lib
  • cargo check -p grovedb --lib
  • git diff --check

Summary by CodeRabbit

  • New Features

    • Implemented version-aware proof validation that conditionally enforces strict rejection of trailing bytes in proofs based on the configured GroveDB version. Legacy versions accept proofs with trailing bytes, while newer versions enforce stricter validation rules.
  • Tests

    • Added regression test to verify backward compatibility for legacy GroveDB versions when validating proofs with trailing bytes.

Review Change Stack

@coderabbitai

coderabbitai Bot commented May 21, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

This PR replaces unconditional trailing-byte rejection during proof deserialization with a version-aware policy flag. Version definitions add decode_rejects_trailing_bytes, which the new decode_grovedb_proof_versioned() function consults before deciding to reject or accept trailing bytes. All verification entry points—core queries and aggregates—are wired to use the versioned decoder, with a regression test confirming legacy versions tolerate trailing bytes.

Changes

Version-aware proof decoding

Layer / File(s) Summary
Version schema: decode_rejects_trailing_bytes field
grovedb-version/src/version/grovedb_versions.rs, grovedb-version/src/version/v1.rs, grovedb-version/src/version/v2.rs, grovedb-version/src/version/v3.rs
GroveDBOperationsProofVersions gains a decode_rejects_trailing_bytes feature field. GROVE_V1 and GROVE_V2 initialize it to 0 (legacy: allow trailing bytes); GROVE_V3 sets it to 1 (strict: reject trailing bytes).
Versioned proof decoder implementation
grovedb/src/operations/proof/mod.rs
decode_grovedb_proof_versioned(proof, grove_version) replaces the canonical decoder, extracting the trailing-byte rejection policy from the version and dispatching to a generalized internal decoder that conditionally rejects based on the policy. Documentation clarifies the policy is version-determined.
Core verification entry points integration
grovedb/src/operations/proof/verify.rs
Four public verifiers (verify_query_with_options, verify_query_get_parent_tree_info_with_options, verify_query_raw, verify_trunk_chunk_proof) switch from canonical decoding to versioned decoding using the provided grove_version.
Aggregate verification paths integration
grovedb/src/operations/proof/aggregate_count/mod.rs, grovedb/src/operations/proof/aggregate_count_and_sum/mod.rs, grovedb/src/operations/proof/aggregate_sum/mod.rs
Six aggregate verifiers (verify_aggregate_count_query, verify_aggregate_count_query_per_key, verify_aggregate_count_and_sum_query, verify_aggregate_count_and_sum_query_per_key, verify_aggregate_sum_query, verify_aggregate_sum_query_per_key) switch to versioned proof decoding while retaining V1-envelope enforcement and leaf/per-key classification.
Test coverage and documentation updates
grovedb/src/tests/proof_advanced_tests.rs, grovedb/src/tests/provable_count_provable_sum_tree_tests.rs
Test comments updated to reference versioned decoding. New regression test verify_query_legacy_version_accepts_proof_with_trailing_bytes constructs a legacy GroveVersion with trailing-byte acceptance enabled, appends a trailing byte to a proof, and verifies that verify_query succeeds under the legacy policy.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • dashpay/grovedb#663: Updates the aggregate-count proof verification entry points that are refactored here to use versioned decoding in grovedb/src/operations/proof/aggregate_count/mod.rs.

Poem

🐰 Trailing bytes, you've met your match!
With versions now to steer your patch—
V3 rejects with strictest care,
While legacy? They're debonair.
Decode with purpose, version-wise,
Proof verification's grand reprise! 🎯

🚥 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 clearly summarizes the main change: implementing version-aware trailing-byte policy for proof decoding, which is the core focus of all modifications across the changeset.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/version-proof-trailing-bytes

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

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/mod.rs (1)

31-37: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Doc comment still says trailing bytes are always rejected.

The comment now conflicts with the versioned policy (v1/v2 can accept trailing bytes, v3 rejects). Please update this block to describe conditional rejection.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@grovedb/src/operations/proof/mod.rs` around lines 31 - 37, Update the module
doc comment in grovedb/src/operations/proof/mod.rs that currently states
"trailing bytes beyond the encoded envelope are rejected" to explain the
conditional behavior by version: state that v1/v2 proofs may accept trailing
bytes while v3 (and later) enforces canonical decoding by rejecting any trailing
bytes; keep the rationale about equality-bytes assumptions and note the
versioned policy decision. Target the top-of-file doc block in this module (the
proof decoding/canonicality paragraph) and amend the wording to mention v1/v2 vs
v3 behavior explicitly.
🧹 Nitpick comments (2)
grovedb/src/operations/proof/aggregate_sum/mod.rs (2)

190-190: ⚡ Quick win

Consider adding error context per coding guidelines.

The bare ? operator doesn't provide context about where the decode failure occurred. As per coding guidelines, wrap errors with context to aid debugging.

Suggested fix
-        let grovedb_proof = super::decode_grovedb_proof_versioned(proof, grove_version)?;
+        let grovedb_proof = super::decode_grovedb_proof_versioned(proof, grove_version)
+            .map_err(|e| Error::CorruptedData(format!("verify_aggregate_sum_query_per_key decode: {}", e)))?;

As per coding guidelines: Wrap errors with context using .map_err(|e| Error::CorruptedData(format!("context: {}", e))) pattern in Rust source files

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@grovedb/src/operations/proof/aggregate_sum/mod.rs` at line 190, The call to
decode_grovedb_proof_versioned(proof, grove_version) uses the bare ? and should
be wrapped with contextual error mapping; replace the bare `?` on the result
used to assign grovedb_proof with `.map_err(|e|
Error::CorruptedData(format!("decoding grovedb proof failed: {}", e)))?` (i.e.,
map the error from decode_grovedb_proof_versioned into Error::CorruptedData with
a clear message) so failures include where the decode failed.

119-119: ⚡ Quick win

Consider adding error context per coding guidelines.

The bare ? operator doesn't provide context about where the decode failure occurred. As per coding guidelines, wrap errors with context to aid debugging.

Suggested fix
-        let grovedb_proof = super::decode_grovedb_proof_versioned(proof, grove_version)?;
+        let grovedb_proof = super::decode_grovedb_proof_versioned(proof, grove_version)
+            .map_err(|e| Error::CorruptedData(format!("verify_aggregate_sum_query decode: {}", e)))?;

As per coding guidelines: Wrap errors with context using .map_err(|e| Error::CorruptedData(format!("context: {}", e))) pattern in Rust source files

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@grovedb/src/operations/proof/aggregate_sum/mod.rs` at line 119, The call to
decode_grovedb_proof_versioned(proof, grove_version) uses a bare `?` and should
be wrapped to add context; replace the `?` on that call so errors are mapped
(e.g., via .map_err(|e| Error::CorruptedData(format!("decoding grovedb proof
(versioned) failed: {}", e)))) to preserve the original error while adding the
descriptive message — update the assignment to `grovedb_proof` accordingly.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@grovedb/src/operations/proof/mod.rs`:
- Around line 31-37: Update the module doc comment in
grovedb/src/operations/proof/mod.rs that currently states "trailing bytes beyond
the encoded envelope are rejected" to explain the conditional behavior by
version: state that v1/v2 proofs may accept trailing bytes while v3 (and later)
enforces canonical decoding by rejecting any trailing bytes; keep the rationale
about equality-bytes assumptions and note the versioned policy decision. Target
the top-of-file doc block in this module (the proof decoding/canonicality
paragraph) and amend the wording to mention v1/v2 vs v3 behavior explicitly.

---

Nitpick comments:
In `@grovedb/src/operations/proof/aggregate_sum/mod.rs`:
- Line 190: The call to decode_grovedb_proof_versioned(proof, grove_version)
uses the bare ? and should be wrapped with contextual error mapping; replace the
bare `?` on the result used to assign grovedb_proof with `.map_err(|e|
Error::CorruptedData(format!("decoding grovedb proof failed: {}", e)))?` (i.e.,
map the error from decode_grovedb_proof_versioned into Error::CorruptedData with
a clear message) so failures include where the decode failed.
- Line 119: The call to decode_grovedb_proof_versioned(proof, grove_version)
uses a bare `?` and should be wrapped to add context; replace the `?` on that
call so errors are mapped (e.g., via .map_err(|e|
Error::CorruptedData(format!("decoding grovedb proof (versioned) failed: {}",
e)))) to preserve the original error while adding the descriptive message —
update the assignment to `grovedb_proof` accordingly.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: ddda047d-74dd-4a1d-9a3e-d62ddd713ea2

📥 Commits

Reviewing files that changed from the base of the PR and between a2129a9 and 2eb554a.

📒 Files selected for processing (11)
  • grovedb-version/src/version/grovedb_versions.rs
  • grovedb-version/src/version/v1.rs
  • grovedb-version/src/version/v2.rs
  • grovedb-version/src/version/v3.rs
  • grovedb/src/operations/proof/aggregate_count/mod.rs
  • grovedb/src/operations/proof/aggregate_count_and_sum/mod.rs
  • grovedb/src/operations/proof/aggregate_sum/mod.rs
  • grovedb/src/operations/proof/mod.rs
  • grovedb/src/operations/proof/verify.rs
  • grovedb/src/tests/proof_advanced_tests.rs
  • grovedb/src/tests/provable_count_provable_sum_tree_tests.rs

@codecov

codecov Bot commented May 21, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 91.43%. Comparing base (a2129a9) to head (2eb554a).

Additional details and impacted files
@@           Coverage Diff            @@
##           develop     #739   +/-   ##
========================================
  Coverage    91.43%   91.43%           
========================================
  Files          236      236           
  Lines        67114    67130   +16     
========================================
+ Hits         61366    61382   +16     
  Misses        5748     5748           
Components Coverage Δ
grovedb-core 88.95% <100.00%> (+<0.01%) ⬆️
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.

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