Skip to content

feat(dpp)!: convert Signer trait to async#3492

Open
QuantumExplorer wants to merge 4 commits intov3.1-devfrom
feat/async-signer-trait
Open

feat(dpp)!: convert Signer trait to async#3492
QuantumExplorer wants to merge 4 commits intov3.1-devfrom
feat/async-signer-trait

Conversation

@QuantumExplorer
Copy link
Copy Markdown
Member

Summary

Convert Signer<K> in rs-dpp to an async trait via #[async_trait], enabling true async signing for iOS HSM / Secure Enclave / keychain backends without blocking any thread during biometric prompts or hardware calls.

Trait shape:

#[async_trait]
pub trait Signer<K>: Send + Sync + Debug {
    async fn sign(&self, key: &K, data: &[u8]) -> Result<BinaryData, ProtocolError>;
    async fn sign_create_witness(&self, key: &K, data: &[u8]) -> Result<AddressWitness, ProtocolError>;
    fn can_sign_with(&self, key: &K) -> bool;  // stays sync
}

Scope

  • All 9 concrete Signer implementations converted (SimpleSigner, SingleKeySigner, DummySigner, 2× TestAddressSigner, IdentitySignerWasm, PlatformAddressSignerWasm, VTableSigner, AddressSigner)
  • Async propagated through rs-dpp state-transition builders, rs-sdk transition builders, rs-drive-abci tests, wasm-sdk, and strategy-tests — 177 files changed
  • Iterator closures calling signer.sign(...) rewritten as sequential for loops (order-preserving, borrow-friendly — no try_join_all)
  • #[stack_size] macro taught to wrap async fn bodies in a tokio current-thread runtime inside the spawned thread so integration tests keep working

Breaking change: rs-sdk-ffi Signer vtable redesign

The old synchronous SignCallback + free_result_callback pair is replaced with a completion-callback pattern:

pub type SignAsyncCallback = unsafe extern "C" fn(
    signer: *const c_void,
    key_bytes: *const u8, key_len: usize,
    data: *const u8, data_len: usize,
    completion_ctx: *mut c_void,
    completion: SignCompletionCallback,
);

pub type SignCompletionCallback = unsafe extern "C" fn(
    completion_ctx: *mut c_void,
    signature: *const u8, signature_len: usize,
    error_message: *const c_char,
);

The iOS side returns from sign_async immediately, stashes (completion_ctx, completion), and invokes completion(ctx, sig, len, err) later — possibly from a different thread, possibly minutes later after a biometric prompt. The Rust side awaits a tokio::sync::oneshot::Receiver in the meantime. No thread is blocked during the wait.

iOS migration required (follow-up PR on swift-sdk)

  • `dash_sdk_signer_create` no longer takes a `free_result_callback` parameter
  • Swift sign callback must use the new async shape: stash the completion, fire the HSM/Secure Enclave request, call `completion(...)` when done
  • `SingleKeySigner` now routes through a native (non-callback) path via `signer_handle_from_single_key` — no C bounce

The iOS Swift code in `packages/swift-sdk/` is left unmodified in this PR; updating it is explicit follow-up work.

Test plan

  • `cargo check --workspace --all-targets` — clean
  • `cargo fmt --all --check` — clean
  • CI: unit tests for rs-dpp, rs-sdk, rs-drive-abci
  • CI: strategy_tests integration tests
  • Follow-up: rebuild iOS xcframework and update swift-sdk Signer wrapper

🤖 Generated with Claude Code

Convert the Signer<K> trait in rs-dpp to an async trait via #[async_trait],
enabling true async signing for iOS HSM / Secure Enclave / keychain backends
without blocking any thread during biometric prompts or hardware calls.

- Signer::sign and Signer::sign_create_witness are now async; can_sign_with
  stays sync
- All 9 concrete Signer implementations converted (SimpleSigner,
  SingleKeySigner, DummySigner, 2x TestAddressSigner, IdentitySignerWasm,
  PlatformAddressSignerWasm, VTableSigner, AddressSigner)
- Propagate async through rs-dpp state-transition builders, rs-sdk transition
  builders, rs-drive-abci tests, wasm-sdk, and strategy-tests
- Iterator closures calling signer.sign(...) rewritten as sequential for
  loops (order-preserving, borrow-friendly)
- Teach #[stack_size] macro to wrap async fn bodies in a tokio current-thread
  runtime inside the spawned thread so integration tests keep working

BREAKING CHANGE: rs-sdk-ffi Signer vtable redesigned with a completion-
callback pattern. The old synchronous SignCallback + free_result_callback
pair is replaced with SignAsyncCallback + SignCompletionCallback, so the
iOS side can return from the sign callback immediately and invoke the Rust
completion function later (from any thread) when the HSM/keychain response
arrives. No thread is blocked during the wait.

Migration notes for iOS consumers:
- dash_sdk_signer_create no longer takes a free_result_callback
- The sign callback signature changes: iOS stashes (completion_ctx,
  completion) and invokes completion(ctx, sig, len, err) when ready
- SingleKeySigner now routes through a native (non-callback) path with no
  C-callback bounce, via signer_handle_from_single_key

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

coderabbitai bot commented Apr 14, 2026

Important

Review skipped

Too many files!

This PR contains 177 files, which is 27 over the limit of 150.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 3952dc77-b024-42e3-8b24-8d334d82a447

📥 Commits

Reviewing files that changed from the base of the PR and between 127ad5e and ccabca7.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (177)
  • .gitignore
  • packages/rs-dash-platform-macros/src/lib.rs
  • packages/rs-dpp/src/identity/signer.rs
  • packages/rs-dpp/src/lib.rs
  • packages/rs-dpp/src/shielded/builder/shield.rs
  • packages/rs-dpp/src/state_transition/mod.rs
  • packages/rs-dpp/src/state_transition/state_transitions/address_funds/address_credit_withdrawal_transition/methods/mod.rs
  • packages/rs-dpp/src/state_transition/state_transitions/address_funds/address_credit_withdrawal_transition/methods/v0/mod.rs
  • packages/rs-dpp/src/state_transition/state_transitions/address_funds/address_credit_withdrawal_transition/v0/v0_methods.rs
  • packages/rs-dpp/src/state_transition/state_transitions/address_funds/address_funding_from_asset_lock_transition/methods/mod.rs
  • packages/rs-dpp/src/state_transition/state_transitions/address_funds/address_funding_from_asset_lock_transition/methods/v0/mod.rs
  • packages/rs-dpp/src/state_transition/state_transitions/address_funds/address_funding_from_asset_lock_transition/v0/v0_methods.rs
  • packages/rs-dpp/src/state_transition/state_transitions/address_funds/address_funds_transfer_transition/methods/mod.rs
  • packages/rs-dpp/src/state_transition/state_transitions/address_funds/address_funds_transfer_transition/methods/v0/mod.rs
  • packages/rs-dpp/src/state_transition/state_transitions/address_funds/address_funds_transfer_transition/signing_tests.rs
  • packages/rs-dpp/src/state_transition/state_transitions/address_funds/address_funds_transfer_transition/v0/v0_methods.rs
  • packages/rs-dpp/src/state_transition/state_transitions/contract/data_contract_create_transition/methods/mod.rs
  • packages/rs-dpp/src/state_transition/state_transitions/contract/data_contract_create_transition/methods/v0/mod.rs
  • packages/rs-dpp/src/state_transition/state_transitions/contract/data_contract_create_transition/v0/v0_methods.rs
  • packages/rs-dpp/src/state_transition/state_transitions/contract/data_contract_update_transition/methods/mod.rs
  • packages/rs-dpp/src/state_transition/state_transitions/contract/data_contract_update_transition/methods/v0/mod.rs
  • packages/rs-dpp/src/state_transition/state_transitions/contract/data_contract_update_transition/v0/v0_methods.rs
  • packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/methods/mod.rs
  • packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/methods/v0/mod.rs
  • packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/methods/v1/mod.rs
  • packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v0/v0_methods.rs
  • packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v1/v0_methods.rs
  • packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v1/v1_methods.rs
  • packages/rs-dpp/src/state_transition/state_transitions/identity/identity_create_from_addresses_transition/methods/mod.rs
  • packages/rs-dpp/src/state_transition/state_transitions/identity/identity_create_from_addresses_transition/methods/v0/mod.rs
  • packages/rs-dpp/src/state_transition/state_transitions/identity/identity_create_from_addresses_transition/v0/v0_methods.rs
  • packages/rs-dpp/src/state_transition/state_transitions/identity/identity_create_transition/methods/mod.rs
  • packages/rs-dpp/src/state_transition/state_transitions/identity/identity_create_transition/methods/v0/mod.rs
  • packages/rs-dpp/src/state_transition/state_transitions/identity/identity_create_transition/v0/v0_methods.rs
  • packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_transfer_to_addresses_transition/methods/mod.rs
  • packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_transfer_to_addresses_transition/methods/v0/mod.rs
  • packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_transfer_to_addresses_transition/v0/v0_methods.rs
  • packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_transfer_transition/methods/mod.rs
  • packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_transfer_transition/methods/v0/mod.rs
  • packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_transfer_transition/v0/v0_methods.rs
  • packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_withdrawal_transition/methods/mod.rs
  • packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_withdrawal_transition/methods/v0/mod.rs
  • packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_withdrawal_transition/v1/v0_methods.rs
  • packages/rs-dpp/src/state_transition/state_transitions/identity/identity_topup_from_addresses_transition/methods/mod.rs
  • packages/rs-dpp/src/state_transition/state_transitions/identity/identity_topup_from_addresses_transition/methods/v0/mod.rs
  • packages/rs-dpp/src/state_transition/state_transitions/identity/identity_topup_from_addresses_transition/v0/v0_methods.rs
  • packages/rs-dpp/src/state_transition/state_transitions/identity/identity_update_transition/methods/mod.rs
  • packages/rs-dpp/src/state_transition/state_transitions/identity/identity_update_transition/methods/v0/mod.rs
  • packages/rs-dpp/src/state_transition/state_transitions/identity/identity_update_transition/v0/v0_methods.rs
  • packages/rs-dpp/src/state_transition/state_transitions/identity/masternode_vote_transition/methods/mod.rs
  • packages/rs-dpp/src/state_transition/state_transitions/identity/masternode_vote_transition/methods/v0/mod.rs
  • packages/rs-dpp/src/state_transition/state_transitions/identity/masternode_vote_transition/v0/v0_methods.rs
  • packages/rs-dpp/src/state_transition/state_transitions/identity/public_key_in_creation/methods/from_public_key_signed_external/mod.rs
  • packages/rs-dpp/src/state_transition/state_transitions/identity/public_key_in_creation/methods/from_public_key_signed_external/v0/mod.rs
  • packages/rs-dpp/src/state_transition/state_transitions/shielded/shield_transition/methods/mod.rs
  • packages/rs-dpp/src/state_transition/state_transitions/shielded/shield_transition/methods/v0/mod.rs
  • packages/rs-dpp/src/state_transition/state_transitions/shielded/shield_transition/v0/v0_methods.rs
  • packages/rs-drive-abci/src/execution/check_tx/v0/mod.rs
  • packages/rs-drive-abci/src/execution/platform_events/block_processing_end_events/tests.rs
  • packages/rs-drive-abci/src/execution/validation/state_transition/check_tx_verification/v0/mod.rs
  • packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/address_credit_withdrawal/tests.rs
  • packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/address_funding_from_asset_lock/tests.rs
  • packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/address_funds_transfer/tests.rs
  • packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/document/creation.rs
  • packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/document/deletion.rs
  • packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/document/dpns.rs
  • packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/document/nft.rs
  • packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/document/replacement.rs
  • packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/document/transfer.rs
  • packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/token/additional_validation/mod.rs
  • packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/token/burn/mod.rs
  • packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/token/config_update/mod.rs
  • packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/token/destroy_frozen_funds/mod.rs
  • packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/token/direct_selling/mod.rs
  • packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/token/distribution/perpetual/block_based.rs
  • packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/token/distribution/perpetual/time_based.rs
  • packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/token/distribution/pre_programmed.rs
  • packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/token/emergency_action/mod.rs
  • packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/token/freeze/mod.rs
  • packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/token/mint/mod.rs
  • packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/token/transfer/mod.rs
  • packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_create/mod.rs
  • packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_update/mod.rs
  • packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_create/mod.rs
  • packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_create_from_addresses/tests.rs
  • packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_credit_transfer/mod.rs
  • packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_credit_transfer_to_addresses/tests.rs
  • packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_credit_withdrawal/mod.rs
  • packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_top_up_from_addresses/tests.rs
  • packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_update/mod.rs
  • packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/masternode_vote/mod.rs
  • packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/mod.rs
  • packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/shield/tests.rs
  • packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/test_helpers.rs
  • packages/rs-drive-abci/tests/strategy_tests/execution.rs
  • packages/rs-drive-abci/tests/strategy_tests/failures.rs
  • packages/rs-drive-abci/tests/strategy_tests/query.rs
  • packages/rs-drive-abci/tests/strategy_tests/strategy.rs
  • packages/rs-drive-abci/tests/strategy_tests/test_cases/address_tests.rs
  • packages/rs-drive-abci/tests/strategy_tests/test_cases/basic_tests.rs
  • packages/rs-drive-abci/tests/strategy_tests/test_cases/chain_lock_update_tests.rs
  • packages/rs-drive-abci/tests/strategy_tests/test_cases/core_height_increase.rs
  • packages/rs-drive-abci/tests/strategy_tests/test_cases/core_update_tests.rs
  • packages/rs-drive-abci/tests/strategy_tests/test_cases/data_contract_history_tests.rs
  • packages/rs-drive-abci/tests/strategy_tests/test_cases/identity_and_document_tests.rs
  • packages/rs-drive-abci/tests/strategy_tests/test_cases/identity_transfer_tests.rs
  • packages/rs-drive-abci/tests/strategy_tests/test_cases/shielded_tests.rs
  • packages/rs-drive-abci/tests/strategy_tests/test_cases/token_tests.rs
  • packages/rs-drive-abci/tests/strategy_tests/test_cases/top_up_tests.rs
  • packages/rs-drive-abci/tests/strategy_tests/test_cases/update_identities_tests.rs
  • packages/rs-drive-abci/tests/strategy_tests/test_cases/upgrade_fork_tests.rs
  • packages/rs-drive-abci/tests/strategy_tests/test_cases/voting_tests.rs
  • packages/rs-drive-abci/tests/strategy_tests/test_cases/withdrawal_tests.rs
  • packages/rs-sdk-ffi/Cargo.toml
  • packages/rs-sdk-ffi/src/address/transitions/transfer.rs
  • packages/rs-sdk-ffi/src/dashpay/contact_request.rs
  • packages/rs-sdk-ffi/src/dpns/register.rs
  • packages/rs-sdk-ffi/src/identity/transfer.rs
  • packages/rs-sdk-ffi/src/identity/withdraw.rs
  • packages/rs-sdk-ffi/src/shielded/transitions/builders.rs
  • packages/rs-sdk-ffi/src/signer.rs
  • packages/rs-sdk-ffi/src/signer_simple.rs
  • packages/rs-sdk-ffi/src/test_utils.rs
  • packages/rs-sdk-ffi/src/token/claim.rs
  • packages/rs-sdk-ffi/src/token/config_update.rs
  • packages/rs-sdk-ffi/src/token/destroy_frozen_funds.rs
  • packages/rs-sdk-ffi/src/token/emergency_action.rs
  • packages/rs-sdk-ffi/src/token/freeze.rs
  • packages/rs-sdk-ffi/src/token/mint.rs
  • packages/rs-sdk-ffi/src/token/purchase.rs
  • packages/rs-sdk-ffi/src/token/set_price.rs
  • packages/rs-sdk-ffi/src/token/transfer.rs
  • packages/rs-sdk-ffi/src/token/unfreeze.rs
  • packages/rs-sdk/src/platform/documents/transitions/create.rs
  • packages/rs-sdk/src/platform/documents/transitions/delete.rs
  • packages/rs-sdk/src/platform/documents/transitions/purchase.rs
  • packages/rs-sdk/src/platform/documents/transitions/replace.rs
  • packages/rs-sdk/src/platform/documents/transitions/set_price.rs
  • packages/rs-sdk/src/platform/documents/transitions/transfer.rs
  • packages/rs-sdk/src/platform/tokens/builders/burn.rs
  • packages/rs-sdk/src/platform/tokens/builders/claim.rs
  • packages/rs-sdk/src/platform/tokens/builders/config_update.rs
  • packages/rs-sdk/src/platform/tokens/builders/destroy.rs
  • packages/rs-sdk/src/platform/tokens/builders/emergency_action.rs
  • packages/rs-sdk/src/platform/tokens/builders/freeze.rs
  • packages/rs-sdk/src/platform/tokens/builders/mint.rs
  • packages/rs-sdk/src/platform/tokens/builders/purchase.rs
  • packages/rs-sdk/src/platform/tokens/builders/set_price.rs
  • packages/rs-sdk/src/platform/tokens/builders/transfer.rs
  • packages/rs-sdk/src/platform/tokens/builders/unfreeze.rs
  • packages/rs-sdk/src/platform/transition/address_credit_withdrawal.rs
  • packages/rs-sdk/src/platform/transition/broadcast_identity.rs
  • packages/rs-sdk/src/platform/transition/purchase_document.rs
  • packages/rs-sdk/src/platform/transition/put_contract.rs
  • packages/rs-sdk/src/platform/transition/put_document.rs
  • packages/rs-sdk/src/platform/transition/put_identity.rs
  • packages/rs-sdk/src/platform/transition/shield.rs
  • packages/rs-sdk/src/platform/transition/top_up_address.rs
  • packages/rs-sdk/src/platform/transition/top_up_identity_from_addresses.rs
  • packages/rs-sdk/src/platform/transition/transfer.rs
  • packages/rs-sdk/src/platform/transition/transfer_address_funds.rs
  • packages/rs-sdk/src/platform/transition/transfer_document.rs
  • packages/rs-sdk/src/platform/transition/transfer_to_addresses.rs
  • packages/rs-sdk/src/platform/transition/update_price_of_document.rs
  • packages/rs-sdk/src/platform/transition/vote.rs
  • packages/rs-sdk/src/platform/transition/withdraw_from_identity.rs
  • packages/simple-signer/Cargo.toml
  • packages/simple-signer/src/signer.rs
  • packages/simple-signer/src/single_key_signer.rs
  • packages/strategy-tests/Cargo.toml
  • packages/strategy-tests/src/lib.rs
  • packages/strategy-tests/src/transitions.rs
  • packages/wasm-dpp2/Cargo.toml
  • packages/wasm-dpp2/src/identity/signer.rs
  • packages/wasm-dpp2/src/platform_address/signer.rs
  • packages/wasm-sdk/src/state_transitions/contract.rs
  • packages/wasm-sdk/src/state_transitions/identity.rs

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
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/async-signer-trait

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 Apr 14, 2026
@thepastaclaw
Copy link
Copy Markdown
Collaborator

thepastaclaw commented Apr 14, 2026

⏳ Review in progress (commit 9169382)

@codecov
Copy link
Copy Markdown

codecov bot commented Apr 14, 2026

Codecov Report

❌ Patch coverage is 94.58874% with 25 lines in your changes missing coverage. Please review.
✅ Project coverage is 84.93%. Comparing base (127ad5e) to head (9169382).
⚠️ Report is 2 commits behind head on v3.1-dev.

Files with missing lines Patch % Lines
...entity_credit_transfer_transition/v0/v0_methods.rs 0.00% 8 Missing ⚠️
..._funding_from_asset_lock_transition/methods/mod.rs 0.00% 3 Missing ⚠️
...identity_credit_transfer_transition/methods/mod.rs 0.00% 3 Missing ⚠️
...ity_topup_from_addresses_transition/methods/mod.rs 0.00% 3 Missing ⚠️
packages/rs-dpp/src/identity/signer.rs 0.00% 2 Missing ⚠️
...ion/methods/from_public_key_signed_external/mod.rs 0.00% 2 Missing ⚠️
.../methods/from_public_key_signed_external/v0/mod.rs 0.00% 2 Missing ⚠️
packages/rs-dpp/src/shielded/builder/shield.rs 88.88% 1 Missing ⚠️
..._create_from_addresses_transition/v0/v0_methods.rs 94.44% 1 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##           v3.1-dev    #3492      +/-   ##
============================================
+ Coverage     84.83%   84.93%   +0.10%     
============================================
  Files          2476     2476              
  Lines        267733   269916    +2183     
============================================
+ Hits         227123   229246    +2123     
- Misses        40610    40670      +60     
Components Coverage Δ
dpp 82.01% <86.77%> (+0.02%) ⬆️
drive 84.11% <ø> (-0.10%) ⬇️
drive-abci 87.85% <100.00%> (+0.38%) ⬆️
sdk ∅ <ø> (∅)
dapi-client ∅ <ø> (∅)
platform-version ∅ <ø> (∅)
platform-value 92.10% <ø> (ø)
platform-wallet ∅ <ø> (∅)
drive-proof-verifier 55.66% <ø> (ø)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 14, 2026

✅ DashSDKFFI.xcframework built for this PR.

SwiftPM (host the zip at a stable URL, then use):

.binaryTarget(
  name: "DashSDKFFI",
  url: "https://your.cdn.example/DashSDKFFI.xcframework.zip",
  checksum: "264aac33d5439625d3c8ddc6884d05a5452cb854e2ff40526754324f6fe1cf87"
)

Xcode manual integration:

  • Download 'DashSDKFFI.xcframework' artifact from the run link above.
  • Drag it into your app target (Frameworks, Libraries & Embedded Content) and set Embed & Sign.
  • If using the Swift wrapper package, point its binaryTarget to the xcframework location or add the package and place the xcframework at the expected path.

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

  1. packages/rs-sdk-ffi/src/signer.rs:266-299: if sign_async returns without ever invoking completion, the completion_ctx box is leaked and rx.await never resolves. The Err(_recv_err) branch here does not catch that case, so this hangs permanently instead of surfacing the intended protocol error. That makes cancellation / forgotten completion paths wedge the signer future forever.

  2. packages/rs-sdk/src/sdk.rs:316-327: auto-detect still parses the first proof with PlatformVersion::latest() and only learns the real protocol version after successful proof parsing. On an older network where proof interpretation differs from latest(), the first proof-backed request can fail before the SDK ever bootstraps itself, so the advertised auto-detect behavior is incomplete.

QuantumExplorer and others added 3 commits April 15, 2026 14:37
…llback

If the FFI signer's sign_async returns without ever invoking completion,
the oneshot Sender sits inside a Box handed to the C side and never drops,
so the previous `rx.await` match arm `Err(_recv_err)` could never fire
and the awaiting async fn would hang forever.

Bound the wait with tokio::time::timeout (5 min — generous enough for
biometric + HSM round-trips). On timeout we surface a recoverable
ProtocolError and leak the one Box<Sender> rather than risk a
use-after-free if the caller eventually does invoke completion.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Comment thread .gitignore Outdated

__pycache__/
.claude/worktrees/
.claude/
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.

did you ignore whole .claude by purpose ? Don't we want some shared claude config between all devs, to unify our performance?

quote! {
builder
.spawn(move || {
::tokio::runtime::Builder::new_current_thread()
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.

This can deadlock, workaround in #3490

use std::sync::Arc;

pub trait Signer<K>: Sync + Debug {
#[async_trait]
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.

Ensure we still want to use async_trtait vs ? Why in lib.rs we have #![allow(async_fn_in_trait)]?

//#![deny(missing_docs)]
#![allow(dead_code)]
#![allow(clippy::result_large_err)]
#![allow(async_fn_in_trait)]
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.

We use legacy async_trtait everywhere, not sure if #![allow(async_fn_in_trait)] is intentional.

let key_slice = std::slice::from_raw_parts(private_key, 32);
let mut key_array = Zeroizing::new([0u8; 32]);
key_array.copy_from_slice(key_slice);

// network won't matter here
// Network doesn't matter for signing purposes.
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.

Hardcoding the mainnet here is not a good approach, as it relies on SignleKeySigner internals. Either pass correct network, or remove the network arg from SingleKeySigner::new_from_slice()

// point, so we bridge by spinning up a current-thread runtime just
// long enough to drive the signing future. This is safe because
// SingleKeySigner's async fn is non-blocking (pure CPU work).
let runtime = match tokio::runtime::Builder::new_current_thread()
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.

Double-check that this actually works. It risks "starting runtime within runtime" error. See also #3490 .

@QuantumExplorer QuantumExplorer added the question Further information is requested label Apr 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

question Further information is requested

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants