Skip to content

Conversation

@QuantumExplorer
Copy link
Member

@QuantumExplorer QuantumExplorer commented Dec 29, 2025

Issue being fixed or feature implemented

Fix checkpoint timing issue causing proof verification failures

GroveDB checkpoints were being created BEFORE the transaction was committed, causing the checkpoint to contain uncommitted state. When using a checkpoint to verify proofs, the proof's root hash wouldn't match the signed app_hash because the checkpoint was missing the final committed changes.

What was done?

Core Changes

  1. Split checkpoint logic into two phases:
    - should_checkpoint - New versioned function that determines if a checkpoint should be created (called before transaction commit, while block_execution_context is still available)
    - create_grovedb_checkpoint - New versioned function that creates the actual GroveDB checkpoint (called AFTER transaction commit so it captures committed state)
  2. Added checkpoint_needed flag to BlockFinalizationOutcome - Signals to the ABCI handler that a checkpoint should be created after commit
  3. Modified finalize_block handler - Now calls create_grovedb_checkpoint after commit_transaction() when checkpoint_needed is true
  4. Simplified update_state_cache - Removed checkpoint-related logic since that's now handled separately
  5. Refactored update_checkpoints - Now uses should_checkpoint internally (kept for backwards compatibility)

New Files

  • should_checkpoint/mod.rs and v0/mod.rs - Checkpoint decision logic with CheckpointNeededInfo struct
  • create_grovedb_checkpoint/mod.rs and v0/mod.rs - Post-commit checkpoint creation

Test Changes

  • Added TestContextProvider for verifying proof signatures in strategy tests
  • Updated expected trunk query element count from 29 to 32 (the old value was incorrect due to using stale checkpoint data)

How Has This Been Tested?

  • cargo test -p drive-abci run_chain_address_transitions_with_checkpoints - Both checkpoint tests pass
  • The tests verify that proofs from checkpoints can be properly verified against the signed app_hash

Breaking Changes

  • update_state_cache no longer takes a checkpointed parameter
  • Internal restructuring of checkpoint creation flow (no external API changes)
  • Added should_checkpoint: OptionalFeatureVersion to DriveAbciBlockEndMethodVersions (set to Some(0) for v7, None for earlier versions)

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

Summary by CodeRabbit

  • New Features

    • Privacy-preserving address balance synchronization API in the SDK with provider interface, tracker, types, metrics, and C FFI bindings for external integrations.
  • Enhancements

    • Trunk- and branch-query verification extended (including trunk-state proofs) and requests can target a checkpoint height for consistent proofs.
    • Automatic GroveDB checkpoint decisioning and creation during block finalization.
    • SDK metadata verification helper made public.
  • Chores

    • Updated grovedb-related dependency revisions.

✏️ Tip: You can customize this high-level summary in your review settings.

@github-actions github-actions bot added this to the v3.0.0 milestone Dec 29, 2025
@github-actions
Copy link

github-actions bot commented Dec 29, 2025

✅ gRPC Query Coverage Report

================================================================================
gRPC Query Coverage Report - NEW QUERIES ONLY
================================================================================

Total queries in proto: 51
Previously known queries: 47
New queries found: 4

================================================================================

New Query Implementation Status:
--------------------------------------------------------------------------------
✓ getAddressInfo                                /home/runner/work/platform/platform/packages/rs-sdk/src/platform/query.rs
✓ getAddressesBranchState                       /home/runner/work/platform/platform/packages/rs-sdk/src/platform/address_sync/mod.rs
✓ getAddressesInfos                             /home/runner/work/platform/platform/packages/rs-sdk/src/platform/fetch_many.rs
✓ getAddressesTrunkState                        /home/runner/work/platform/platform/packages/rs-sdk/src/platform/address_sync/mod.rs

================================================================================
Summary:
--------------------------------------------------------------------------------
New queries implemented: 4 (100.0%)
New queries missing: 0 (0.0%)

Total known queries: 51
  - Implemented: 48
  - Not implemented: 2
  - Excluded: 1

Not implemented queries:
  - getConsensusParams
  - getTokenPreProgrammedDistributions

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 29, 2025

📝 Walkthrough

Walkthrough

Threads a new checkpoint_height through branch proofs and GroveDB selection, adds trunk-state proof handling, introduces checkpoint decision/creation in drive-abci, implements privacy-preserving address-balance sync (trunk + parallel branch queries) with Rust FFI, adds gRPC transport stubs, and bumps grovedb revisions.

Changes

Cohort / File(s) Summary
Proto & gRPC transport
packages/dapi-grpc/protos/platform/v0/platform.proto, packages/rs-dapi-client/src/transport/grpc.rs
Added checkpoint_height (uint64, field 3) to GetAddressesBranchStateRequestV0; added TransportRequest impls for GetAddressesTrunkState and GetAddressesBranchState.
Drive prove API surface
packages/rs-drive/src/drive/address_funds/prove/prove_address_funds_branch_query/*, .../v0/*
Threaded checkpoint_height: BlockHeight through prove_address_funds_branch_query APIs and forwarded into v0 implementations.
GroveDB proved branch query
packages/rs-drive/src/util/grove_operations/grove_get_proved_branch_chunk_query/{mod.rs,v0/mod.rs}
Introduced GroveDBToUse parameter and branching (Current, LatestCheckpoint, Checkpoint(height)); v0 selects appropriate grove DB (loads checkpoint DBs) and preserves cost accounting; errors on missing checkpoints.
Query handler
packages/rs-drive-abci/src/query/address_funds/addresses_branch_state/v0/mod.rs
Extracts checkpoint_height from incoming request and forwards it to proof generation.
Proof verifier (trunk)
packages/rs-drive-proof-verifier/src/proof.rs
Added FromProof impl to handle GetAddressesTrunkState responses, verifying Grovedb trunk proofs and TenderDash signatures into GroveTrunkQueryResult.
GroveDB dependency bumps
packages/rs-drive/Cargo.toml, packages/rs-platform-version/Cargo.toml
Updated grovedb-related git revs to 83a8fe5b6... across crates.
Address sync (Rust SDK)
packages/rs-sdk/src/platform/address_sync/*, packages/rs-sdk/src/platform.rs, packages/rs-sdk/src/sdk.rs
New address_sync module: types, AddressProvider trait, KeyLeafTracker, sync_address_balances workflow (trunk + parallel branch queries, privacy leaf selection, proof verification). Exposed Sdk::sync_address_balances and made metadata verification public.
Address sync (FFI)
packages/rs-sdk-ffi/src/address_sync/{mod.rs,provider.rs,types.rs}, packages/rs-sdk-ffi/src/lib.rs
New FFI-safe types, vtable, AddressProviderFFI wrapper, create/free helpers, entry points (dash_sdk_sync_address_balances*), result allocation/free utilities, tests, and crate re-export.
Mocks & tests
packages/rs-sdk/src/mock/requests.rs, packages/rs-drive-abci/tests/strategy_tests/test_cases/address_tests.rs
Added MockResponse stub for GroveTrunkQueryResult (unimplemented) and TestContextProvider plus a test validating trunk proof signature verification; updated expected trunk element counts.
Drive-ABCI checkpoint flow
packages/rs-drive-abci/src/execution/platform_events/block_end/*, packages/rs-drive-abci/src/execution/engine/finalize_block_proposal/v0/mod.rs, packages/rs-drive-abci/src/abci/handler/finalize_block.rs, packages/rs-drive-abci/Cargo.toml
Added should_checkpoint decision API and create_grovedb_checkpoint (v0) to create/rotate on-disk GroveDB checkpoints; update_checkpoints now uses should_checkpoint; BlockFinalizationOutcome gains checkpoint_needed; added local drive-proof-verifier dep.
Update-state cache changes
packages/rs-drive-abci/src/execution/platform_events/block_end/update_state_cache/*
Removed checkpointed flag from update_state_cache/v0 and pruned checkpoint persistence from the v0 implementation.
Platform-version additions
packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_method_versions/{mod.rs,v1..v7.rs}, packages/rs-platform-version/src/version/mocks/v3_test.rs
Added optional should_checkpoint field to DriveAbciBlockEndMethodVersions and initialized it across version constants (None mostly, Some(0) in v7).
rs-drive imports
packages/rs-drive/src/drive/mod.rs
Adjusted/reordered imports (moved Arc top-level, added conditional server imports: BTreeMap, PathBuf, BlockHeight, TimestampMillis).

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant Sdk
    participant Provider
    participant TrunkExec
    participant BranchExec
    participant GroveDB
    participant ProofVerifier

    Note over Sdk,Provider: Start address sync
    Client->>Sdk: sync_address_balances(provider, config)
    Sdk->>Provider: pending_addresses()
    Provider-->>Sdk: [(index,key),...]

    rect rgba(235,245,255,0.9)
    Note over Sdk,TrunkExec: Trunk query + verification
    Sdk->>TrunkExec: execute_trunk_query()
    TrunkExec->>GroveDB: trunk_query(leaf_paths)
    GroveDB-->>TrunkExec: trunk_response + proof
    TrunkExec->>ProofVerifier: verify_trunk_response(response, proof)
    ProofVerifier-->>Sdk: verified_trunk_result
    end

    rect rgba(232,255,240,0.9)
    Note over Sdk,BranchExec: Iterative branch queries (parallel, checkpoint selection)
    loop while tracker not empty && iterations < max
      Sdk->>BranchExec: execute_branch_queries(leaves[], checkpoint_height?)
      par Parallel branches
        BranchExec->>GroveDB: branch_query(leaf, depth, grove_db_selector)
        GroveDB-->>BranchExec: branch_response + proof
      end
      BranchExec->>ProofVerifier: verify_branch_responses(responses)
      ProofVerifier-->>Sdk: verified_branch_results
      Sdk->>Provider: on_address_found/absent(...)
    end
    end

    Sdk->>Provider: highest_found_index()
    Provider-->>Sdk: highest_index?
    Sdk-->>Client: AddressSyncResult{found, absent, metrics}
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Poem

🐰 I hop through trunks and search each branch,
I chase checkpoint heights with eager lurch.
FFI whispers from far-off lands,
proofs verified by careful hands.
Sync complete — a carrot for my search!

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly describes the main changes: SDK support for platform addresses and a checkpoint timing fix that addresses proof verification issues.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings

📜 Recent review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1d847a1 and 25981a1.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (1)
  • packages/rs-sdk-trusted-context-provider/src/provider.rs
✅ Files skipped from review due to trivial changes (1)
  • packages/rs-sdk-trusted-context-provider/src/provider.rs
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (20)
  • GitHub Check: Rust packages (dapi-grpc) / Unused dependencies
  • GitHub Check: Rust packages (dapi-grpc) / Tests
  • GitHub Check: Rust packages (dapi-grpc) / Linting
  • GitHub Check: Rust packages (wasm-sdk) / Tests
  • GitHub Check: Rust packages (dpp) / Tests
  • GitHub Check: Rust packages (rs-dapi-client) / Tests
  • GitHub Check: Rust packages (drive) / Linting
  • GitHub Check: Rust packages (drive) / Tests
  • GitHub Check: Rust packages (drive-abci) / Check each feature
  • GitHub Check: Rust packages (rs-dapi-client) / Linting
  • GitHub Check: Rust packages (drive-abci) / Linting
  • GitHub Check: Rust packages (rs-dapi-client) / Check each feature
  • GitHub Check: Rust packages (drive-abci) / Tests
  • GitHub Check: Build Docker images (RS-DAPI, rs-dapi, rs-dapi) / Build RS-DAPI image
  • GitHub Check: Build Docker images (Drive, drive, drive-abci, SDK_TEST_DATA=true
    ) / Build Drive image
  • GitHub Check: Build Docker images (Dashmate helper, dashmate-helper, dashmate-helper) / Build Dashmate helper image
  • GitHub Check: Build JS packages / Build JS
  • GitHub Check: Rust crates security audit
  • GitHub Check: Build rs-sdk-ffi for iOS targets (aarch64-apple-ios-sim)
  • GitHub Check: Build rs-sdk-ffi for iOS targets (aarch64-apple-ios)

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.

Copy link
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 (6)
packages/rs-sdk/src/mock/requests.rs (1)

508-521: Intentional panic for GroveTrunkQueryResult mock serialization

The MockResponse impl explicitly panics via unimplemented!() to signal that trunk state results must not be recorded/replayed in the current mocking setup. This is acceptable as long as tests and tools never expect to persist or replay these values; otherwise you’ll get a hard fail at runtime.

If you want a slightly clearer failure mode, you could consider panic!() with the same message instead of unimplemented!(), but functionally this is fine.

packages/rs-sdk/src/platform/address_sync/provider.rs (1)

50-104: Trait method set is sufficient; consider future ergonomics

The method set (gap_limit, pending_addresses, on_address_found, on_address_absent, has_pending, highest_found_index) is minimal yet complete for the current sync design. Returning a Vec from pending_addresses is fine for now; if large address sets become common, switching to an iterator or borrowing API could be a later optimization.

packages/rs-sdk/src/platform/address_sync/tracker.rs (1)

51-55: Potential memory accumulation in leaf_info map.

When add_key is called multiple times with different leaves, or when update_leaf moves keys to new leaves, old LeafInfo entries remain in the leaf_info map even after their refcount drops to zero. Over many iterations, this could accumulate stale entries.

Consider cleaning up leaf_info entries when their refcount reaches zero, or documenting that this is intentional for potential future lookups.

🔎 Optional cleanup in key_found
 pub fn key_found(&mut self, key: &[u8]) {
     if let Some(leaf) = self.key_to_leaf.remove(key) {
         if let Some(count) = self.leaf_refcount.get_mut(&leaf) {
             *count = count.saturating_sub(1);
+            if *count == 0 {
+                self.leaf_refcount.remove(&leaf);
+                self.leaf_info.remove(&leaf);
+            }
         }
     }
 }
packages/rs-sdk/src/platform/address_sync/mod.rs (1)

346-359: Branch query failures are silently logged but not propagated.

When a branch query fails (lines 353-356, 369-371), the error is only logged with warn! and the loop continues. While this provides resilience, it means some addresses may never be resolved if their branch queries consistently fail, and the caller has no indication of partial failures.

Consider either:

  1. Tracking failed leaves for retry in subsequent iterations
  2. Including failure metrics in AddressSyncMetrics
  3. Documenting this behavior explicitly
packages/rs-sdk-ffi/src/address_sync/provider.rs (2)

83-86: unsafe impl Send requires careful consideration of callback thread-safety.

The Send implementation assumes that callbacks can be safely invoked from any thread. However, the actual safety depends on:

  1. The C caller ensuring their callbacks are thread-safe
  2. The context pointer being safe to access across threads

Consider adding documentation in the public API (or vtable comments) warning callers that callbacks must be thread-safe if the provider will be used with async operations.

🔎 Suggested documentation enhancement
 // SAFETY: AddressProviderFFI only contains function pointers and an opaque context
 // The actual thread safety depends on the callback implementations
+// IMPORTANT: Callers must ensure that all callbacks are thread-safe and that
+// the context pointer can be safely accessed from multiple threads if the
+// provider is used with async operations.
 unsafe impl Send for AddressProviderFFI {}

98-127: Vtable pointer is dereferenced without null check in trait methods.

The CallbackAddressProvider trait implementation dereferences self.ffi.vtable without checking for null. While dash_sdk_address_provider_create validates the vtable pointer, direct construction of AddressProviderFFI (as done in tests at lines 238-241) could theoretically have a null vtable.

Since CallbackAddressProvider is pub(crate) and the tests use a valid static vtable, this is acceptable, but consider adding a debug assertion in CallbackAddressProvider::new() for defensive programming.

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 517862d and 2ed7ba1.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (21)
  • packages/dapi-grpc/protos/platform/v0/platform.proto
  • packages/rs-dapi-client/src/transport/grpc.rs
  • packages/rs-drive-abci/src/query/address_funds/addresses_branch_state/v0/mod.rs
  • packages/rs-drive-proof-verifier/src/proof.rs
  • packages/rs-drive/Cargo.toml
  • packages/rs-drive/src/drive/address_funds/prove/prove_address_funds_branch_query/mod.rs
  • packages/rs-drive/src/drive/address_funds/prove/prove_address_funds_branch_query/v0/mod.rs
  • packages/rs-drive/src/util/grove_operations/grove_get_proved_branch_chunk_query/mod.rs
  • packages/rs-drive/src/util/grove_operations/grove_get_proved_branch_chunk_query/v0/mod.rs
  • packages/rs-platform-version/Cargo.toml
  • packages/rs-sdk-ffi/src/address_sync/mod.rs
  • packages/rs-sdk-ffi/src/address_sync/provider.rs
  • packages/rs-sdk-ffi/src/address_sync/types.rs
  • packages/rs-sdk-ffi/src/lib.rs
  • packages/rs-sdk/src/mock/requests.rs
  • packages/rs-sdk/src/platform.rs
  • packages/rs-sdk/src/platform/address_sync/mod.rs
  • packages/rs-sdk/src/platform/address_sync/provider.rs
  • packages/rs-sdk/src/platform/address_sync/tracker.rs
  • packages/rs-sdk/src/platform/address_sync/types.rs
  • packages/rs-sdk/src/sdk.rs
🧰 Additional context used
📓 Path-based instructions (1)
**/*.rs

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.rs: Rust code must pass cargo clippy --workspace linter checks
Rust code must be formatted using cargo fmt --all

**/*.rs: Use 4-space indent for Rust files
Follow rustfmt defaults and keep code clippy-clean for Rust modules
Use snake_case for Rust module names
Use PascalCase for Rust type names
Use SCREAMING_SNAKE_CASE for Rust constants

Files:

  • packages/rs-sdk/src/platform.rs
  • packages/rs-sdk/src/mock/requests.rs
  • packages/rs-sdk-ffi/src/lib.rs
  • packages/rs-drive-proof-verifier/src/proof.rs
  • packages/rs-drive/src/util/grove_operations/grove_get_proved_branch_chunk_query/mod.rs
  • packages/rs-sdk/src/sdk.rs
  • packages/rs-sdk/src/platform/address_sync/provider.rs
  • packages/rs-drive/src/drive/address_funds/prove/prove_address_funds_branch_query/v0/mod.rs
  • packages/rs-sdk-ffi/src/address_sync/types.rs
  • packages/rs-sdk/src/platform/address_sync/types.rs
  • packages/rs-dapi-client/src/transport/grpc.rs
  • packages/rs-drive-abci/src/query/address_funds/addresses_branch_state/v0/mod.rs
  • packages/rs-drive/src/drive/address_funds/prove/prove_address_funds_branch_query/mod.rs
  • packages/rs-sdk/src/platform/address_sync/mod.rs
  • packages/rs-sdk/src/platform/address_sync/tracker.rs
  • packages/rs-sdk-ffi/src/address_sync/mod.rs
  • packages/rs-drive/src/util/grove_operations/grove_get_proved_branch_chunk_query/v0/mod.rs
  • packages/rs-sdk-ffi/src/address_sync/provider.rs
🧠 Learnings (33)
📓 Common learnings
Learnt from: CR
Repo: dashpay/platform PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T13:10:23.481Z
Learning: Applies to **/swift-sdk/**/*.{swift,h,m,c} : iOS SDK must combine both Core (SPV wallet) and Platform (identity/documents) functionality in the unified SDK with proper function naming: `dash_core_sdk_*` prefix for Core functions, `dash_sdk_*` prefix for Platform functions, and `dash_unified_sdk_*` prefix for unified functions
Learnt from: QuantumExplorer
Repo: dashpay/platform PR: 2257
File: packages/rs-drive-abci/src/mimic/test_quorum.rs:159-164
Timestamp: 2024-11-20T16:16:01.830Z
Learning: QuantumExplorer prefers not to receive auto-generated messages asking to post on social media.
📚 Learning: 2024-10-10T10:30:19.883Z
Learnt from: lklimek
Repo: dashpay/platform PR: 2232
File: packages/rs-sdk/src/mock/sdk.rs:90-95
Timestamp: 2024-10-10T10:30:19.883Z
Learning: In `packages/rs-sdk/src/mock/sdk.rs`, the `load_expectations` method in `MockDashPlatformSdk` remains asynchronous (`async`) for backward compatibility, even though it now delegates to the synchronous `load_expectations_sync` method.

Applied to files:

  • packages/rs-sdk/src/platform.rs
  • packages/rs-sdk/src/mock/requests.rs
  • packages/rs-sdk-ffi/src/address_sync/types.rs
  • packages/rs-sdk-ffi/src/address_sync/mod.rs
📚 Learning: 2024-11-28T13:49:17.301Z
Learnt from: shumkov
Repo: dashpay/platform PR: 2317
File: packages/rs-dapi-client/src/address_list.rs:175-180
Timestamp: 2024-11-28T13:49:17.301Z
Learning: In Rust code in `packages/rs-dapi-client/src/address_list.rs`, do not change the interface of deprecated methods like `add_uri`, even to fix potential panics.

Applied to files:

  • packages/rs-sdk/src/platform.rs
  • packages/rs-sdk/src/platform/address_sync/provider.rs
  • packages/rs-sdk-ffi/src/address_sync/types.rs
  • packages/rs-sdk/src/platform/address_sync/types.rs
  • packages/rs-drive-abci/src/query/address_funds/addresses_branch_state/v0/mod.rs
  • packages/rs-sdk-ffi/src/address_sync/mod.rs
  • packages/rs-sdk-ffi/src/address_sync/provider.rs
📚 Learning: 2024-10-18T15:39:51.172Z
Learnt from: lklimek
Repo: dashpay/platform PR: 2254
File: packages/rs-sdk/src/sdk.rs:585-585
Timestamp: 2024-10-18T15:39:51.172Z
Learning: The 'platform' project uses Rust version 1.80, so code in 'packages/rs-sdk' can use features available in Rust 1.80, such as the `abs_diff()` method.

Applied to files:

  • packages/rs-sdk/src/platform.rs
  • packages/rs-platform-version/Cargo.toml
📚 Learning: 2025-01-23T09:23:32.740Z
Learnt from: lklimek
Repo: dashpay/platform PR: 2405
File: packages/rs-sdk/src/sync.rs:88-95
Timestamp: 2025-01-23T09:23:32.740Z
Learning: The `block_on` function in `packages/rs-sdk/src/sync.rs` is currently only used in tests, and its WebAssembly implementation is deferred until there's a user request for it.

Applied to files:

  • packages/rs-sdk/src/platform.rs
  • packages/rs-sdk-ffi/src/lib.rs
📚 Learning: 2024-10-29T14:44:01.184Z
Learnt from: lklimek
Repo: dashpay/platform PR: 2277
File: packages/rs-dapi-client/src/executor.rs:38-38
Timestamp: 2024-10-29T14:44:01.184Z
Learning: In `packages/rs-dapi-client/src/executor.rs`, for the structs `ExecutionError<E>` and `ExecutionResponse<R>`, only the serde derives (`Serialize`, `Deserialize`) should be conditional based on the "mocks" feature; the other derives (`Debug`, `Clone`, `Eq`, `PartialEq`) should always be present.

Applied to files:

  • packages/rs-sdk/src/mock/requests.rs
📚 Learning: 2024-10-29T14:13:35.584Z
Learnt from: lklimek
Repo: dashpay/platform PR: 2277
File: packages/dapi-grpc/src/mock.rs:95-109
Timestamp: 2024-10-29T14:13:35.584Z
Learning: In test code (e.g., `packages/dapi-grpc/src/mock.rs`), panicking on deserialization errors is acceptable behavior.

Applied to files:

  • packages/rs-sdk/src/mock/requests.rs
📚 Learning: 2024-10-10T10:30:25.283Z
Learnt from: lklimek
Repo: dashpay/platform PR: 2232
File: packages/rs-sdk/src/mock/sdk.rs:129-130
Timestamp: 2024-10-10T10:30:25.283Z
Learning: In the codebase `packages/rs-sdk/src/mock/sdk.rs`, `tokio::sync::Mutex` is used instead of `std::sync::Mutex` because `std::sync::MutexGuard` is not `Send` and cannot be used in async contexts.

Applied to files:

  • packages/rs-sdk/src/mock/requests.rs
📚 Learning: 2024-10-29T14:16:40.972Z
Learnt from: lklimek
Repo: dashpay/platform PR: 2277
File: packages/rs-dapi-client/src/address_list.rs:63-73
Timestamp: 2024-10-29T14:16:40.972Z
Learning: In the Rust SDK, it's acceptable to use `expect()` that panics on errors in the `Mockable` trait implementations during testing, and the `Mockable` trait will be refactored in a future PR.

Applied to files:

  • packages/rs-sdk/src/mock/requests.rs
📚 Learning: 2024-10-29T14:16:00.141Z
Learnt from: lklimek
Repo: dashpay/platform PR: 2277
File: packages/dapi-grpc/src/mock.rs:125-145
Timestamp: 2024-10-29T14:16:00.141Z
Learning: Using `serde_json` encoding produces deterministic output required to identify requests and responses by hash, therefore `serde_json` is used as the basic serialization algorithm for mocking.

Applied to files:

  • packages/rs-sdk/src/mock/requests.rs
📚 Learning: 2024-10-29T14:40:54.727Z
Learnt from: lklimek
Repo: dashpay/platform PR: 2277
File: packages/rs-sdk/src/core/transaction.rs:0-0
Timestamp: 2024-10-29T14:40:54.727Z
Learning: In `packages/rs-sdk/src/platform/document_query.rs` and `packages/rs-sdk/src/core/transaction.rs`, certain places don't implement `IntoInner`, so direct error mappings cannot be simplified using `IntoInner`. A TODO comment has been added to address this in a future PR.

Applied to files:

  • packages/rs-sdk/src/mock/requests.rs
📚 Learning: 2025-11-25T13:10:23.481Z
Learnt from: CR
Repo: dashpay/platform PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T13:10:23.481Z
Learning: Use `rs-drive-proof-verifier` for cryptographic proof verification

Applied to files:

  • packages/rs-sdk/src/mock/requests.rs
  • packages/rs-drive-proof-verifier/src/proof.rs
📚 Learning: 2024-10-09T00:22:57.778Z
Learnt from: lklimek
Repo: dashpay/platform PR: 2207
File: packages/rs-drive-proof-verifier/src/proof.rs:1646-1664
Timestamp: 2024-10-09T00:22:57.778Z
Learning: In the implementation of `FromProof<platform::GetContestedResourceIdentityVotesRequest>` in `packages/rs-drive-proof-verifier/src/proof.rs`, when matching `maybe_votes`, using `.expect()` on `v.into_iter().next()` is acceptable because the prior match arm `Some(v) if v.is_empty()` ensures that the map is not empty, preventing a panic.

Applied to files:

  • packages/rs-sdk/src/mock/requests.rs
  • packages/rs-drive-proof-verifier/src/proof.rs
📚 Learning: 2024-10-30T11:19:59.163Z
Learnt from: lklimek
Repo: dashpay/platform PR: 2277
File: packages/rs-sdk/tests/fetch/config.rs:233-233
Timestamp: 2024-10-30T11:19:59.163Z
Learning: In the Rust SDK's `rs-sdk/tests` integration tests (e.g., in `packages/rs-sdk/tests/fetch/config.rs`), we cannot create objects during tests because there is no support for object creation in this context. Therefore, hardcoded values for test identities must be used.

Applied to files:

  • packages/rs-sdk/src/mock/requests.rs
  • packages/rs-sdk-ffi/src/lib.rs
  • packages/rs-sdk/src/platform/address_sync/types.rs
📚 Learning: 2025-11-25T13:10:23.481Z
Learnt from: CR
Repo: dashpay/platform PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T13:10:23.481Z
Learning: Applies to **/swift-sdk/**/*.{swift,h,m,c} : iOS SDK must combine both Core (SPV wallet) and Platform (identity/documents) functionality in the unified SDK with proper function naming: `dash_core_sdk_*` prefix for Core functions, `dash_sdk_*` prefix for Platform functions, and `dash_unified_sdk_*` prefix for unified functions

Applied to files:

  • packages/rs-sdk-ffi/src/lib.rs
  • packages/rs-sdk-ffi/src/address_sync/mod.rs
📚 Learning: 2025-09-03T16:37:11.605Z
Learnt from: QuantumExplorer
Repo: dashpay/platform PR: 2756
File: packages/rs-drive-abci/src/execution/platform_events/core_based_updates/update_masternode_list/update_state_masternode_list/v0/mod.rs:11-11
Timestamp: 2025-09-03T16:37:11.605Z
Learning: In packages/rs-dpp/Cargo.toml, the abci feature already includes core_rpc_client, and core_rpc_client is defined as ["dep:dashcore-rpc"]. This means rs-drive-abci can access dashcore-rpc types through dpp when using the abci feature.

Applied to files:

  • packages/rs-sdk-ffi/src/lib.rs
  • packages/rs-drive/Cargo.toml
  • packages/rs-platform-version/Cargo.toml
📚 Learning: 2025-01-15T08:09:59.365Z
Learnt from: shumkov
Repo: dashpay/platform PR: 2422
File: packages/rs-drive-abci/src/execution/platform_events/protocol_upgrade/perform_events_on_first_block_of_protocol_change/v0/mod.rs:152-163
Timestamp: 2025-01-15T08:09:59.365Z
Learning: In the `transition_to_version_8` function, errors from `grove_get_path_query` when retrieving active contested resource votes are intentionally logged and ignored (returning `Ok(())`) to allow the protocol upgrade to proceed despite query failures.

Applied to files:

  • packages/rs-drive-proof-verifier/src/proof.rs
📚 Learning: 2025-01-19T07:36:46.042Z
Learnt from: QuantumExplorer
Repo: dashpay/platform PR: 2431
File: packages/rs-drive/Cargo.toml:55-60
Timestamp: 2025-01-19T07:36:46.042Z
Learning: The grovedb dependencies in packages/rs-drive/Cargo.toml and related files are intentionally kept at specific revisions rather than using the latest stable version, with plans to update them at a later time.

Applied to files:

  • packages/rs-drive-proof-verifier/src/proof.rs
  • packages/rs-drive/src/util/grove_operations/grove_get_proved_branch_chunk_query/mod.rs
  • packages/rs-drive/Cargo.toml
  • packages/rs-drive/src/drive/address_funds/prove/prove_address_funds_branch_query/v0/mod.rs
  • packages/rs-platform-version/Cargo.toml
  • packages/rs-drive/src/util/grove_operations/grove_get_proved_branch_chunk_query/v0/mod.rs
📚 Learning: 2024-10-30T11:04:33.634Z
Learnt from: lklimek
Repo: dashpay/platform PR: 2277
File: packages/rs-sdk/src/platform/fetch_unproved.rs:0-0
Timestamp: 2024-10-30T11:04:33.634Z
Learning: In `packages/rs-sdk/src/platform/fetch_unproved.rs`, the `execute()` method consumes the request object, so cloning the request is necessary before passing it to `execute()` and `maybe_from_unproved_with_metadata`.

Applied to files:

  • packages/rs-drive-proof-verifier/src/proof.rs
📚 Learning: 2025-03-07T12:37:44.555Z
Learnt from: ogabrielides
Repo: dashpay/platform PR: 2486
File: packages/rs-drive/src/drive/platform_state/store_reduced_platform_state_bytes/v0/mod.rs:1-29
Timestamp: 2025-03-07T12:37:44.555Z
Learning: GroveDB operations like `insert()` return a tuple that includes a cost value which needs to be unwrapped with `.unwrap()` before error handling with `.map_err()`.

Applied to files:

  • packages/rs-drive/src/util/grove_operations/grove_get_proved_branch_chunk_query/mod.rs
  • packages/rs-drive/src/drive/address_funds/prove/prove_address_funds_branch_query/v0/mod.rs
  • packages/rs-drive/src/util/grove_operations/grove_get_proved_branch_chunk_query/v0/mod.rs
📚 Learning: 2024-10-18T15:43:32.447Z
Learnt from: lklimek
Repo: dashpay/platform PR: 2254
File: packages/rs-sdk/src/sdk.rs:654-658
Timestamp: 2024-10-18T15:43:32.447Z
Learning: In `packages/rs-sdk/src/sdk.rs`, within the `verify_metadata_height` function, when using `compare_exchange` on `last_seen_height`, it's acceptable to use `Ordering::Relaxed` for the failure ordering, as any inconsistency would only trigger an extra loop iteration without affecting correctness.

Applied to files:

  • packages/rs-sdk/src/sdk.rs
  • packages/rs-drive/src/drive/address_funds/prove/prove_address_funds_branch_query/mod.rs
📚 Learning: 2024-12-05T09:29:38.918Z
Learnt from: shumkov
Repo: dashpay/platform PR: 2375
File: packages/rs-drive-abci/Cargo.toml:61-63
Timestamp: 2024-12-05T09:29:38.918Z
Learning: In the `drive-abci` package, avoid adding unused dependencies like `hashbrown` to `Cargo.toml`. The team relies on CI to detect dependency version issues.

Applied to files:

  • packages/rs-drive/Cargo.toml
📚 Learning: 2024-10-29T10:42:00.521Z
Learnt from: lklimek
Repo: dashpay/platform PR: 2277
File: packages/rs-dapi-client/Cargo.toml:22-22
Timestamp: 2024-10-29T10:42:00.521Z
Learning: In `packages/rs-dapi-client/Cargo.toml`, `backon` will not work without the `tokio-sleep` feature in our setup, so it's unnecessary to declare `tokio-sleep` as a separate feature in the `[features]` section.

Applied to files:

  • packages/rs-drive/Cargo.toml
📚 Learning: 2025-03-11T09:39:23.071Z
Learnt from: shumkov
Repo: dashpay/platform PR: 2489
File: packages/rs-dpp/Cargo.toml:32-32
Timestamp: 2025-03-11T09:39:23.071Z
Learning: In the Dash Platform project, dependencies are currently managed using Git repository references with tags (repo+tag format in Cargo.toml) rather than published crates, as the team is not currently publishing crates to crates.io.

Applied to files:

  • packages/rs-drive/Cargo.toml
  • packages/rs-platform-version/Cargo.toml
📚 Learning: 2024-10-09T00:22:57.778Z
Learnt from: QuantumExplorer
Repo: dashpay/platform PR: 2215
File: packages/rs-drive-abci/src/execution/engine/run_block_proposal/mod.rs:105-105
Timestamp: 2024-10-09T00:22:57.778Z
Learning: In `run_block_proposal` in `packages/rs-drive-abci/src/execution/engine/run_block_proposal/mod.rs`, when retrieving `last_block_time_ms`, it's acceptable to use `platform_state` instead of `block_platform_state`, even after updating the protocol version.

Applied to files:

  • packages/rs-drive/src/drive/address_funds/prove/prove_address_funds_branch_query/v0/mod.rs
  • packages/rs-drive-abci/src/query/address_funds/addresses_branch_state/v0/mod.rs
  • packages/rs-drive/src/drive/address_funds/prove/prove_address_funds_branch_query/mod.rs
📚 Learning: 2024-11-22T08:19:14.448Z
Learnt from: shumkov
Repo: dashpay/platform PR: 2345
File: packages/rs-drive-abci/src/execution/platform_events/protocol_upgrade/perform_events_on_first_block_of_protocol_change/v0/mod.rs:93-99
Timestamp: 2024-11-22T08:19:14.448Z
Learning: In `packages/rs-drive-abci/src/execution/platform_events/protocol_upgrade/perform_events_on_first_block_of_protocol_change/v0/mod.rs`, the `insert_contract` method requires an owned `BlockInfo`, so cloning `block_info` is necessary when calling it.

Applied to files:

  • packages/rs-drive/src/drive/address_funds/prove/prove_address_funds_branch_query/v0/mod.rs
  • packages/rs-drive-abci/src/query/address_funds/addresses_branch_state/v0/mod.rs
  • packages/rs-drive/src/drive/address_funds/prove/prove_address_funds_branch_query/mod.rs
📚 Learning: 2024-10-08T13:28:03.529Z
Learnt from: QuantumExplorer
Repo: dashpay/platform PR: 2227
File: packages/rs-drive-abci/src/platform_types/platform_state/mod.rs:141-141
Timestamp: 2024-10-08T13:28:03.529Z
Learning: When converting `PlatformStateV0` to `PlatformStateForSavingV1` in `packages/rs-drive-abci/src/platform_types/platform_state/mod.rs`, only version `0` needs to be handled in the match on `platform_state_for_saving_structure_default` because the changes are retroactive.

Applied to files:

  • packages/rs-drive/src/drive/address_funds/prove/prove_address_funds_branch_query/v0/mod.rs
  • packages/rs-drive-abci/src/query/address_funds/addresses_branch_state/v0/mod.rs
  • packages/rs-drive/src/drive/address_funds/prove/prove_address_funds_branch_query/mod.rs
  • packages/rs-platform-version/Cargo.toml
📚 Learning: 2024-10-06T16:18:07.994Z
Learnt from: QuantumExplorer
Repo: dashpay/platform PR: 2215
File: packages/rs-drive-abci/src/execution/engine/run_block_proposal/mod.rs:119-120
Timestamp: 2024-10-06T16:18:07.994Z
Learning: In the `run_block_proposal` function in `packages/rs-drive-abci/src/execution/engine/run_block_proposal/mod.rs`, it's acceptable to pass `platform_state` to `perform_events_on_first_block_of_protocol_change`, even if `block_platform_state` has been updated.

Applied to files:

  • packages/rs-drive/src/drive/address_funds/prove/prove_address_funds_branch_query/v0/mod.rs
  • packages/rs-drive-abci/src/query/address_funds/addresses_branch_state/v0/mod.rs
  • packages/rs-drive/src/drive/address_funds/prove/prove_address_funds_branch_query/mod.rs
📚 Learning: 2024-10-22T10:53:12.111Z
Learnt from: shumkov
Repo: dashpay/platform PR: 2259
File: packages/rs-dapi-client/src/dapi_client.rs:137-139
Timestamp: 2024-10-22T10:53:12.111Z
Learning: In `packages/rs-dapi-client/src/dapi_client.rs`, when passing data into asynchronous code, ensure that data structures are `Send + Sync`. Using `Arc<AtomicUsize>` is necessary for the retry counter.

Applied to files:

  • packages/rs-sdk-ffi/src/address_sync/types.rs
  • packages/rs-sdk/src/platform/address_sync/types.rs
📚 Learning: 2025-11-25T13:10:23.481Z
Learnt from: CR
Repo: dashpay/platform PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T13:10:23.481Z
Learning: Applies to **/swift-sdk/**/*.swift : Swift code should properly wrap FFI functions and maintain type safety across the Swift/Rust boundary

Applied to files:

  • packages/rs-sdk-ffi/src/address_sync/types.rs
  • packages/rs-sdk-ffi/src/address_sync/mod.rs
  • packages/rs-sdk-ffi/src/address_sync/provider.rs
📚 Learning: 2025-10-09T15:59:28.329Z
Learnt from: lklimek
Repo: dashpay/platform PR: 2716
File: packages/rs-dapi/src/services/platform_service/broadcast_state_transition.rs:181-187
Timestamp: 2025-10-09T15:59:28.329Z
Learning: In `packages/rs-dapi/src/services/platform_service/broadcast_state_transition.rs`, the maintainer requires logging full state transition bytes (`tx_bytes = hex::encode(st_bytes)`) at debug level when a state transition passes CheckTx but is removed from the block by the proposer, to facilitate debugging of this rare edge case.

Applied to files:

  • packages/rs-drive-abci/src/query/address_funds/addresses_branch_state/v0/mod.rs
📚 Learning: 2024-11-20T20:43:41.185Z
Learnt from: QuantumExplorer
Repo: dashpay/platform PR: 2257
File: packages/rs-drive-abci/tests/strategy_tests/masternodes.rs:212-220
Timestamp: 2024-11-20T20:43:41.185Z
Learning: In `packages/rs-drive-abci/tests/strategy_tests/masternodes.rs`, the pattern of generating a `PrivateKey`, converting it to bytes, and reconstructing a `BlsPrivateKey` from those bytes is intentional. Avoid suggesting to simplify this code in future reviews.

Applied to files:

  • packages/rs-drive-abci/src/query/address_funds/addresses_branch_state/v0/mod.rs
  • packages/rs-drive/src/drive/address_funds/prove/prove_address_funds_branch_query/mod.rs
📚 Learning: 2024-10-03T11:51:06.980Z
Learnt from: shumkov
Repo: dashpay/platform PR: 2201
File: packages/rs-platform-version/src/version/v2.rs:1186-1188
Timestamp: 2024-10-03T11:51:06.980Z
Learning: In the `IdentityTransitionVersions` structure within `packages/rs-platform-version/src/version/v2.rs`, the field `credit_withdrawal` does not need the `identity_` prefix since it is already encompassed within identity state transitions.

Applied to files:

  • packages/rs-drive-abci/src/query/address_funds/addresses_branch_state/v0/mod.rs
🧬 Code graph analysis (5)
packages/rs-drive-proof-verifier/src/proof.rs (2)
packages/rs-drive/src/verify/address_funds/verify_address_funds_trunk_query/mod.rs (1)
  • verify_address_funds_trunk_query (31-49)
packages/rs-drive-proof-verifier/src/verify.rs (1)
  • verify_tenderdash_proof (31-119)
packages/rs-sdk/src/sdk.rs (2)
packages/wasm-sdk/src/queries/mod.rs (1)
  • metadata (278-280)
packages/dapi-grpc/clients/platform/v0/web/platform_pb.d.ts (1)
  • ResponseMetadata (57-84)
packages/rs-dapi-client/src/transport/grpc.rs (1)
packages/rs-drive-abci/src/query/service.rs (2)
  • get_addresses_trunk_state (832-842)
  • get_addresses_branch_state (844-854)
packages/rs-drive/src/util/grove_operations/grove_get_proved_branch_chunk_query/v0/mod.rs (1)
packages/rs-drive/src/error/mod.rs (4)
  • from (80-82)
  • from (86-88)
  • from (92-94)
  • from (98-100)
packages/rs-sdk-ffi/src/address_sync/provider.rs (2)
packages/rs-sdk-ffi/src/address_sync/types.rs (1)
  • empty (151-156)
packages/rs-sdk-ffi/src/context_provider.rs (1)
  • provider (37-39)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (20)
  • GitHub Check: Rust packages (drive-abci) / Detect immutable structure changes
  • GitHub Check: Rust packages (drive-abci) / Unused dependencies
  • GitHub Check: Rust packages (drive) / Formatting
  • GitHub Check: Rust packages (drive) / Detect immutable structure changes
  • GitHub Check: Rust packages (drive-abci) / Tests
  • GitHub Check: Rust packages (drive) / Tests
  • GitHub Check: Rust packages (drive) / Unused dependencies
  • GitHub Check: Rust packages (drive-abci) / Linting
  • GitHub Check: Rust packages (rs-sdk-ffi) / Linting
  • GitHub Check: Rust packages (rs-sdk-ffi) / Tests
  • GitHub Check: Rust packages (rs-dapi-client) / Check each feature
  • GitHub Check: Rust packages (rs-sdk-ffi) / Unused dependencies
  • GitHub Check: Rust packages (dapi-grpc) / Tests
  • GitHub Check: Rust packages (wasm-dpp) / Tests
  • GitHub Check: Rust packages (rs-dapi-client) / Tests
  • GitHub Check: Rust packages (rs-dapi-client) / Detect immutable structure changes
  • GitHub Check: Rust packages (dapi-grpc) / Unused dependencies
  • GitHub Check: Rust packages (dash-sdk) / Unused dependencies
  • GitHub Check: Build JS packages / Build JS
  • GitHub Check: Rust crates security audit
🔇 Additional comments (35)
packages/rs-drive/Cargo.toml (1)

55-60: LGTM! Local path dependencies for grovedb crates.

The migration from git-based references to local path-based dependencies for grovedb crates is appropriate for local development and testing. This enables development against a local grovedb checkout while maintaining the same optional and default-features configuration.

Based on learnings, grovedb dependencies are intentionally managed at specific versions with plans for coordinated updates.

packages/rs-platform-version/Cargo.toml (1)

14-14: LGTM! Consistent local path dependency migration.

The grovedb-version dependency migration to local path is consistent with the broader pattern of using local grovedb crates for development, as seen in rs-drive/Cargo.toml.

packages/rs-dapi-client/src/transport/grpc.rs (1)

645-661: LGTM! Standard transport implementations for address state queries.

The new gRPC transport implementations for GetAddressesTrunkState and GetAddressesBranchState follow the established pattern used throughout this file. The use of default request settings is appropriate for these query operations, consistent with similar address-related endpoints like get_address_info and get_addresses_infos.

packages/rs-drive/src/util/grove_operations/grove_get_proved_branch_chunk_query/mod.rs (2)

9-9: LGTM! Added GroveDBToUse support.

The import enables the new checkpoint-based query functionality.


15-52: LGTM! Well-documented API extension for checkpoint support.

The addition of the grove_db_to_use parameter enables querying from different GroveDB instances (current, latest checkpoint, or specific checkpoint). The documentation clearly describes the new parameter and its purpose, and the version dispatch correctly propagates it to the v0 implementation.

packages/rs-drive/src/util/grove_operations/grove_get_proved_branch_chunk_query/v0/mod.rs (2)

1-9: LGTM! Necessary imports for checkpoint support.

The new imports enable checkpoint-based GroveDB selection and error handling.


11-59: LGTM! Well-structured checkpoint-based query implementation.

The implementation correctly handles three GroveDB sources:

  • Current: Standard path using the main grove instance
  • LatestCheckpoint: Retrieves the most recent checkpoint
  • Checkpoint(height): Retrieves a specific checkpoint by height

Key strengths:

  • Consistent cost tracking across all branches
  • Appropriate error handling for missing checkpoints
  • Clean match-based branching logic
  • Each path follows the same prove_branch_chunk → push cost → return pattern
packages/rs-drive/src/drive/address_funds/prove/prove_address_funds_branch_query/mod.rs (3)

9-9: LGTM! Required import for checkpoint support.


12-60: LGTM! Well-documented API extension for checkpoint-based proofs.

The addition of the checkpoint_height parameter enables querying address funds at specific checkpoints or the latest checkpoint. The documentation clearly explains:

  • The parameter's purpose (consistency across trunk/branch queries)
  • When to use it (should match trunk query response height)
  • The new error condition (CheckpointNotFound)

The version dispatch correctly propagates the new parameter.


62-113: LGTM! Consistent parameter addition to operations variant.

The checkpoint_height parameter is consistently added to the operations-tracking variant with the same documentation pattern as the main method.

packages/rs-drive/src/drive/address_funds/prove/prove_address_funds_branch_query/v0/mod.rs (2)

1-9: LGTM! Required imports for checkpoint functionality.


10-68: LGTM! Clean checkpoint-to-GroveDBToUse translation.

The implementation correctly:

  1. Adds checkpoint_height parameter to both method variants
  2. Translates the optional checkpoint height to GroveDBToUse enum:
    • Some(height)GroveDBToUse::Checkpoint(height) for specific checkpoint
    • NoneGroveDBToUse::LatestCheckpoint for most recent
  3. Passes platform_version.drive (not platform_version) to grove_get_proved_branch_chunk_query, which is correct since that method expects &DriveVersion

The depth validation logic remains unchanged and appropriate.

packages/rs-sdk-ffi/src/lib.rs (2)

8-8: LGTM! New address_sync module added.

The module declaration follows the established pattern in this file.


37-41: LGTM! Consistent public re-exports.

The re-export of address_sync follows the established pattern of re-exporting all modules at the crate root, making the FFI surface accessible to external consumers.

packages/rs-sdk/src/platform.rs (1)

8-8: Expose address_sync module looks correct

Publicly re‑exporting the new address_sync module here is consistent with the existing platform surface and keeps SDK consumers’ import paths coherent.

packages/rs-sdk/src/mock/requests.rs (1)

35-41: Importing GroveTrunkQueryResult into mocks is coherent

Bringing GroveTrunkQueryResult into this mocking module aligns with the new FromProof support and keeps all MockResponse impls centralized.

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

2019-2024: Checkpoint height field is a clean, additive extension

Adding optional uint64 checkpoint_height = 3; to GetAddressesBranchStateRequestV0 is backward compatible and documents the coupling to trunk metadata clearly. This wires well into the updated Drive branch‑proof APIs that take an optional checkpoint height.

packages/rs-drive-proof-verifier/src/proof.rs (2)

54-54: Import aligns with new trunk-state verification

Bringing GroveTrunkQueryResult into scope here is expected given the new FromProof implementation below and matches how other Drive/Grove types are imported.


944-971: Trunk-state FromProof implementation follows existing verification pattern

The FromProof<platform::GetAddressesTrunkStateRequest> for GroveTrunkQueryResult implementation:

  • Extracts Proof and ResponseMetadata,
  • Delegates Grovedb verification to Drive::verify_address_funds_trunk_query,
  • Runs verify_tenderdash_proof,
  • Returns the verified GroveTrunkQueryResult plus metadata/proof.

This mirrors other FromProof implementations (identities, balances, etc.) and looks correct for integrating trunk proofs into the verifier.

packages/rs-sdk/src/platform/address_sync/types.rs (4)

6-17: Address key/index aliases are reasonable and flexible

Using Vec<u8> for keys and u32 for indices keeps the types generic enough for different wallet schemes while still documenting the intended 32‑byte key size in comments.


18-55: AddressSyncConfig defaults and semantics look sensible

The configuration fields (privacy count, max concurrent requests, iteration cap) are clearly documented and the Default impl matches the documented values (32, 10, 50). This should be a good starting point for most callers.


57-106: AddressSyncResult structure and helpers are straightforward

The result type cleanly separates found vs absent addresses, tracks the highest found index, and exposes convenience methods (new, total_balance, non_zero_count). The custom Default delegating to new() keeps construction consistent.


107-144: Metrics API is minimal but useful

AddressSyncMetrics tracks trunk/branch counts, elements, bytes, and iterations, with helpers for total query count and average proof size. The average_proof_bytes guard for zero queries avoids division by zero and is clippy‑clean.

packages/rs-sdk/src/sdk.rs (2)

285-299: Exposing verify_response_metadata as public is a good integration point

Making verify_response_metadata public allows higher‑level components (like the new address sync flows or external callers) to reuse the SDK’s staleness checks instead of duplicating height/time validation logic. The implementation remains unchanged and still respects the configured tolerances.


635-665: verify_metadata_time visibility change is safe and keeps behavior intact

Promoting verify_metadata_time to pub(crate) doesn’t alter behavior and still backs the existing tests and verify_response_metadata path. The use of abs_diff with u64 metadata and now_ms is correct, and stale vs valid logging remains unchanged.

packages/rs-drive-abci/src/query/address_funds/addresses_branch_state/v0/mod.rs (1)

12-25: Checkpoint height plumbed correctly into branch-state query

Destructuring checkpoint_height from GetAddressesBranchStateRequestV0 and forwarding it to self.drive.prove_address_funds_branch_query is the expected glue for checkpoint‑aware branch proofs. The rest of the query/response handling is unchanged.

packages/rs-sdk/src/platform/address_sync/provider.rs (1)

1-49: AddressProvider trait cleanly abstracts wallet-specific logic

The trait documentation and example explain the intended gap‑limit behaviour and pending‑address lifecycle well, and the methods cover all the hooks the sync engine needs (supply addresses, react to found/absent, report highest index). Marking it Send is appropriate for async/address‑sync usage.

packages/rs-sdk/src/platform/address_sync/tracker.rs (1)

1-131: Well-structured tracking implementation.

The KeyLeafTracker provides a clean abstraction for managing the key-to-leaf mappings with proper reference counting. The use of saturating_sub prevents underflow, and the API is well-documented with clear method purposes.

packages/rs-sdk-ffi/src/address_sync/types.rs (2)

66-81: Raw pointer types lack Send/Sync impls - verify thread safety requirements.

DashSDKFoundAddress contains raw *mut u8 pointers. If these types are used across threads (e.g., passed between async tasks or FFI callbacks on different threads), explicit Send/Sync implementations with appropriate safety documentation would be needed.

The current design appears correct for single-threaded FFI usage, but verify this matches the intended usage pattern.


1-157: FFI types are well-designed for C interoperability.

The types follow proper FFI conventions with #[repr(C)], clear documentation of field semantics, and appropriate use of raw pointers with length fields. The Default implementations provide sensible values.

packages/rs-sdk/src/platform/address_sync/mod.rs (1)

94-198: Well-designed privacy-preserving synchronization workflow.

The implementation correctly handles:

  • Iterative trunk/branch query strategy
  • Privacy adjustment for small subtrees
  • Parallel branch query execution with concurrency limits
  • Metrics tracking for observability
  • Gap limit behavior with provider callbacks

The documentation is comprehensive and the code follows Rust idioms.

packages/rs-sdk-ffi/src/address_sync/mod.rs (4)

160-225: Memory allocation in convert_sync_result is correctly paired with dash_sdk_address_sync_result_free.

The allocation pattern using Box::into_raw(into_boxed_slice()) for arrays and corresponding Box::from_raw(slice::from_raw_parts_mut(...)) for deallocation is consistent. The key data is also properly allocated with Box::into_raw(into_boxed_slice()) and freed in the matching pattern.


297-312: Provider cleanup correctly handles the destroy callback.

The dash_sdk_address_provider_free function properly:

  • Handles null input
  • Checks for null vtable before dereferencing
  • Invokes the optional destroy callback for custom cleanup

This follows good FFI patterns.


70-76: Blocking async execution is appropriate for FFI.

The use of runtime.block_on() to execute the async sync_address_balances is the correct pattern for exposing async Rust code to C/FFI consumers. Callers should be aware this is a blocking call.


1-376: Comprehensive FFI bindings with proper memory management.

The module provides a complete FFI surface for address synchronization with:

  • Clear safety documentation for all public functions
  • Consistent null pointer handling
  • Proper memory lifecycle management
  • Both raw-pointer and result-based error handling variants
  • Utility functions for querying results

The naming follows the dash_sdk_* prefix convention as per coding guidelines for Platform functions.

Comment on lines 184 to 194
pub unsafe extern "C" fn dash_sdk_pending_address_list_free(list: *mut DashSDKPendingAddressList) {
if list.is_null() {
return;
}

let list = Box::from_raw(list);
if !list.addresses.is_null() && list.count > 0 {
// Only free the addresses array, not the key data (which is owned by caller)
let _ = Box::from_raw(std::slice::from_raw_parts_mut(list.addresses, list.count));
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Incorrect memory deallocation pattern for array.

Using Box::from_raw(std::slice::from_raw_parts_mut(...)) to free an array is incorrect. Box<[T]> and raw slices have different memory layouts. If the array was allocated via Vec::into_boxed_slice() then Box::into_raw(), this would work, but the current pattern is fragile and may cause undefined behavior depending on how the C caller allocated the memory.

Since the doc comment states "if the caller allocated the list dynamically," consider clarifying what allocation pattern is expected, or use Vec::from_raw_parts for deallocation.

🔎 Suggested fix
 #[no_mangle]
 pub unsafe extern "C" fn dash_sdk_pending_address_list_free(list: *mut DashSDKPendingAddressList) {
     if list.is_null() {
         return;
     }

     let list = Box::from_raw(list);
     if !list.addresses.is_null() && list.count > 0 {
         // Only free the addresses array, not the key data (which is owned by caller)
-        let _ = Box::from_raw(std::slice::from_raw_parts_mut(list.addresses, list.count));
+        // Drop the Vec to deallocate the addresses array
+        let _ = Vec::from_raw_parts(list.addresses, list.count, list.count);
     }
 }

Note: This assumes the array was allocated with the same allocator. If the C side allocates memory differently, this function should not be used, and the C caller should handle deallocation instead.

📝 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
pub unsafe extern "C" fn dash_sdk_pending_address_list_free(list: *mut DashSDKPendingAddressList) {
if list.is_null() {
return;
}
let list = Box::from_raw(list);
if !list.addresses.is_null() && list.count > 0 {
// Only free the addresses array, not the key data (which is owned by caller)
let _ = Box::from_raw(std::slice::from_raw_parts_mut(list.addresses, list.count));
}
}
pub unsafe extern "C" fn dash_sdk_pending_address_list_free(list: *mut DashSDKPendingAddressList) {
if list.is_null() {
return;
}
let list = Box::from_raw(list);
if !list.addresses.is_null() && list.count > 0 {
// Only free the addresses array, not the key data (which is owned by caller)
// Drop the Vec to deallocate the addresses array
let _ = Vec::from_raw_parts(list.addresses, list.count, list.count);
}
}
🤖 Prompt for AI Agents
In packages/rs-sdk-ffi/src/address_sync/provider.rs around lines 184 to 194, the
current deallocation uses Box::from_raw on a raw slice which is an
unsafe/incorrect layout assumption; instead reconstruct the allocation as a Vec
from raw parts and let it drop (e.g., Vec::from_raw_parts(list.addresses as *mut
T, list.count, list.count)) so the allocator and layout match, and update the
doc comment to specify the expected allocation pattern/ownership (or require the
C caller to free if different allocator is used).

Comment on lines +173 to +183
// Check if provider has extended pending addresses (gap limit behavior)
for (index, key) in provider.pending_addresses() {
if !key_to_index.contains_key(&key) {
key_to_index.insert(key.clone(), index);
// New key needs to be traced - it will be picked up in next iteration
// For now, trace it using the trunk result if possible
if let Some((leaf_key, info)) = trunk_result.trace_key_to_leaf(&key) {
tracker.add_key(key, leaf_key, info);
}
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Newly added addresses may not be synchronized if trunk lacks their path.

When the provider extends pending addresses (gap limit behavior), new keys are traced via trunk_result.trace_key_to_leaf(). If the trunk doesn't contain the path to the new key's location (e.g., if it falls outside the trunk's depth), the key is silently not added to the tracker and won't be synchronized.

Consider handling this case by either re-executing a trunk query or documenting this limitation.

🤖 Prompt for AI Agents
In packages/rs-sdk/src/platform/address_sync/mod.rs around lines 173 to 183,
newly added provider pending addresses are skipped if
trunk_result.trace_key_to_leaf(&key) returns None (trunk lacks the path),
causing those keys to never be tracked; modify the logic so that when
trace_key_to_leaf returns None you do not silently drop the key — instead either
(a) enqueue the key in a “pending_unresolved” set so it will be retried after
the next trunk query, or (b) trigger/re-execute a trunk query with increased
depth and retry tracing immediately, and only skip when retry fails; ensure the
key_to_index insertion remains and add a clear code-path that records unresolved
keys so they are synchronized later.

Comment on lines +464 to +469
fn extract_balance_from_element(element: &Element) -> u64 {
match element {
Element::SumItem(value, _) => *value as u64,
_ => 0,
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

# First, let's examine the file and the specific function
cat -n packages/rs-sdk/src/platform/address_sync/mod.rs | sed -n '460,475p'

Repository: dashpay/platform

Length of output: 655


🏁 Script executed:

# Search for Element and SumItem definitions to understand the structure
rg -n "enum Element" packages/rs-sdk/src/ -A 10 --type rust

Repository: dashpay/platform

Length of output: 42


🏁 Script executed:

# Check how SumItem values are created and used for balances
rg -n "SumItem" packages/rs-sdk/src/platform/address_sync/ --type rust -B 2 -A 2

Repository: dashpay/platform

Length of output: 912


🏁 Script executed:

# Look for how balance values are inserted into the tree
rg -n "extract_balance_from_element" packages/rs-sdk/src/ --type rust -B 5 -A 5

Repository: dashpay/platform

Length of output: 4041


🏁 Script executed:

# Search for where balances are stored/inserted to see if there's validation
rg -n "address.*balance\|balance.*tree" packages/rs-sdk/src/platform/address_sync/ --type rust -i | head -30

Repository: dashpay/platform

Length of output: 42


🏁 Script executed:

# Find where Element is defined
fd -e rs -x grep -l "enum Element" {} \; | head -20

Repository: dashpay/platform

Length of output: 121


🏁 Script executed:

# Search for SumItem creation in the codebase to see if there's validation
rg -n "SumItem\(" --type rust | head -30

Repository: dashpay/platform

Length of output: 4873


🏁 Script executed:

# Check how balance values flow into the address tree
rg -n "address.*fund\|fund.*tree" packages/rs-sdk/src/platform/ --type rust -i -C 2 | head -50

Repository: dashpay/platform

Length of output: 42


🏁 Script executed:

# Look for balance validation or assertions
rg -n "balance.*<.*0\|balance.*negative\|assert.*balance" packages/rs-sdk/src/platform/ --type rust -i | head -20

Repository: dashpay/platform

Length of output: 42


🏁 Script executed:

# Look at the explicit >= 0 check in verify_token_pre_programmed_distributions
cat -n packages/rs-drive/src/verify/tokens/verify_token_pre_programmed_distributions/v0/mod.rs | sed -n '75,90p'

Repository: dashpay/platform

Length of output: 907


🏁 Script executed:

# Also check the grove_get_raw_value_u64 for comparison
cat -n packages/rs-drive/src/util/grove_operations/grove_get_raw_value_u64_from_encoded_var_vec/v0/mod.rs | sed -n '30,45p'

Repository: dashpay/platform

Length of output: 940


🏁 Script executed:

# Check if there are any other similar balance extraction functions
rg -n "Element::SumItem.*as u64" --type rust -B 2 -A 2

Repository: dashpay/platform

Length of output: 1281


🏁 Script executed:

# Look at identity balance specifically to see if negatives are handled
rg -n "identity_balance\|identity.*balance" packages/rs-drive/src/verify/identity/ --type rust -B 3 -A 3 | head -40

Repository: dashpay/platform

Length of output: 42


Add explicit validation for negative SumItem values to match patterns used elsewhere in the codebase.

Element::SumItem stores an i64, and the cast *value as u64 will wrap negative values to large positive numbers. While address balances should never be negative in normal operation, the codebase shows that negative SumItem values are possible (see packages/rs-drive/src/verify/tokens/verify_token_pre_programmed_distributions/v0/mod.rs:80-84, which explicitly checks for and rejects negative values as data corruption). Consider adding a defensive check here to match that pattern:

 fn extract_balance_from_element(element: &Element) -> u64 {
     match element {
-        Element::SumItem(value, _) => *value as u64,
+        Element::SumItem(value, _) => {
+            debug_assert!(*value >= 0, "Unexpected negative balance: {}", value);
+            (*value).max(0) as u64
+        }
         _ => 0,
     }
 }
📝 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
fn extract_balance_from_element(element: &Element) -> u64 {
match element {
Element::SumItem(value, _) => *value as u64,
_ => 0,
}
}
fn extract_balance_from_element(element: &Element) -> u64 {
match element {
Element::SumItem(value, _) => {
debug_assert!(*value >= 0, "Unexpected negative balance: {}", value);
(*value).max(0) as u64
}
_ => 0,
}
}
🤖 Prompt for AI Agents
In packages/rs-sdk/src/platform/address_sync/mod.rs around lines 464-469, the
current cast of Element::SumItem i64 to u64 will wrap negative values; add an
explicit check for negative values used elsewhere in the codebase: if *value < 0
treat it as data corruption (log or report the error) and return 0 (or propagate
an Err if you prefer to change the signature), otherwise cast to u64 and return
the value.

Copy link
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 (3)
packages/rs-drive-abci/tests/strategy_tests/test_cases/address_tests.rs (3)

817-886: Consider extracting common test setup.

This test duplicates significant setup code from run_chain_address_transitions_with_checkpoints (lines 428-606). Both tests use nearly identical NetworkStrategy and PlatformConfig with only minor differences (block_signing and block_commit_signature_verification flags).

Consider extracting a helper function to reduce duplication:

fn create_address_transfer_strategy() -> NetworkStrategy {
    NetworkStrategy {
        strategy: Strategy {
            start_contracts: vec![],
            operations: vec![
                Operation {
                    op_type: OperationType::AddressTransfer(
                        dash_to_credits!(5)..=dash_to_credits!(5),
                        1..=4,
                        Some(0.2),
                        None,
                    ),
                    frequency: Frequency {
                        times_per_block_range: 1..3,
                        chance_per_block: None,
                    },
                },
                Operation {
                    op_type: OperationType::AddressFundingFromCoreAssetLock(
                        dash_to_credits!(20)..=dash_to_credits!(20),
                    ),
                    frequency: Frequency {
                        times_per_block_range: 1..3,
                        chance_per_block: None,
                    },
                },
            ],
            start_identities: StartIdentities::default(),
            start_addresses: StartAddresses::default(),
            identity_inserts: IdentityInsertInfo {
                frequency: Frequency {
                    times_per_block_range: 1..2,
                    chance_per_block: None,
                },
                ..Default::default()
            },
            identity_contract_nonce_gaps: None,
            signer: None,
        },
        total_hpmns: 100,
        extra_normal_mns: 0,
        validator_quorum_count: 24,
        chain_lock_quorum_count: 24,
        upgrading_info: None,
        proposer_strategy: Default::default(),
        rotate_quorums: false,
        failure_testing: None,
        query_testing: None,
        verify_state_transition_results: true,
        sign_instant_locks: true,
        ..Default::default()
    }
}

fn create_checkpoint_platform_config(enable_signing: bool) -> PlatformConfig {
    PlatformConfig {
        validator_set: ValidatorSetConfig::default_100_67(),
        chain_lock: ChainLockConfig::default_100_67(),
        instant_lock: InstantLockConfig::default_100_67(),
        execution: ExecutionConfig {
            verify_sum_trees: true,
            ..Default::default()
        },
        block_spacing_ms: 180000, // 3 mins
        testing_configs: PlatformTestConfig {
            block_signing: enable_signing,
            block_commit_signature_verification: enable_signing,
            disable_checkpoints: false,
            ..PlatformTestConfig::default_minimal_verifications()
        },
        ..Default::default()
    }
}

812-813: Consider moving imports to module level.

While function-scoped imports are valid in Rust, it's more conventional to declare imports at the module level for better discoverability and consistency with the rest of the file.

🔎 Proposed refactor

Move these imports to the top of the file with the other imports:

 use dpp::state_transition::StateTransition;
 use drive::drive::Drive;
+use drive::grovedb::GroveTrunkQueryResult;
 use drive_abci::config::{
     ChainLockConfig, ExecutionConfig, InstantLockConfig, PlatformConfig, PlatformTestConfig,
     ValidatorSetConfig,
 };
+use dpp::dashcore::Network;

And remove from the function:

     #[test]
     fn run_chain_address_transitions_with_proof_signature_verification() {
-        use dpp::dashcore::Network;
-        use drive::grovedb::GroveTrunkQueryResult;
-
         drive_abci::logging::init_for_tests(LogLevel::Debug);

891-899: Remove unnecessary clone.

The config is cloned on line 895 but not used afterward. The clone is unnecessary since run_chain_for_strategy does not consume the config.

🔎 Proposed fix
         let outcome = run_chain_for_strategy(
             &mut platform,
             13,
             strategy,
-            config.clone(),
+            config,
             15,
             &mut None,
             &mut None,
         );
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2ed7ba1 and 40e2fbe.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (3)
  • packages/rs-drive-abci/Cargo.toml
  • packages/rs-drive-abci/tests/strategy_tests/test_cases/address_tests.rs
  • packages/rs-drive/src/util/grove_operations/grove_get_proved_branch_chunk_query/v0/mod.rs
🧰 Additional context used
📓 Path-based instructions (2)
**/*.rs

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.rs: Rust code must pass cargo clippy --workspace linter checks
Rust code must be formatted using cargo fmt --all

**/*.rs: Use 4-space indent for Rust files
Follow rustfmt defaults and keep code clippy-clean for Rust modules
Use snake_case for Rust module names
Use PascalCase for Rust type names
Use SCREAMING_SNAKE_CASE for Rust constants

Files:

  • packages/rs-drive/src/util/grove_operations/grove_get_proved_branch_chunk_query/v0/mod.rs
  • packages/rs-drive-abci/tests/strategy_tests/test_cases/address_tests.rs
**/tests/**/*.{js,jsx,ts,tsx,rs}

📄 CodeRabbit inference engine (AGENTS.md)

**/tests/**/*.{js,jsx,ts,tsx,rs}: Name tests descriptively, starting with 'should …'
Unit and integration tests should not perform network calls; mock dependencies

Files:

  • packages/rs-drive-abci/tests/strategy_tests/test_cases/address_tests.rs
🧠 Learnings (15)
📓 Common learnings
Learnt from: CR
Repo: dashpay/platform PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T13:10:23.481Z
Learning: Applies to **/swift-sdk/**/*.{swift,h,m,c} : iOS SDK must combine both Core (SPV wallet) and Platform (identity/documents) functionality in the unified SDK with proper function naming: `dash_core_sdk_*` prefix for Core functions, `dash_sdk_*` prefix for Platform functions, and `dash_unified_sdk_*` prefix for unified functions
Learnt from: QuantumExplorer
Repo: dashpay/platform PR: 2257
File: packages/rs-drive-abci/src/mimic/test_quorum.rs:159-164
Timestamp: 2024-11-20T16:16:01.830Z
Learning: QuantumExplorer prefers not to receive auto-generated messages asking to post on social media.
📚 Learning: 2024-12-05T09:29:38.918Z
Learnt from: shumkov
Repo: dashpay/platform PR: 2375
File: packages/rs-drive-abci/Cargo.toml:61-63
Timestamp: 2024-12-05T09:29:38.918Z
Learning: In the `drive-abci` package, avoid adding unused dependencies like `hashbrown` to `Cargo.toml`. The team relies on CI to detect dependency version issues.

Applied to files:

  • packages/rs-drive-abci/Cargo.toml
📚 Learning: 2025-01-19T07:36:46.042Z
Learnt from: QuantumExplorer
Repo: dashpay/platform PR: 2431
File: packages/rs-drive/Cargo.toml:55-60
Timestamp: 2025-01-19T07:36:46.042Z
Learning: The grovedb dependencies in packages/rs-drive/Cargo.toml and related files are intentionally kept at specific revisions rather than using the latest stable version, with plans to update them at a later time.

Applied to files:

  • packages/rs-drive-abci/Cargo.toml
  • packages/rs-drive/src/util/grove_operations/grove_get_proved_branch_chunk_query/v0/mod.rs
📚 Learning: 2025-09-03T16:37:11.605Z
Learnt from: QuantumExplorer
Repo: dashpay/platform PR: 2756
File: packages/rs-drive-abci/src/execution/platform_events/core_based_updates/update_masternode_list/update_state_masternode_list/v0/mod.rs:11-11
Timestamp: 2025-09-03T16:37:11.605Z
Learning: In packages/rs-dpp/Cargo.toml, the abci feature already includes core_rpc_client, and core_rpc_client is defined as ["dep:dashcore-rpc"]. This means rs-drive-abci can access dashcore-rpc types through dpp when using the abci feature.

Applied to files:

  • packages/rs-drive-abci/Cargo.toml
📚 Learning: 2025-01-24T07:54:55.723Z
Learnt from: QuantumExplorer
Repo: dashpay/platform PR: 2440
File: packages/rs-drive-abci/Cargo.toml:76-76
Timestamp: 2025-01-24T07:54:55.723Z
Learning: In the drive-abci package, bls-signatures is intentionally declared twice:
1. As an optional dependency in [dependencies] to make it an optional feature in production
2. As a non-optional dependency in [dev-dependencies] to ensure it's always available for tests

Applied to files:

  • packages/rs-drive-abci/Cargo.toml
📚 Learning: 2025-11-25T13:10:23.481Z
Learnt from: CR
Repo: dashpay/platform PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T13:10:23.481Z
Learning: Use `rs-drive-proof-verifier` for cryptographic proof verification

Applied to files:

  • packages/rs-drive-abci/Cargo.toml
📚 Learning: 2024-10-09T00:22:57.778Z
Learnt from: shumkov
Repo: dashpay/platform PR: 2206
File: packages/rs-drive-abci/tests/strategy_tests/main.rs:89-89
Timestamp: 2024-10-09T00:22:57.778Z
Learning: In tests located in the `packages/rs-drive-abci/tests` directory, the team prefers to use specific protocol versions (e.g., `PROTOCOL_VERSION_1`) instead of `PROTOCOL_VERSION_LATEST`.

Applied to files:

  • packages/rs-drive-abci/Cargo.toml
📚 Learning: 2024-10-09T00:22:57.778Z
Learnt from: shumkov
Repo: dashpay/platform PR: 2206
File: packages/rs-drive-abci/tests/strategy_tests/main.rs:1162-1162
Timestamp: 2024-10-09T00:22:57.778Z
Learning: In the Rust test file `packages/rs-drive-abci/tests/strategy_tests/main.rs`, specific protocol versions like `PROTOCOL_VERSION_1` are intentionally used in tests instead of `PROTOCOL_VERSION_LATEST`.

Applied to files:

  • packages/rs-drive-abci/Cargo.toml
  • packages/rs-drive-abci/tests/strategy_tests/test_cases/address_tests.rs
📚 Learning: 2025-03-07T12:37:44.555Z
Learnt from: ogabrielides
Repo: dashpay/platform PR: 2486
File: packages/rs-drive/src/drive/platform_state/store_reduced_platform_state_bytes/v0/mod.rs:1-29
Timestamp: 2025-03-07T12:37:44.555Z
Learning: GroveDB operations like `insert()` return a tuple that includes a cost value which needs to be unwrapped with `.unwrap()` before error handling with `.map_err()`.

Applied to files:

  • packages/rs-drive/src/util/grove_operations/grove_get_proved_branch_chunk_query/v0/mod.rs
📚 Learning: 2024-11-20T20:43:41.185Z
Learnt from: QuantumExplorer
Repo: dashpay/platform PR: 2257
File: packages/rs-drive-abci/tests/strategy_tests/masternodes.rs:212-220
Timestamp: 2024-11-20T20:43:41.185Z
Learning: In `packages/rs-drive-abci/tests/strategy_tests/masternodes.rs`, the pattern of generating a `PrivateKey`, converting it to bytes, and reconstructing a `BlsPrivateKey` from those bytes is intentional. Avoid suggesting to simplify this code in future reviews.

Applied to files:

  • packages/rs-drive-abci/tests/strategy_tests/test_cases/address_tests.rs
📚 Learning: 2024-11-20T16:05:40.200Z
Learnt from: QuantumExplorer
Repo: dashpay/platform PR: 2257
File: packages/rs-drive-abci/src/platform_types/signature_verification_quorum_set/v0/for_saving.rs:148-151
Timestamp: 2024-11-20T16:05:40.200Z
Learning: In `packages/rs-drive-abci/src/platform_types/signature_verification_quorum_set/v0/for_saving.rs`, when converting public keys from `QuorumForSavingV0` to `VerificationQuorum`, it's acceptable to use `.expect()` for public key conversion, as the conversion has been verified and panics are acceptable in this context.

Applied to files:

  • packages/rs-drive-abci/tests/strategy_tests/test_cases/address_tests.rs
📚 Learning: 2024-10-30T11:19:59.163Z
Learnt from: lklimek
Repo: dashpay/platform PR: 2277
File: packages/rs-sdk/tests/fetch/config.rs:233-233
Timestamp: 2024-10-30T11:19:59.163Z
Learning: In the Rust SDK's `rs-sdk/tests` integration tests (e.g., in `packages/rs-sdk/tests/fetch/config.rs`), we cannot create objects during tests because there is no support for object creation in this context. Therefore, hardcoded values for test identities must be used.

Applied to files:

  • packages/rs-drive-abci/tests/strategy_tests/test_cases/address_tests.rs
📚 Learning: 2024-10-21T01:03:42.458Z
Learnt from: QuantumExplorer
Repo: dashpay/platform PR: 2227
File: packages/rs-dpp/src/core_types/validator_set/v0/mod.rs:299-299
Timestamp: 2024-10-21T01:03:42.458Z
Learning: In the `test_serialize_deserialize_validator_set_v0` test within `packages/rs-dpp/src/core_types/validator_set/v0/mod.rs`, deterministic BLS keys cannot be easily used; therefore, using `BlsPublicKey::generate()` is acceptable.

Applied to files:

  • packages/rs-drive-abci/tests/strategy_tests/test_cases/address_tests.rs
📚 Learning: 2024-10-06T16:18:07.994Z
Learnt from: QuantumExplorer
Repo: dashpay/platform PR: 2215
File: packages/rs-drive-abci/src/execution/engine/run_block_proposal/mod.rs:119-120
Timestamp: 2024-10-06T16:18:07.994Z
Learning: In the `run_block_proposal` function in `packages/rs-drive-abci/src/execution/engine/run_block_proposal/mod.rs`, it's acceptable to pass `platform_state` to `perform_events_on_first_block_of_protocol_change`, even if `block_platform_state` has been updated.

Applied to files:

  • packages/rs-drive-abci/tests/strategy_tests/test_cases/address_tests.rs
📚 Learning: 2024-10-06T16:17:34.571Z
Learnt from: QuantumExplorer
Repo: dashpay/platform PR: 2215
File: packages/rs-drive-abci/src/execution/engine/run_block_proposal/mod.rs:105-105
Timestamp: 2024-10-06T16:17:34.571Z
Learning: In `run_block_proposal` in `packages/rs-drive-abci/src/execution/engine/run_block_proposal/mod.rs`, when retrieving `last_block_time_ms`, it's acceptable to use `platform_state` instead of `block_platform_state`, even after updating the protocol version.

Applied to files:

  • packages/rs-drive-abci/tests/strategy_tests/test_cases/address_tests.rs
🧬 Code graph analysis (1)
packages/rs-drive/src/util/grove_operations/grove_get_proved_branch_chunk_query/v0/mod.rs (1)
packages/rs-drive/src/error/mod.rs (4)
  • from (80-82)
  • from (86-88)
  • from (92-94)
  • from (98-100)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (20)
  • GitHub Check: Rust packages (rs-sdk-ffi) / Formatting
  • GitHub Check: Rust packages (rs-sdk-ffi) / Linting
  • GitHub Check: Rust packages (dapi-grpc) / Tests
  • GitHub Check: Rust packages (rs-sdk-ffi) / Tests
  • GitHub Check: Rust packages (dapi-grpc) / Formatting
  • GitHub Check: Rust packages (dapi-grpc) / Linting
  • GitHub Check: Rust packages (dash-sdk) / Linting
  • GitHub Check: Rust packages (dash-sdk) / Tests
  • GitHub Check: Rust packages (dash-sdk) / Check each feature
  • GitHub Check: Rust packages (rs-sdk-ffi) / Unused dependencies
  • GitHub Check: Rust packages (dash-sdk) / Unused dependencies
  • GitHub Check: Rust packages (dapi-grpc) / Unused dependencies
  • GitHub Check: Rust packages (dash-sdk) / Formatting
  • GitHub Check: Rust packages (dapi-grpc) / Check each feature
  • GitHub Check: Rust packages (drive) / Unused dependencies
  • GitHub Check: Rust packages (wasm-sdk) / Tests
  • GitHub Check: Rust packages (dpp) / Tests
  • GitHub Check: Rust packages (drive-abci) / Unused dependencies
  • GitHub Check: Rust packages (rs-dapi-client) / Unused dependencies
  • GitHub Check: Rust crates security audit
🔇 Additional comments (6)
packages/rs-drive/src/util/grove_operations/grove_get_proved_branch_chunk_query/v0/mod.rs (1)

1-59: LGTM! Clean implementation of checkpoint-aware proof retrieval.

The branching logic for GroveDBToUse is well-structured with consistent cost tracking across all three paths. Error handling appropriately distinguishes between "no checkpoints available" and "specific checkpoint not found" cases. The documentation clearly describes the new parameter.

packages/rs-drive-abci/Cargo.toml (1)

98-98: No action needed: drive-proof-verifier is correctly placed in [dev-dependencies] only.

Verification confirms that drive-proof-verifier is intentionally declared only in the [dev-dependencies] section. Production code has no imports of this crate; the only reference found is a tracing log level string in test configuration. This is the correct design for a test-only dependency.

packages/rs-drive-abci/tests/strategy_tests/test_cases/address_tests.rs (4)

12-14: LGTM!

The new imports appropriately support the proof verification test infrastructure, including quorum key management, context provision, and proof verification via FromProof.

Also applies to: 16-16, 24-24, 27-27, 29-30


35-62: LGTM!

The TestContextProvider struct and constructor are well-designed test scaffolding. The use of .expect() for the public key conversion is acceptable in test code, as the conversion should always succeed for valid test quorum data.


64-101: LGTM!

The ContextProvider implementation provides the minimal test infrastructure needed. The get_quorum_public_key method correctly looks up keys from the test quorum map, while the other methods appropriately return stub values (None or 1) since they're not needed for this test scenario.


958-1018: LGTM! Comprehensive proof signature verification.

The core test logic is excellent. It properly:

  • Creates a TestContextProvider with quorum public keys from the test execution
  • Verifies proof signatures using FromProof::maybe_from_proof_with_metadata
  • Validates trunk query results (elements, leaf_keys, chunk_depths)
  • Verifies proof structure (quorum_hash length, signature length, quorum_type)
  • Includes helpful logging for debugging

The assertion on line 968 correctly identifies this as "the key test" for proof signature verification, and the detailed verification steps that follow provide good coverage of the proof validation pathway.

Comment on lines +810 to +811
#[test]
fn run_chain_address_transitions_with_proof_signature_verification() {
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Rename test to follow naming convention.

Per coding guidelines, test names should start with should_. Consider renaming to something like should_verify_proof_signatures_when_querying_address_trunk_state_with_checkpoints.

🔎 Proposed fix
-    #[test]
-    fn run_chain_address_transitions_with_proof_signature_verification() {
+    #[test]
+    fn should_verify_proof_signatures_when_querying_address_trunk_state_with_checkpoints() {

As per coding guidelines, test names should start with 'should …'

📝 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
#[test]
fn run_chain_address_transitions_with_proof_signature_verification() {
#[test]
fn should_verify_proof_signatures_when_querying_address_trunk_state_with_checkpoints() {
🤖 Prompt for AI Agents
In packages/rs-drive-abci/tests/strategy_tests/test_cases/address_tests.rs
around lines 810-811, the test function name
run_chain_address_transitions_with_proof_signature_verification does not follow
the project's test naming convention (must start with should_); rename the
function to a descriptive should_* name (for example
should_verify_proof_signatures_when_querying_address_trunk_state_with_checkpoints),
update any internal references or documentation that call the old name, and run
cargo test to confirm the renamed test compiles and executes.

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

♻️ Duplicate comments (1)
packages/rs-drive-abci/tests/strategy_tests/test_cases/address_tests.rs (1)

810-811: Rename test to follow naming convention.

The test name should start with should_ per coding guidelines. Consider renaming to should_verify_proof_signatures_when_querying_address_trunk_state_with_checkpoints.

As per coding guidelines, test names should start with 'should …'

🧹 Nitpick comments (2)
packages/rs-drive-abci/tests/strategy_tests/test_cases/address_tests.rs (1)

64-101: Consider documenting the limited scope of stub methods.

The ContextProvider implementation is correct for the address trunk query test. However, the stub implementations (get_data_contract, get_token_configuration, get_platform_activation_height) return minimal values that work for address queries but may cause silent failures if this provider is reused for tests involving contracts or tokens.

🔎 Suggested documentation addition
 /// A test ContextProvider that provides quorum public keys from a map of test quorums.
-/// This is used to verify proof signatures in strategy tests.
+/// This is used to verify proof signatures in strategy tests.
+///
+/// **Note**: This provider only implements `get_quorum_public_key` fully.
+/// Other methods return stub values suitable for address trunk queries only.
+/// Do not reuse for tests requiring contracts, tokens, or specific activation heights.
 struct TestContextProvider {
     quorum_public_keys: BTreeMap<([u8; 32], u32), [u8; 48]>,
 }
packages/rs-drive-abci/src/execution/platform_events/block_end/should_checkpoint/v0/mod.rs (1)

30-30: Consider removing inline(always) for a function with I/O.

The inline(always) attribute is aggressive for a function that loads checkpoints from storage. Since this function performs I/O operations (line 60), forced inlining may not provide benefits and could increase code size. Consider using #[inline] or removing the attribute entirely to let the compiler decide.

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 40e2fbe and 26fd5b7.

📒 Files selected for processing (21)
  • packages/rs-drive-abci/src/abci/handler/finalize_block.rs
  • packages/rs-drive-abci/src/execution/engine/finalize_block_proposal/v0/mod.rs
  • packages/rs-drive-abci/src/execution/platform_events/block_end/create_grovedb_checkpoint/mod.rs
  • packages/rs-drive-abci/src/execution/platform_events/block_end/create_grovedb_checkpoint/v0/mod.rs
  • packages/rs-drive-abci/src/execution/platform_events/block_end/mod.rs
  • packages/rs-drive-abci/src/execution/platform_events/block_end/should_checkpoint/mod.rs
  • packages/rs-drive-abci/src/execution/platform_events/block_end/should_checkpoint/v0/mod.rs
  • packages/rs-drive-abci/src/execution/platform_events/block_end/update_checkpoints/v0/mod.rs
  • packages/rs-drive-abci/src/execution/platform_events/block_end/update_state_cache/mod.rs
  • packages/rs-drive-abci/src/execution/platform_events/block_end/update_state_cache/v0/mod.rs
  • packages/rs-drive-abci/src/platform_types/block_execution_outcome/v0/mod.rs
  • packages/rs-drive-abci/tests/strategy_tests/test_cases/address_tests.rs
  • packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_method_versions/mod.rs
  • packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_method_versions/v1.rs
  • packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_method_versions/v2.rs
  • packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_method_versions/v3.rs
  • packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_method_versions/v4.rs
  • packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_method_versions/v5.rs
  • packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_method_versions/v6.rs
  • packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_method_versions/v7.rs
  • packages/rs-platform-version/src/version/mocks/v3_test.rs
💤 Files with no reviewable changes (1)
  • packages/rs-drive-abci/src/execution/platform_events/block_end/update_state_cache/mod.rs
🧰 Additional context used
📓 Path-based instructions (2)
**/*.rs

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.rs: Rust code must pass cargo clippy --workspace linter checks
Rust code must be formatted using cargo fmt --all

**/*.rs: Use 4-space indent for Rust files
Follow rustfmt defaults and keep code clippy-clean for Rust modules
Use snake_case for Rust module names
Use PascalCase for Rust type names
Use SCREAMING_SNAKE_CASE for Rust constants

Files:

  • packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_method_versions/mod.rs
  • packages/rs-drive-abci/src/platform_types/block_execution_outcome/v0/mod.rs
  • packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_method_versions/v2.rs
  • packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_method_versions/v6.rs
  • packages/rs-drive-abci/src/abci/handler/finalize_block.rs
  • packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_method_versions/v4.rs
  • packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_method_versions/v5.rs
  • packages/rs-drive-abci/src/execution/platform_events/block_end/create_grovedb_checkpoint/mod.rs
  • packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_method_versions/v7.rs
  • packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_method_versions/v1.rs
  • packages/rs-drive-abci/src/execution/platform_events/block_end/create_grovedb_checkpoint/v0/mod.rs
  • packages/rs-drive-abci/src/execution/engine/finalize_block_proposal/v0/mod.rs
  • packages/rs-drive-abci/src/execution/platform_events/block_end/mod.rs
  • packages/rs-drive-abci/src/execution/platform_events/block_end/should_checkpoint/v0/mod.rs
  • packages/rs-drive-abci/src/execution/platform_events/block_end/update_state_cache/v0/mod.rs
  • packages/rs-platform-version/src/version/mocks/v3_test.rs
  • packages/rs-drive-abci/tests/strategy_tests/test_cases/address_tests.rs
  • packages/rs-drive-abci/src/execution/platform_events/block_end/update_checkpoints/v0/mod.rs
  • packages/rs-drive-abci/src/execution/platform_events/block_end/should_checkpoint/mod.rs
  • packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_method_versions/v3.rs
**/tests/**/*.{js,jsx,ts,tsx,rs}

📄 CodeRabbit inference engine (AGENTS.md)

**/tests/**/*.{js,jsx,ts,tsx,rs}: Name tests descriptively, starting with 'should …'
Unit and integration tests should not perform network calls; mock dependencies

Files:

  • packages/rs-drive-abci/tests/strategy_tests/test_cases/address_tests.rs
🧠 Learnings (18)
📓 Common learnings
Learnt from: CR
Repo: dashpay/platform PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T13:10:23.481Z
Learning: Applies to **/swift-sdk/**/*.{swift,h,m,c} : iOS SDK must combine both Core (SPV wallet) and Platform (identity/documents) functionality in the unified SDK with proper function naming: `dash_core_sdk_*` prefix for Core functions, `dash_sdk_*` prefix for Platform functions, and `dash_unified_sdk_*` prefix for unified functions
Learnt from: QuantumExplorer
Repo: dashpay/platform PR: 2257
File: packages/rs-drive-abci/src/mimic/test_quorum.rs:159-164
Timestamp: 2024-11-20T16:16:01.830Z
Learning: QuantumExplorer prefers not to receive auto-generated messages asking to post on social media.
📚 Learning: 2024-10-08T13:28:03.529Z
Learnt from: QuantumExplorer
Repo: dashpay/platform PR: 2227
File: packages/rs-drive-abci/src/platform_types/platform_state/mod.rs:141-141
Timestamp: 2024-10-08T13:28:03.529Z
Learning: When converting `PlatformStateV0` to `PlatformStateForSavingV1` in `packages/rs-drive-abci/src/platform_types/platform_state/mod.rs`, only version `0` needs to be handled in the match on `platform_state_for_saving_structure_default` because the changes are retroactive.

Applied to files:

  • packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_method_versions/mod.rs
  • packages/rs-drive-abci/src/platform_types/block_execution_outcome/v0/mod.rs
  • packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_method_versions/v2.rs
  • packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_method_versions/v6.rs
  • packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_method_versions/v4.rs
  • packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_method_versions/v5.rs
  • packages/rs-drive-abci/src/execution/platform_events/block_end/create_grovedb_checkpoint/mod.rs
  • packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_method_versions/v7.rs
  • packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_method_versions/v1.rs
  • packages/rs-drive-abci/src/execution/platform_events/block_end/create_grovedb_checkpoint/v0/mod.rs
  • packages/rs-drive-abci/src/execution/engine/finalize_block_proposal/v0/mod.rs
  • packages/rs-drive-abci/src/execution/platform_events/block_end/mod.rs
  • packages/rs-drive-abci/src/execution/platform_events/block_end/should_checkpoint/v0/mod.rs
  • packages/rs-drive-abci/src/execution/platform_events/block_end/update_state_cache/v0/mod.rs
  • packages/rs-platform-version/src/version/mocks/v3_test.rs
  • packages/rs-drive-abci/src/execution/platform_events/block_end/update_checkpoints/v0/mod.rs
  • packages/rs-drive-abci/src/execution/platform_events/block_end/should_checkpoint/mod.rs
  • packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_method_versions/v3.rs
📚 Learning: 2025-05-28T16:22:26.334Z
Learnt from: QuantumExplorer
Repo: dashpay/platform PR: 2644
File: packages/rs-drive/src/cache/system_contracts.rs:18-19
Timestamp: 2025-05-28T16:22:26.334Z
Learning: In packages/rs-drive/src/cache/system_contracts.rs, the `active_since_protocol_version` field in `ActiveSystemDataContract` struct is intentionally added for future use, not current implementation. QuantumExplorer confirmed this is "meant for later" when questioned about the `#[allow(unused)]` attribute.

Applied to files:

  • packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_method_versions/mod.rs
  • packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_method_versions/v2.rs
  • packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_method_versions/v4.rs
  • packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_method_versions/v5.rs
  • packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_method_versions/v1.rs
  • packages/rs-platform-version/src/version/mocks/v3_test.rs
📚 Learning: 2024-11-20T10:01:50.837Z
Learnt from: QuantumExplorer
Repo: dashpay/platform PR: 2257
File: packages/rs-drive-abci/src/platform_types/platform_state/v0/old_structures/mod.rs:94-94
Timestamp: 2024-11-20T10:01:50.837Z
Learning: In `packages/rs-drive-abci/src/platform_types/platform_state/v0/old_structures/mod.rs`, when converting with `PublicKey::try_from`, it's acceptable to use `.expect()` to handle potential conversion errors.

Applied to files:

  • packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_method_versions/mod.rs
  • packages/rs-drive-abci/src/execution/platform_events/block_end/create_grovedb_checkpoint/mod.rs
  • packages/rs-drive-abci/src/execution/platform_events/block_end/should_checkpoint/v0/mod.rs
  • packages/rs-drive-abci/src/execution/platform_events/block_end/update_state_cache/v0/mod.rs
📚 Learning: 2024-10-09T00:22:57.778Z
Learnt from: shumkov
Repo: dashpay/platform PR: 2206
File: packages/rs-drive-abci/tests/strategy_tests/main.rs:1162-1162
Timestamp: 2024-10-09T00:22:57.778Z
Learning: In the Rust test file `packages/rs-drive-abci/tests/strategy_tests/main.rs`, specific protocol versions like `PROTOCOL_VERSION_1` are intentionally used in tests instead of `PROTOCOL_VERSION_LATEST`.

Applied to files:

  • packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_method_versions/mod.rs
  • packages/rs-platform-version/src/version/mocks/v3_test.rs
  • packages/rs-drive-abci/tests/strategy_tests/test_cases/address_tests.rs
📚 Learning: 2024-10-09T00:22:57.778Z
Learnt from: QuantumExplorer
Repo: dashpay/platform PR: 2215
File: packages/rs-drive-abci/src/execution/engine/run_block_proposal/mod.rs:105-105
Timestamp: 2024-10-09T00:22:57.778Z
Learning: In `run_block_proposal` in `packages/rs-drive-abci/src/execution/engine/run_block_proposal/mod.rs`, when retrieving `last_block_time_ms`, it's acceptable to use `platform_state` instead of `block_platform_state`, even after updating the protocol version.

Applied to files:

  • packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_method_versions/mod.rs
  • packages/rs-drive-abci/src/platform_types/block_execution_outcome/v0/mod.rs
  • packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_method_versions/v6.rs
  • packages/rs-drive-abci/src/abci/handler/finalize_block.rs
  • packages/rs-drive-abci/src/execution/platform_events/block_end/create_grovedb_checkpoint/mod.rs
  • packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_method_versions/v7.rs
  • packages/rs-drive-abci/src/execution/platform_events/block_end/create_grovedb_checkpoint/v0/mod.rs
  • packages/rs-drive-abci/src/execution/engine/finalize_block_proposal/v0/mod.rs
  • packages/rs-drive-abci/src/execution/platform_events/block_end/mod.rs
  • packages/rs-drive-abci/src/execution/platform_events/block_end/should_checkpoint/v0/mod.rs
  • packages/rs-drive-abci/src/execution/platform_events/block_end/update_state_cache/v0/mod.rs
  • packages/rs-drive-abci/tests/strategy_tests/test_cases/address_tests.rs
  • packages/rs-drive-abci/src/execution/platform_events/block_end/update_checkpoints/v0/mod.rs
  • packages/rs-drive-abci/src/execution/platform_events/block_end/should_checkpoint/mod.rs
📚 Learning: 2024-10-06T16:18:07.994Z
Learnt from: QuantumExplorer
Repo: dashpay/platform PR: 2215
File: packages/rs-drive-abci/src/execution/engine/run_block_proposal/mod.rs:119-120
Timestamp: 2024-10-06T16:18:07.994Z
Learning: In the `run_block_proposal` function in `packages/rs-drive-abci/src/execution/engine/run_block_proposal/mod.rs`, it's acceptable to pass `platform_state` to `perform_events_on_first_block_of_protocol_change`, even if `block_platform_state` has been updated.

Applied to files:

  • packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_method_versions/mod.rs
  • packages/rs-drive-abci/src/platform_types/block_execution_outcome/v0/mod.rs
  • packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_method_versions/v6.rs
  • packages/rs-drive-abci/src/abci/handler/finalize_block.rs
  • packages/rs-drive-abci/src/execution/platform_events/block_end/create_grovedb_checkpoint/mod.rs
  • packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_method_versions/v7.rs
  • packages/rs-drive-abci/src/execution/platform_events/block_end/create_grovedb_checkpoint/v0/mod.rs
  • packages/rs-drive-abci/src/execution/engine/finalize_block_proposal/v0/mod.rs
  • packages/rs-drive-abci/src/execution/platform_events/block_end/mod.rs
  • packages/rs-drive-abci/src/execution/platform_events/block_end/should_checkpoint/v0/mod.rs
  • packages/rs-drive-abci/src/execution/platform_events/block_end/update_state_cache/v0/mod.rs
  • packages/rs-drive-abci/tests/strategy_tests/test_cases/address_tests.rs
  • packages/rs-drive-abci/src/execution/platform_events/block_end/update_checkpoints/v0/mod.rs
  • packages/rs-drive-abci/src/execution/platform_events/block_end/should_checkpoint/mod.rs
📚 Learning: 2024-11-22T08:19:14.448Z
Learnt from: shumkov
Repo: dashpay/platform PR: 2345
File: packages/rs-drive-abci/src/execution/platform_events/protocol_upgrade/perform_events_on_first_block_of_protocol_change/v0/mod.rs:93-99
Timestamp: 2024-11-22T08:19:14.448Z
Learning: In `packages/rs-drive-abci/src/execution/platform_events/protocol_upgrade/perform_events_on_first_block_of_protocol_change/v0/mod.rs`, the `insert_contract` method requires an owned `BlockInfo`, so cloning `block_info` is necessary when calling it.

Applied to files:

  • packages/rs-drive-abci/src/platform_types/block_execution_outcome/v0/mod.rs
  • packages/rs-drive-abci/src/abci/handler/finalize_block.rs
  • packages/rs-drive-abci/src/execution/platform_events/block_end/create_grovedb_checkpoint/mod.rs
  • packages/rs-drive-abci/src/execution/platform_events/block_end/create_grovedb_checkpoint/v0/mod.rs
  • packages/rs-drive-abci/src/execution/engine/finalize_block_proposal/v0/mod.rs
  • packages/rs-drive-abci/src/execution/platform_events/block_end/mod.rs
  • packages/rs-drive-abci/src/execution/platform_events/block_end/should_checkpoint/v0/mod.rs
  • packages/rs-drive-abci/src/execution/platform_events/block_end/update_state_cache/v0/mod.rs
  • packages/rs-drive-abci/src/execution/platform_events/block_end/update_checkpoints/v0/mod.rs
  • packages/rs-drive-abci/src/execution/platform_events/block_end/should_checkpoint/mod.rs
📚 Learning: 2024-11-03T10:39:11.242Z
Learnt from: shumkov
Repo: dashpay/platform PR: 2305
File: packages/rs-drive-abci/src/abci/handler/finalize_block.rs:81-0
Timestamp: 2024-11-03T10:39:11.242Z
Learning: In `packages/rs-drive-abci/src/abci/handler/finalize_block.rs`, the use of `.expect("commit transaction")` after `app.commit_transaction(platform_version)` is intentional due to the provided comment explaining its necessity. Do not flag this usage in future reviews.

Applied to files:

  • packages/rs-drive-abci/src/platform_types/block_execution_outcome/v0/mod.rs
  • packages/rs-drive-abci/src/abci/handler/finalize_block.rs
  • packages/rs-drive-abci/src/execution/platform_events/block_end/create_grovedb_checkpoint/mod.rs
  • packages/rs-drive-abci/src/execution/engine/finalize_block_proposal/v0/mod.rs
  • packages/rs-drive-abci/src/execution/platform_events/block_end/mod.rs
  • packages/rs-drive-abci/src/execution/platform_events/block_end/should_checkpoint/v0/mod.rs
  • packages/rs-drive-abci/src/execution/platform_events/block_end/update_state_cache/v0/mod.rs
  • packages/rs-drive-abci/tests/strategy_tests/test_cases/address_tests.rs
  • packages/rs-drive-abci/src/execution/platform_events/block_end/should_checkpoint/mod.rs
📚 Learning: 2025-10-09T15:59:28.329Z
Learnt from: lklimek
Repo: dashpay/platform PR: 2716
File: packages/rs-dapi/src/services/platform_service/broadcast_state_transition.rs:181-187
Timestamp: 2025-10-09T15:59:28.329Z
Learning: In `packages/rs-dapi/src/services/platform_service/broadcast_state_transition.rs`, the maintainer requires logging full state transition bytes (`tx_bytes = hex::encode(st_bytes)`) at debug level when a state transition passes CheckTx but is removed from the block by the proposer, to facilitate debugging of this rare edge case.

Applied to files:

  • packages/rs-drive-abci/src/abci/handler/finalize_block.rs
  • packages/rs-drive-abci/src/execution/engine/finalize_block_proposal/v0/mod.rs
  • packages/rs-drive-abci/src/execution/platform_events/block_end/should_checkpoint/v0/mod.rs
  • packages/rs-drive-abci/src/execution/platform_events/block_end/update_state_cache/v0/mod.rs
  • packages/rs-drive-abci/tests/strategy_tests/test_cases/address_tests.rs
📚 Learning: 2025-01-19T07:36:46.042Z
Learnt from: QuantumExplorer
Repo: dashpay/platform PR: 2431
File: packages/rs-drive/Cargo.toml:55-60
Timestamp: 2025-01-19T07:36:46.042Z
Learning: The grovedb dependencies in packages/rs-drive/Cargo.toml and related files are intentionally kept at specific revisions rather than using the latest stable version, with plans to update them at a later time.

Applied to files:

  • packages/rs-drive-abci/src/execution/platform_events/block_end/create_grovedb_checkpoint/mod.rs
  • packages/rs-drive-abci/src/execution/platform_events/block_end/create_grovedb_checkpoint/v0/mod.rs
  • packages/rs-drive-abci/src/execution/platform_events/block_end/mod.rs
📚 Learning: 2024-10-09T00:22:57.778Z
Learnt from: QuantumExplorer
Repo: dashpay/platform PR: 2215
File: packages/rs-drive-abci/src/execution/platform_events/core_based_updates/update_masternode_identities/create_owner_identity/v1/mod.rs:19-30
Timestamp: 2024-10-09T00:22:57.778Z
Learning: In the Rust file `packages/rs-drive-abci/src/execution/platform_events/core_based_updates/update_masternode_identities/create_owner_identity/v1/mod.rs`, within the `create_owner_identity_v1` function, the `add_public_keys` method of the `Identity` struct cannot fail and does not require explicit error handling.

Applied to files:

  • packages/rs-drive-abci/src/execution/platform_events/block_end/create_grovedb_checkpoint/mod.rs
  • packages/rs-drive-abci/src/execution/platform_events/block_end/create_grovedb_checkpoint/v0/mod.rs
📚 Learning: 2024-11-20T20:43:41.185Z
Learnt from: QuantumExplorer
Repo: dashpay/platform PR: 2257
File: packages/rs-drive-abci/tests/strategy_tests/masternodes.rs:212-220
Timestamp: 2024-11-20T20:43:41.185Z
Learning: In `packages/rs-drive-abci/tests/strategy_tests/masternodes.rs`, the pattern of generating a `PrivateKey`, converting it to bytes, and reconstructing a `BlsPrivateKey` from those bytes is intentional. Avoid suggesting to simplify this code in future reviews.

Applied to files:

  • packages/rs-drive-abci/src/execution/engine/finalize_block_proposal/v0/mod.rs
  • packages/rs-drive-abci/tests/strategy_tests/test_cases/address_tests.rs
📚 Learning: 2024-10-09T00:22:57.778Z
Learnt from: shumkov
Repo: dashpay/platform PR: 2201
File: packages/rs-platform-version/src/version/v2.rs:1186-1188
Timestamp: 2024-10-09T00:22:57.778Z
Learning: In the `IdentityTransitionVersions` structure within `packages/rs-platform-version/src/version/v2.rs`, the field `credit_withdrawal` does not need the `identity_` prefix since it is already encompassed within identity state transitions.

Applied to files:

  • packages/rs-drive-abci/src/execution/platform_events/block_end/update_state_cache/v0/mod.rs
  • packages/rs-drive-abci/tests/strategy_tests/test_cases/address_tests.rs
📚 Learning: 2025-11-25T13:10:23.481Z
Learnt from: CR
Repo: dashpay/platform PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T13:10:23.481Z
Learning: Use Rust for core platform components (Drive, DAPI server, DPP implementation)

Applied to files:

  • packages/rs-drive-abci/src/execution/platform_events/block_end/update_state_cache/v0/mod.rs
📚 Learning: 2024-11-20T16:05:40.200Z
Learnt from: QuantumExplorer
Repo: dashpay/platform PR: 2257
File: packages/rs-drive-abci/src/platform_types/signature_verification_quorum_set/v0/for_saving.rs:148-151
Timestamp: 2024-11-20T16:05:40.200Z
Learning: In `packages/rs-drive-abci/src/platform_types/signature_verification_quorum_set/v0/for_saving.rs`, when converting public keys from `QuorumForSavingV0` to `VerificationQuorum`, it's acceptable to use `.expect()` for public key conversion, as the conversion has been verified and panics are acceptable in this context.

Applied to files:

  • packages/rs-drive-abci/tests/strategy_tests/test_cases/address_tests.rs
📚 Learning: 2024-10-30T11:19:59.163Z
Learnt from: lklimek
Repo: dashpay/platform PR: 2277
File: packages/rs-sdk/tests/fetch/config.rs:233-233
Timestamp: 2024-10-30T11:19:59.163Z
Learning: In the Rust SDK's `rs-sdk/tests` integration tests (e.g., in `packages/rs-sdk/tests/fetch/config.rs`), we cannot create objects during tests because there is no support for object creation in this context. Therefore, hardcoded values for test identities must be used.

Applied to files:

  • packages/rs-drive-abci/tests/strategy_tests/test_cases/address_tests.rs
📚 Learning: 2025-06-18T03:44:14.385Z
Learnt from: QuantumExplorer
Repo: dashpay/platform PR: 2673
File: packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_update/mod.rs:1164-1197
Timestamp: 2025-06-18T03:44:14.385Z
Learning: QuantumExplorer determined that a CodeRabbit suggestion about fixing signable_bytes calculation in identity update tests with contract-bound keys was incorrect - the code flow is working as intended without the suggested changes.

Applied to files:

  • packages/rs-drive-abci/tests/strategy_tests/test_cases/address_tests.rs
🧬 Code graph analysis (2)
packages/rs-drive-abci/src/execution/platform_events/block_end/mod.rs (3)
packages/rs-drive-abci/src/execution/platform_events/block_end/should_checkpoint/mod.rs (1)
  • should_checkpoint (20-39)
packages/rs-drive-abci/src/execution/platform_events/block_end/update_checkpoints/mod.rs (1)
  • update_checkpoints (33-52)
packages/rs-drive-abci/src/execution/platform_events/block_end/create_grovedb_checkpoint/mod.rs (1)
  • create_grovedb_checkpoint (26-44)
packages/rs-drive-abci/src/execution/platform_events/block_end/update_checkpoints/v0/mod.rs (1)
packages/rs-drive-abci/src/execution/platform_events/block_end/should_checkpoint/mod.rs (1)
  • should_checkpoint (20-39)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (19)
  • GitHub Check: Rust packages (rs-sdk-ffi) / Unused dependencies
  • GitHub Check: Rust packages (rs-sdk-ffi) / Linting
  • GitHub Check: Rust packages (dash-sdk) / Formatting
  • GitHub Check: Rust packages (rs-sdk-ffi) / Tests
  • GitHub Check: Rust packages (dash-sdk) / Check each feature
  • GitHub Check: Rust packages (rs-sdk-ffi) / Formatting
  • GitHub Check: Rust packages (dash-sdk) / Tests
  • GitHub Check: Rust packages (dash-sdk) / Linting
  • GitHub Check: Rust packages (dash-sdk) / Unused dependencies
  • GitHub Check: Rust packages (dapi-grpc) / Tests
  • GitHub Check: Rust packages (dapi-grpc) / Unused dependencies
  • GitHub Check: Rust packages (drive) / Tests
  • GitHub Check: Rust packages (dapi-grpc) / Linting
  • GitHub Check: Rust packages (drive-abci) / Unused dependencies
  • GitHub Check: Rust packages (dapi-grpc) / Formatting
  • GitHub Check: Rust packages (drive-abci) / Linting
  • GitHub Check: Rust packages (rs-dapi-client) / Unused dependencies
  • GitHub Check: Rust packages (drive) / Unused dependencies
  • GitHub Check: Rust crates security audit
🔇 Additional comments (28)
packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_method_versions/mod.rs (1)

135-135: LGTM! Field addition is well-placed.

The new should_checkpoint field is correctly positioned between validator_set_update and update_checkpoints, which makes semantic sense for the checkpoint flow.

packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_method_versions/v7.rs (1)

121-121: LGTM! Checkpoint feature enabled for v7.

The initialization of should_checkpoint: Some(0) correctly enables the checkpoint feature for protocol version 11 (v7), as documented in the file comment on Line 15.

packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_method_versions/v5.rs (1)

124-124: LGTM! Backward compatibility maintained for v5.

The should_checkpoint: None correctly disables the checkpoint feature for this version, maintaining backward compatibility.

packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_method_versions/v3.rs (1)

120-120: LGTM! Backward compatibility maintained for v3.

The should_checkpoint: None correctly disables the checkpoint feature for this version.

packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_method_versions/v4.rs (1)

120-120: LGTM! Backward compatibility maintained for v4.

The should_checkpoint: None correctly disables the checkpoint feature for this version.

packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_method_versions/v6.rs (1)

122-122: LGTM! Backward compatibility maintained for v6.

The should_checkpoint: None correctly disables the checkpoint feature for v6, which was introduced for tokens (protocol version 9), while checkpoints are introduced later in v7.

packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_method_versions/v2.rs (1)

121-121: LGTM! Backward compatibility maintained for v2.

The should_checkpoint: None correctly disables the checkpoint feature for this version.

packages/rs-platform-version/src/version/mocks/v3_test.rs (1)

155-155: Test mock correctly mirrors v3 behavior.

The test mock initialization in v3_test.rs at line 155 correctly reflects the production v3 configuration, with should_checkpoint: None. All version files (v1 through v7) consistently include the should_checkpoint field in their DriveAbciBlockEndMethodVersions struct initialization.

packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_method_versions/v1.rs (1)

116-122: LGTM! Checkpoint field addition follows existing pattern.

The addition of should_checkpoint: None to the DriveAbciBlockEndMethodVersions in v1 is consistent with the existing update_checkpoints: None field and appropriately initializes the baseline version before the checkpoint feature is enabled in later versions.

packages/rs-drive-abci/tests/strategy_tests/test_cases/address_tests.rs (4)

12-30: LGTM! Imports properly support proof verification infrastructure.

The new imports (Hash, QuorumHash, ContextProvider traits, BTreeMap, Arc, etc.) are all utilized in the TestContextProvider implementation and the new proof signature verification test.


35-62: LGTM! Test context provider constructor is well-structured.

The TestContextProvider::from_quorums constructor correctly builds a lookup map of quorum public keys from the test quorum info. The use of .expect() for the public key conversion is acceptable in test code, and the composite key (quorum_hash, quorum_type) properly supports multiple quorum types.


593-594: LGTM! Trunk query element count updated for checkpoint feature.

The assertion update from 29 to 32 expected elements in trunk queries is consistent across both checkpoint tests and aligns with the broader checkpoint-aware trunk/branch query changes introduced in this PR.

Also applies to: 790-791


812-1019: LGTM! Comprehensive proof signature verification test.

This test is well-structured and thoroughly validates the FromProof-based verification flow:

  • Clear documentation explaining the test's purpose
  • Proper setup with quorum signing enabled (block_signing: true)
  • Uses TestContextProvider to supply quorum public keys for verification
  • Key verification at lines 958-968 using maybe_from_proof_with_metadata with signature checking
  • Comprehensive assertions on metadata, trunk results, and proof structure
  • Good debug logging for troubleshooting

The test correctly demonstrates that proof signatures can be verified using the ContextProvider trait and FromProof pattern.

packages/rs-drive-abci/src/platform_types/block_execution_outcome/v0/mod.rs (1)

31-40: LGTM!

The new checkpoint_needed field is well-documented and the From implementation correctly defaults it to false, which is appropriate since a SimpleValidationResult conversion represents an early return (typically an error case) where no checkpoint should be created.

packages/rs-drive-abci/src/execution/engine/finalize_block_proposal/v0/mod.rs (1)

230-251: LGTM!

The checkpoint decision is correctly computed before block_execution_context is consumed by block_platform_state_owned(). The explicit comment on line 230 documenting this constraint is helpful for future maintainers. The conversion from Option<CheckpointNeededInfo> to bool via .is_some() is appropriate.

packages/rs-drive-abci/src/execution/platform_events/block_end/update_state_cache/v0/mod.rs (1)

35-62: LGTM!

The function has been properly refactored to focus solely on state cache updates, removing checkpoint-related logic. This separation of concerns aligns with the new architecture where checkpoints are created post-commit in the ABCI handler. The logic for updating validator set, block info, and persisting state remains correct.

packages/rs-drive-abci/src/abci/handler/finalize_block.rs (1)

99-102: Checkpoint creation correctly positioned after transaction commit.

The checkpoint is created after the transaction is committed, ensuring it captures the committed state. The error is propagated, which will cause the node to restart (similar to commit failure behavior per existing patterns).

Consider whether a checkpoint creation failure should be fatal. If the main data is already committed, failing to create a checkpoint might be recoverable by retrying on the next block. However, if checkpoints are critical for SDK address synchronization, the current strict error handling may be appropriate.

packages/rs-drive-abci/src/execution/platform_events/block_end/mod.rs (1)

9-16: LGTM!

The module structure is well-organized:

  • should_checkpoint is appropriately scoped to crate::execution
  • create_grovedb_checkpoint is pub(crate) to allow access from the ABCI handler
  • The "legacy" comment on update_checkpoints clearly communicates its role
packages/rs-drive-abci/src/execution/platform_events/block_end/create_grovedb_checkpoint/mod.rs (1)

26-44: LGTM!

The version dispatch follows the established pattern in the codebase. Documentation correctly emphasizes that this must be called after transaction commit.

packages/rs-drive-abci/src/execution/platform_events/block_end/create_grovedb_checkpoint/v0/mod.rs (1)

31-75: LGTM on checkpoint creation logic.

The checkpoint path construction, directory creation, GroveDB checkpoint creation, and platform state serialization are all handled correctly with appropriate error mapping.

One minor note: #[inline(always)] on line 31 has minimal benefit for a function that performs I/O operations, but it's not harmful.

packages/rs-drive-abci/src/execution/platform_events/block_end/update_checkpoints/v0/mod.rs (1)

21-90: Verify whether update_checkpoints_v0 should still be active or if the flow has migrated to separate functions.

The code comment labels update_checkpoints as "legacy", but the function is still actively called. However, update_checkpoints_v0 and create_grovedb_checkpoint_v0 serve different purposes: update_checkpoints_v0 combines checkpoint decision logic (via should_checkpoint) with creation and returns a bool, while create_grovedb_checkpoint_v0 only creates checkpoints after commit, additionally persisting platform state to disk and updating the checkpoint_platform_states cache.

If both functions remain in use, there's a real inconsistency: update_checkpoints_v0 does not update checkpoint_platform_states, while create_grovedb_checkpoint_v0 does. This could cause the cache to become stale if update_checkpoints_v0 is the primary checkpoint creation path. Clarify whether the separation is intentional or if one should be deprecated.

packages/rs-drive-abci/src/execution/platform_events/block_end/should_checkpoint/v0/mod.rs (5)

1-10: LGTM! Clean and necessary imports.

All imports are appropriately scoped and used within the implementation.


12-20: LGTM! Well-designed data structure.

The use of Arc<BTreeMap<...>> for current_checkpoints is efficient for shared ownership, and the struct clearly conveys the information needed for checkpoint creation.


36-50: LGTM! Robust configuration handling.

The testing config feature gate and configuration validation (checking for zero values) provide good defensive programming to handle misconfigured or disabled checkpoints.


52-69: LGTM! Correct checkpoint interval logic.

The arithmetic for computing most_recent_checkpoint_interval_time (line 56-57) correctly floors the block time to the nearest checkpoint interval boundary. The decision logic (lines 63-69) ensures exactly one checkpoint per interval by checking that the last checkpoint preceded the current interval and the current block has reached or passed the interval boundary.


71-82: LGTM! Efficient result construction.

Cloning the Arc (line 73) is efficient as it only increments the reference count without copying the underlying checkpoint data.

packages/rs-drive-abci/src/execution/platform_events/block_end/should_checkpoint/mod.rs (2)

1-10: LGTM! Clean module structure.

The module declaration, re-export of CheckpointNeededInfo, and imports follow standard Rust patterns for versioned implementations.


12-40: LGTM! Well-structured version dispatch.

The version dispatch pattern follows best practices:

  • Returns Ok(None) when the checkpoint feature is not enabled for the platform version
  • Correctly delegates to should_checkpoint_v0 for version 0
  • Provides clear error messages with known versions for unsupported versions

The public visibility of the method is appropriate for a platform API entry point.

Comment on lines +110 to +119
let current_checkpoint_states = self.checkpoint_platform_states.load();
let mut new_checkpoint_states = BTreeMap::new();

// Add the current platform state for this new checkpoint
new_checkpoint_states.insert(block_height, Arc::clone(&platform_state));

// Copy only the states for checkpoints we're keeping
for (height, state) in current_checkpoint_states.iter().skip(to_skip) {
new_checkpoint_states.insert(*height, Arc::clone(state));
}
Copy link
Contributor

@coderabbitai coderabbitai bot Dec 29, 2025

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Potential inconsistency in checkpoint_platform_states pruning.

The to_skip value is calculated from current_checkpoints.len() (line 82-83), but it's also used to skip entries in current_checkpoint_states (line 117). If these two maps ever become out of sync (different heights/counts), the wrong states could be pruned.

Consider calculating to_skip independently for checkpoint_platform_states:

🔎 Proposed fix
         // Update checkpoint_platform_states cache
         let current_checkpoint_states = self.checkpoint_platform_states.load();
         let mut new_checkpoint_states = BTreeMap::new();
+        
+        // Calculate how many old checkpoint states to skip independently
+        let states_to_skip = current_checkpoint_states.len().saturating_sub(max_old_to_keep);

         // Add the current platform state for this new checkpoint
         new_checkpoint_states.insert(block_height, Arc::clone(&platform_state));

         // Copy only the states for checkpoints we're keeping
-        for (height, state) in current_checkpoint_states.iter().skip(to_skip) {
+        for (height, state) in current_checkpoint_states.iter().skip(states_to_skip) {
             new_checkpoint_states.insert(*height, Arc::clone(state));
         }
🤖 Prompt for AI Agents
In
packages/rs-drive-abci/src/execution/platform_events/block_end/create_grovedb_checkpoint/v0/mod.rs
around lines 110 to 119, the code uses a to_skip value derived from
current_checkpoints to skip entries when copying from current_checkpoint_states,
which can prune the wrong entries if the two collections differ; change the
logic to compute the skip/count based on current_checkpoint_states itself (or
compute a number_to_keep and then skip
current_checkpoint_states.iter().take_while/skip accordingly) so that you prune
entries consistently from the same map you are iterating, ensuring you clone
only the most recent N states from checkpoint_platform_states rather than
relying on current_checkpoints length.

Copy link
Member Author

Choose a reason for hiding this comment

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

It's fine

Copy link
Contributor

Choose a reason for hiding this comment

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

@QuantumExplorer, understood! I'll leave the checkpoint pruning logic as is.


🧠 Learnings used
Learnt from: QuantumExplorer
Repo: dashpay/platform PR: 2227
File: packages/rs-drive-abci/src/platform_types/platform_state/mod.rs:141-141
Timestamp: 2024-10-08T13:28:03.529Z
Learning: When converting `PlatformStateV0` to `PlatformStateForSavingV1` in `packages/rs-drive-abci/src/platform_types/platform_state/mod.rs`, only version `0` needs to be handled in the match on `platform_state_for_saving_structure_default` because the changes are retroactive.

Learnt from: QuantumExplorer
Repo: dashpay/platform PR: 2215
File: packages/rs-drive-abci/src/execution/engine/run_block_proposal/mod.rs:119-120
Timestamp: 2024-10-06T16:18:07.994Z
Learning: In the `run_block_proposal` function in `packages/rs-drive-abci/src/execution/engine/run_block_proposal/mod.rs`, it's acceptable to pass `platform_state` to `perform_events_on_first_block_of_protocol_change`, even if `block_platform_state` has been updated.

Learnt from: QuantumExplorer
Repo: dashpay/platform PR: 2215
File: packages/rs-drive-abci/src/execution/engine/run_block_proposal/mod.rs:105-105
Timestamp: 2024-10-09T00:22:57.778Z
Learning: In `run_block_proposal` in `packages/rs-drive-abci/src/execution/engine/run_block_proposal/mod.rs`, when retrieving `last_block_time_ms`, it's acceptable to use `platform_state` instead of `block_platform_state`, even after updating the protocol version.

Learnt from: QuantumExplorer
Repo: dashpay/platform PR: 2215
File: packages/rs-drive-abci/src/execution/engine/run_block_proposal/mod.rs:105-105
Timestamp: 2024-10-06T16:17:34.571Z
Learning: In `run_block_proposal` in `packages/rs-drive-abci/src/execution/engine/run_block_proposal/mod.rs`, when retrieving `last_block_time_ms`, it's acceptable to use `platform_state` instead of `block_platform_state`, even after updating the protocol version.

Learnt from: lklimek
Repo: dashpay/platform PR: 2716
File: packages/rs-dapi/src/services/platform_service/broadcast_state_transition.rs:181-187
Timestamp: 2025-10-09T15:59:28.329Z
Learning: In `packages/rs-dapi/src/services/platform_service/broadcast_state_transition.rs`, the maintainer requires logging full state transition bytes (`tx_bytes = hex::encode(st_bytes)`) at debug level when a state transition passes CheckTx but is removed from the block by the proposer, to facilitate debugging of this rare edge case.

Learnt from: lklimek
Repo: dashpay/platform PR: 2254
File: packages/rs-sdk/src/sdk.rs:654-658
Timestamp: 2024-10-18T15:43:32.447Z
Learning: In `packages/rs-sdk/src/sdk.rs`, within the `verify_metadata_height` function, when using `compare_exchange` on `last_seen_height`, it's acceptable to use `Ordering::Relaxed` for the failure ordering, as any inconsistency would only trigger an extra loop iteration without affecting correctness.

Learnt from: QuantumExplorer
Repo: dashpay/platform PR: 2673
File: packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_update/mod.rs:1164-1197
Timestamp: 2025-06-18T03:44:14.385Z
Learning: QuantumExplorer determined that a CodeRabbit suggestion about fixing signable_bytes calculation in identity update tests with contract-bound keys was incorrect - the code flow is working as intended without the suggested changes.

Learnt from: QuantumExplorer
Repo: dashpay/platform PR: 2431
File: packages/rs-drive/Cargo.toml:55-60
Timestamp: 2025-01-19T07:36:46.042Z
Learning: The grovedb dependencies in packages/rs-drive/Cargo.toml and related files are intentionally kept at specific revisions rather than using the latest stable version, with plans to update them at a later time.

Learnt from: QuantumExplorer
Repo: dashpay/platform PR: 2257
File: packages/rs-drive-abci/src/mimic/test_quorum.rs:159-164
Timestamp: 2024-11-20T16:16:01.830Z
Learning: QuantumExplorer prefers not to receive auto-generated messages asking to post on social media.

Learnt from: CR
Repo: dashpay/platform PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T13:10:23.481Z
Learning: Applies to **/swift-sdk/**/*.{swift,h,m,c} : iOS SDK must combine both Core (SPV wallet) and Platform (identity/documents) functionality in the unified SDK with proper function naming: `dash_core_sdk_*` prefix for Core functions, `dash_sdk_*` prefix for Platform functions, and `dash_unified_sdk_*` prefix for unified functions

@QuantumExplorer QuantumExplorer changed the title feat: sdk support for platform addresses feat(platform): sdk support for platform addresses Dec 29, 2025
Copy link
Member Author

@QuantumExplorer QuantumExplorer left a comment

Choose a reason for hiding this comment

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

Self Reviewed

@QuantumExplorer QuantumExplorer changed the title feat(platform): sdk support for platform addresses feat(platform): sdk support for platform addresses and checkpoint fix Dec 29, 2025
Copy link
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: 0

♻️ Duplicate comments (1)
packages/rs-sdk-ffi/src/address_sync/provider.rs (1)

184-197: Incorrect memory deallocation pattern for slice.

This is a duplicate of the existing review comment. Using Box::from_raw(std::ptr::slice_from_raw_parts_mut(...)) to free an array allocated via Vec::into_boxed_slice() then Box::into_raw() works, but the pattern is fragile. The code in mod.rs (lines 181-182) uses into_boxed_slice() followed by Box::into_raw() which pairs correctly with Box::from_raw(slice_from_raw_parts_mut(...)).

However, the doc comment states this frees memory "if the caller allocated the list dynamically" — but this function should only be used for Rust-allocated memory. Clarify ownership semantics.

🧹 Nitpick comments (4)
packages/rs-sdk-ffi/src/address_sync/provider.rs (2)

83-85: unsafe impl Send lacks soundness guarantees.

The comment acknowledges that thread safety depends on callback implementations, but providing unsafe impl Send unconditionally shifts the burden to callers without any mechanism to enforce it. If a caller provides non-thread-safe callbacks, this will cause undefined behavior.

Consider documenting this requirement more prominently in the public API or adding a marker/assertion mechanism.


98-104: Missing vtable null check before dereference.

In gap_limit() and all other trait methods, self.ffi.vtable is dereferenced without checking for null first. While the contract may expect a valid vtable, defensive null checks would prevent undefined behavior if violated.

🔎 Suggested defensive check pattern
 fn gap_limit(&self) -> AddressIndex {
     unsafe {
+        if self.ffi.vtable.is_null() {
+            return 0; // or panic with descriptive message
+        }
         let vtable = &*self.ffi.vtable;
         (vtable.gap_limit)(self.ffi.context)
     }
 }
packages/rs-sdk-ffi/src/address_sync/mod.rs (2)

31-92: Null return doesn't convey error details to caller.

When sdk_handle or provider is null, or when the sync operation fails, this function returns null. The caller has no way to distinguish between different error conditions. Consider using the _with_result variant as the primary API or at minimum document that callers should check for null and use the alternate function for error details.


298-312: Provider vtable accessed after Box reconstruction.

After Box::from_raw(provider), the provider is owned by the Box. Accessing provider.vtable after this is safe because the Box hasn't been dropped yet. However, consider restructuring for clarity:

🔎 Slightly clearer flow
 pub unsafe extern "C" fn dash_sdk_address_provider_free(provider: *mut AddressProviderFFI) {
     if provider.is_null() {
         return;
     }

     let provider = Box::from_raw(provider);
 
     // Call the destroy callback if provided
-    if !provider.vtable.is_null() {
-        let vtable = &*provider.vtable;
-        if let Some(destroy) = vtable.destroy {
-            destroy(provider.context);
-        }
-    }
+    if let Some(destroy) = provider.vtable.as_ref().and_then(|vt| vt.destroy) {
+        destroy(provider.context);
+    }
+    // provider is dropped here, freeing the AddressProviderFFI struct
 }

Note: This requires changing vtable from raw pointer to Option<&AddressProviderVTable> or using a helper. The current code is correct but the null check on a raw pointer followed by dereference could be simplified.

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2cbbaa1 and 776caa1.

📒 Files selected for processing (2)
  • packages/rs-sdk-ffi/src/address_sync/mod.rs
  • packages/rs-sdk-ffi/src/address_sync/provider.rs
🧰 Additional context used
📓 Path-based instructions (1)
**/*.rs

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.rs: Rust code must pass cargo clippy --workspace linter checks
Rust code must be formatted using cargo fmt --all

**/*.rs: Use 4-space indent for Rust files
Follow rustfmt defaults and keep code clippy-clean for Rust modules
Use snake_case for Rust module names
Use PascalCase for Rust type names
Use SCREAMING_SNAKE_CASE for Rust constants

Files:

  • packages/rs-sdk-ffi/src/address_sync/provider.rs
  • packages/rs-sdk-ffi/src/address_sync/mod.rs
🧠 Learnings (6)
📓 Common learnings
Learnt from: QuantumExplorer
Repo: dashpay/platform PR: 2257
File: packages/rs-drive-abci/src/mimic/test_quorum.rs:159-164
Timestamp: 2024-11-20T16:16:01.830Z
Learning: QuantumExplorer prefers not to receive auto-generated messages asking to post on social media.
📚 Learning: 2024-11-28T13:49:17.301Z
Learnt from: shumkov
Repo: dashpay/platform PR: 2317
File: packages/rs-dapi-client/src/address_list.rs:175-180
Timestamp: 2024-11-28T13:49:17.301Z
Learning: In Rust code in `packages/rs-dapi-client/src/address_list.rs`, do not change the interface of deprecated methods like `add_uri`, even to fix potential panics.

Applied to files:

  • packages/rs-sdk-ffi/src/address_sync/provider.rs
  • packages/rs-sdk-ffi/src/address_sync/mod.rs
📚 Learning: 2024-10-10T10:30:19.883Z
Learnt from: lklimek
Repo: dashpay/platform PR: 2232
File: packages/rs-sdk/src/mock/sdk.rs:90-95
Timestamp: 2024-10-10T10:30:19.883Z
Learning: In `packages/rs-sdk/src/mock/sdk.rs`, the `load_expectations` method in `MockDashPlatformSdk` remains asynchronous (`async`) for backward compatibility, even though it now delegates to the synchronous `load_expectations_sync` method.

Applied to files:

  • packages/rs-sdk-ffi/src/address_sync/mod.rs
📚 Learning: 2025-11-25T13:10:23.481Z
Learnt from: CR
Repo: dashpay/platform PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T13:10:23.481Z
Learning: Applies to **/swift-sdk/**/*.swift : Swift code should properly wrap FFI functions and maintain type safety across the Swift/Rust boundary

Applied to files:

  • packages/rs-sdk-ffi/src/address_sync/mod.rs
📚 Learning: 2025-11-25T13:10:23.481Z
Learnt from: CR
Repo: dashpay/platform PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T13:10:23.481Z
Learning: Applies to **/swift-sdk/**/*.{swift,h,m,c} : iOS SDK must combine both Core (SPV wallet) and Platform (identity/documents) functionality in the unified SDK with proper function naming: `dash_core_sdk_*` prefix for Core functions, `dash_sdk_*` prefix for Platform functions, and `dash_unified_sdk_*` prefix for unified functions

Applied to files:

  • packages/rs-sdk-ffi/src/address_sync/mod.rs
📚 Learning: 2024-10-22T10:53:12.111Z
Learnt from: shumkov
Repo: dashpay/platform PR: 2259
File: packages/rs-dapi-client/src/dapi_client.rs:137-139
Timestamp: 2024-10-22T10:53:12.111Z
Learning: In `packages/rs-dapi-client/src/dapi_client.rs`, when passing data into asynchronous code, ensure that data structures are `Send + Sync`. Using `Arc<AtomicUsize>` is necessary for the retry counter.

Applied to files:

  • packages/rs-sdk-ffi/src/address_sync/mod.rs
🧬 Code graph analysis (1)
packages/rs-sdk-ffi/src/address_sync/provider.rs (2)
packages/rs-sdk-ffi/src/address_sync/types.rs (1)
  • empty (151-156)
packages/rs-sdk-ffi/src/context_provider.rs (1)
  • provider (37-39)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (16)
  • GitHub Check: Rust packages (dapi-grpc) / Formatting
  • GitHub Check: Rust packages (drive) / Tests
  • GitHub Check: Rust packages (drive) / Unused dependencies
  • GitHub Check: Rust packages (rs-sdk-ffi) / Unused dependencies
  • GitHub Check: Rust packages (rs-sdk-ffi) / Tests
  • GitHub Check: Rust packages (wasm-dpp2) / Tests
  • GitHub Check: Rust packages (wasm-dpp) / Tests
  • GitHub Check: Rust packages (dpp) / Tests
  • GitHub Check: Rust packages (wasm-sdk) / Tests
  • GitHub Check: Build Docker images (Dashmate helper, dashmate-helper, dashmate-helper) / Build Dashmate helper image
  • GitHub Check: Build Docker images (RS-DAPI, rs-dapi, rs-dapi) / Build RS-DAPI image
  • GitHub Check: Build Docker images (Drive, drive, drive-abci) / Build Drive image
  • GitHub Check: Rust crates security audit
  • GitHub Check: Build JS packages / Build JS
  • GitHub Check: Build rs-sdk-ffi for iOS targets (aarch64-apple-ios-sim)
  • GitHub Check: Build rs-sdk-ffi for iOS targets (aarch64-apple-ios)
🔇 Additional comments (6)
packages/rs-sdk-ffi/src/address_sync/provider.rs (1)

239-259: LGTM!

The tests adequately verify basic callback provider functionality with a static vtable.

packages/rs-sdk-ffi/src/address_sync/mod.rs (5)

48-49: Unsafe dereference without lifetime guarantees.

The code creates references from raw pointers (&*(sdk_handle as *const SDKWrapper) and &mut *provider) that are used across an async boundary (block_on). While block_on executes synchronously, the safety comment should document that the referenced data must remain valid for the duration of the call.


160-225: Memory allocation pattern is correct and consistent.

The convert_sync_result function properly:

  • Allocates key data via into_boxed_slice() + Box::into_raw()
  • Allocates entry arrays via into_boxed_slice() + Box::into_raw()
  • Handles empty collections with null pointers

This pairs correctly with the deallocation in dash_sdk_address_sync_result_free.


234-268: Deallocation correctly mirrors allocation.

The free function properly:

  1. Reconstructs and drops the result Box
  2. Iterates through found/absent entries to free individual key buffers
  3. Frees the entry arrays themselves

The use of std::ptr::slice_from_raw_parts_mut with Box::from_raw correctly matches the Box::into_raw(boxed_slice) allocation pattern used in convert_sync_result.


319-333: Helper functions are well-implemented.

Both dash_sdk_address_sync_result_total_balance and dash_sdk_address_sync_result_non_zero_count properly handle null pointers and empty results, providing safe accessor patterns for FFI consumers.

Also applies to: 340-354


360-375: Tests verify default configuration values.

The tests confirm expected defaults for DashSDKAddressSyncConfig and DashSDKAddressSyncMetrics. Consider adding tests for the sync result helper functions with mock data.

Copy link
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: 0

♻️ Duplicate comments (1)
packages/rs-drive-abci/tests/strategy_tests/test_cases/address_tests.rs (1)

812-813: Rename test to follow naming convention.

This test name should start with should_ per coding guidelines. Consider renaming to should_verify_proof_signatures_when_querying_address_trunk_state_with_checkpoints.

🧹 Nitpick comments (1)
packages/rs-drive-abci/tests/strategy_tests/test_cases/address_tests.rs (1)

814-815: Consider moving local imports to module level.

The use statements inside the test function work but are inconsistent with the rest of the file where imports are at the module level. This is a minor style preference.

🔎 Proposed fix

Move these imports to the top of the module with other imports:

 use dpp::dash_to_credits;
 use dpp::dashcore::hashes::Hash;
+use dpp::dashcore::Network;
 use dpp::dashcore::QuorumHash;
 ...
+use drive::grovedb::GroveTrunkQueryResult;

Then remove the local imports from the test function:

     #[test]
     fn run_chain_address_transitions_with_proof_signature_verification() {
-        use dpp::dashcore::Network;
-        use drive::grovedb::GroveTrunkQueryResult;
-
         drive_abci::logging::init_for_tests(LogLevel::Debug);
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 776caa1 and 1d847a1.

📒 Files selected for processing (1)
  • packages/rs-drive-abci/tests/strategy_tests/test_cases/address_tests.rs
🧰 Additional context used
📓 Path-based instructions (2)
**/*.rs

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.rs: Rust code must pass cargo clippy --workspace linter checks
Rust code must be formatted using cargo fmt --all

**/*.rs: Use 4-space indent for Rust files
Follow rustfmt defaults and keep code clippy-clean for Rust modules
Use snake_case for Rust module names
Use PascalCase for Rust type names
Use SCREAMING_SNAKE_CASE for Rust constants

Files:

  • packages/rs-drive-abci/tests/strategy_tests/test_cases/address_tests.rs
**/tests/**/*.{js,jsx,ts,tsx,rs}

📄 CodeRabbit inference engine (AGENTS.md)

**/tests/**/*.{js,jsx,ts,tsx,rs}: Name tests descriptively, starting with 'should …'
Unit and integration tests should not perform network calls; mock dependencies

Files:

  • packages/rs-drive-abci/tests/strategy_tests/test_cases/address_tests.rs
🧠 Learnings (12)
📓 Common learnings
Learnt from: QuantumExplorer
Repo: dashpay/platform PR: 2257
File: packages/rs-drive-abci/src/mimic/test_quorum.rs:159-164
Timestamp: 2024-11-20T16:16:01.830Z
Learning: QuantumExplorer prefers not to receive auto-generated messages asking to post on social media.
📚 Learning: 2024-11-20T20:43:41.185Z
Learnt from: QuantumExplorer
Repo: dashpay/platform PR: 2257
File: packages/rs-drive-abci/tests/strategy_tests/masternodes.rs:212-220
Timestamp: 2024-11-20T20:43:41.185Z
Learning: In `packages/rs-drive-abci/tests/strategy_tests/masternodes.rs`, the pattern of generating a `PrivateKey`, converting it to bytes, and reconstructing a `BlsPrivateKey` from those bytes is intentional. Avoid suggesting to simplify this code in future reviews.

Applied to files:

  • packages/rs-drive-abci/tests/strategy_tests/test_cases/address_tests.rs
📚 Learning: 2024-11-20T16:05:40.200Z
Learnt from: QuantumExplorer
Repo: dashpay/platform PR: 2257
File: packages/rs-drive-abci/src/platform_types/signature_verification_quorum_set/v0/for_saving.rs:148-151
Timestamp: 2024-11-20T16:05:40.200Z
Learning: In `packages/rs-drive-abci/src/platform_types/signature_verification_quorum_set/v0/for_saving.rs`, when converting public keys from `QuorumForSavingV0` to `VerificationQuorum`, it's acceptable to use `.expect()` for public key conversion, as the conversion has been verified and panics are acceptable in this context.

Applied to files:

  • packages/rs-drive-abci/tests/strategy_tests/test_cases/address_tests.rs
📚 Learning: 2024-10-04T09:08:47.901Z
Learnt from: shumkov
Repo: dashpay/platform PR: 2206
File: packages/rs-drive-abci/tests/strategy_tests/main.rs:1162-1162
Timestamp: 2024-10-04T09:08:47.901Z
Learning: In the Rust test file `packages/rs-drive-abci/tests/strategy_tests/main.rs`, specific protocol versions like `PROTOCOL_VERSION_1` are intentionally used in tests instead of `PROTOCOL_VERSION_LATEST`.

Applied to files:

  • packages/rs-drive-abci/tests/strategy_tests/test_cases/address_tests.rs
📚 Learning: 2024-10-30T11:19:59.163Z
Learnt from: lklimek
Repo: dashpay/platform PR: 2277
File: packages/rs-sdk/tests/fetch/config.rs:233-233
Timestamp: 2024-10-30T11:19:59.163Z
Learning: In the Rust SDK's `rs-sdk/tests` integration tests (e.g., in `packages/rs-sdk/tests/fetch/config.rs`), we cannot create objects during tests because there is no support for object creation in this context. Therefore, hardcoded values for test identities must be used.

Applied to files:

  • packages/rs-drive-abci/tests/strategy_tests/test_cases/address_tests.rs
📚 Learning: 2024-10-21T01:03:42.458Z
Learnt from: QuantumExplorer
Repo: dashpay/platform PR: 2227
File: packages/rs-dpp/src/core_types/validator_set/v0/mod.rs:299-299
Timestamp: 2024-10-21T01:03:42.458Z
Learning: In the `test_serialize_deserialize_validator_set_v0` test within `packages/rs-dpp/src/core_types/validator_set/v0/mod.rs`, deterministic BLS keys cannot be easily used; therefore, using `BlsPublicKey::generate()` is acceptable.

Applied to files:

  • packages/rs-drive-abci/tests/strategy_tests/test_cases/address_tests.rs
📚 Learning: 2024-10-03T11:51:06.980Z
Learnt from: shumkov
Repo: dashpay/platform PR: 2201
File: packages/rs-platform-version/src/version/v2.rs:1186-1188
Timestamp: 2024-10-03T11:51:06.980Z
Learning: In the `IdentityTransitionVersions` structure within `packages/rs-platform-version/src/version/v2.rs`, the field `credit_withdrawal` does not need the `identity_` prefix since it is already encompassed within identity state transitions.

Applied to files:

  • packages/rs-drive-abci/tests/strategy_tests/test_cases/address_tests.rs
📚 Learning: 2024-10-06T16:18:07.994Z
Learnt from: QuantumExplorer
Repo: dashpay/platform PR: 2215
File: packages/rs-drive-abci/src/execution/engine/run_block_proposal/mod.rs:119-120
Timestamp: 2024-10-06T16:18:07.994Z
Learning: In the `run_block_proposal` function in `packages/rs-drive-abci/src/execution/engine/run_block_proposal/mod.rs`, it's acceptable to pass `platform_state` to `perform_events_on_first_block_of_protocol_change`, even if `block_platform_state` has been updated.

Applied to files:

  • packages/rs-drive-abci/tests/strategy_tests/test_cases/address_tests.rs
📚 Learning: 2025-10-09T15:59:28.329Z
Learnt from: lklimek
Repo: dashpay/platform PR: 2716
File: packages/rs-dapi/src/services/platform_service/broadcast_state_transition.rs:181-187
Timestamp: 2025-10-09T15:59:28.329Z
Learning: In `packages/rs-dapi/src/services/platform_service/broadcast_state_transition.rs`, the maintainer requires logging full state transition bytes (`tx_bytes = hex::encode(st_bytes)`) at debug level when a state transition passes CheckTx but is removed from the block by the proposer, to facilitate debugging of this rare edge case.

Applied to files:

  • packages/rs-drive-abci/tests/strategy_tests/test_cases/address_tests.rs
📚 Learning: 2025-06-18T03:44:14.385Z
Learnt from: QuantumExplorer
Repo: dashpay/platform PR: 2673
File: packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_update/mod.rs:1164-1197
Timestamp: 2025-06-18T03:44:14.385Z
Learning: QuantumExplorer determined that a CodeRabbit suggestion about fixing signable_bytes calculation in identity update tests with contract-bound keys was incorrect - the code flow is working as intended without the suggested changes.

Applied to files:

  • packages/rs-drive-abci/tests/strategy_tests/test_cases/address_tests.rs
📚 Learning: 2024-11-03T10:39:11.242Z
Learnt from: shumkov
Repo: dashpay/platform PR: 2305
File: packages/rs-drive-abci/src/abci/handler/finalize_block.rs:81-0
Timestamp: 2024-11-03T10:39:11.242Z
Learning: In `packages/rs-drive-abci/src/abci/handler/finalize_block.rs`, the use of `.expect("commit transaction")` after `app.commit_transaction(platform_version)` is intentional due to the provided comment explaining its necessity. Do not flag this usage in future reviews.

Applied to files:

  • packages/rs-drive-abci/tests/strategy_tests/test_cases/address_tests.rs
📚 Learning: 2024-10-09T00:22:57.778Z
Learnt from: QuantumExplorer
Repo: dashpay/platform PR: 2215
File: packages/rs-drive-abci/src/execution/engine/run_block_proposal/mod.rs:105-105
Timestamp: 2024-10-09T00:22:57.778Z
Learning: In `run_block_proposal` in `packages/rs-drive-abci/src/execution/engine/run_block_proposal/mod.rs`, when retrieving `last_block_time_ms`, it's acceptable to use `platform_state` instead of `block_platform_state`, even after updating the protocol version.

Applied to files:

  • packages/rs-drive-abci/tests/strategy_tests/test_cases/address_tests.rs
🔇 Additional comments (4)
packages/rs-drive-abci/tests/strategy_tests/test_cases/address_tests.rs (4)

37-103: LGTM! Well-designed test context provider.

The TestContextProvider is cleanly implemented with appropriate trait methods for testing proof signature verification. The from_quorums helper correctly extracts and maps quorum public keys, and the error handling with InvalidQuorum is appropriate.

Based on retrieved learnings, the use of .expect() for public key conversion at line 58 is acceptable in this test context.


871-892: LGTM! Comprehensive test configuration for proof signature verification.

The test correctly enables block_signing and block_commit_signature_verification in the test config, which is essential for the signature verification test to be meaningful. The use of CHAIN_ID from the mimic module ensures consistency with test infrastructure.


938-970: LGTM! Key proof verification logic is well-structured.

The test correctly:

  1. Constructs a TestContextProvider from the chain's validator quorums
  2. Executes a trunk state query
  3. Verifies the proof signature using maybe_from_proof_with_metadata

This validates the fix described in the PR objectives where checkpoints are now created after transaction commit.


593-597: All trunk query element count assertions are consistently expecting 32 elements.

The assertions at lines 593-597 and 790-794 both expect 32 elements, which aligns with a third assertion at line 995. However, the claim about a change from 29→32 cannot be verified from code inspection alone, and the correctness of the expected value of 32 requires validation against the actual trunk query structure definition or implementation logic.

@QuantumExplorer QuantumExplorer merged commit f935213 into v3.0-dev Dec 29, 2025
105 of 106 checks passed
@QuantumExplorer QuantumExplorer deleted the feat/sdkSupportForPlatformAddresses branch December 29, 2025 21:49
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