Skip to content

feat(drive): add document history retrieval#3725

Open
PastaPastaPasta wants to merge 4 commits into
v3.1-devfrom
codex/document-history-retrieval
Open

feat(drive): add document history retrieval#3725
PastaPastaPasta wants to merge 4 commits into
v3.1-devfrom
codex/document-history-retrieval

Conversation

@PastaPastaPasta
Copy link
Copy Markdown
Member

@PastaPastaPasta PastaPastaPasta commented May 21, 2026

Issue being fixed or feature implemented

Adds an end-to-end public read path for document history when documentsKeepHistory is enabled. Today Drive stores historical revisions, but SDK users cannot retrieve them through DAPI / Evo SDK APIs.

What was done?

  • Added getDocumentHistory to DAPI proto and Rust gRPC transport.
  • Added Drive document-history fetch/prove/verify APIs over the existing keep-history subtree.
  • Added Drive ABCI query handling with ID and pagination validation.
  • Added proof-verifier support for timestamp-keyed DocumentHistory.
  • Exposed document-history queries through rs-sdk, wasm-sdk, and js-evo-sdk.
  • Added focused Drive history tests and js-evo-sdk facade forwarding tests.

How Has This Been Tested?

  • cargo check -p dapi-grpc -p platform-version -p drive -p drive-abci
  • cargo check -p drive-proof-verifier -p rs-dapi-client -p dash-sdk -p wasm-sdk
  • cargo check -p drive-abci
  • cargo test -p drive document_history -- --nocapture
  • PATH="/opt/homebrew/opt/llvm/bin:$PATH" CC_wasm32_unknown_unknown="/opt/homebrew/opt/llvm/bin/clang" CXX_wasm32_unknown_unknown="/opt/homebrew/opt/llvm/bin/clang++" yarn workspace @dashevo/wasm-sdk build
  • yarn workspace @dashevo/evo-sdk build
  • yarn workspace @dashevo/evo-sdk test:unit

Breaking Changes

None.

Checklist:

  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have added or updated relevant unit/integration/functional/e2e tests
  • I have added "!" to the title and described breaking changes in the corresponding section if my code contains any
  • I have made corresponding changes to the documentation if needed

For repository code-owners and collaborators only

  • I have assigned this pull request to a milestone

This pull request was created by Codex.

Summary by CodeRabbit

  • New Features
    • Document history query: fetch past revisions with time filtering, pagination (limit, offset) and enforced max limit.
    • Optional cryptographic proof support for verifiable history results.
    • SDK & WASM: new public query type and APIs to request history and history-with-proof; convenience facade methods added.
    • gRPC/web clients and JS bindings updated to expose the new getDocumentHistory RPC.

Review Change Stack

@github-actions github-actions Bot added this to the v3.1.0 milestone May 21, 2026
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 21, 2026

📝 Walkthrough

Walkthrough

Implements end-to-end document history: protobuf/gRPC RPC, Drive query/prove/verify implementations with version dispatch and limit validation, proof-verifier integration, and SDK bindings for Rust, WASM, and JavaScript including client stubs and tests.

Changes

Document History Query & Proof Implementation

Layer / File(s) Summary
Proto & gRPC Service Setup
packages/dapi-grpc/protos/platform/v0/platform.proto, packages/dapi-grpc/build.rs
Adds getDocumentHistory RPC and GetDocumentHistoryRequest/GetDocumentHistoryResponse protobuf messages and updates codegen versioned request/response lists.
gRPC Clients & JS Bindings
packages/dapi-grpc/clients/platform/v0/*, packages/dapi-grpc/clients/platform/v0/nodejs/*
Adds generated JS/TS proto bindings and client wrappers for GetDocumentHistory, including Node/web promise clients and gRPC-web service descriptors.
Transport wiring (Rust)
packages/rs-dapi-client/src/transport/grpc.rs
Wires transport binding for GetDocumentHistoryRequestPlatformGrpcClient::get_document_history.
QueryService endpoint & ABci module
packages/rs-drive-abci/src/query/document_history/*, packages/rs-drive-abci/src/query/service.rs
Adds query_document_history entry, query_document_history_v0 validation/dispatch, and get_document_history gRPC handler.
Drive: fetch query construction & limit validation
packages/rs-drive/src/drive/document/query/fetch_document_history_query/*
Implements fetch_document_history_query_v0, dispatcher, and validate_document_history_limit enforcing MAX_DOCUMENT_HISTORY_FETCH_LIMIT.
Drive: fetch implementation & tests
packages/rs-drive/src/drive/document/get_fetch/fetch_document_history/*
Adds fetch_document_history/fetch_document_history_v0 to execute path queries, decode timestamps, deserialize documents into BTreeMap, and includes pagination/ordering and proof tests.
Drive: proof generation
packages/rs-drive/src/drive/document/prove/prove_document_history/*
Adds prove_document_history dispatch and prove_document_history_v0 that returns proved-path bytes.
Drive: proof verification
packages/rs-drive/src/verify/document/verify_document_history/*
Adds verify_document_history and verify_document_history_v0 to verify GroveDB proofs, validate paths, decode timestamps, and reconstruct documents.
Proof verifier integration
packages/rs-drive-proof-verifier/src/proof.rs, packages/rs-drive-proof-verifier/src/types.rs
Implements FromProof for GetDocumentHistoryRequest to verify document-history proofs and adds DocumentHistory alias and length wiring.
Platform version tables & mocks
packages/rs-platform-version/src/version/..., packages/rs-platform-version/src/version/mocks/v2_test.rs
Adds document_history and related method-version fields to version structs/constants and test mocks, initialized to 0.
Rust SDK integration
packages/rs-sdk/src/platform/documents/document_history_query.rs, packages/rs-sdk/src/platform/query.rs, packages/rs-sdk/src/platform/fetch.rs
Adds DocumentHistoryQuery type, Query<GetDocumentHistoryRequest> impl, and Fetch<DocumentHistory> mapping; re-exports query type.
WASM SDK bindings
packages/wasm-sdk/src/queries/document.rs
Adds DocumentHistoryQuery JS type binding, parser, and wasm-bindgen methods getDocumentHistory and getDocumentHistoryWithProofInfo returning JS Map and proof metadata.
JS Evo SDK facade & tests
packages/js-evo-sdk/src/documents/facade.ts, packages/js-evo-sdk/tests/unit/facades/documents.spec.ts
Adds DocumentsFacade.history/historyWithProof wrappers and unit tests stubbing wasmSdk history methods.
Misc: module wiring & errors
packages/rs-drive/src/drive/document/mod.rs, packages/rs-drive/src/error/drive.rs, various mod.rs additions
Adds module declarations, MAX_DOCUMENT_HISTORY_FETCH_LIMIT constant and DriveError::InvalidDocumentHistoryFetchLimit variant, and small import/formatting edits.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Suggested labels

dapi-endpoint

Suggested reviewers

  • shumkov
  • QuantumExplorer
  • thepastaclaw

Poem

🐰 I hopped through timestamps, bytes, and keys,
Traced every revision with elegant ease,
From proto to proof and JS Map delight,
A rabbit’s small cheer for histories bright!

🚥 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 PR title 'feat(drive): add document history retrieval' clearly and concisely describes the main feature addition: document history retrieval functionality in the drive component.
Docstring Coverage ✅ Passed Docstring coverage is 86.67% 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/document-history-retrieval

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

packages/dapi-grpc/clients/platform/v0/web/platform_pb.d.ts

Parsing error: Unexpected token :

packages/dapi-grpc/clients/platform/v0/web/platform_pb_service.d.ts

Parsing error: Unexpected token PlatformbroadcastStateTransition


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
Copy link
Copy Markdown

codecov Bot commented May 21, 2026

Codecov Report

❌ Patch coverage is 28.07018% with 41 lines in your changes missing coverage. Please review.
✅ Project coverage is 87.17%. Comparing base (f741df2) to head (4e481a1).

Files with missing lines Patch % Lines
packages/rs-drive-proof-verifier/src/proof.rs 26.78% 41 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff            @@
##           v3.1-dev    #3725   +/-   ##
=========================================
  Coverage     87.17%   87.17%           
=========================================
  Files          2601     2601           
  Lines        318220   318220           
=========================================
  Hits         277408   277408           
  Misses        40812    40812           
Components Coverage Δ
dpp 87.67% <ø> (ø)
drive 85.95% <100.00%> (ø)
drive-abci 89.68% <ø> (ø)
sdk ∅ <ø> (∅)
dapi-client ∅ <ø> (∅)
platform-version ∅ <ø> (∅)
platform-value 92.17% <ø> (ø)
platform-wallet ∅ <ø> (∅)
drive-proof-verifier 49.16% <26.78%> (ø)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

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.

Actionable comments posted: 1

🧹 Nitpick comments (1)
packages/rs-platform-version/src/version/drive_versions/drive_document_method_versions/mod.rs (1)

25-27: ⚡ Quick win

Add freeze assertions for the new historical query method slots.

These fields become part of historical method tables too; adding explicit freeze checks (like the existing primary_key_tree_type guard) will prevent accidental version bumps in already-shipped protocol tables.

Proposed test additions
 #[cfg(test)]
 mod historical_method_table_freeze {
@@
     #[test]
     fn v3_primary_key_tree_type_selects_v1_dispatch() {
         assert_eq!(
             DRIVE_DOCUMENT_METHOD_VERSIONS_V3.primary_key_tree_type, 1,
@@
         );
     }
+
+    #[test]
+    fn v2_document_history_query_slots_are_frozen_at_v0_dispatch() {
+        assert_eq!(DRIVE_DOCUMENT_METHOD_VERSIONS_V2.query.fetch_document_history_query, 0);
+        assert_eq!(DRIVE_DOCUMENT_METHOD_VERSIONS_V2.query.fetch_document_history, 0);
+        assert_eq!(DRIVE_DOCUMENT_METHOD_VERSIONS_V2.query.prove_document_history, 0);
+    }
+
+    #[test]
+    fn v3_document_history_query_slots_are_frozen_at_v0_dispatch() {
+        assert_eq!(DRIVE_DOCUMENT_METHOD_VERSIONS_V3.query.fetch_document_history_query, 0);
+        assert_eq!(DRIVE_DOCUMENT_METHOD_VERSIONS_V3.query.fetch_document_history, 0);
+        assert_eq!(DRIVE_DOCUMENT_METHOD_VERSIONS_V3.query.prove_document_history, 0);
+    }
 }
🤖 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/drive_document_method_versions/mod.rs`
around lines 25 - 27, Add freeze assertions for the new historical method slots
so they cannot be changed after shipping: in the same place where
primary_key_tree_type is guarded, add checks that fetch_document_history_query,
fetch_document_history, and prove_document_history are frozen (or assert their
versions/flags) to prevent accidental bumps in historical method tables; mirror
the exact pattern used for primary_key_tree_type to locate and implement these
guards inside the drive_document_method_versions module.
🤖 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/verify/document/verify_document_history/v0/mod.rs`:
- Around line 17-27: The current verify_document_history_v0 decodes every proved
history entry using a single DocumentTypeRef which breaks when the contract
schema changed; update verify_document_history_v0 so that for each history entry
you resolve the DocumentTypeRef that was active at that entry's timestamp (i.e.
lookup the contract revision for the entry's revision/timestamp and use that
revision's document type) before decoding, or alternatively detect if the
requested range spans multiple contract revisions and return a clear error
rejecting cross-revision history requests; make this change where entries are
iterated/decoded (and similarly for the logic referenced around lines 62-69) so
each Document is decoded against the correct historical schema.

---

Nitpick comments:
In
`@packages/rs-platform-version/src/version/drive_versions/drive_document_method_versions/mod.rs`:
- Around line 25-27: Add freeze assertions for the new historical method slots
so they cannot be changed after shipping: in the same place where
primary_key_tree_type is guarded, add checks that fetch_document_history_query,
fetch_document_history, and prove_document_history are frozen (or assert their
versions/flags) to prevent accidental bumps in historical method tables; mirror
the exact pattern used for primary_key_tree_type to locate and implement these
guards inside the drive_document_method_versions module.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: 5743c558-0198-4f06-ab5c-4d3a5b2526c6

📥 Commits

Reviewing files that changed from the base of the PR and between f741df2 and b5a9d0b.

📒 Files selected for processing (41)
  • packages/dapi-grpc/build.rs
  • packages/dapi-grpc/protos/platform/v0/platform.proto
  • packages/js-evo-sdk/src/documents/facade.ts
  • packages/js-evo-sdk/tests/unit/facades/documents.spec.ts
  • packages/rs-dapi-client/src/transport/grpc.rs
  • packages/rs-drive-abci/src/query/document_history/mod.rs
  • packages/rs-drive-abci/src/query/document_history/v0/mod.rs
  • packages/rs-drive-abci/src/query/mod.rs
  • packages/rs-drive-abci/src/query/service.rs
  • packages/rs-drive-proof-verifier/src/proof.rs
  • packages/rs-drive-proof-verifier/src/types.rs
  • packages/rs-drive/src/drive/document/get_fetch/fetch_document_history/mod.rs
  • packages/rs-drive/src/drive/document/get_fetch/fetch_document_history/v0/mod.rs
  • packages/rs-drive/src/drive/document/get_fetch/mod.rs
  • packages/rs-drive/src/drive/document/mod.rs
  • packages/rs-drive/src/drive/document/prove/mod.rs
  • packages/rs-drive/src/drive/document/prove/prove_document_history/mod.rs
  • packages/rs-drive/src/drive/document/prove/prove_document_history/v0/mod.rs
  • packages/rs-drive/src/drive/document/query/fetch_document_history_query/mod.rs
  • packages/rs-drive/src/drive/document/query/fetch_document_history_query/v0/mod.rs
  • packages/rs-drive/src/drive/document/query/mod.rs
  • packages/rs-drive/src/error/drive.rs
  • packages/rs-drive/src/verify/document/mod.rs
  • packages/rs-drive/src/verify/document/verify_document_history/mod.rs
  • packages/rs-drive/src/verify/document/verify_document_history/v0/mod.rs
  • packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_query_versions/mod.rs
  • packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_query_versions/v1.rs
  • packages/rs-platform-version/src/version/drive_versions/drive_document_method_versions/mod.rs
  • packages/rs-platform-version/src/version/drive_versions/drive_document_method_versions/v1.rs
  • packages/rs-platform-version/src/version/drive_versions/drive_document_method_versions/v2.rs
  • packages/rs-platform-version/src/version/drive_versions/drive_document_method_versions/v3.rs
  • packages/rs-platform-version/src/version/drive_versions/drive_verify_method_versions/mod.rs
  • packages/rs-platform-version/src/version/drive_versions/drive_verify_method_versions/v1.rs
  • packages/rs-platform-version/src/version/mocks/v2_test.rs
  • packages/rs-sdk/src/mock/sdk.rs
  • packages/rs-sdk/src/platform.rs
  • packages/rs-sdk/src/platform/documents/document_history_query.rs
  • packages/rs-sdk/src/platform/documents/mod.rs
  • packages/rs-sdk/src/platform/fetch.rs
  • packages/rs-sdk/src/platform/query.rs
  • packages/wasm-sdk/src/queries/document.rs

Comment on lines +17 to +27
pub(super) fn verify_document_history_v0(
proof: &[u8],
contract_id: [u8; 32],
document_type_name: &str,
document_type: DocumentTypeRef,
document_id: [u8; 32],
start_at_ms: u64,
limit: Option<u16>,
offset: Option<u16>,
platform_version: &PlatformVersion,
) -> Result<(RootHash, Option<BTreeMap<u64, Document>>), Error> {
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 | 🟠 Major | 🏗️ Heavy lift

Resolve the document type per historical revision.

This implementation decodes every proved history entry with one DocumentTypeRef. That only holds if the contract schema never changed. Once a data contract update modifies this document type, older revisions in the same history range will be verified against the latest schema and can fail to decode or be interpreted incorrectly. Please either resolve the contract revision that was active for each timestamp, or explicitly reject history ranges that cross contract revisions until that lookup is wired in.

Also applies to: 62-69

🤖 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/verify/document/verify_document_history/v0/mod.rs`
around lines 17 - 27, The current verify_document_history_v0 decodes every
proved history entry using a single DocumentTypeRef which breaks when the
contract schema changed; update verify_document_history_v0 so that for each
history entry you resolve the DocumentTypeRef that was active at that entry's
timestamp (i.e. lookup the contract revision for the entry's revision/timestamp
and use that revision's document type) before decoding, or alternatively detect
if the requested range spans multiple contract revisions and return a clear
error rejecting cross-revision history requests; make this change where entries
are iterated/decoded (and similarly for the logic referenced around lines 62-69)
so each Document is decoded against the correct historical schema.

Copy link
Copy Markdown
Collaborator

@thepastaclaw thepastaclaw left a comment

Choose a reason for hiding this comment

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

Code Review

The document-history plumbing is mostly coherent, but three user-visible issues remain in the shipped surface. One is blocking: the protobuf service added getDocumentHistory, but the checked-in @dashevo/dapi-grpc generated clients were not regenerated, so published consumers of that package cannot call the new RPC. The other two issues are pagination-semantics regressions: empty history pages are treated as missing resources in the non-proof path and collapsed to None in proof verification.

Note: Inline posting through review_poster.py failed with GitHub HTTP 422, so I posted the same verified findings as a top-level review body.

Reviewed commit: b5a9d0b

🔴 1 blocking | 🟡 2 suggestion(s)

Verified findings

blocking: The new RPC is declared in the proto, but the checked-in generated DAPI clients do not expose it

packages/dapi-grpc/protos/platform/v0/platform.proto (line 38)

@dashevo/dapi-grpc ships generated client artifacts from packages/dapi-grpc/clients and re-exports them from node.js and browser.js. After adding rpc getDocumentHistory(...), the repository still contains no generated getDocumentHistory / GetDocumentHistory* symbols under packages/dapi-grpc/clients/platform/v0, so workspace and published-package consumers that rely on those checked-in clients cannot construct or invoke the new method. The Rust path works because it regenerates from the proto during build, but the package that advertises generated clients is stale in the committed source.

suggestion: Empty document-history pages are converted into `NotFound` in the non-proof path

packages/rs-drive-abci/src/query/document_history/v0/mod.rs (line 120)

This branch turns any empty result set into QueryError::NotFound, which breaks normal pagination semantics. Requests such as offset past the last revision or start_at_ms after the newest revision are valid queries against an existing document history and should return an empty page, not a transport error. As written, raw DAPI callers using prove = false cannot paginate until exhaustion without treating the final page as failure, and they cannot distinguish an empty page from an actually invalid document ID.

suggestion: Proof verification collapses an empty history page into `None`

packages/rs-drive/src/verify/document/verify_document_history/v0/mod.rs (line 83)

verify_document_history_v0() returns None whenever the verified map is empty. That loses information for paginated history queries, because a valid empty page and a genuinely absent history become indistinguishable after proof verification. The analogous contract-history verifier returns Some(empty_map), which preserves collection semantics. Returning Some(documents) here keeps the proof-decoded result lossless and aligns the verifier with the collection behavior expected by limit/offset queries.

Ok((root_hash, Some(documents)))
🤖 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.

- [BLOCKING] In `packages/dapi-grpc/protos/platform/v0/platform.proto`:38-39: The new RPC is declared in the proto, but the checked-in generated DAPI clients do not expose it
  `@dashevo/dapi-grpc` ships generated client artifacts from `packages/dapi-grpc/clients` and re-exports them from `node.js` and `browser.js`. After adding `rpc getDocumentHistory(...)`, the repository still contains no generated `getDocumentHistory` / `GetDocumentHistory*` symbols under `packages/dapi-grpc/clients/platform/v0`, so workspace and published-package consumers that rely on those checked-in clients cannot construct or invoke the new method. The Rust path works because it regenerates from the proto during build, but the package that advertises generated clients is stale in the committed source.
- [SUGGESTION] In `packages/rs-drive-abci/src/query/document_history/v0/mod.rs`:120-123: Empty document-history pages are converted into `NotFound` in the non-proof path
  This branch turns any empty result set into `QueryError::NotFound`, which breaks normal pagination semantics. Requests such as `offset` past the last revision or `start_at_ms` after the newest revision are valid queries against an existing document history and should return an empty page, not a transport error. As written, raw DAPI callers using `prove = false` cannot paginate until exhaustion without treating the final page as failure, and they cannot distinguish an empty page from an actually invalid document ID.
- [SUGGESTION] In `packages/rs-drive/src/verify/document/verify_document_history/v0/mod.rs`:83-89: Proof verification collapses an empty history page into `None`
  `verify_document_history_v0()` returns `None` whenever the verified map is empty. That loses information for paginated history queries, because a valid empty page and a genuinely absent history become indistinguishable after proof verification. The analogous contract-history verifier returns `Some(empty_map)`, which preserves collection semantics. Returning `Some(documents)` here keeps the proof-decoded result lossless and aligns the verifier with the collection behavior expected by limit/offset queries.

@PastaPastaPasta PastaPastaPasta force-pushed the codex/document-history-retrieval branch from 5bf74f3 to 4e481a1 Compare May 22, 2026 01:33
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.

♻️ Duplicate comments (1)
packages/rs-drive/src/verify/document/verify_document_history/v0/mod.rs (1)

62-70: ⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

Decode each history entry against the schema active at that timestamp.

All entries are deserialized with a single document_type (Line 68). If history spans contract revisions, older entries can be decoded with the wrong schema. Please resolve document type per historical revision (or explicitly reject cross-revision ranges).

🤖 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/verify/document/verify_document_history/v0/mod.rs`
around lines 62 - 70, The code currently decodes every history entry using the
single variable document_type inside the maybe_document mapping (see
maybe_element.map and the call to Document::from_bytes), which will mis-decode
entries from older contract revisions; change the logic so that for each element
you resolve the correct document_type for that element's historical revision
(e.g., read the element's revision/timestamp/metadata from maybe_element or its
container) and pass that resolved type into Document::from_bytes(document_bytes,
resolved_document_type, platform_version), or alternatively detect when the
history spans multiple incompatible revisions and return an explicit error
(reject cross-revision ranges). Ensure you update the code path around
maybe_element, into_item_bytes(), and Document::from_bytes to use the per-entry
resolved_document_type instead of the outer document_type.
🤖 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.

Duplicate comments:
In `@packages/rs-drive/src/verify/document/verify_document_history/v0/mod.rs`:
- Around line 62-70: The code currently decodes every history entry using the
single variable document_type inside the maybe_document mapping (see
maybe_element.map and the call to Document::from_bytes), which will mis-decode
entries from older contract revisions; change the logic so that for each element
you resolve the correct document_type for that element's historical revision
(e.g., read the element's revision/timestamp/metadata from maybe_element or its
container) and pass that resolved type into Document::from_bytes(document_bytes,
resolved_document_type, platform_version), or alternatively detect when the
history spans multiple incompatible revisions and return an explicit error
(reject cross-revision ranges). Ensure you update the code path around
maybe_element, into_item_bytes(), and Document::from_bytes to use the per-entry
resolved_document_type instead of the outer document_type.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 2189f8e5-9f7c-4bfc-9c9f-75296b7fa464

📥 Commits

Reviewing files that changed from the base of the PR and between b5a9d0b and 5bf74f3.

📒 Files selected for processing (12)
  • packages/dapi-grpc/clients/drive/v0/nodejs/drive_pbjs.js
  • packages/dapi-grpc/clients/platform/v0/nodejs/PlatformPromiseClient.js
  • packages/dapi-grpc/clients/platform/v0/nodejs/platform_pbjs.js
  • packages/dapi-grpc/clients/platform/v0/nodejs/platform_protoc.js
  • packages/dapi-grpc/clients/platform/v0/web/PlatformPromiseClient.js
  • packages/dapi-grpc/clients/platform/v0/web/platform_pb.d.ts
  • packages/dapi-grpc/clients/platform/v0/web/platform_pb.js
  • packages/dapi-grpc/clients/platform/v0/web/platform_pb_service.d.ts
  • packages/dapi-grpc/clients/platform/v0/web/platform_pb_service.js
  • packages/rs-drive-abci/src/query/document_history/v0/mod.rs
  • packages/rs-drive/src/drive/document/get_fetch/fetch_document_history/mod.rs
  • packages/rs-drive/src/verify/document/verify_document_history/v0/mod.rs
✅ Files skipped from review due to trivial changes (3)
  • packages/dapi-grpc/clients/platform/v0/web/platform_pb_service.d.ts
  • packages/dapi-grpc/clients/platform/v0/nodejs/platform_protoc.js
  • packages/dapi-grpc/clients/platform/v0/web/platform_pb.js

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.

Actionable comments posted: 3

🧹 Nitpick comments (1)
packages/rs-drive-proof-verifier/src/proof.rs (1)

1432-1509: ⚡ Quick win

Add GetDocumentHistory error-path coverage.

This impl adds request decoding, contract lookup, document-type resolution, and pagination parsing, but the test module below does not exercise those branches yet. Mirroring the malformed-request tests used for the adjacent FromProof impls would make regressions here much cheaper to catch.

🤖 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-proof-verifier/src/proof.rs` around lines 1432 - 1509, The
new FromProof for platform::GetDocumentHistoryRequest lacks unit tests for its
error paths; add tests mirroring the malformed-request cases used by adjacent
FromProof impls to exercise request decoding failures (EmptyVersion / malformed
v0 fields), u32_to_u16_opt pagination errors, provider.get_data_contract
returning None (not found), data_contract.document_type_for_name errors, and
response proof/metadata absence (NoProofInResult / EmptyResponseMetadata);
create tests that call DocumentHistory::maybe_from_proof_with_metadata with
crafted requests/responses to trigger each branch and assert the expected Error
variant, referencing maybe_from_proof_with_metadata, u32_to_u16_opt,
provider.get_data_contract, data_contract.document_type_for_name, and
verify_document_history as anchors when crafting the cases.
🤖 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-proof-verifier/src/proof.rs`:
- Around line 1503-1505: The return currently maps maybe_history to
IndexMap::from_iter and can yield Some(IndexMap::new()) for empty histories;
update the tuple return so the mapped history is converted to an Option that
normalizes empty maps to None by calling into_option() on the mapped result
(i.e., replace maybe_history.map(IndexMap::from_iter) with
maybe_history.map(IndexMap::from_iter).into_option() or equivalent) so the
behavior matches FromProof and other collection helpers; keep mtd.clone()
unchanged.

In `@packages/rs-sdk/src/platform/fetch.rs`:
- Around line 339-341: The impl of the Fetch trait for
drive_proof_verifier::types::DocumentHistory is missing the required associated
type Query; update the impl for Fetch (the block implementing Fetch for
drive_proof_verifier::types::DocumentHistory) to declare type Query =
platform_proto::GetDocumentHistoryQuery (or the correct query type used by this
API) alongside the existing type Request so the impl satisfies the Fetch trait’s
associated types.

In `@packages/rs-sdk/src/platform/query.rs`:
- Around line 189-209: The impl for Query<proto::GetDocumentHistoryRequest> on
DocumentHistoryQuery has the wrong signature: replace the existing fn
query(self, prove: bool) with the trait-required signature fn query(&self,
settings: &crate::platform::QuerySettings<'_>) ->
Result<proto::GetDocumentHistoryRequest, Error>; read the proof flag and any
pagination parameters from settings (instead of the old boolean) and build the
proto::GetDocumentHistoryRequest using self.document_type_name,
self.data_contract_id, self.document_id, self.limit, self.offset,
self.start_at_ms, and settings.prove (or equivalent), returning the constructed
request wrapped in Ok to satisfy the Query trait.

---

Nitpick comments:
In `@packages/rs-drive-proof-verifier/src/proof.rs`:
- Around line 1432-1509: The new FromProof for
platform::GetDocumentHistoryRequest lacks unit tests for its error paths; add
tests mirroring the malformed-request cases used by adjacent FromProof impls to
exercise request decoding failures (EmptyVersion / malformed v0 fields),
u32_to_u16_opt pagination errors, provider.get_data_contract returning None (not
found), data_contract.document_type_for_name errors, and response proof/metadata
absence (NoProofInResult / EmptyResponseMetadata); create tests that call
DocumentHistory::maybe_from_proof_with_metadata with crafted requests/responses
to trigger each branch and assert the expected Error variant, referencing
maybe_from_proof_with_metadata, u32_to_u16_opt, provider.get_data_contract,
data_contract.document_type_for_name, and verify_document_history as anchors
when crafting the cases.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: a0f1f9eb-5ee3-4071-897a-68445222073d

📥 Commits

Reviewing files that changed from the base of the PR and between 5bf74f3 and 4e481a1.

📒 Files selected for processing (51)
  • packages/dapi-grpc/build.rs
  • packages/dapi-grpc/clients/drive/v0/nodejs/drive_pbjs.js
  • packages/dapi-grpc/clients/platform/v0/nodejs/PlatformPromiseClient.js
  • packages/dapi-grpc/clients/platform/v0/nodejs/platform_pbjs.js
  • packages/dapi-grpc/clients/platform/v0/nodejs/platform_protoc.js
  • packages/dapi-grpc/clients/platform/v0/web/PlatformPromiseClient.js
  • packages/dapi-grpc/clients/platform/v0/web/platform_pb.d.ts
  • packages/dapi-grpc/clients/platform/v0/web/platform_pb.js
  • packages/dapi-grpc/clients/platform/v0/web/platform_pb_service.d.ts
  • packages/dapi-grpc/clients/platform/v0/web/platform_pb_service.js
  • packages/dapi-grpc/protos/platform/v0/platform.proto
  • packages/js-evo-sdk/src/documents/facade.ts
  • packages/js-evo-sdk/tests/unit/facades/documents.spec.ts
  • packages/rs-dapi-client/src/transport/grpc.rs
  • packages/rs-drive-abci/src/query/document_history/mod.rs
  • packages/rs-drive-abci/src/query/document_history/v0/mod.rs
  • packages/rs-drive-abci/src/query/mod.rs
  • packages/rs-drive-abci/src/query/service.rs
  • packages/rs-drive-proof-verifier/src/proof.rs
  • packages/rs-drive-proof-verifier/src/types.rs
  • packages/rs-drive/src/drive/document/get_fetch/fetch_document_history/mod.rs
  • packages/rs-drive/src/drive/document/get_fetch/fetch_document_history/v0/mod.rs
  • packages/rs-drive/src/drive/document/get_fetch/mod.rs
  • packages/rs-drive/src/drive/document/mod.rs
  • packages/rs-drive/src/drive/document/prove/mod.rs
  • packages/rs-drive/src/drive/document/prove/prove_document_history/mod.rs
  • packages/rs-drive/src/drive/document/prove/prove_document_history/v0/mod.rs
  • packages/rs-drive/src/drive/document/query/fetch_document_history_query/mod.rs
  • packages/rs-drive/src/drive/document/query/fetch_document_history_query/v0/mod.rs
  • packages/rs-drive/src/drive/document/query/mod.rs
  • packages/rs-drive/src/error/drive.rs
  • packages/rs-drive/src/verify/document/mod.rs
  • packages/rs-drive/src/verify/document/verify_document_history/mod.rs
  • packages/rs-drive/src/verify/document/verify_document_history/v0/mod.rs
  • packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_query_versions/mod.rs
  • packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_query_versions/v0.rs
  • packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_query_versions/v1.rs
  • packages/rs-platform-version/src/version/drive_versions/drive_document_method_versions/mod.rs
  • packages/rs-platform-version/src/version/drive_versions/drive_document_method_versions/v1.rs
  • packages/rs-platform-version/src/version/drive_versions/drive_document_method_versions/v2.rs
  • packages/rs-platform-version/src/version/drive_versions/drive_document_method_versions/v3.rs
  • packages/rs-platform-version/src/version/drive_versions/drive_verify_method_versions/mod.rs
  • packages/rs-platform-version/src/version/drive_versions/drive_verify_method_versions/v1.rs
  • packages/rs-platform-version/src/version/mocks/v2_test.rs
  • packages/rs-sdk/src/mock/sdk.rs
  • packages/rs-sdk/src/platform.rs
  • packages/rs-sdk/src/platform/documents/document_history_query.rs
  • packages/rs-sdk/src/platform/documents/mod.rs
  • packages/rs-sdk/src/platform/fetch.rs
  • packages/rs-sdk/src/platform/query.rs
  • packages/wasm-sdk/src/queries/document.rs
✅ Files skipped from review due to trivial changes (6)
  • packages/rs-drive-abci/src/query/mod.rs
  • packages/rs-sdk/src/platform.rs
  • packages/dapi-grpc/clients/platform/v0/nodejs/platform_protoc.js
  • packages/rs-drive/src/drive/document/prove/mod.rs
  • packages/dapi-grpc/clients/platform/v0/web/platform_pb.d.ts
  • packages/dapi-grpc/clients/platform/v0/web/platform_pb.js

Comment on lines +1503 to +1505
Ok((
maybe_history.map(IndexMap::from_iter),
mtd.clone(),
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 | ⚡ Quick win

Normalize empty histories to None.

This can return Some(IndexMap::new()) for an empty verified page, which breaks the collection semantics documented on FromProof and makes empty history behave differently from the other collection helpers in this file. Run the mapped history through into_option() before returning it.

Suggested change
-        Ok((
-            maybe_history.map(IndexMap::from_iter),
-            mtd.clone(),
-            proof.clone(),
-        ))
+        let history = maybe_history
+            .map(IndexMap::from_iter)
+            .and_then(|history| history.into_option());
+
+        Ok((history, mtd.clone(), proof.clone()))
📝 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
Ok((
maybe_history.map(IndexMap::from_iter),
mtd.clone(),
let history = maybe_history
.map(IndexMap::from_iter)
.and_then(|history| history.into_option());
Ok((history, mtd.clone(), proof.clone()))
🤖 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-proof-verifier/src/proof.rs` around lines 1503 - 1505, The
return currently maps maybe_history to IndexMap::from_iter and can yield
Some(IndexMap::new()) for empty histories; update the tuple return so the mapped
history is converted to an Option that normalizes empty maps to None by calling
into_option() on the mapped result (i.e., replace
maybe_history.map(IndexMap::from_iter) with
maybe_history.map(IndexMap::from_iter).into_option() or equivalent) so the
behavior matches FromProof and other collection helpers; keep mtd.clone()
unchanged.

Comment on lines +339 to +341
impl Fetch for drive_proof_verifier::types::DocumentHistory {
type Request = platform_proto::GetDocumentHistoryRequest;
}
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 | 🔴 Critical | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Fetch trait associated type requirements:"
rg -n -C3 'pub trait Fetch|type Query:|type Request:' packages/rs-sdk/src/platform/fetch.rs

echo
echo "DocumentHistory Fetch impl:"
rg -n -C4 'impl Fetch for drive_proof_verifier::types::DocumentHistory|type Query =|type Request =' packages/rs-sdk/src/platform/fetch.rs

Repository: dashpay/platform

Length of output: 7666


Add missing type Query to Fetch impl for DocumentHistory

Fetch requires both associated types; impl Fetch for drive_proof_verifier::types::DocumentHistory defines only type Request, so this impl is incomplete and won’t compile (packages/rs-sdk/src/platform/fetch.rs, lines 339-341).

💡 Proposed fix
 impl Fetch for drive_proof_verifier::types::DocumentHistory {
+    type Query = platform_proto::GetDocumentHistoryRequest;
     type Request = platform_proto::GetDocumentHistoryRequest;
 }
📝 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
impl Fetch for drive_proof_verifier::types::DocumentHistory {
type Request = platform_proto::GetDocumentHistoryRequest;
}
impl Fetch for drive_proof_verifier::types::DocumentHistory {
type Query = platform_proto::GetDocumentHistoryRequest;
type Request = platform_proto::GetDocumentHistoryRequest;
}
🤖 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-sdk/src/platform/fetch.rs` around lines 339 - 341, The impl of
the Fetch trait for drive_proof_verifier::types::DocumentHistory is missing the
required associated type Query; update the impl for Fetch (the block
implementing Fetch for drive_proof_verifier::types::DocumentHistory) to declare
type Query = platform_proto::GetDocumentHistoryQuery (or the correct query type
used by this API) alongside the existing type Request so the impl satisfies the
Fetch trait’s associated types.

Comment on lines +189 to +209
impl Query<proto::GetDocumentHistoryRequest> for DocumentHistoryQuery {
fn query(self, prove: bool) -> Result<proto::GetDocumentHistoryRequest, Error> {
if !prove {
unimplemented!("queries without proofs are not supported yet");
}

Ok(proto::GetDocumentHistoryRequest {
version: Some(proto::get_document_history_request::Version::V0(
proto::get_document_history_request::GetDocumentHistoryRequestV0 {
data_contract_id: self.data_contract_id.to_vec(),
document_type_name: self.document_type_name,
document_id: self.document_id.to_vec(),
limit: self.limit,
offset: self.offset,
start_at_ms: self.start_at_ms,
prove,
},
)),
})
}
}
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 | 🔴 Critical | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE="packages/rs-sdk/src/platform/query.rs"

echo "Trait contract:"
rg -n -C2 'pub trait Query<.*>|fn query\(&self, settings: &crate::platform::QuerySettings' "$FILE"

echo
echo "DocumentHistoryQuery implementation:"
rg -n -C4 'impl Query<proto::GetDocumentHistoryRequest> for DocumentHistoryQuery|fn query\(' "$FILE"

Repository: dashpay/platform

Length of output: 17814


Fix Query trait impl signature for DocumentHistoryQuery.

Query<proto::GetDocumentHistoryRequest> requires fn query(&self, settings: &crate::platform::QuerySettings<'_>), but DocumentHistoryQuery implements fn query(self, prove: bool), violating the trait contract and preventing compilation.

🤖 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-sdk/src/platform/query.rs` around lines 189 - 209, The impl for
Query<proto::GetDocumentHistoryRequest> on DocumentHistoryQuery has the wrong
signature: replace the existing fn query(self, prove: bool) with the
trait-required signature fn query(&self, settings:
&crate::platform::QuerySettings<'_>) -> Result<proto::GetDocumentHistoryRequest,
Error>; read the proof flag and any pagination parameters from settings (instead
of the old boolean) and build the proto::GetDocumentHistoryRequest using
self.document_type_name, self.data_contract_id, self.document_id, self.limit,
self.offset, self.start_at_ms, and settings.prove (or equivalent), returning the
constructed request wrapped in Ok to satisfy the Query trait.

Copy link
Copy Markdown
Collaborator

@thepastaclaw thepastaclaw left a comment

Choose a reason for hiding this comment

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

Code Review

Prior finding 1 is FIXED: getDocumentHistory is now declared in the proto and exposed by the checked-in generated DAPI clients in both Node and web artifacts. Prior finding 2 is FIXED: the ABCI non-proof path now returns an empty document_entries list instead of converting empty pages into NotFound, and prior finding 3 is FIXED: proof verification now preserves empty history pages as Some(empty) rather than collapsing them to absence. There are no carried-forward prior findings at 5bf74f34797caf6b8dff9d5979f799b55e9e4122, and I did not confirm any new PR-specific correctness issues in the latest delta.

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.

2 participants