feat: ranked aggregate indexes with provable top-K queries (protocol v14) - #4266
feat: ranked aggregate indexes with provable top-K queries (protocol v14)#4266QuantumExplorer wants to merge 8 commits into
Conversation
…l v14
Contracts can now declare that an index's groups are rankable by an
aggregate (rankedCountable / rankedSummable / rankedAverageable, each
requiring its range* counterpart), upgrading the index's terminal
property-name tree to a GroveDB indexed tree (ProvableCountIndexedTree /
ProvableSumIndexedTree / ProvableCountProvableSumIndexedTree) whose
per-axis ordered secondaries are maintained on every document write.
Queries of the form
SELECT AVG(grade) GROUP BY restaurantId HAVING AVG(grade) IN TOP(5)
are served in O(log n + k) with proofs, over the existing
GetDocumentsRequestV1 wire surface (the only proto change is the
additive RankedEntries response message).
- rs-dpp: meta-schema v3 grammar + validation (single-property,
non-unique indexes only; flags immutable on contract update), gated
on document_type_schema >= 3 so pre-v14 contracts cannot declare it
- rs-drive: indexed-tree construction at contract registration,
secondary maintenance through the normal batch write path, cost
estimation, the drive_document_ranked_query family and
verify/document_ranked
- rs-drive-abci: HAVING ranking routing, feature-gated so protocol v13
nodes keep rejecting HAVING and mixed-version networks agree
- rs-drive-proof-verifier + rs-sdk: DocumentRankedEntries::fetch with
proof verification bound to the signed app hash
- rs-platform-version: protocol v14, behaviorally identical to v13
until a contract uses the new grammar
- grovedb pinned to develop 4c6720b, which includes the indexed-tree
family (grovedb #657) plus the subset-verification regression fix and
verify-only proof gating shipped via grovedb #781
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
📝 WalkthroughWalkthroughProtocol v14 adds ranked aggregate indexes and ChangesRanked aggregate contracts and versioning
Ranked index storage
Ranked query execution
Proofs and SDK integration
Compatibility and generated support
Estimated code review effort: 5 (Critical) | ~120 minutes Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
|
🔍 Review in progress — actively reviewing now (commit 2404e74) |
There was a problem hiding this comment.
Actionable comments posted: 8
🧹 Nitpick comments (7)
packages/rs-drive/src/query/drive_document_ranked_query/tests.rs (1)
1234-1280: 🚀 Performance & Scalability | 🔵 Trivial | 💤 Low valueConfirm the exhaustive bit sweep keeps an acceptable test runtime.
The loop runs
8 * proof.len()full proof verifications. For a proof of a few hundred bytes this is several thousand verifications, and debug-profile CI amplifies the cost. If the measured runtime is high, reduce the sweep to a deterministic sample of byte offsets and keep the "some mutations verify with a diverged root" sanity check.🤖 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 `@packages/rs-drive/src/query/drive_document_ranked_query/tests.rs` around lines 1234 - 1280, Measure the runtime of the exhaustive mutation loop in a_tampered_proof_never_verifies_to_the_honest_root_hash; if it is excessive, replace the full 8 * proof.len() sweep with a deterministic sample of byte offsets and bit positions. Preserve tampering coverage and the verified_at_all > 0 sanity check so at least some mutations must verify to a divergent root.packages/rs-drive/src/query/drive_document_ranked_query/mode_detection.rs (1)
44-56: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winUse
DriveError::UnknownVersionMismatchfor the unknown method version.The unknown-version arm returns
QuerySyntaxError::Unsupported. In rs-drive-abci that maps to a client-visible query rejection, so a node misconfiguration is reported as a malformed request. The sibling ranked dispatcherDriveDocumentRankedQuery::verify_ranked_top_k_proofusesDriveError::UnknownVersionMismatchfor the same condition. Align the two so version faults stay internal errors.♻️ Proposed change
0 => detect_ranked_mode_v0(select, group_by, having, where_clauses, pagination), - version => Err(Error::Query(QuerySyntaxError::Unsupported(format!( - "detect_ranked_mode: unknown method version {version}; only 0 is supported" - )))), + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "detect_ranked_mode".to_string(), + known_versions: vec![0], + received: version, + })),Add
use crate::error::drive::DriveError;to the imports.🤖 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 `@packages/rs-drive/src/query/drive_document_ranked_query/mode_detection.rs` around lines 44 - 56, Update the unknown-version arm in the ranked-mode dispatcher to return DriveError::UnknownVersionMismatch instead of QuerySyntaxError::Unsupported, matching DriveDocumentRankedQuery::verify_ranked_top_k_proof. Add the required crate::error::drive::DriveError import and preserve the supported version-0 dispatch.packages/rs-drive/src/query/mod.rs (1)
886-898: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winPreserve the underlying
OrderClauseparse error.
QuerySyntaxError::InvalidOrderByPropertiesonly takes&'static str, butOrderClause::from_componentsreturns detailed failures such as non-text fields or invalidasc/descvalues. Add aStringpayload variant here so each rejected clause can report its actual reason and index.🤖 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 `@packages/rs-drive/src/query/mod.rs` around lines 886 - 898, Update the order_by parsing flow around OrderClause::from_components to preserve its detailed parse error, including the rejected clause’s reason and index, instead of replacing it with a static InvalidOrderByProperties message. Add a String-carrying QuerySyntaxError variant and map the underlying error into it while keeping the existing non-array validation unchanged.packages/dapi-grpc/protos/platform/v0/platform.proto (1)
1349-1357: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueAdd the ranked shapes to the
GetDocumentsResponseV1wire-shape table.The message-level docstring lists one row per
select×group_by×provecombination. It has no row for the ranked path. Add the ranked rows so the table stays the single reference for response routing.📝 Suggested docstring rows
// - `having=RANKING` (no prove) → `result.data.ranked.entries`. // - `having=RANKING` (prove) → `result.proof`.🤖 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 `@packages/dapi-grpc/protos/platform/v0/platform.proto` around lines 1349 - 1357, Update the GetDocumentsResponseV1 message-level wire-shape docstring to add rows for having=RANKING without prove routing to result.data.ranked.entries and having=RANKING with prove routing to result.proof. Keep the existing table entries unchanged and place the new rows with the other select/group_by/prove response combinations.packages/rs-drive/src/fees/op.rs (1)
1095-1102: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueConsider canonicalizing
ranked_axesbefore building the TLV.The mapped list is passed to grovedb exactly as the caller supplied it. grovedb's
validate_pcpsit_axesthen rejects an unsorted or duplicated list with an error. Sorting by tag and de-duplicating here would make the helper tolerant of caller ordering, at negligible cost for a list of at most three entries.🤖 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 `@packages/rs-drive/src/fees/op.rs` around lines 1095 - 1102, Canonicalize the axes in the TreeType::ProvableCountProvableSumIndexedTree branch before passing them to Self::for_known_path_key_empty_provable_count_provable_sum_indexed_tree: sort the mapped entries by axis tag and remove duplicate tags. Preserve the existing None values and storage_flags while ensuring the resulting ranked_axes list is ordered and unique for grovedb validation.packages/rs-drive/src/drive/contract/update/update_contract/v0/mod.rs (1)
484-537: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winReuse the generic indexed-tree helper to remove the duplicated dispatch.
The existing-doctype branch above (Lines 358-368) already resolves the same pair and delegates to
batch_insert_empty_index_tree_if_not_exists, which handles every tree variant and carriesranked_axes. This branch repeats the whole match, and it is a near-copy of the dispatch inpackages/rs-drive/src/drive/contract/insert/insert_contract/v0/mod.rs. Three copies of the same table must stay in lock-step, and a missed arm produces an on-disk layout that differs between fresh insert and contract update. Consider collapsing this branch onto the same helper.🤖 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 `@packages/rs-drive/src/drive/contract/update/update_contract/v0/mod.rs` around lines 484 - 537, Replace the TreeType match in the new-doctype branch with the existing generic indexed-tree helper used by the existing-doctype path, `batch_insert_empty_index_tree_if_not_exists`. Pass through `type_path`, `KeyRef(index_bytes)`, `ranked_axes`, storage flags, batch operations, and `drive_version`, preserving the helper’s handling for every tree variant.packages/rs-drive/src/drive/contract/insert/insert_contract/v0/mod.rs (1)
440-455: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueConsider routing the single-axis arms through the validating dispatcher.
The
ProvableCountIndexedTreeandProvableSumIndexedTreearms discardranked_axes. The element constructors do not need the TLV, so the written tree is correct today. HoweverLowLevelDriveOperation::for_known_path_key_empty_indexed_treeadditionally asserts that the resolved axis set matches the variant ([IndexAxis::Count]/[IndexAxis::Sum]). Calling the per-variant helpers directly skips that assertion, so a future resolver change that pairs, for example,ProvableCountIndexedTreewith[IndexAxis::Avg]would silently create a tree whose secondary is keyed on the wrong aggregate. Routing all three arms through the dispatcher keeps the invariant enforced in one place.🤖 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 `@packages/rs-drive/src/drive/contract/insert/insert_contract/v0/mod.rs` around lines 440 - 455, Update the ProvableCountIndexedTree and ProvableSumIndexedTree arms in the tree insertion dispatch to call LowLevelDriveOperation::for_known_path_key_empty_indexed_tree, passing ranked_axes and the existing insertion context. Route all three indexed-tree variants through this validating dispatcher, preserving the current per-variant construction behavior while enforcing axis-to-variant validation.
🤖 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.
Inline comments:
In `@packages/rs-dpp/schema/meta_schemas/document/v3/document-meta.json`:
- Around line 3-4: Update the v3 meta-schema header’s $comment to identify it as
the v3 document meta-schema, state that it activates with protocol v14 (the
corresponding contract version), and correct the release-specific freeze
wording. Verify the $id compatibility requirement separately; preserve the
existing v1 URL if it is intentionally frozen, and document that it is a
compatibility identifier rather than the file path.
In `@packages/rs-dpp/src/validation/meta_validators/mod.rs`:
- Around line 247-254: Correct the stale v3 document meta-schema comments in
packages/rs-dpp/src/validation/meta_validators/mod.rs (lines 247-254) and
packages/rs-platform-version/src/version/dpp_versions/dpp_contract_versions/v6.rs
(line 54) so they accurately describe the existing rankedCountable,
rankedSummable, rankedAverageable, and dependentRequired validation; remove the
incorrect v6 claim rather than changing schema behavior.
In `@packages/rs-drive-proof-verifier/src/lib.rs`:
- Around line 17-23: Update the rustdoc link in the public re-export
documentation for DocumentRankedEntries to reference the public
verify_ranked_top_k_proof re-export rather than the private
proof::document_ranked path, using the existing public symbol without changing
the surrounding documentation.
In
`@packages/rs-drive/src/drive/contract/insert/insert_contract/v0/tests/ranked_index_e2e_tests.rs`:
- Around line 232-238: Update expected_avg_fixed_point to use Euclidean division
via div_euclid on the scaled sum and count, matching the documented
toward-negative-infinity rounding for negative sums while preserving the
existing calculation and types.
In `@packages/rs-drive/src/drive/document/mod.rs`:
- Around line 56-58: Gate all imports or nearest parent module declarations that
reference ranked_index_tree_type behind the server feature, including
estimated_sum_trees_for_value_tree_type, non-server contract index
insert/update/delete code, and
batch_insert_empty_provable_count_provable_sum_indexed_tree. Ensure non-server
feature builds no longer compile these dependent paths while preserving their
existing server-only behavior.
In
`@packages/rs-drive/src/drive/document/update/internal/update_document_for_contract_operations/v0/mod.rs`:
- Around line 495-503: Update the re-materialization logic around
batch_insert_empty_index_tree_if_not_exists to call
property_name_tree_type_and_ranked_axes(current_index_level) instead of
property_name_tree_type_for_index_level. Ensure the terminal property-name level
of a single-property ranked index is recreated with its indexed tree type and
ranked_axes, while preserving normal-tree behavior for non-ranked levels.
In `@packages/rs-drive/src/query/drive_document_ranked_query/execute_top_k.rs`:
- Around line 135-167: Update execute_top_k_with_proof to detect grovedb’s
dedicated empty-tree error variant, when available, and map it to the
appropriate typed Drive-specific error before the generic Error::GroveDB
conversion. Preserve generic grovedb failures through Error::GroveDB, and keep
the existing empty-ranking limitation documentation without matching
error-message text.
In `@packages/rs-platform-version/Cargo.toml`:
- Line 14: Update the grovedb-version dependency revision in Cargo.toml to a
valid commit or tag resolvable from the configured GroveDB repository, while
retaining the intended GroveDB changes.
---
Nitpick comments:
In `@packages/dapi-grpc/protos/platform/v0/platform.proto`:
- Around line 1349-1357: Update the GetDocumentsResponseV1 message-level
wire-shape docstring to add rows for having=RANKING without prove routing to
result.data.ranked.entries and having=RANKING with prove routing to
result.proof. Keep the existing table entries unchanged and place the new rows
with the other select/group_by/prove response combinations.
In `@packages/rs-drive/src/drive/contract/insert/insert_contract/v0/mod.rs`:
- Around line 440-455: Update the ProvableCountIndexedTree and
ProvableSumIndexedTree arms in the tree insertion dispatch to call
LowLevelDriveOperation::for_known_path_key_empty_indexed_tree, passing
ranked_axes and the existing insertion context. Route all three indexed-tree
variants through this validating dispatcher, preserving the current per-variant
construction behavior while enforcing axis-to-variant validation.
In `@packages/rs-drive/src/drive/contract/update/update_contract/v0/mod.rs`:
- Around line 484-537: Replace the TreeType match in the new-doctype branch with
the existing generic indexed-tree helper used by the existing-doctype path,
`batch_insert_empty_index_tree_if_not_exists`. Pass through `type_path`,
`KeyRef(index_bytes)`, `ranked_axes`, storage flags, batch operations, and
`drive_version`, preserving the helper’s handling for every tree variant.
In `@packages/rs-drive/src/fees/op.rs`:
- Around line 1095-1102: Canonicalize the axes in the
TreeType::ProvableCountProvableSumIndexedTree branch before passing them to
Self::for_known_path_key_empty_provable_count_provable_sum_indexed_tree: sort
the mapped entries by axis tag and remove duplicate tags. Preserve the existing
None values and storage_flags while ensuring the resulting ranked_axes list is
ordered and unique for grovedb validation.
In `@packages/rs-drive/src/query/drive_document_ranked_query/mode_detection.rs`:
- Around line 44-56: Update the unknown-version arm in the ranked-mode
dispatcher to return DriveError::UnknownVersionMismatch instead of
QuerySyntaxError::Unsupported, matching
DriveDocumentRankedQuery::verify_ranked_top_k_proof. Add the required
crate::error::drive::DriveError import and preserve the supported version-0
dispatch.
In `@packages/rs-drive/src/query/drive_document_ranked_query/tests.rs`:
- Around line 1234-1280: Measure the runtime of the exhaustive mutation loop in
a_tampered_proof_never_verifies_to_the_honest_root_hash; if it is excessive,
replace the full 8 * proof.len() sweep with a deterministic sample of byte
offsets and bit positions. Preserve tampering coverage and the verified_at_all >
0 sanity check so at least some mutations must verify to a divergent root.
In `@packages/rs-drive/src/query/mod.rs`:
- Around line 886-898: Update the order_by parsing flow around
OrderClause::from_components to preserve its detailed parse error, including the
rejected clause’s reason and index, instead of replacing it with a static
InvalidOrderByProperties message. Add a String-carrying QuerySyntaxError variant
and map the underlying error into it while keeping the existing non-array
validation unchanged.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 6654c4f5-c86c-499b-b898-399c5707474d
⛔ Files ignored due to path filters (1)
Cargo.lockis excluded by!**/*.lock
📒 Files selected for processing (94)
packages/dapi-grpc/protos/platform/v0/platform.protopackages/rs-dpp/Cargo.tomlpackages/rs-dpp/schema/meta_schemas/document/v3/document-meta.jsonpackages/rs-dpp/src/data_contract/document_type/class_methods/try_from_schema/v0/mod.rspackages/rs-dpp/src/data_contract/document_type/class_methods/try_from_schema/v1/mod.rspackages/rs-dpp/src/data_contract/document_type/class_methods/try_from_schema/v2/mod.rspackages/rs-dpp/src/data_contract/document_type/index/mod.rspackages/rs-dpp/src/data_contract/document_type/index/random_index.rspackages/rs-dpp/src/data_contract/document_type/index_level/find_first_change.rspackages/rs-dpp/src/data_contract/document_type/index_level/mod.rspackages/rs-dpp/src/data_contract/document_type/methods/validate_update/v0/mod.rspackages/rs-dpp/src/data_contract/factory/v0/mod.rspackages/rs-dpp/src/data_contract/methods/registration_cost/v1/mod.rspackages/rs-dpp/src/validation/meta_validators/mod.rspackages/rs-drive-abci/Cargo.tomlpackages/rs-drive-abci/src/query/document_query/v1/compute_aggregate_mode_and_check_limit/mod.rspackages/rs-drive-abci/src/query/document_query/v1/compute_aggregate_mode_and_check_limit/v0/mod.rspackages/rs-drive-abci/src/query/document_query/v1/compute_aggregate_mode_and_check_limit/v1/mod.rspackages/rs-drive-abci/src/query/document_query/v1/mod.rspackages/rs-drive-abci/src/query/document_query/v1/tests.rspackages/rs-drive-proof-verifier/src/lib.rspackages/rs-drive-proof-verifier/src/proof.rspackages/rs-drive-proof-verifier/src/proof/document_ranked.rspackages/rs-drive/Cargo.tomlpackages/rs-drive/src/cache/system_contracts.rspackages/rs-drive/src/drive/contract/estimation_costs/mod.rspackages/rs-drive/src/drive/contract/insert/insert_contract/v0/mod.rspackages/rs-drive/src/drive/contract/insert/insert_contract/v0/tests/mod.rspackages/rs-drive/src/drive/contract/insert/insert_contract/v0/tests/ranked_index_e2e_tests.rspackages/rs-drive/src/drive/contract/update/update_contract/v0/mod.rspackages/rs-drive/src/drive/document/delete/remove_indices_for_index_level_for_contract_operations/v1/mod.rspackages/rs-drive/src/drive/document/delete/remove_indices_for_top_index_level_for_contract_operations/v1/mod.rspackages/rs-drive/src/drive/document/estimation_costs/estimated_sum_trees_for_value_tree_type.rspackages/rs-drive/src/drive/document/insert/add_indices_for_index_level_for_contract_operations/v1/mod.rspackages/rs-drive/src/drive/document/insert/add_indices_for_top_index_level_for_contract_operations/v1/mod.rspackages/rs-drive/src/drive/document/mod.rspackages/rs-drive/src/drive/document/ranked_index_tree_type.rspackages/rs-drive/src/drive/document/update/internal/update_document_for_contract_operations/v0/mod.rspackages/rs-drive/src/fees/op.rspackages/rs-drive/src/query/drive_document_count_query/tests.rspackages/rs-drive/src/query/drive_document_ranked_query/drive_dispatcher.rspackages/rs-drive/src/query/drive_document_ranked_query/execute_top_k.rspackages/rs-drive/src/query/drive_document_ranked_query/executors/mod.rspackages/rs-drive/src/query/drive_document_ranked_query/executors/top_k_no_proof.rspackages/rs-drive/src/query/drive_document_ranked_query/executors/top_k_proof.rspackages/rs-drive/src/query/drive_document_ranked_query/index_picker.rspackages/rs-drive/src/query/drive_document_ranked_query/mod.rspackages/rs-drive/src/query/drive_document_ranked_query/mode_detection.rspackages/rs-drive/src/query/drive_document_ranked_query/path.rspackages/rs-drive/src/query/drive_document_ranked_query/tests.rspackages/rs-drive/src/query/drive_document_sum_query/tests.rspackages/rs-drive/src/query/mod.rspackages/rs-drive/src/util/grove_operations/batch_insert_empty_provable_count_indexed_tree/mod.rspackages/rs-drive/src/util/grove_operations/batch_insert_empty_provable_count_indexed_tree/v0/mod.rspackages/rs-drive/src/util/grove_operations/batch_insert_empty_provable_count_provable_sum_indexed_tree/mod.rspackages/rs-drive/src/util/grove_operations/batch_insert_empty_provable_count_provable_sum_indexed_tree/v0/mod.rspackages/rs-drive/src/util/grove_operations/batch_insert_empty_provable_sum_indexed_tree/mod.rspackages/rs-drive/src/util/grove_operations/batch_insert_empty_provable_sum_indexed_tree/v0/mod.rspackages/rs-drive/src/util/grove_operations/batch_insert_empty_tree_if_not_exists/mod.rspackages/rs-drive/src/util/grove_operations/batch_insert_empty_tree_if_not_exists/v0/mod.rspackages/rs-drive/src/util/grove_operations/grove_insert_empty_tree/v0/mod.rspackages/rs-drive/src/util/grove_operations/mod.rspackages/rs-drive/src/verify/document_ranked/mod.rspackages/rs-drive/src/verify/document_ranked/verify_ranked_top_k_proof/mod.rspackages/rs-drive/src/verify/document_ranked/verify_ranked_top_k_proof/v0/mod.rspackages/rs-drive/src/verify/mod.rspackages/rs-drive/tests/supporting_files/contract/restaurants/restaurants-contract.jsonpackages/rs-platform-version/Cargo.tomlpackages/rs-platform-version/src/version/dpp_versions/dpp_contract_versions/mod.rspackages/rs-platform-version/src/version/dpp_versions/dpp_contract_versions/v6.rspackages/rs-platform-version/src/version/drive_abci_versions/drive_abci_query_versions/mod.rspackages/rs-platform-version/src/version/drive_abci_versions/drive_abci_query_versions/v2.rspackages/rs-platform-version/src/version/drive_versions/drive_document_method_versions/mod.rspackages/rs-platform-version/src/version/drive_versions/drive_document_method_versions/v1.rspackages/rs-platform-version/src/version/drive_versions/drive_document_method_versions/v2.rspackages/rs-platform-version/src/version/drive_versions/drive_document_method_versions/v3.rspackages/rs-platform-version/src/version/drive_versions/drive_document_method_versions/v4.rspackages/rs-platform-version/src/version/drive_versions/drive_grove_method_versions/mod.rspackages/rs-platform-version/src/version/drive_versions/drive_grove_method_versions/v1.rspackages/rs-platform-version/src/version/drive_versions/drive_verify_method_versions/mod.rspackages/rs-platform-version/src/version/drive_versions/drive_verify_method_versions/v1.rspackages/rs-platform-version/src/version/drive_versions/mod.rspackages/rs-platform-version/src/version/drive_versions/v9.rspackages/rs-platform-version/src/version/mod.rspackages/rs-platform-version/src/version/protocol_version.rspackages/rs-platform-version/src/version/v14.rspackages/rs-platform-wallet/Cargo.tomlpackages/rs-sdk-ffi/src/system/queries/path_elements.rspackages/rs-sdk/Cargo.tomlpackages/rs-sdk/src/mock/requests.rspackages/rs-sdk/src/platform/documents/document_ranked_entries.rspackages/rs-sdk/src/platform/documents/mod.rspackages/rs-sdk/src/platform/documents/ranked_proof_helpers.rspackages/wasm-sdk/src/queries/system.rs
thepastaclaw
left a comment
There was a problem hiding this comment.
Preliminary review — Codex only
The ranked storage and proof paths are extensively implemented, but three correctness issues block merge: MAX/MIN omit tied extrema, explicit false ranked flags are rejected by the meta-schema, and the committed generated gRPC clients cannot decode ranked responses. The WASM projection also needs two compatibility fixes, while several smaller documentation and test-helper issues remain.
Validated blockers were found in the Codex precheck. Sonnet is deferred until a fresh Codex revalidation clears the blocker gate.
Review provenance
- Codex reviewers:
gpt-5.6-sol— general (completed),gpt-5.6-sol— security-auditor (completed),gpt-5.6-sol— rust-quality (completed),gpt-5.6-sol— ffi-engineer (completed) - Verifier:
gpt-5.6-sol— verifier - Sonnet: not run (deferred by blocker gate)
🔴 3 blocking | 🟡 2 suggestion(s) | 💬 3 nitpick(s)
2 additional finding(s) omitted (not in diff).
🤖 Prompt for all review comments with AI agents
These findings are from an automated code review. Verify each finding against the current code and only fix it if needed.
In `packages/rs-drive/src/query/drive_document_ranked_query/mode_detection.rs`:
- [BLOCKING] packages/rs-drive/src/query/drive_document_ranked_query/mode_detection.rs:187-205: MAX and MIN omit groups tied at the extreme
The wire and Drive contracts define `HAVING COUNT(*) EQ MAX` as selecting every group whose aggregate equals the maximum scalar. This branch instead converts MAX/MIN into a directional top-K read with `k = 1`. The indexed secondary breaks equal aggregates by group key, so only one tied group is returned and the other groups satisfying the predicate are silently omitted. Reject MAX/MIN until a tie-aware primitive is available, or retrieve and prove every entry tied at the extreme.
In `packages/dapi-grpc/protos/platform/v0/platform.proto`:
- [BLOCKING] packages/dapi-grpc/protos/platform/v0/platform.proto:1349-1357: Regenerate the committed gRPC clients for ranked results
The protobuf adds `RankedEntry`, `RankedEntries`, and oneof field 5, but the maintained bindings under `packages/dapi-grpc/clients/platform/v0/` contain no ranked symbols. For example, the Node decoder's oneof still lists only `documents|counts|sums|averages` and skips field 5 as unknown, while the Web, Python, and Objective-C APIs expose no ranked accessor. A non-proof ranked response therefore loses its result when decoded by the shipped clients. Run the existing dapi-grpc generation script and commit every maintained binding.
In `packages/rs-dpp/schema/meta_schemas/document/v3/document-meta.json`:
- [BLOCKING] packages/rs-dpp/schema/meta_schemas/document/v3/document-meta.json:486-493: Explicit false ranked flags incorrectly require range axes
JSON Schema's `dependentRequired` is triggered by property presence rather than its boolean value. Consequently, `"rankedCountable": false` still requires `rangeCountable`, and `"rankedAverageable": false` still requires `rangeAverageable`. This contradicts the fields' “When true” semantics and `Index::try_from_value_map`, which parses false as an ordinary opt-out and only enforces the range prerequisite when the resolved ranked flag is true. Replace these dependencies with value-sensitive `if`/`then` conditions, or declare the optional ranked properties as `const: true` if explicit false is intentionally unsupported.
In `packages/wasm-sdk/src/queries/system.rs`:
- [SUGGESTION] packages/wasm-sdk/src/queries/system.rs:861-875: Expose indexed-tree sums through the WASM PathElement API
`PathElementWasm::from_element` obtains its JavaScript `sum` property through this function. Both `ProvableSumIndexedTree` and `ProvableCountProvableSumIndexedTree` carry an `i64` sum, but they currently fall through to `None`, so JavaScript sees a recognized indexed element type with an unexpectedly undefined aggregate. Project these sums in the same way as the corresponding non-indexed variants.
- [SUGGESTION] packages/wasm-sdk/src/queries/system.rs:20-68: Add indexed-tree runtime values to the WASM TypeScript union
The `elementType` getter now emits six values absent from `GroveElementType`: `provableSumIndexedTree`, `provableCountIndexedTree`, `provableCountProvableSumIndexedTree`, and their three `nonCounted` forms. JavaScript receives these strings, but generated TypeScript declarations claim they are impossible, making exhaustive switches and validators unsound. Add all six strings to the custom TypeScript section.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## v4.2-dev #4266 +/- ##
=============================================
- Coverage 87.52% 66.84% -20.69%
=============================================
Files 2678 27 -2651
Lines 341047 2835 -338212
=============================================
- Hits 298516 1895 -296621
+ Misses 42531 940 -41591
🚀 New features to boost your workflow:
|
- Reject MAX / MIN rankings instead of mapping them to TOP(1) / BOTTOM(1): '= MAX' selects every group tied at the extreme, which the axis secondary cannot prove (ties break by group key), so a k = 1 read would silently omit tied groups. Positional TOP(1) / BOTTOM(1) remain the single-best-ranked forms. - Meta-schema v3: the three ranked prerequisite rules are now value-sensitive if/then conditionals, so an explicit 'rankedCountable: false' no longer demands its range axis, matching the structural parser's opt-out semantics. - wasm-sdk: project the i64 sum of ProvableSumIndexedTree / ProvableCountProvableSumIndexedTree path elements and add the six indexed element-type strings to the TypeScript union. - Average fixed-point test helper now mirrors grovedb's euclidean floor; new signed-sum doctype in the restaurants fixture exercises negative averages where truncating division would disagree. - Stale v3 meta-schema header and version-table comments corrected. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…657-integration-b6f426 # Conflicts: # packages/rs-platform-version/src/version/v14.rs
Pulls in the terminal non-Merk proof-binding fix (dashpay/grovedb#782): CommitmentTree / MmrTree / BulkAppendTree / DenseTree elements reported as a query's final result are now bound to the parent value_hash, so a malicious node can no longer serve forged aggregates (e.g. a wrong shielded note count) under a genuine root hash. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…657-integration-b6f426 # Conflicts: # packages/rs-drive/src/util/grove_operations/batch_insert_empty_tree_if_not_exists/mod.rs # packages/rs-drive/src/util/grove_operations/batch_insert_empty_tree_if_not_exists/v0/mod.rs # packages/rs-platform-version/src/version/drive_versions/drive_document_method_versions/v4.rs # packages/rs-platform-version/src/version/drive_versions/v9.rs # packages/rs-platform-version/src/version/v14.rs
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Regenerated with the repo's pinned docker toolchain (yarn workspace @dashevo/dapi-grpc build): RankedEntry / RankedEntries and the ResultData.ranked oneof arm now exist in the Node, Web, Python and Objective-C bindings; drive_pbjs.js picks the messages up through its platform.proto import. Diff is additive — the only removals are the four-variant oneof lists becoming five-variant and proto doc comments flowing into generated jsdoc. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
packages/rs-drive/src/query/drive_document_ranked_query/mode_detection.rs (1)
136-178: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winRemove
MAX/MINfrom these error messages.Both messages still advertise
MAXandMINas accepted ranking operands. Lines 191-204 now reject both kinds. A user who follows either message gets a second rejection.
- Line 142: "(
IN TOP(n),IN BOTTOM(n),EQ MAXorEQ MIN)".- Line 173: "(
TOP(n)/BOTTOM(n)/MAX/MIN)".📝 Proposed message fixes
- "ranked queries require exactly one `having` clause carrying the ranking \ - (`IN TOP(n)`, `IN BOTTOM(n)`, `EQ MAX` or `EQ MIN`); got {}. Multiple \ + "ranked queries require exactly one `having` clause carrying the ranking \ + (`IN TOP(n)` or `IN BOTTOM(n)`); got {}. Multiple \- (`TOP(n)` / `BOTTOM(n)` / `MAX` / `MIN`). Thresholds need a range walk \ + (`TOP(n)` / `BOTTOM(n)`). Thresholds need a range walk \🤖 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 `@packages/rs-drive/src/query/drive_document_ranked_query/mode_detection.rs` around lines 136 - 178, Update the two error messages in the ranked-query validation around the single-clause check and ranking operand check to advertise only the supported TOP(n) and BOTTOM(n) ranking forms; remove MAX and MIN references while preserving the existing validation behavior.packages/rs-drive/src/fees/op.rs (1)
655-694: 📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick winResolve the contradiction about indexed parents between the two dispatchers.
wrap_in_non_aggregated_for_parent_tree_typenow acceptsProvableCountIndexedTree,ProvableSumIndexedTree, andProvableCountProvableSumIndexedTreeas aggregating parents. The new zero-contribution dispatcher states the opposite at Line 865-882: indexed trees are property-name trees, never value trees, so they cannot host zero-contributing children, and it rejects them explicitly.Both functions answer the same question for the same parent role. Only one answer can be right.
If indexed parents are structurally impossible, remove the three indexed variants from these arms and let them fall to the
_arm. If they are reachable, correct the rejection text and reasoning infor_known_path_key_empty_tree_contributing_zero_to_parent. Note also that this function is described as the frozen v0 dispatcher, and pre-v14 contracts never produce indexed trees, so the added arms are unreachable for v0/v1 walkers.🤖 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 `@packages/rs-drive/src/fees/op.rs` around lines 655 - 694, Resolve the inconsistent indexed-parent handling between wrap_in_non_aggregated_for_parent_tree_type and for_known_path_key_empty_tree_contributing_zero_to_parent. Treat ProvableCountIndexedTree, ProvableSumIndexedTree, and ProvableCountProvableSumIndexedTree consistently in both dispatchers; because the frozen v0/v1 path cannot produce indexed trees and the zero-contribution dispatcher rejects them, remove these variants from the aggregating arms so they fall through to the existing fallback handling.
🧹 Nitpick comments (2)
packages/rs-drive/src/query/drive_document_ranked_query/mode_detection.rs (1)
191-253: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick winFold the direction and
kresolution into one match to drop theunreachable!.The second match repeats the
Max | Minarm only to panic. The arm is unreachable today, because the first match returns early. A future edit that moves or removes the early return turns a validation error into a panic on a request-handling path.One match over
ranking.kindthat yields(descending, k)removes the panic and keeps exhaustiveness, which is the stated goal of the current arm.🤖 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 `@packages/rs-drive/src/query/drive_document_ranked_query/mode_detection.rs` around lines 191 - 253, Combine the two ranking.kind matches into one exhaustive match that returns both descending and k. Preserve the existing Max/Min validation error, Top/Bottom n validation, operator checks, and limit checks, while removing the unreachable! arm and destructuring the resulting tuple for downstream use.packages/rs-drive/src/fees/op.rs (1)
2439-2617: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winExtend the matrix test to pin
wrap_in_non_aggregated_for_parent_tree_typeas well.The test pins every cell of
for_known_path_key_empty_tree_contributing_zero_to_parent, including the indexed rejections. It does not cover the v0 dispatcher, whose indexed-parent arms changed in this PR. Add a small loop that asserts the intended result forwrap_in_non_aggregated_for_parent_tree_typewith each indexed parent, once the contradiction noted at Line 655-694 is resolved.🤖 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 `@packages/rs-drive/src/fees/op.rs` around lines 2439 - 2617, Extend zero_contribution_dispatcher_full_matrix with a focused loop covering wrap_in_non_aggregated_for_parent_tree_type for every indexed parent type, asserting the intended result for each. Resolve the existing contradiction around the indexed-parent behavior first, then use the established dispatch/assertion patterns to pin the v0 dispatcher’s expected acceptance or rejection.
🤖 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.
Inline comments:
In `@packages/rs-drive-abci/Cargo.toml`:
- Line 85: Update the protocol v14 version mapping centered on DRIVE_VERSION_V9
so its grove_version uses GROVE_V4 rather than GROVE_V3, and update any related
protocol-v14 configuration or mapping consistently. Ensure PLATFORM_V14.drive
selects GroveDB v4 behavior at activation while leaving other protocol versions
unchanged.
In `@packages/rs-drive/src/query/having.rs`:
- Around line 146-151: Update the cross-group ranking documentation near
HavingRankingKind to state that only Equal works with Top(1)/Bottom(1), while In
works with Top(N)/Bottom(N); remove the broader scalar-comparison claim and
preserve the existing Min/Max rejection note.
---
Outside diff comments:
In `@packages/rs-drive/src/fees/op.rs`:
- Around line 655-694: Resolve the inconsistent indexed-parent handling between
wrap_in_non_aggregated_for_parent_tree_type and
for_known_path_key_empty_tree_contributing_zero_to_parent. Treat
ProvableCountIndexedTree, ProvableSumIndexedTree, and
ProvableCountProvableSumIndexedTree consistently in both dispatchers; because
the frozen v0/v1 path cannot produce indexed trees and the zero-contribution
dispatcher rejects them, remove these variants from the aggregating arms so they
fall through to the existing fallback handling.
In `@packages/rs-drive/src/query/drive_document_ranked_query/mode_detection.rs`:
- Around line 136-178: Update the two error messages in the ranked-query
validation around the single-clause check and ranking operand check to advertise
only the supported TOP(n) and BOTTOM(n) ranking forms; remove MAX and MIN
references while preserving the existing validation behavior.
---
Nitpick comments:
In `@packages/rs-drive/src/fees/op.rs`:
- Around line 2439-2617: Extend zero_contribution_dispatcher_full_matrix with a
focused loop covering wrap_in_non_aggregated_for_parent_tree_type for every
indexed parent type, asserting the intended result for each. Resolve the
existing contradiction around the indexed-parent behavior first, then use the
established dispatch/assertion patterns to pin the v0 dispatcher’s expected
acceptance or rejection.
In `@packages/rs-drive/src/query/drive_document_ranked_query/mode_detection.rs`:
- Around line 191-253: Combine the two ranking.kind matches into one exhaustive
match that returns both descending and k. Preserve the existing Max/Min
validation error, Top/Bottom n validation, operator checks, and limit checks,
while removing the unreachable! arm and destructuring the resulting tuple for
downstream use.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: b07c4bf9-773d-4b85-987f-6748f7652dd5
⛔ Files ignored due to path filters (1)
Cargo.lockis excluded by!**/*.lock
📒 Files selected for processing (50)
packages/dapi-grpc/clients/drive/v0/nodejs/drive_pbjs.jspackages/dapi-grpc/clients/platform/v0/nodejs/platform_pbjs.jspackages/dapi-grpc/clients/platform/v0/nodejs/platform_protoc.jspackages/dapi-grpc/clients/platform/v0/objective-c/Platform.pbobjc.hpackages/dapi-grpc/clients/platform/v0/objective-c/Platform.pbobjc.mpackages/dapi-grpc/clients/platform/v0/python/platform_pb2.pypackages/dapi-grpc/clients/platform/v0/web/platform_pb.d.tspackages/dapi-grpc/clients/platform/v0/web/platform_pb.jspackages/dapi-grpc/protos/platform/v0/platform.protopackages/rs-dpp/Cargo.tomlpackages/rs-dpp/schema/meta_schemas/document/v3/document-meta.jsonpackages/rs-dpp/src/data_contract/document_type/class_methods/try_from_schema/v2/mod.rspackages/rs-drive-abci/Cargo.tomlpackages/rs-drive-abci/src/query/document_query/v1/compute_aggregate_mode_and_check_limit/mod.rspackages/rs-drive-abci/src/query/document_query/v1/compute_aggregate_mode_and_check_limit/v1/mod.rspackages/rs-drive-abci/src/query/document_query/v1/conversions.rspackages/rs-drive-abci/src/query/document_query/v1/mod.rspackages/rs-drive-abci/src/query/document_query/v1/tests.rspackages/rs-drive-proof-verifier/src/lib.rspackages/rs-drive-proof-verifier/src/proof.rspackages/rs-drive-proof-verifier/src/proof/document_ranked.rspackages/rs-drive/Cargo.tomlpackages/rs-drive/src/drive/contract/insert/insert_contract/v0/tests/ranked_index_e2e_tests.rspackages/rs-drive/src/drive/document/delete/remove_indices_for_index_level_for_contract_operations/v2/mod.rspackages/rs-drive/src/drive/document/delete/remove_indices_for_top_index_level_for_contract_operations/v2/mod.rspackages/rs-drive/src/drive/document/index_level_tree_types.rspackages/rs-drive/src/drive/document/insert/add_indices_for_index_level_for_contract_operations/v2/mod.rspackages/rs-drive/src/drive/document/insert/add_indices_for_top_index_level_for_contract_operations/v2/mod.rspackages/rs-drive/src/drive/document/mod.rspackages/rs-drive/src/drive/document/update/internal/update_document_for_contract_operations/v1/mod.rspackages/rs-drive/src/fees/op.rspackages/rs-drive/src/query/drive_document_ranked_query/drive_dispatcher.rspackages/rs-drive/src/query/drive_document_ranked_query/mod.rspackages/rs-drive/src/query/drive_document_ranked_query/mode_detection.rspackages/rs-drive/src/query/drive_document_ranked_query/tests.rspackages/rs-drive/src/query/having.rspackages/rs-drive/src/util/grove_operations/batch_insert_empty_tree_if_not_exists/mod.rspackages/rs-drive/src/util/grove_operations/batch_insert_empty_tree_if_not_exists/v0/mod.rspackages/rs-drive/tests/supporting_files/contract/restaurants/restaurants-contract.jsonpackages/rs-platform-version/Cargo.tomlpackages/rs-platform-version/src/version/dpp_versions/dpp_contract_versions/v6.rspackages/rs-platform-version/src/version/drive_versions/drive_document_method_versions/v4.rspackages/rs-platform-version/src/version/drive_versions/v9.rspackages/rs-platform-version/src/version/v14.rspackages/rs-platform-wallet/Cargo.tomlpackages/rs-sdk/Cargo.tomlpackages/rs-sdk/src/platform/documents/document_query.rspackages/rs-sdk/src/platform/documents/document_ranked_entries.rspackages/rs-sdk/src/platform/documents/ranked_proof_helpers.rspackages/wasm-sdk/src/queries/system.rs
🚧 Files skipped from review as they are similar to previous changes (17)
- packages/rs-drive/Cargo.toml
- packages/rs-platform-version/src/version/dpp_versions/dpp_contract_versions/v6.rs
- packages/rs-drive/src/drive/document/mod.rs
- packages/rs-platform-version/src/version/drive_versions/v9.rs
- packages/rs-platform-version/Cargo.toml
- packages/rs-sdk/Cargo.toml
- packages/rs-platform-wallet/Cargo.toml
- packages/rs-drive-abci/src/query/document_query/v1/compute_aggregate_mode_and_check_limit/v1/mod.rs
- packages/rs-drive-abci/src/query/document_query/v1/compute_aggregate_mode_and_check_limit/mod.rs
- packages/rs-sdk/src/platform/documents/ranked_proof_helpers.rs
- packages/rs-dpp/Cargo.toml
- packages/rs-drive-proof-verifier/src/lib.rs
- packages/rs-drive-proof-verifier/src/proof/document_ranked.rs
- packages/dapi-grpc/protos/platform/v0/platform.proto
- packages/rs-drive-abci/src/query/document_query/v1/mod.rs
- packages/rs-drive-abci/src/query/document_query/v1/tests.rs
- packages/rs-sdk/src/platform/documents/document_ranked_entries.rs
GROVE_V4 gates the indexed-tree batch cleanup behaviors (overwrite inspection + delete-tree actual-type cleanup namespaces). Indexed trees only exist from protocol v14, so staying on GROVE_V3 would let a batch overwrite of a ranked index orphan its per-axis secondary storage. The gate charges one extra stored-element read per overwrite-capable op, so the latest-version fee-constant tests move up by that read while the first-version tests keep the released values — pinning that the cost change activates exactly at v14. Also narrows the HavingRightOperand ranking-operator doc to what evaluation actually accepts (Equal with Top(1)/Bottom(1), In with Top(N)/Bottom(N)). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
packages/rs-platform-version/src/version/drive_versions/v9.rs (1)
145-151: 🗄️ Data Integrity & Integration | 🔵 Trivial | 🏗️ Heavy liftAdd a regression test for the Grove version gate.
DRIVE_VERSION_V9now selectsGROVE_V4, which changes cleanup behavior for ranked-index secondary storage. Add an integration test that overwrites a ranked index in a batch and verifies that obsolete secondary storage is deleted. Also verify that the protocol v13 version does not selectGROVE_V4.As per coding guidelines, the pull request must include tests. The PR objectives state that live protocol v14 tests remain pending.
🤖 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 `@packages/rs-platform-version/src/version/drive_versions/v9.rs` around lines 145 - 151, Add an integration regression test covering the DRIVE_VERSION_V9 Grove-version gate: perform a batch overwrite of a ranked index and verify obsolete per-axis secondary storage is removed. Also assert that the protocol v13 version selects a Grove version earlier than GROVE_V4, while DRIVE_VERSION_V9 selects GROVE_V4; keep live protocol v14 coverage unchanged or pending.Source: Coding guidelines
🤖 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.
Inline comments:
In `@packages/rs-drive/src/drive/identity/update/mod.rs`:
- Line 62: Align the processing_fee expectation near the identity update test
with its explanation: either update the nearby comment to account for the full
4,040-credit increase, remove the insufficient explanation, or correct
processing_fee if the increase is unintended.
---
Nitpick comments:
In `@packages/rs-platform-version/src/version/drive_versions/v9.rs`:
- Around line 145-151: Add an integration regression test covering the
DRIVE_VERSION_V9 Grove-version gate: perform a batch overwrite of a ranked index
and verify obsolete per-axis secondary storage is removed. Also assert that the
protocol v13 version selects a Grove version earlier than GROVE_V4, while
DRIVE_VERSION_V9 selects GROVE_V4; keep live protocol v14 coverage unchanged or
pending.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 13e93bf3-4f42-4286-9369-de1333490a08
📒 Files selected for processing (5)
packages/rs-drive/src/drive/identity/balance/update.rspackages/rs-drive/src/drive/identity/update/mod.rspackages/rs-drive/src/drive/tokens/balance/update.rspackages/rs-drive/src/query/having.rspackages/rs-platform-version/src/version/drive_versions/v9.rs
🚧 Files skipped from review as they are similar to previous changes (1)
- packages/rs-drive/src/query/having.rs
Issue being fixed or feature implemented
Platform's 4.0 aggregates can compute counts, sums and averages over document groups, but answering "which groups rank highest?" (e.g. top 5 restaurants by average grade) requires scanning every group —
O(n)work with anO(n)proof, so it was never offered.GroveDB's indexed-tree family (dashpay/grovedb#657, follow-ups in dashpay/grovedb#781) pairs each aggregate-bearing tree with per-axis ordered secondaries, making provable top-K reads
O(log n + k). This PR integrates that at the contract level and activates it at protocol v14.What was done?
Contract grammar (rs-dpp, meta-schema v3,
document_type_schema >= 3)rankedCountable/rankedSummable/rankedAverageable, each requiring itsrange*counterpart; parsed intoIndex/IndexLevelTypeInfofind_first_ranked_change); pre-v14 contracts get the same "unexpected property name" rejection as beforeStorage (rs-drive)
ProvableCountIndexedTree/ProvableSumIndexedTree/ProvableCountProvableSumIndexedTree(axes)— a byte-compatible mirror of the tree it replaces, so existing range-aggregate queries keep working on itdrive/document/ranked_index_tree_type.rsused by contract insert/update and all document index walkers; three newbatch_insert_empty_provable_*_indexed_treegrove-op helpers; estimation maps indexed trees to their non-indexed mirror weights (estimated ≥ actual verified per variant)Queries (rs-drive → rs-drive-abci → wire)
query/drive_document_ranked_query/: validation (detect_ranked_mode, versioned), executors overindexed_{count,sum,avg}_top_kandprove_indexed_axis_top_k,MAX_RANKED_LIMIT = 100;verify/document_ranked/wrapsGroveDb::verify_indexed_axis_top_kdocument_query/v1:compute_aggregate_mode_and_check_limitv1 routes a singleHAVINGranking clause (TOP(n)/BOTTOM(n)/MAX/MIN) todispatch_ranked_v1; protocol v13 keeps feature version 0 and still rejects everyHAVING, so mixed-version networks agreeRankedEntry/RankedEntriesmessages and aResultData.rankedarm; requests reuse the existingselects/group_by/havingfields ofGetDocumentsRequestV1. Avg entries carry the grovedb fixed-point i128 (scaleAVG_FIXED_POINT_SCALE, currently 10^19) as 16 BE bytes; clients divideClients (rs-drive-proof-verifier, rs-sdk)
DocumentRankedEntries: Fetchwith proof verification bound to the signed app hash viaverify_tenderdash_proof;ranking_havingconstructor; empty-ranking-with-proof surfaces as an explicit error (grovedb has no absence envelope for indexed-axis proofs)Versioning (rs-platform-version)
CONTRACT_VERSIONS_V6(meta-schema v3),DRIVE_VERSION_V9(detect_ranked_mode+ grove/verify method slots),DRIVE_ABCI_QUERY_VERSIONS_V2(ranked routing gate). Behaviorally identical to v13 until a contract uses the new grammarv5.0.1→ develop4c6720b(contains chore(drive): comprehensive logging for same block execution #657 + feat(dashmate): pack release script #781; feat(dashmate): pack release script #781 also fixes a subset-verification regression that chore(drive): comprehensive logging for same block execution #657 introduced for pre-existing shielded proofs)How Has This Been Tested?
rs-dppindex grammar/immutability/gating tests (28) — parsing, desugaring, per-flag rejections, PV13 vs PV14 acceptancers-driveinsert_contract/v0/tests/ranked_index_e2e_tests.rs— all three variants through real batches: registration shape (axes TLV), ranking across inserts/updates/deletes,verify_grovedbintegrity after every test;restaurantsfixture addedrs-drivedrive_document_ranked_query/tests.rs(28) — validation matrix, all axes/kinds, prove→verify round-trips against the live root hash, tamper rejection, tie ordering, multi-index prover/verifier index agreementrs-drive-abcidocument_query/v1/tests.rsranked module (13) — wire-level requests per axis, proof responses, PV13 rejection, empty-ranking-prove clean error, malformed-shape rejectionsrs-drive-proof-verifier(12) +rs-sdk(7 unit + doctest) — wire round-trip against the abci ground-truth shape, 16-byte avg decode incl. negatives, order preservationcargo test -p drive --lib3300 ·-p dpp --lib3834 ·-p drive-abci --lib query::604 ·-p platform-version13 ·-p drive-proof-verifier257 ·-p dash-sdk --lib/--doc181/12 — all 0 failures;cargo check --workspace --all-targets,cargo check -p drive --no-default-features --features verify, clippy clean on all touched crates,cargo fmtcleanNot yet covered (needs a live PV14 network, which doesn't exist): recorded SDK
tests/vectorsfixtures and live e2e; JS/Java/ObjC/Python generated gRPC clients still need regeneration (yarn workspace @dashevo/dapi-grpc build, docker).Breaking Changes
None for existing networks or clients: the new consensus behavior is entirely gated behind protocol v14 (a v13→v14 upgrade is a no-op until a contract uses the new grammar), the wire change is additive, and existing aggregate queries are unaffected. Merging does make nodes signal v14 as their desired version.
Checklist:
For repository code-owners and collaborators only
🤖 Generated with Claude Code
Summary by CodeRabbit
HAVING TOP(n)andBOTTOM(n)for count, sum, and average results.MIN/MAXlimitations.