Skip to content

feat(rs-sdk-ffi): expose SDK protocol version pinning#3734

Closed
thepastaclaw wants to merge 9 commits into
dashpay:v3.1-devfrom
thepastaclaw:feature/ffi-sdk-protocol-version
Closed

feat(rs-sdk-ffi): expose SDK protocol version pinning#3734
thepastaclaw wants to merge 9 commits into
dashpay:v3.1-devfrom
thepastaclaw:feature/ffi-sdk-protocol-version

Conversation

@thepastaclaw
Copy link
Copy Markdown
Collaborator

@thepastaclaw thepastaclaw commented May 25, 2026

Summary

Adds additive FFI and Swift SDK support for explicitly pinning the Dash
Platform protocol version used by SdkBuilder.

  • Adds dash_sdk_*_with_protocol_version constructors for plain, extended,
    trusted, and callback-backed FFI SDK creation
  • Keeps existing constructors ABI-compatible and mapped to protocol_version = 0
    auto-detect behavior
  • Exposes Swift SDK(network:protocolVersion:), defaulting to 0, so iOS
    callers can pass 11 to pin Platform protocol version v11
  • Documents C, Swift, and Python usage examples

Validation

  • cargo fmt --all -- --check
  • cargo test -p rs-sdk-ffi sdk::tests --lib — 4 passed
  • Commit hook: workspace cargo check
  • code-review dashpay/platform upstream/v3.1-dev feature/ffi-sdk-protocol-version
    — Recommendation: ship
  • Verified generated cbindgen header contains the new protocol-version FFI
    functions

Summary by CodeRabbit

  • New Features

    • SDK initialization now supports optional protocol version pinning (defaults to auto-detect).
    • Added skip_asset_lock_proof_verification configuration option.
  • Documentation

    • Updated code examples across C, Swift, and Python with new SDK initialization patterns and configuration options.

Review Change Stack

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 25, 2026

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: b4692f8c-4c77-464d-81ae-b5f3651ebf97

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

This PR adds protocol-version-aware SDK creation across Rust FFI, Swift, and documentation. New C API constructors accept an explicit protocol version parameter; internal helpers validate and resolve protocol versions or default to auto-detect. Trusted SDK setup now enforces stricter DAPI defaults and error handling. Swift wrapper and docs are updated to demonstrate both pinned and auto-detect usage patterns.

Changes

Protocol Version Pinning Feature

Layer / File(s) Summary
Protocol version resolution and DAPI parsing helpers
packages/rs-sdk-ffi/src/sdk.rs
Import PlatformVersion; add resolve_platform_version (maps 0 to auto-detect, validates others via PlatformVersion::get), parse_dapi_addresses, build_sdk_builder, and apply_platform_version helper functions to centralize protocol-version pinning and DAPI address parsing logic.
Context provider wiring and SDK creation internals
packages/rs-sdk-ffi/src/sdk.rs
Introduce apply_context_provider (handles explicit per-instance provider, core-sdk-handle-driven creation via global callbacks, or fallback), make_sdk_result (unified FFI result construction), and refactor create_sdk_from_config and create_extended_sdk_from_config to use shared builder/config helpers with standardized error conversions.
Trusted SDK builder construction and DAPI handling
packages/rs-sdk-ffi/src/sdk.rs
Update trusted provider construction with regtest-local sidecar URL support; refactor DAPI defaults to apply only for Testnet/Mainnet when null (reject other networks), reject empty DAPI as InvalidParameter; attach provider to builder and spawn async task to prefetch quorum caches.
C API constructors with protocol version support
packages/rs-sdk-ffi/src/sdk.rs
Add four new protocol-version-aware exported constructors (dash_sdk_create_with_protocol_version, dash_sdk_create_extended_with_protocol_version, dash_sdk_create_trusted_with_protocol_version, dash_sdk_create_with_callbacks_and_protocol_version); replace existing constructors with thin ABI wrappers delegating to protocol-version-aware internals.
Protocol version behavior and validation tests
packages/rs-sdk-ffi/src/sdk.rs
Add unit test module asserting protocol version pinning works for SDK creation, invalid protocol versions are rejected for untrusted and trusted constructors, and resolve_platform_version(11) returns pinned platform version.
Swift SDK wrapper protocol version integration
packages/swift-sdk/Sources/SwiftDashSDK/SDK.swift
Extend SDK initializer to accept optional protocolVersion parameter (default 0 for auto-detect); update documentation and both local and non-local FFI calls to use dash_sdk_create_trusted_with_protocol_version passing through the protocol version.
Documentation and integration examples
packages/rs-sdk-ffi/README.md
Update C and Python examples to add skip_asset_lock_proof_verification field and switch to dash_sdk_create_with_protocol_version(..., 11); replace Swift example's DashSDKConfig + dash_sdk_create with SDK initializer showing auto-detect and pinned variants; extend API reference with new constructor entry.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested reviewers

  • QuantumExplorer
  • shumkov

🐰 A version pinned, a builder refined,
Protocol paths more carefully designed,
With helpers and tests, the SDK stands tall,
From Rust to Swift, it answers the call!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: exposing SDK protocol version pinning functionality across FFI and Swift, matching the primary objective and the substantial implementation across multiple files.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@github-actions github-actions Bot added this to the v3.1.0 milestone May 25, 2026
@thepastaclaw thepastaclaw requested a review from lklimek May 25, 2026 09:12
@thepastaclaw
Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 25, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/rs-sdk-ffi/src/sdk.rs`:
- Around line 341-349: The branch that checks config.core_sdk_handle only tests
for non-null but never uses it, so per-instance handles in DashSDKConfigExtended
are ignored; update the logic in dash_sdk_create_extended_with_protocol_version
to use the provided handle when non-null (e.g. obtain a context provider tied to
core_sdk_handle instead of unconditionally calling
CallbackContextProvider::from_global()), and pass that provider into
builder.with_context_provider; ensure you still fall back to from_global() only
when core_sdk_handle is null or when a handle-specific provider cannot be
created, producing the same error path via internal_error_result when
appropriate.
- Around line 139-163: The trusted setup logic (trusted_builder/trusted_setup)
currently re-parses dapi_addresses and rejects an empty string while
parse_dapi_addresses treats "" as None; change the trusted setup to call
parse_dapi_addresses(dapi_addresses) and branch on the resulting
Option<AddressList> (None = fallback to network defaults, Some(list) = use
provided addresses) instead of re-parsing the raw C string; apply the same
replacement at the other duplicate site that currently re-parses (the second
block that mirrors this logic) so both places treat an empty C string
consistently as “not provided.”
- Around line 165-176: The shared builder functions (e.g., base_builder and the
protocol-version constructors that call builder_with_protocol_version and
ultimately SdkBuilder::new or SdkBuilder::new_mock) only apply
network/dapi_addresses/protocol_version and ignore DashSDKConfig fields
request_retry_count, request_timeout_ms, and skip_asset_lock_proof_verification;
update these builders to propagate those config fields into the SdkBuilder
before returning (e.g., chain calls to the builder to set retry count, request
timeout, and enable/disable asset-lock-proof verification using the SdkBuilder
methods that control transport retry/timeout and verification flags) so the
values from DashSDKConfig are honored when build() is called.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: e421833c-e05a-4604-9e8c-e2755527c8a3

📥 Commits

Reviewing files that changed from the base of the PR and between 9f3bfa3 and 29648e9.

📒 Files selected for processing (3)
  • packages/rs-sdk-ffi/README.md
  • packages/rs-sdk-ffi/src/sdk.rs
  • packages/swift-sdk/Sources/SwiftDashSDK/SDK.swift

Comment thread packages/rs-sdk-ffi/src/sdk.rs Outdated
Comment thread packages/rs-sdk-ffi/src/sdk.rs Outdated
Comment thread packages/rs-sdk-ffi/src/sdk.rs Outdated
@thepastaclaw thepastaclaw force-pushed the feature/ffi-sdk-protocol-version branch from 29648e9 to 65f0822 Compare May 25, 2026 09:36
@thepastaclaw
Copy link
Copy Markdown
Collaborator Author

Addressed the CodeRabbit findings in the PR branch: trusted setup now reuses the shared DAPI address parser (so empty strings fall back to defaults), shared FFI builders propagate retry/timeout/proof settings, and extended SDK creation binds global callbacks to the provided per-instance Core SDK handle when present.\n\nValidation:\n- cargo test -p rs-sdk-ffi --no-default-features --features mocks\n- cargo check -p rs-sdk-ffi

@thepastaclaw
Copy link
Copy Markdown
Collaborator Author

Addressed CodeRabbit finding 1 on the current PR branch.

  • Updated dash_sdk_create_extended_with_protocol_version / create_extended_internal to use a handle-specific callback context provider when core_sdk_handle is non-null, with fallback to global callbacks only if the handle-specific provider cannot be created.
  • Added CallbackContextProvider::from_core_sdk_handle(...) and a targeted test covering handle override behavior.
  • Verified findings 2 and 3 against the refreshed branch tip (65f0822ac) before changing code. They were already present there: trusted setup already routes through parse_dapi_addresses(...), there is no duplicate stale block, and shared builder config already propagates request settings / proof flags.

Validation run:

  • cargo test -p rs-sdk-ffi from_core_sdk_handle_overrides_global_handle -- --nocapture -> passed
  • cargo test -p rs-sdk-ffi dash_sdk_create_trusted_pins_protocol_version -- --nocapture -> passed
  • cargo test -p rs-sdk-ffi trusted_builder_treats_empty_dapi_addresses_as_defaults -- --nocapture -> passed

@thepastaclaw
Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 25, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adds an additive API across the Rust FFI layer and Swift wrapper to allow callers to explicitly pin the Dash Platform protocol version used by SdkBuilder, while preserving existing constructors’ default auto-detect behavior (protocol_version = 0).

Changes:

  • Added new *_with_protocol_version FFI constructors and refactored SDK creation to share common builder/config logic.
  • Updated Swift SDK initializer to accept an optional protocolVersion parameter (defaulting to 0) and call the new trusted FFI constructor.
  • Updated rs-sdk-ffi README examples for C/Swift/Python to show protocol-version pinning usage.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.

File Description
packages/swift-sdk/Sources/SwiftDashSDK/SDK.swift Adds protocolVersion parameter (default 0) and forwards it into the trusted FFI constructor.
packages/rs-sdk-ffi/src/sdk.rs Introduces protocol-version-aware creation entrypoints, shared builder helpers, and adds tests around pinning/validation.
packages/rs-sdk-ffi/src/context_callbacks.rs Adds support for overriding the global callback handle with a per-instance Core SDK handle, plus unit tests.
packages/rs-sdk-ffi/README.md Updates language binding examples and API reference to include the new protocol-version pinning constructor.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread packages/rs-sdk-ffi/src/sdk.rs Outdated
Comment on lines +179 to +181
builder
.with_settings(request_settings_from_config(config))
.with_proofs(!config.skip_asset_lock_proof_verification)
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Addressed in 687508c. Added an explanatory comment at the with_proofs call site in apply_common_builder_config and expanded the field-level Rustdoc on DashSDKConfig::skip_asset_lock_proof_verification to state explicitly that it controls Platform state-proof verification for all SDK requests. The C example in the README has an equivalent note.

Comment thread packages/rs-sdk-ffi/src/sdk.rs Outdated
Comment on lines +341 to +347
} else if !config.core_sdk_handle.is_null() {
let core_sdk_handle = unsafe { &*config.core_sdk_handle };
if let Some(callback_provider) =
crate::context_callbacks::CallbackContextProvider::from_core_sdk_handle(core_sdk_handle)
.or_else(crate::context_callbacks::CallbackContextProvider::from_global)
{
builder = builder.with_context_provider(callback_provider);
Comment on lines +255 to +260
unsafe { set_global_callbacks(callbacks).expect("set callbacks") };

let provider = CallbackContextProvider::from_core_sdk_handle(&CoreSDKHandle {
client: per_instance_handle,
})
.expect("provider from callbacks");
Comment on lines 80 to 86
DashSDKConfig config = {
.network = DASH_SDK_NETWORK_TESTNET,
.dapi_addresses = "seed-1.testnet.networks.dash.org",
.skip_asset_lock_proof_verification = false,
.request_retry_count = 3,
.request_timeout_ms = 30000
};
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/rs-sdk-ffi/src/context_callbacks.rs`:
- Around line 245-269: This test mutates global callback state via
set_global_callbacks and doesn't restore it; wrap the mutation so
GLOBAL_CALLBACKS is restored after the test (e.g., capture the previous
callbacks before calling set_global_callbacks and restore them in a
drop/teardown or use a scoped helper) to avoid leaking state to other tests;
update the test around ContextProviderCallbacks / set_global_callbacks /
CallbackContextProvider::from_core_sdk_handle to save the prior
GLOBAL_CALLBACKS, set the test callbacks, run the assertions, and then restore
the saved callbacks in all paths (including on panic) so parallel tests remain
deterministic.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 4053e0f6-0c16-453a-8c68-aae168b65dc7

📥 Commits

Reviewing files that changed from the base of the PR and between 29648e9 and 3e624bc.

📒 Files selected for processing (4)
  • packages/rs-sdk-ffi/README.md
  • packages/rs-sdk-ffi/src/context_callbacks.rs
  • packages/rs-sdk-ffi/src/sdk.rs
  • packages/swift-sdk/Sources/SwiftDashSDK/SDK.swift

Comment thread packages/rs-sdk-ffi/src/context_callbacks.rs
@thepastaclaw thepastaclaw force-pushed the feature/ffi-sdk-protocol-version branch 3 times, most recently from feca7c0 to 22365d9 Compare May 25, 2026 10:07
@thepastaclaw
Copy link
Copy Markdown
Collaborator Author

Addressed the latest CodeRabbit/Copilot review items in feca7c0:

  • isolated/restored global callback state in the context callback test
  • stopped falling back to global callbacks when a non-null Core SDK handle cannot produce a provider; now returns InvalidParameter
  • clarified the legacy skip_asset_lock_proof_verification flag as toggling SDK request proofs in code and README examples
  • updated the context provider integration test to use a valid handle with a null client instead of a dangling pointer

Validation:

  • cargo test -p rs-sdk-ffi --no-default-features --features mocks
  • cargo check -p rs-sdk-ffi

@thepastaclaw thepastaclaw force-pushed the feature/ffi-sdk-protocol-version branch 2 times, most recently from feca7c0 to 22365d9 Compare May 25, 2026 10:33
@lklimek lklimek requested a review from Copilot May 25, 2026 13:50
Comment thread packages/rs-sdk-ffi/src/sdk.rs Outdated
/// - The returned handle inside `DashSDKResult` must be destroyed using the SDK destroy function to avoid leaks.
#[no_mangle]
pub unsafe extern "C" fn dash_sdk_create_extended_with_protocol_version(
config: *const DashSDKConfigExtended,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Why not just add protocol_version to DashSDKConfigExtended ? New constructors won't be needed.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Good call — done in 687508c. protocol_version is now a field on DashSDKConfigExtended (0 = auto-detect), and the redundant dash_sdk_create_extended_with_protocol_version constructor has been removed. The two dash_sdk_create_with_callbacks variants are also consolidated behind a shared inner helper that sets the new field. We kept the plain-config _with_protocol_version constructors because adding a new field to DashSDKConfig itself touches a much larger surface (it is used by many tests, the Swift SDK, and the Python/C examples in the README), so that change felt out of scope for this PR.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 5 comments.

Comment thread packages/rs-sdk-ffi/src/sdk.rs Outdated
Comment on lines +873 to +877
debug!("dash_sdk_create_trusted: testing basic HTTP connectivity");
match reqwest::get("https://www.google.com").await {
Ok(_) => debug!("dash_sdk_create_trusted: basic HTTP test successful (Google)"),
Err(e) => warn!(error = %e, "dash_sdk_create_trusted: basic HTTP test failed"),
}
Comment thread packages/rs-sdk-ffi/src/sdk.rs Outdated
Comment on lines +879 to +886
// Try the quorums endpoint directly
debug!("dash_sdk_create_trusted: testing quorums endpoint directly");
match reqwest::get("https://quorums.testnet.networks.dash.org/quorums").await {
Ok(resp) => debug!(status = %resp.status(), "dash_sdk_create_trusted: direct quorums endpoint test successful"),
Err(e) => warn!(error = %e, "dash_sdk_create_trusted: direct quorums endpoint test failed"),
}

// Now try through the provider
Comment thread packages/rs-sdk-ffi/src/sdk.rs Outdated
Comment on lines +708 to +709
/// - `config` must be a valid pointer to a DashSDKConfig structure
/// # Safety
Comment thread packages/rs-sdk-ffi/src/sdk.rs Outdated
Comment on lines +188 to +216
/// Create a new SDK instance with an explicit protocol version override
///
/// `protocol_version == 0` preserves the default auto-detect behavior.
///
/// # Safety
/// - `config` must be a valid pointer to a DashSDKConfig structure for the duration of the call.
/// - The returned handle inside `DashSDKResult` must be destroyed using the SDK destroy function to avoid leaks.
#[no_mangle]
pub unsafe extern "C" fn dash_sdk_create_with_protocol_version(
config: *const DashSDKConfig,
protocol_version: u32,
) -> DashSDKResult {
if config.is_null() {
return DashSDKResult::error(DashSDKError::new(
DashSDKErrorCode::InvalidParameter,
"Config is null".to_string(),
));
}

let config = &*config;

// Parse configuration
let network: Network = config.network.into();

let platform_version = match resolve_platform_version(protocol_version) {
Ok(platform_version) => platform_version,
Err(result) => return result,
};

Comment on lines +145 to +147
# Create SDK instance pinned to protocol version 11.
# Pass 0 to keep the default auto-detect behavior.
result = lib.dash_sdk_create_with_protocol_version(byref(config), 11)
@thepastaclaw
Copy link
Copy Markdown
Collaborator Author

Addressed the valid review points on this branch:

  • Factored the SDK creation/config parsing paths in packages/rs-sdk-ffi/src/sdk.rs so the protocol-version entry points reuse shared helpers instead of duplicating builder setup.
  • Removed the extra trusted-prefetch reqwest::get() probes to google.com and the hardcoded testnet quorums URL; trusted setup now only warms caches through the configured TrustedHttpContextProvider.
  • Removed the duplicate rustdoc # Safety headings.
  • Updated the README C/Python config examples to include the current DashSDKConfig fields.

I did not move protocol_version onto DashSDKConfigExtended. Adding a field to that exported #[repr(C)] struct would change its ABI/layout for existing dash_sdk_create_extended callers and can cause older compiled clients to pass a shorter struct than Rust now expects. I kept the current exported functions and reduced the duplication internally instead.

Validation run:

  • cargo fmt --all
  • cargo test -p rs-sdk-ffi
  • cargo clippy -p rs-sdk-ffi --all-targets -- -D warnings

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 25, 2026

@thepastaclaw Thanks for the thorough update! The changes look well-reasoned — in particular, keeping protocol_version out of DashSDKConfigExtended to preserve the #[repr(C)] ABI is the right call for existing callers. Triggering the incremental review now.


✏️ Learnings added
Learnt from: thepastaclaw
URL: https://github.com/dashpay/platform/pull/3734

Timestamp: 2026-05-25T14:23:56.241Z
Learning: In `packages/rs-sdk-ffi/src/sdk.rs`, `protocol_version` was intentionally NOT added as a field to `DashSDKConfigExtended` (a `#[repr(C)]` struct exported via FFI) because adding a field would change its ABI/memory layout and cause older compiled C/Swift/Python clients that pass a shorter struct to mismatch what Rust expects. Instead, `protocol_version` is passed as a separate parameter to new `_with_protocol_version` FFI entry points, keeping existing `dash_sdk_create_extended` callers ABI-compatible.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

♻️ Duplicate comments (2)
packages/rs-sdk-ffi/src/sdk.rs (2)

137-145: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Thread the rest of DashSDKConfig through both builder helpers.

These paths still only apply network/DAPI/protocol version. skip_asset_lock_proof_verification, request_retry_count, and request_timeout_ms are never consumed before build(), so callers can set them and still get the default SDK behavior.

#!/bin/bash
set -euo pipefail

echo "== DashSDKConfig field usage in sdk.rs and types.rs =="
rg -n -C1 'skip_asset_lock_proof_verification|request_retry_count|request_timeout_ms' \
  packages/rs-sdk-ffi/src/sdk.rs \
  packages/rs-sdk-ffi/src/types.rs

echo
echo "== Candidate SdkBuilder setters/call sites in Rust sources =="
rg -n -C2 'with_.*(retry|timeout)|asset.*lock.*proof|proof.*verification|skip_asset_lock' . --glob '*.rs'

Also applies to: 303-357

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/rs-sdk-ffi/src/sdk.rs` around lines 137 - 145, The builder helpers
(both SdkBuilder::new(address_list) and SdkBuilder::new_mock()) fail to apply
DashSDKConfig fields skip_asset_lock_proof_verification, request_retry_count,
and request_timeout_ms; update build_sdk_builder (and the other helper path
around lines 303-357) to call the corresponding SdkBuilder setters after
creating the builder and before returning: read
config.skip_asset_lock_proof_verification and call the builder method that
disables/enables proof verification (e.g.,
with_skip_asset_lock_proof_verification or equivalent), set request retry count
via the builder method for retries (e.g., with_request_retry_count), and convert
config.request_timeout_ms into the builder timeout setter (e.g.,
with_request_timeout_ms or with_request_timeout using Duration::from_millis) so
both branches (SdkBuilder::new and SdkBuilder::new_mock) consistently consume
these config values.

166-175: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Use core_sdk_handle instead of falling back to globals here.

Once this branch sees a non-null handle, it still calls CallbackContextProvider::from_global() and never reads the handle value. That makes the per-instance handle in DashSDKConfigExtended a no-op and can bind the SDK to the wrong Core SDK instance or fail with the global-registration error even when a valid handle was passed.

#!/bin/bash
set -euo pipefail

echo "== core_sdk_handle branch in packages/rs-sdk-ffi/src/sdk.rs =="
rg -n -C2 'core_sdk_handle|from_global\(' packages/rs-sdk-ffi/src/sdk.rs

echo
echo "== handle-specific provider helpers in packages/rs-sdk-ffi/src/context_callbacks.rs =="
rg -n -C2 'from_core_sdk_handle|from_global' packages/rs-sdk-ffi/src/context_callbacks.rs
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/rs-sdk-ffi/src/sdk.rs` around lines 166 - 175, The branch that
checks config.core_sdk_handle.is_null() incorrectly always calls
CallbackContextProvider::from_global(), ignoring the per-instance handle; change
it to construct the provider from the passed handle when config.core_sdk_handle
is non-null (e.g. call
crate::context_callbacks::CallbackContextProvider::from_core_sdk_handle(core_sdk_handle)
or equivalent) and pass that provider into
builder.with_context_provider(callback_provider); if from_core_sdk_handle
returns None or an error, return the same DashSDKResult::error as the current
global-failure path. Ensure you reference config.core_sdk_handle (or the local
core_sdk_handle variable) and use CallbackContextProvider::from_core_sdk_handle
instead of CallbackContextProvider::from_global().
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Duplicate comments:
In `@packages/rs-sdk-ffi/src/sdk.rs`:
- Around line 137-145: The builder helpers (both SdkBuilder::new(address_list)
and SdkBuilder::new_mock()) fail to apply DashSDKConfig fields
skip_asset_lock_proof_verification, request_retry_count, and request_timeout_ms;
update build_sdk_builder (and the other helper path around lines 303-357) to
call the corresponding SdkBuilder setters after creating the builder and before
returning: read config.skip_asset_lock_proof_verification and call the builder
method that disables/enables proof verification (e.g.,
with_skip_asset_lock_proof_verification or equivalent), set request retry count
via the builder method for retries (e.g., with_request_retry_count), and convert
config.request_timeout_ms into the builder timeout setter (e.g.,
with_request_timeout_ms or with_request_timeout using Duration::from_millis) so
both branches (SdkBuilder::new and SdkBuilder::new_mock) consistently consume
these config values.
- Around line 166-175: The branch that checks config.core_sdk_handle.is_null()
incorrectly always calls CallbackContextProvider::from_global(), ignoring the
per-instance handle; change it to construct the provider from the passed handle
when config.core_sdk_handle is non-null (e.g. call
crate::context_callbacks::CallbackContextProvider::from_core_sdk_handle(core_sdk_handle)
or equivalent) and pass that provider into
builder.with_context_provider(callback_provider); if from_core_sdk_handle
returns None or an error, return the same DashSDKResult::error as the current
global-failure path. Ensure you reference config.core_sdk_handle (or the local
core_sdk_handle variable) and use CallbackContextProvider::from_core_sdk_handle
instead of CallbackContextProvider::from_global().

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 88e7bbd9-96a3-4710-aadd-8a459c530616

📥 Commits

Reviewing files that changed from the base of the PR and between 3e624bc and ef353c1.

📒 Files selected for processing (3)
  • packages/rs-sdk-ffi/README.md
  • packages/rs-sdk-ffi/src/sdk.rs
  • packages/swift-sdk/Sources/SwiftDashSDK/SDK.swift

@thepastaclaw
Copy link
Copy Markdown
Collaborator Author

Addressed the latest CodeRabbit follow-ups in db8a8db:\n\n- shared FFI SDK builder setup now applies proof verification, retry, and timeout config consistently, including trusted builders\n- extended SDK creation now uses the supplied Core SDK handle via the registered callbacks instead of falling back to the global callback handle\n- trusted SDK creation reuses DAPI address parsing so empty addresses use network defaults\n\nValidation:\n- cargo fmt --all\n- cargo test -p rs-sdk-ffi --no-default-features --features mocks\n- cargo check -p rs-sdk-ffi

- Move `protocol_version` into `DashSDKConfigExtended` per Lukasz's
  request: `dash_sdk_create_extended` now reads the field directly
  (0 = auto-detect) and the redundant
  `dash_sdk_create_extended_with_protocol_version` constructor is
  removed. Consolidates the two `dash_sdk_create_with_callbacks`
  variants behind a shared inner helper that sets the new field.
- Make the `GLOBAL_CALLBACKS` unit tests deterministic by adding a
  `test_support::lock_global_callbacks_for_test` guard that
  serializes test access and restores any prior callbacks on drop.
- Mark `CallbackContextProvider::from_core_sdk_handle` `unsafe`
  (it dereferences a raw pointer) and document the contract; update
  call sites accordingly.
- Clarify in code and docs that `skip_asset_lock_proof_verification`
  toggles `SdkBuilder::with_proofs` for *all* requests rather than
  asset-lock-specific proofs.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.

Comment thread packages/rs-sdk-ffi/src/sdk.rs Outdated
Comment on lines +19 to +35
/// with `InvalidParameter`. Callers that zero-initialize the struct
/// (e.g., Swift's `DashSDKConfigExtended()` or C `{0}` initializer)
/// automatically inherit the auto-detect default.
pub protocol_version: u32,
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Addressed in 24eb5dfd86 + 6c448d8575 and pushed to the PR branch.

Fix summary:

  • restored DashSDKConfigExtended to its original 3-field ABI/layout (no trailing protocol_version field)
  • kept dash_sdk_create_extended ABI-compatible and auto-detecting by default
  • added/restored separate protocol-version entry points: dash_sdk_create_with_protocol_version, dash_sdk_create_extended_with_protocol_version, dash_sdk_create_trusted_with_protocol_version, and dash_sdk_create_with_callbacks_and_protocol_version
  • updated Swift and README to use the separate _with_protocol_version APIs

Validation:

  • cargo fmt --all -- --check
  • cargo check -p rs-sdk-ffi --no-default-features --features mocks
  • cargo test -p rs-sdk-ffi --no-default-features --features mocks --lib sdk::tests

@thepastaclaw
Copy link
Copy Markdown
Collaborator Author

Refactored the protocol-version pinning change to use DashSDKConfigExtended.protocol_version instead of adding new exported constructors.

Summary:

  • removed the new *_with_protocol_version FFI constructors
  • added protocol_version to DashSDKConfigExtended (0 keeps auto-detect/default behavior)
  • updated Swift to populate DashSDKConfigExtended and call the existing extended creation path
  • updated the README examples accordingly

Validation:

  • cargo fmt --all -- --check
  • cargo check -p rs-sdk-ffi --no-default-features --features mocks
  • focused rs-sdk-ffi tests for the extended protocol-version path

The broader rs-sdk-ffi test run still hits the existing trusted-provider/network lookup issue in this environment, unrelated to this refactor.

@lklimek lklimek requested a review from Copilot May 27, 2026 07:49
thepastaclaw and others added 2 commits May 27, 2026 02:52
Adding `protocol_version` to the exported `#[repr(C)]`
`DashSDKConfigExtended` struct breaks ABI for existing callers. Drop
the field and expose protocol-version pinning through dedicated
exported constructors instead, leaving `dash_sdk_create_extended`'s
ABI unchanged (auto-detect by default).

New / restored entry points:
- dash_sdk_create_with_protocol_version
- dash_sdk_create_extended_with_protocol_version
- dash_sdk_create_trusted_with_protocol_version
- dash_sdk_create_with_callbacks_and_protocol_version

Swift `SDK` initializer now calls
`dash_sdk_create_trusted_with_protocol_version` directly; README C and
Python examples document the separate functions; tests cover the new
constructors and no longer rely on a config field.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…creator

`dash_sdk_create_with_callbacks_inner` was dispatching through the
public `dash_sdk_create_extended` / `dash_sdk_create_extended_with_protocol_version`
extern wrappers, paying an extra null-check on a stack-borrowed
reference and a second dispatch hop. Call
`create_extended_sdk_from_config` directly with a pre-resolved
platform version. Resolving the version before the wrapper allocation
also keeps an `InvalidParameter` early return from leaking the
context-provider box.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated 6 comments.

Comment on lines +139 to +148
if protocolVersion == 0 {
result = dash_sdk_create_trusted(&config)
} else {
var extendedConfig = DashSDKConfigExtended()
extendedConfig.base_config = config
extendedConfig.context_provider = nil
extendedConfig.core_sdk_handle = nil
extendedConfig.protocol_version = protocolVersion
result = dash_sdk_create_extended(&extendedConfig)
}
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Addressed in 6c448d8575: Swift now keeps the trusted creation path for both auto-detect and pinned protocol versions by calling dash_sdk_create_trusted_with_protocol_version(...). It no longer falls back to extended/mock creation when protocolVersion != 0.

Comment thread packages/rs-sdk-ffi/src/sdk.rs Outdated
Comment on lines +28 to +34
/// Optional Platform protocol version to pin the SDK to.
///
/// `0` preserves the default auto-detect behavior; any non-zero value
/// must correspond to a known `PlatformVersion` or SDK creation fails
/// with `InvalidParameter`. Callers that zero-initialize the struct
/// (e.g., Swift's `DashSDKConfigExtended()` or C `{0}` initializer)
/// automatically inherit the auto-detect default.
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Addressed in 24eb5dfd86 + 6c448d8575: DashSDKConfigExtended is back to its original three-field ABI/layout, and pinned versions use separate _with_protocol_version entry points instead of extending the exported struct.


create_trusted_sdk_from_config(&*config, None)
}

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Addressed in 24eb5dfd86 + 6c448d8575: added dash_sdk_create_trusted_with_protocol_version(config, protocol_version), while dash_sdk_create_trusted(config) remains the ABI-compatible auto-detect wrapper.

Comment thread packages/rs-sdk-ffi/src/types.rs Outdated
Comment on lines +75 to +81
/// SDK requests (wired to [`SdkBuilder::with_proofs(false)`]). The field
/// name reflects its original use case (skipping asset-lock proofs in
/// tests), but its effect is broader: callers should treat it as a
/// global "skip proofs" switch and only enable it for testing or for
/// trusted-context flows where proof verification is not desired.
///
/// [`SdkBuilder::with_proofs(false)`]: https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-sdk/src/sdk.rs
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Addressed in 5657829897: replaced the branch-specific GitHub URL with an intra-doc link to dash_sdk::SdkBuilder::with_proofs.

Validation: cargo fmt --all -- --check, cargo check -p rs-sdk-ffi --no-default-features --features mocks, and focused rs-sdk-ffi SDK tests passed. I also tried RUSTDOCFLAGS='-D warnings' cargo doc -p rs-sdk-ffi --no-deps --no-default-features --features mocks; it now gets past this link and fails on a pre-existing unrelated broken KeyType intra-doc link in signer.rs.

Comment on lines 86 to 92
DashSDKConfig config = {
.network = DASH_SDK_NETWORK_TESTNET,
.dapi_addresses = "seed-1.testnet.networks.dash.org",
.skip_asset_lock_proof_verification = false,
.request_retry_count = 3,
.request_timeout_ms = 30000
};
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Addressed in 5657829897: the C example now uses a full DAPI URI with scheme and port: https://seed-1.testnet.networks.dash.org:1443.

Comment on lines 160 to 166
config = DashSDKConfig(
network=1, # Testnet
dapi_addresses=b"seed-1.testnet.networks.dash.org",
skip_asset_lock_proof_verification=False,
request_retry_count=3,
request_timeout_ms=30000
)
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Addressed in 5657829897: the Python example now uses the same full DAPI URI form (https://seed-1.testnet.networks.dash.org:1443) so it satisfies AddressList::from_str parsing.

@lklimek
Copy link
Copy Markdown
Contributor

lklimek commented May 27, 2026

Replaced by #3751

@lklimek lklimek closed this May 27, 2026
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