Skip to content

fix: version-gate commit_batch accumulated costs - #637

Merged
QuantumExplorer merged 2 commits into
developfrom
fix/version-gate-commit-batch-costs
Mar 10, 2026
Merged

fix: version-gate commit_batch accumulated costs#637
QuantumExplorer merged 2 commits into
developfrom
fix/version-gate-commit-batch-costs

Conversation

@QuantumExplorer

@QuantumExplorer QuantumExplorer commented Mar 10, 2026

Copy link
Copy Markdown
Member

Summary

  • Version-gates the commit_batch cost fix from 4a0731e so it only applies to protocol version 3+
  • V1/V2 (commit: 0): discard batch costs from commit_batch (legacy behavior matching pre-fix)
  • V3 (commit: 1): preserve accumulated batch costs (seek counts, storage costs)
  • Adds MerkCommitVersions struct to MerkVersions and passes grove_version through Merk::commit

Test plan

  • cargo build clean
  • cargo test -p grovedb-merk — 344 passed
  • cargo test -p grovedb --lib — 1403 passed
  • cargo test -p grovedb-version — 47 passed
  • cargo clippy -- -D warnings clean
  • CI passes

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Introduced version metadata for batch commits so the system can track batch-related commit behavior per release.
  • Refactor

    • Commit handling is now version-aware: newer versions include accumulated batch costs in commit reports, while older versions preserve legacy cost reporting. Initialization of the new version metadata is included for supported releases.

The fix in 4a0731e changed commit_batch to return accumulated batch
costs instead of discarding them. This affects cost calculations which
need to be consistent per protocol version.

- V1/V2: commit version 0 — discard batch costs (legacy behavior)
- V3: commit version 1 — preserve accumulated batch costs

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

coderabbitai Bot commented Mar 10, 2026

Copy link
Copy Markdown
Contributor

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: f58701c1-79a0-4fe1-8431-e45a2d65b7b6

📥 Commits

Reviewing files that changed from the base of the PR and between 041ed2c and 460c1a1.

📒 Files selected for processing (5)
  • grovedb-version/src/version/merk_versions.rs
  • grovedb-version/src/version/v1.rs
  • grovedb-version/src/version/v2.rs
  • grovedb-version/src/version/v3.rs
  • merk/src/merk/mod.rs

📝 Walkthrough

Walkthrough

Adds a new nested version struct MerkBatchVersions to Merk versioning, extends MerkAverageCaseCostsVersions with sum_tree_estimated_size, initializes the new field in v1–v3, and makes commit version-aware by passing grove_version through apply paths and using it in Merk::commit to conditionally propagate batch costs.

Changes

Cohort / File(s) Summary
Version definitions
grovedb-version/src/version/merk_versions.rs
Added pub struct MerkBatchVersions { pub commit: FeatureVersion } and added sum_tree_estimated_size: FeatureVersion to MerkAverageCaseCostsVersions. MerkVersions now includes batch: MerkBatchVersions.
Version constants (v1/v2/v3)
grovedb-version/src/version/v1.rs, grovedb-version/src/version/v2.rs, grovedb-version/src/version/v3.rs
Imported MerkBatchVersions and initialized merk_versions.batch in GROVE_V1/V2/V3 (v1/v2 commit = 0, v3 commit = 1) alongside existing average_case_costs initialization.
Commit callsite update
merk/src/merk/apply.rs
Updated callsite in apply_unchecked to pass an additional grove_version argument into commit(...).
Commit implementation & API
merk/src/merk/mod.rs
Merk::commit signature now accepts grove_version: &GroveVersion. Commit logic conditionally preserves or discards accumulated batch costs depending on grove_version.merk_versions.batch.commit >= 1.

Sequence Diagram(s)

sequenceDiagram
    participant Caller as Caller
    participant Apply as Merk::apply_unchecked
    participant Merk as Merk::commit
    participant GV as GroveVersion
    participant Cost as CostAccumulator

    Caller->>Apply: invoke apply_unchecked(key_updates, aux, ...)
    Activate Apply
    Apply->>Merk: commit(key_updates, aux, options, old_specialized_cost, grove_version)
    Activate Merk
    Merk->>GV: read merk_versions.batch.commit
    alt GV.batch.commit >= 1
        Merk->>Cost: preserve and add accumulated batch costs
    else GV.batch.commit < 1
        Merk->>Cost: discard batch costs (legacy)
    end
    Merk-->>Apply: return CommitResult (with cost info)
    Deactivate Merk
    Apply-->>Caller: return result
    Deactivate Apply
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 I hopped through code with a curious twitch,
A batch version planted — a small, tidy stitch.
Now commits look to versions before they relay,
Old paths stay gentle, new paths keep the pay.

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'fix: version-gate commit_batch accumulated costs' accurately describes the main change: implementing version-gating for commit_batch cost handling based on protocol version.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% 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 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/version-gate-commit-batch-costs

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.

@codecov

codecov Bot commented Mar 10, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 90.84%. Comparing base (2c9117c) to head (460c1a1).
⚠️ Report is 1 commits behind head on develop.

Additional details and impacted files
@@           Coverage Diff            @@
##           develop     #637   +/-   ##
========================================
  Coverage    90.84%   90.84%           
========================================
  Files          182      182           
  Lines        51772    51781    +9     
========================================
+ Hits         47034    47043    +9     
  Misses        4738     4738           
Components Coverage Δ
grovedb-core 89.04% <ø> (ø)
merk 91.94% <100.00%> (+<0.01%) ⬆️
storage 86.36% <ø> (ø)
commitment-tree 96.41% <ø> (ø)
mmr 96.72% <ø> (ø)
bulk-append-tree 90.85% <ø> (ø)
element 97.56% <ø> (ø)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Access path is now grove_version.merk_versions.batch.commit
instead of grove_version.merk_versions.commit.commit.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

@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.

Actionable comments posted: 1

Caution

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

⚠️ Outside diff range comments (1)
merk/src/merk/mod.rs (1)

381-388: ⚠️ Potential issue | 🟠 Major

Fix error wrapping at line 505 and confirm API break acceptability.

Line 505 violates the error-wrapping guideline: .map_err(StorageError) should be .map_err(|e| Error::CorruptedData(format!("storage commit failed: {}", e))) to provide context.

Additionally, this PR adds grove_version: &GroveVersion as a required parameter to the public Merk::commit method—a breaking change. If 4.x compatibility is a requirement, this needs an explicit migration path in the release notes and semver bump confirmation.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@merk/src/merk/mod.rs` around lines 381 - 388, The commit method's error
handling incorrectly uses .map_err(StorageError) on the storage commit call;
change it to map the error into a contextual Error variant such as
Error::CorruptedData with a message like "storage commit failed: {e}" (i.e.,
.map_err(|e| Error::CorruptedData(format!("storage commit failed: {}", e))))
inside the pub fn commit(...) implementation to preserve context; also note that
adding grove_version: &GroveVersion to the public Merk::commit signature is an
API-breaking change—confirm a semver bump and add a migration note in the
release notes documenting the new parameter (or provide a compatibility shim)
before merging.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@merk/src/merk/mod.rs`:
- Line 505: The call to self.storage.commit_batch(batch) currently maps all
failures to StorageError, losing call-site context; change the mapping to wrap
the error with a descriptive message (e.g., via .map_err(|e|
Error::CorruptedData(format!("commit_batch failed: {}", e)))) so the returned
error includes that it originated from commit_batch; update the binding
commit_result (or its use) to use this contextualized map_err instead of
StorageError.

---

Outside diff comments:
In `@merk/src/merk/mod.rs`:
- Around line 381-388: The commit method's error handling incorrectly uses
.map_err(StorageError) on the storage commit call; change it to map the error
into a contextual Error variant such as Error::CorruptedData with a message like
"storage commit failed: {e}" (i.e., .map_err(|e|
Error::CorruptedData(format!("storage commit failed: {}", e)))) inside the pub
fn commit(...) implementation to preserve context; also note that adding
grove_version: &GroveVersion to the public Merk::commit signature is an
API-breaking change—confirm a semver bump and add a migration note in the
release notes documenting the new parameter (or provide a compatibility shim)
before merging.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 2deee038-c69f-428f-a914-ccf6bc887960

📥 Commits

Reviewing files that changed from the base of the PR and between 2c9117c and 041ed2c.

📒 Files selected for processing (6)
  • grovedb-version/src/version/merk_versions.rs
  • grovedb-version/src/version/v1.rs
  • grovedb-version/src/version/v2.rs
  • grovedb-version/src/version/v3.rs
  • merk/src/merk/apply.rs
  • merk/src/merk/mod.rs

Comment thread merk/src/merk/mod.rs
.commit_batch(batch)
.map_err(StorageError)
.add_cost(cost)
let commit_result = self.storage.commit_batch(batch).map_err(StorageError);

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.

⚠️ Potential issue | 🟡 Minor

Add call-site context before returning commit_batch failures.

This new path collapses the final batch flush failure into a bare StorageError, which makes it much harder to tell from logs that the error came from commit_batch rather than earlier tree work.

🛠️ Proposed fix
-        let commit_result = self.storage.commit_batch(batch).map_err(StorageError);
+        let commit_result = self
+            .storage
+            .commit_batch(batch)
+            .map_err(|e| Error::CorruptedData(format!("commit_batch failed: {}", e)));
As per coding guidelines, "Wrap errors with context using `.map_err(|e| Error::CorruptedData(format!("context: {}", e)))` pattern in Rust source files".
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
let commit_result = self.storage.commit_batch(batch).map_err(StorageError);
let commit_result = self
.storage
.commit_batch(batch)
.map_err(|e| Error::CorruptedData(format!("commit_batch failed: {}", e)));
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@merk/src/merk/mod.rs` at line 505, The call to
self.storage.commit_batch(batch) currently maps all failures to StorageError,
losing call-site context; change the mapping to wrap the error with a
descriptive message (e.g., via .map_err(|e|
Error::CorruptedData(format!("commit_batch failed: {}", e)))) so the returned
error includes that it originated from commit_batch; update the binding
commit_result (or its use) to use this contextualized map_err instead of
StorageError.

@QuantumExplorer
QuantumExplorer merged commit 3e42bc0 into develop Mar 10, 2026
9 of 10 checks passed
@QuantumExplorer
QuantumExplorer deleted the fix/version-gate-commit-batch-costs branch March 10, 2026 03:18
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