Skip to content

Commit 73697a8

Browse files
feat(grovedb): wire ProvableSumTree through insert/read/batch paths
Phase 3 of the ProvableSumTree feature — wires the variant through the extension traits, cost calculator, reconstruction helper, batch propagation, and read-path subtree validation so that direct insertion, nested aggregation, and child-sum mutation behave correctly end-to-end. Phase 1 (commit c95cf74) added the variant and its twins; Phase 2 (commit 3364f08) introduced node_hash_with_sum and the proof Node family. The "behave like SumTree" fallback Phase 1 leaned on covered most surfaces but several dispatch sites guarded subsequent operations through explicit per-variant match arms — those sites would silently drop ProvableSumTree or fail to traverse into it. Phase 3 fills each in deliberately. EXTENSION TRAITS — merk/src/element/tree_type.rs ElementTreeTypeExtensions had six trait methods that enumerated tree variants explicitly: root_key_and_tree_type_owned, root_key_and_tree_type, tree_flags_and_type, tree_type, maybe_tree_type, tree_feature_type. Each was missing its ProvableSumTree arm — get_feature_type was the only one already wired (Phase 1). Adding the missing arms unblocks callers across get, batch, and visualize that thread tree types through these helpers to decide layout, hashing, and aggregate-data extraction. tree_feature_type now maps ProvableSumTree -> ProvableSummedMerkNode(sum) explicitly, matching the parallel ProvableCountedMerkNode wiring. COST CALCULATOR — merk/src/element/costs.rs get_specialized_cost, the layered_value_byte_cost path in specialized_costs_for_key_value, the layered_value_defined_cost type filter, and the value_defined_cost dispatch all enumerated the eight Merk-tree variants and would have either returned None or mis-sized a ProvableSumTree element. Added explicit ProvableSumTree => SUM_TREE_COST_SIZE arms (parity with SumTree as established in Phase 1) and the matching LayeredValueDefinedCost branch. RECONSTRUCTION — merk/src/element/reconstruct.rs ElementReconstructExtensions::reconstruct_with_root_key, used by batch propagation to rebuild a tree element after a root-key update, returned None for ProvableSumTree. Added the arm that pulls aggregate_data.as_sum_i64() into Element::ProvableSumTree(root, sum, flags); without this, batch operations that mutated a ProvableSumTree subtree would lose their tree element entirely during the parent's upward propagation. as_sum_i64 already handles the AggregateData::ProvableSum case (Phase 2). BATCH PROPAGATION — grovedb/src/batch/mod.rs The InsertTreeWithRootHash else-if chain that transcribes a Merk-tree mutation into the appropriate root-hash-bearing operation enumerated each tree-element variant explicitly. ProvableSumTree was missing, so a batch that mutated a ProvableSumTree subtree would fall through to the CommitmentTree arm — wrong shape entirely. Mirrored the ProvableCountSumTree arm directly. The accompanying tree-cost match list above (used by the apply_batch storage-cost callback) was also missing the variant. READ-PATH SUBTREE VALIDATION — grovedb/src/operations/get/mod.rs check_subtree_exists rejected paths whose final segment resolved to a ProvableSumTree because the variant wasn't in its accepted-tree match list. This would have broken every query that traversed INTO a ProvableSumTree. TESTS — grovedb/src/tests/provable_sum_tree_tests.rs Ten tests covering Phase 3's externally-observable surface: - Round-trip insert/read with aggregate-sum tracking. - Aggregation across mixed positive/negative/zero values + i64::MIN/ i64::MAX extremes. - Root-hash divergence vs a plain SumTree with identical children (the Phase 2 cornerstone, verified end-to-end via open_transactional_merk_at_path). - Nested ProvableSumTree[A] -> ProvableSumTree[B] aggregate propagation; mutation of B's children shifts the grovedb root hash. - Wrapper interactions: NonCounted(ProvableSumTree) contributes 0 to a CountTree parent; NotSummed(ProvableSumTree) contributes 0 to a SumTree parent; the wrapped tree's own aggregate is preserved (verified via get_raw, which retains the wrapper byte). - Deleting a SumItem child shifts the ProvableSumTree root hash because the aggregate sum is hash-bound. - Direct insert of a ProvableSumTree built from an existing template. The wrapper round-trip tests use db.get_raw rather than db.get because db.get strips wrappers via into_underlying — by design. Workspace cargo test --all-features green: 2891 tests passing (was 2881 in Phase 2 + 10 new), zero failures. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 46466d1 commit 73697a8

7 files changed

Lines changed: 760 additions & 0 deletions

File tree

grovedb/src/batch/mod.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2519,6 +2519,7 @@ where
25192519
| Element::CountSumTree(..)
25202520
| Element::ProvableCountTree(..)
25212521
| Element::ProvableCountSumTree(..)
2522+
| Element::ProvableSumTree(..)
25222523
| Element::CommitmentTree(..)
25232524
| Element::MmrTree(..)
25242525
| Element::BulkAppendTree(..)
@@ -2827,6 +2828,20 @@ impl GroveDb {
28272828
..,
28282829
flags,
28292830
) = element
2831+
{
2832+
*mutable_occupied_entry =
2833+
GroveOp::InsertTreeWithRootHash {
2834+
hash: root_hash,
2835+
root_key: calculated_root_key,
2836+
flags: flags.clone(),
2837+
aggregate_data,
2838+
non_counted,
2839+
not_summed,
2840+
}
2841+
} else if let Element::ProvableSumTree(
2842+
..,
2843+
flags,
2844+
) = element
28302845
{
28312846
*mutable_occupied_entry =
28322847
GroveOp::InsertTreeWithRootHash {

grovedb/src/operations/get/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,7 @@ impl GroveDb {
403403
| Ok(Element::CountSumTree(..))
404404
| Ok(Element::ProvableCountTree(..))
405405
| Ok(Element::ProvableCountSumTree(..))
406+
| Ok(Element::ProvableSumTree(..))
406407
| Ok(Element::CommitmentTree(..))
407408
| Ok(Element::MmrTree(..))
408409
| Ok(Element::BulkAppendTree(..))

grovedb/src/tests/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ mod provable_count_sum_tree_tests;
3939
mod provable_count_tree_comprehensive_test;
4040
mod provable_count_tree_structure_test;
4141
mod provable_count_tree_test;
42+
mod provable_sum_tree_tests;
4243
mod query_result_type_tests;
4344
mod reference_path_tests;
4445
mod replication_session_tests;

0 commit comments

Comments
 (0)