Skip to content

Conversation

@lklimek
Copy link
Contributor

@lklimek lklimek commented Jan 7, 2026

Issue being fixed or feature implemented

sync_address_balances not tested

What was done?

Added test for sync_address_balances.

Requires #2956 and #2955 to be merged first

How Has This Been Tested?

green GHA

Breaking Changes

None

Checklist:

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

For repository code-owners and collaborators only

  • I have assigned this pull request to a milestone

Summary by CodeRabbit

  • Tests

    • Added end-to-end tests for address balance synchronization, including found/absent tracking and highest-sync-index verification.
    • Included new test vectors and expanded mock test coverage for address trunk state scenarios.
  • Bug Fixes

    • Improved freshness/staleness handling for address state queries to respect configured metadata time tolerances.

✏️ 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 Jan 7, 2026
@github-actions
Copy link

github-actions bot commented Jan 7, 2026

✅ gRPC Query Coverage Report

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

Total queries in proto: 53
Previously known queries: 47
New queries found: 6

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

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
✓ getRecentAddressBalanceChanges                /home/runner/work/platform/platform/packages/rs-sdk/src/platform/query.rs
✓ getRecentCompactedAddressBalanceChanges       /home/runner/work/platform/platform/packages/rs-sdk/src/platform/query.rs

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

Total known queries: 53
  - Implemented: 50
  - Not implemented: 2
  - Excluded: 1

Not implemented queries:
  - getConsensusParams
  - getTokenPreProgrammedDistributions

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 7, 2026

📝 Walkthrough

Walkthrough

Adds a new test for address balance synchronization (TestAddressProvider), registers the test module under the mocks feature, extends the mock SDK to load expectations for GetAddressesTrunkStateRequest, and adds a JSON test vector used by the new test.

Changes

Cohort / File(s) Summary
Test Module
packages/rs-sdk/tests/fetch/address_sync.rs, packages/rs-sdk/tests/fetch/mod.rs
New test address_sync.rs implementing TestAddressProvider to simulate pending/found/absent addresses and assert balances; module added to mod.rs under #[cfg(feature = "mocks")].
Mock SDK
packages/rs-sdk/src/mock/sdk.rs
Added a match arm in load_expectations_sync to handle GetAddressesTrunkStateRequest via load_expectation::<proto::GetAddressesTrunkStateRequest>.
Test Vector
packages/rs-sdk/tests/vectors/test_sync_address_balances/quorum_pubkey-106-498b4b317d090a9f3e372986bed30f7154967d852f194ec6441fa5a1c233380e.json
New JSON file containing a hex string used as a test vector for address balance sync tests.
SDK freshness criteria
packages/rs-sdk/src/sdk.rs
Adjusted freshness criteria for get_addresses_trunk_state and get_addresses_branch_state to conditionally disable time-based staleness when metadata_time_tolerance_ms is None.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 I hopped through tests with a soft little tap,
Mock SDK opened and I checked every map,
Balances counted, absent flags waved,
Vectors in JSON, the burrow well-saved,
A tiny rabbit cheers this tidy new lap.

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'test(sdk): test sync_address_balances' directly corresponds to the main objective of the PR, which is to add a test for the sync_address_balances function, as reflected in the new test module and related test vector additions.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

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.

@lklimek lklimek marked this pull request as draft January 7, 2026 13:18
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

🧹 Nitpick comments (2)
packages/rs-sdk/tests/fetch/address_sync.rs (1)

64-65: Consider renaming to follow test naming convention.

Per coding guidelines, tests should be named descriptively starting with "should_". Consider renaming to something like should_sync_address_balances_and_track_found_absent_addresses.

Suggested rename
-#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
-async fn test_sync_address_balances() {
+#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
+async fn should_sync_address_balances_and_track_found_absent_addresses() {

As per coding guidelines for test naming.

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

130-139: Consider validating depth limits consistency.

The code extracts min_query_depth and max_query_depth from platform version settings without validating that min_query_depth <= max_query_depth. If platform configuration is incorrect, the subsequent clamp operations could produce unexpected results.

Suggested validation
 let min_query_depth = platform_version
     .drive
     .methods
     .address_funds
     .address_funds_query_min_depth;
 let max_query_depth = platform_version
     .drive
     .methods
     .address_funds
     .address_funds_query_max_depth;
+
+if min_query_depth > max_query_depth {
+    return Err(Error::Protocol(dpp::ProtocolError::CorruptedCodeExecution(
+        format!(
+            "Invalid platform depth limits: min {} > max {}",
+            min_query_depth, max_query_depth
+        ),
+    )));
+}
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 86524da and 78d1208.

📒 Files selected for processing (3)
  • packages/rs-sdk/src/platform/address_sync/mod.rs
  • packages/rs-sdk/tests/fetch/address_sync.rs
  • packages/rs-sdk/tests/fetch/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-sdk/tests/fetch/mod.rs
  • packages/rs-sdk/tests/fetch/address_sync.rs
  • packages/rs-sdk/src/platform/address_sync/mod.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-sdk/tests/fetch/mod.rs
  • packages/rs-sdk/tests/fetch/address_sync.rs
🧠 Learnings (8)
📚 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/tests/fetch/mod.rs
  • packages/rs-sdk/tests/fetch/address_sync.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/tests/fetch/mod.rs
  • packages/rs-sdk/tests/fetch/address_sync.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/tests/fetch/mod.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/tests/fetch/mod.rs
📚 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/tests/fetch/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-sdk/src/platform/address_sync/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-sdk/src/platform/address_sync/mod.rs
📚 Learning: 2025-02-03T23:38:33.414Z
Learnt from: QuantumExplorer
Repo: dashpay/platform PR: 2450
File: packages/rs-drive/src/drive/tokens/distribution/fetch/pre_programmed_distributions/mod.rs:75-81
Timestamp: 2025-02-03T23:38:33.414Z
Learning: GroveDB's `as_sum_item_value()` method returns an `i64`, so sum items cannot exceed `i64::MAX` by design.

Applied to files:

  • packages/rs-sdk/src/platform/address_sync/mod.rs
🧬 Code graph analysis (1)
packages/rs-sdk/tests/fetch/address_sync.rs (1)
packages/rs-sdk/src/platform/address_sync/types.rs (1)
  • total_balance (91-93)
⏰ 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). (13)
  • GitHub Check: Rust packages (dash-sdk) / Linting
  • GitHub Check: Rust packages (rs-sdk-ffi) / Tests
  • GitHub Check: Rust packages (wasm-sdk) / Tests
  • GitHub Check: Rust packages (dash-sdk) / Tests
  • GitHub Check: Rust packages (dash-sdk) / Unused dependencies
  • GitHub Check: Rust packages (dash-sdk) / Check each feature
  • 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 Docker images (RS-DAPI, rs-dapi, rs-dapi) / Build RS-DAPI 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)
🔇 Additional comments (8)
packages/rs-sdk/tests/fetch/mod.rs (1)

10-10: LGTM!

The module inclusion is properly placed under the mocks feature gate and maintains alphabetical ordering.

packages/rs-sdk/tests/fetch/address_sync.rs (3)

15-33: LGTM!

The test provider structure is well-designed with appropriate fields for tracking address sync state during testing.


35-61: LGTM!

The AddressProvider trait implementation correctly maintains state, with proper tracking of the highest found index using map_or and max.


66-103: LGTM!

The test comprehensively validates address sync behavior, checking found/absent tracking, balance extraction, total balance calculation, and highest found index. The use of hardcoded test addresses aligns with the testing patterns for this codebase.

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

147-153: LGTM!

The function call correctly passes the platform-configured depth limits to enable privacy-aware depth clamping.


286-334: LGTM!

The depth clamping logic correctly ensures all query depths stay within platform limits:

  • Direct leaf queries use clamped tree depth
  • Ancestor queries properly reduce depth using saturating_sub before clamping
  • Fallback cases also use clamped depth

485-490: Verify the safety of the i64 to u64 cast.

The cast from value (likely i64 based on GroveDB's sum item design) to u64 at line 487 could produce incorrect results if value is negative. While address balances should never be negative in normal operation, consider adding a defensive check or clarification.

Suggested defensive check
 fn extract_balance_from_element(element: &Element) -> u64 {
     match element {
-        Element::ItemWithSumItem(_, value, _) => *value as u64,
+        Element::ItemWithSumItem(_, value, _) => {
+            if *value < 0 {
+                warn!("Negative balance {} found in address funds tree", value);
+                0
+            } else {
+                *value as u64
+            }
+        }
         _ => 0,
     }
 }

Alternatively, if negative values are impossible by platform invariants, a comment explaining this would be helpful.


545-552: LGTM!

The test correctly validates balance extraction from the updated Element::ItemWithSumItem variant.

@lklimek lklimek marked this pull request as ready for review January 8, 2026 07:13
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

🧹 Nitpick comments (1)
packages/rs-sdk/src/sdk.rs (1)

267-279: Logic correctly implements conditional staleness checking.

The implementation properly enables global disabling of staleness checks while maintaining special handling for checkpoint queries (trunk/branch state methods). When metadata_time_tolerance_ms is Some, these methods use a fixed 31-minute tolerance regardless of the actual tolerance value, which is appropriate for their different freshness requirements.

💡 Optional: Consider using `map` for clarity

Using map instead of and more explicitly shows the value transformation intent:

             "get_addresses_trunk_state" | "get_addresses_branch_state" => (
                 None,
-                self.metadata_time_tolerance_ms
-                    .and(Some(ADDRESS_STATE_TIME_TOLERANCE_MS)),
+                self.metadata_time_tolerance_ms
+                    .map(|_| ADDRESS_STATE_TIME_TOLERANCE_MS),
             ),

Both are functionally equivalent, but map is more commonly used for value transformation and may be more immediately understood by readers.

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0d84e1e and 02c7284.

📒 Files selected for processing (1)
  • 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/sdk.rs
🧠 Learnings (2)
📚 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
📚 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/sdk.rs
🧬 Code graph analysis (1)
packages/rs-sdk/src/sdk.rs (3)
packages/rs-sdk/src/platform/documents/document_query.rs (1)
  • method_name (144-146)
packages/rs-dapi-client/src/transport.rs (1)
  • method_name (49-49)
packages/rs-sdk/src/platform/types/evonode.rs (1)
  • method_name (60-62)
⏰ 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). (13)
  • GitHub Check: Rust packages (dash-sdk) / Check each feature
  • GitHub Check: Rust packages (rs-sdk-ffi) / Tests
  • GitHub Check: Rust packages (wasm-sdk) / Tests
  • GitHub Check: Rust packages (dash-sdk) / Tests
  • GitHub Check: Rust packages (dash-sdk) / Unused dependencies
  • GitHub Check: Rust packages (dash-sdk) / Linting
  • 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 Docker images (RS-DAPI, rs-dapi, rs-dapi) / Build RS-DAPI 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)
  • GitHub Check: Build rs-sdk-ffi for iOS targets (aarch64-apple-ios-sim)
🔇 Additional comments (1)
packages/rs-sdk/src/sdk.rs (1)

264-266: Clear documentation of global staleness check disabling.

The added documentation effectively explains how setting tolerance to None disables staleness checks globally, which helps users understand this important configuration option.

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.

3 participants