Skip to content

feat(platform-wallet): surface ProRegTx masternode details in iOS via rust-dashcore bump#4112

Merged
QuantumExplorer merged 4 commits into
v4.1-devfrom
claude/bump-rust-dashcore-876
Jul 13, 2026
Merged

feat(platform-wallet): surface ProRegTx masternode details in iOS via rust-dashcore bump#4112
QuantumExplorer merged 4 commits into
v4.1-devfrom
claude/bump-rust-dashcore-876

Conversation

@QuantumExplorer

@QuantumExplorer QuantumExplorer commented Jul 13, 2026

Copy link
Copy Markdown
Member

Issue being fixed or feature implemented

dashpay/rust-dashcore#876 landed typed DIP-2/DIP-3 special-transaction payloads (ProRegTx service IP, collateral, key hashes) plus provider-record retention, but nothing in the platform stack consumed them: a masternode registration in the wallet showed up as just "Provider Registration" with no details. This PR bumps the pin to pick that work up and surfaces the payload end-to-end in the iOS app.

What was done?

Dependency bump (Cargo.toml/Cargo.lock): rust-dashcore 234e3c43337f6ccc, picking up #876 (typed special-tx payloads + provider retention), #867 (AssetLock routing covers CoinJoin/DashPay accounts), #868 (CoinJoin gap limit 30 → 100).

Rust — rs-platform-wallet-ffi/src/core_wallet_types.rs (all DIP-3 decoding stays in Rust):

  • TransactionRecordFFI gains optional provider fields: provider_service_address (C string "ip:port"), provider_pro_tx_hash, collateral txid+vout, owner/voting key hashes — inline arrays with has_* flags following the existing block_hash/has_fee pattern, freed in free_wallet_changeset_ffi.
  • New provider_payload_fields() seam decodes dashcore::TransactionPayload::{ProviderRegistration, ProviderUpdateService} where tx_record_to_ffi builds the record (ProRegTx: service/collateral/key hashes; ProUpServTx: service + proTxHash).

Swift SDK (pure persist/bridge per architecture rules): PersistentTransaction gains matching optional columns + hex display helpers; PlatformWalletPersistenceHandler.upsertTransaction marshals the FFI fields gated on the has_* flags.

SwiftExampleApp: TransactionDetailView renders a "Masternode" section (service address, proTxHash, collateral, key hashes with tap-to-copy rows) for provider registration / update-service transactions.

Follow-ups deliberately out of scope: payout address (needs network-dependent script→address encoding), operator BLS key, and proTxHash follow in the compact-filter watch set (rust-dashcore#861 remainder — without it, ProUpServTx updates for owned masternodes don't match during sync).

How Has This Been Tested?

  • New Rust tests in platform-wallet-ffi: provider_registration_payload_fields_extracted (rust-dashcore's testnet collateral-ProRegTx fixture; asserts service 1.2.5.6:19999, owner/voting key hashes, collateral) and non_provider_tx_has_no_provider_fields. cargo test -p platform-wallet-ffi green; clippy clean.
  • cargo check --workspace --all-targets green against the new pin.
  • build_ios.sh --target sim (warnings-as-errors) green; regenerated headers carry the new fields.
  • On-simulator: app boots on an existing store, SwiftData lightweight-migrates (six new optional columns verified in ZPERSISTENTTRANSACTION), 1,775 pre-existing transaction rows intact.

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

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added masternode registration and service-update details to transaction records.
    • Transaction details now display service addresses, collateral information, and owner/voting key hashes when available.
    • Added copy-to-clipboard support for displayed masternode hashes and identifiers.
    • Masternode transaction data is now preserved for future viewing.
  • Bug Fixes

    • Improved recognition and handling of provider-specific transaction payloads.

QuantumExplorer and others added 2 commits July 13, 2026 20:12
Picks up dashpay/rust-dashcore#876 (FFISpecialTransactionPayload on
FFITransactionRecord, exposing ProRegTx service IP), #867 (AssetLock
routing covers CoinJoin/DashPay accounts) and #868 (CoinJoin gap
limit 30 -> 100 for dashj parity).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…nsaction records

Extracts the DIP-3 provider payload (service address, collateral
outpoint, owner/voting key hashes, and proTxHash for ProUpServTx)
from dashcore's typed special_transaction_payload where the persister
builds TransactionRecordFFI, persists the optional fields on
PersistentTransaction, and renders a Masternode section in the
transaction detail view for provider registration/update-service
transactions.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

@QuantumExplorer, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 41 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: f0b53911-30fd-49a5-8ef5-0fb6bedaedc7

📥 Commits

Reviewing files that changed from the base of the PR and between 627cb6c and 2391dd2.

📒 Files selected for processing (4)
  • packages/rs-platform-wallet-ffi/src/core_wallet_types.rs
  • packages/swift-sdk/Sources/SwiftDashSDK/Persistence/Models/PersistentTransaction.swift
  • packages/swift-sdk/Sources/SwiftDashSDK/PlatformWallet/PlatformWalletPersistenceHandler.swift
  • packages/swift-sdk/SwiftExampleApp/SwiftExampleApp/Core/Views/TransactionDetailView.swift
📝 Walkthrough

Walkthrough

The update pins Dashcore dependencies to a new revision, extracts DIP-3 provider payloads through Rust FFI, persists them in Swift transaction records, and displays provider registration or service-update details in the example app.

Changes

Provider payload pipeline

Layer / File(s) Summary
Dashcore revision and provider FFI fields
Cargo.toml, packages/rs-platform-wallet-ffi/src/core_wallet_types.rs
Dashcore dependencies use a new revision, while the FFI decodes provider payloads, exposes optional fields, wires them into transaction records, frees service-address strings, and tests provider and non-provider transactions.
Swift provider payload persistence
packages/swift-sdk/Sources/SwiftDashSDK/Persistence/Models/PersistentTransaction.swift, packages/swift-sdk/Sources/SwiftDashSDK/PlatformWallet/PlatformWalletPersistenceHandler.swift
Swift persistence stores provider fields, classifies provider transaction types, formats hashes and collateral, and maps FFI values using presence flags.
Provider transaction detail display
packages/swift-sdk/SwiftExampleApp/SwiftExampleApp/Core/Views/TransactionDetailView.swift
Transaction details conditionally render provider registration or service-update fields with copyable rows.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Dashcore
  participant RustFFI
  participant SwiftPersistence
  participant TransactionDetailView
  Dashcore->>RustFFI: decode DIP-3 provider payload
  RustFFI->>SwiftPersistence: expose provider fields and presence flags
  SwiftPersistence->>TransactionDetailView: provide persisted provider values
  TransactionDetailView->>TransactionDetailView: render provider details conditionally
Loading

Possibly related issues

Possibly related PRs

Suggested labels: Client Only

Suggested reviewers: shumkov, lklimek, zocolini, llbartekll

🚥 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 clearly reflects the main changes: a rust-dashcore bump and exposing masternode provider details in the iOS wallet.
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.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/bump-rust-dashcore-876

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.

@github-actions github-actions Bot added this to the v4.1.0 milestone Jul 13, 2026
@thepastaclaw

thepastaclaw commented Jul 13, 2026

Copy link
Copy Markdown
Collaborator

🔍 Review in progress — actively reviewing now (commit 627cb6c)

…dashcore-876

# Conflicts:
#	packages/swift-sdk/Sources/SwiftDashSDK/Persistence/Models/PersistentTransaction.swift

@coderabbitai coderabbitai Bot left a comment

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.

🧹 Nitpick comments (2)
packages/swift-sdk/SwiftExampleApp/SwiftExampleApp/Core/Views/TransactionDetailView.swift (1)

91-155: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Extract copyableHashRow usage into the existing Transaction ID / Block Hash blocks too.

The new copyableHashRow(title:value:) helper duplicates the exact tap-to-copy markup already inlined for "Transaction ID" (Line 204) and "Block Hash" (Line 232). Since the helper now exists, replacing both call sites removes ~50 lines of triplicated layout code.

♻️ Proposed refactor to reuse the new helper
-                        // Transaction ID
-                        VStack(alignment: .leading, spacing: 8) {
-                            Text("Transaction ID")
-                                .font(.caption)
-                                .foregroundColor(.secondary)
-
-                            Button {
-                                copyToClipboard(transaction.txidHex)
-                            } label: {
-                                HStack {
-                                    Text(transaction.txidHex)
-                                        .font(.system(.footnote, design: .monospaced))
-                                        .foregroundColor(.primary)
-                                        .lineLimit(nil)
-                                        .fixedSize(horizontal: false, vertical: true)
-
-                                    Spacer()
-
-                                    Image(systemName: "doc.on.doc")
-                                        .font(.caption)
-                                        .foregroundColor(.blue)
-                                }
-                                .padding()
-                                .background(Color(UIColor.secondarySystemBackground))
-                                .cornerRadius(8)
-                            }
-                        }
-
-                        // Block Hash (if available)
-                        if let blockHash = blockHashHex {
-                            VStack(alignment: .leading, spacing: 8) {
-                                Text("Block Hash")
-                                    .font(.caption)
-                                    .foregroundColor(.secondary)
-
-                                Button {
-                                    copyToClipboard(blockHash)
-                                } label: {
-                                    HStack {
-                                        Text(blockHash)
-                                            .font(.system(.footnote, design: .monospaced))
-                                            .foregroundColor(.primary)
-                                            .lineLimit(nil)
-                                            .fixedSize(horizontal: false, vertical: true)
-
-                                        Spacer()
-
-                                        Image(systemName: "doc.on.doc")
-                                            .font(.caption)
-                                            .foregroundColor(.blue)
-                                    }
-                                    .padding()
-                                    .background(Color(UIColor.secondarySystemBackground))
-                                    .cornerRadius(8)
-                                }
-                            }
-                        }
+                        copyableHashRow(title: "Transaction ID", value: transaction.txidHex)
+
+                        if let blockHash = blockHashHex {
+                            copyableHashRow(title: "Block Hash", value: blockHash)
+                        }

Also applies to: 204-260

🤖 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/swift-sdk/SwiftExampleApp/SwiftExampleApp/Core/Views/TransactionDetailView.swift`
around lines 91 - 155, Update the existing Transaction ID and Block Hash
sections in TransactionDetailView to call copyableHashRow(title:value:) instead
of duplicating their inline tap-to-copy layout. Preserve their current titles,
values, and conditional rendering while removing only the repeated markup.
packages/rs-platform-wallet-ffi/src/core_wallet_types.rs (1)

956-975: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Add ProUpServTx fixture coverage for provider_payload_fields. The ProviderUpdateServicePayloadType branch has no test, so the service-address reconstruction and pro_tx_hash extraction can regress silently; add a known ProUpServTx fixture alongside provider_registration_payload_fields_extracted.

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

In `@packages/rs-platform-wallet-ffi/src/core_wallet_types.rs` around lines 956 -
975, Add a ProUpServTx fixture-based test alongside
provider_registration_payload_fields_extracted, exercising
provider_payload_fields with ProviderUpdateServicePayloadType. Assert the
reconstructed service_address and extracted pro_tx_hash match the known fixture
values.
🤖 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.

Nitpick comments:
In `@packages/rs-platform-wallet-ffi/src/core_wallet_types.rs`:
- Around line 956-975: Add a ProUpServTx fixture-based test alongside
provider_registration_payload_fields_extracted, exercising
provider_payload_fields with ProviderUpdateServicePayloadType. Assert the
reconstructed service_address and extracted pro_tx_hash match the known fixture
values.

In
`@packages/swift-sdk/SwiftExampleApp/SwiftExampleApp/Core/Views/TransactionDetailView.swift`:
- Around line 91-155: Update the existing Transaction ID and Block Hash sections
in TransactionDetailView to call copyableHashRow(title:value:) instead of
duplicating their inline tap-to-copy layout. Preserve their current titles,
values, and conditional rendering while removing only the repeated markup.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: b5dbd9ff-b7c7-4587-b844-b1d65b8b1c52

📥 Commits

Reviewing files that changed from the base of the PR and between 5b90fbd and 627cb6c.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (5)
  • Cargo.toml
  • packages/rs-platform-wallet-ffi/src/core_wallet_types.rs
  • packages/swift-sdk/Sources/SwiftDashSDK/Persistence/Models/PersistentTransaction.swift
  • packages/swift-sdk/Sources/SwiftDashSDK/PlatformWallet/PlatformWalletPersistenceHandler.swift
  • packages/swift-sdk/SwiftExampleApp/SwiftExampleApp/Core/Views/TransactionDetailView.swift

…ture test

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@QuantumExplorer

Copy link
Copy Markdown
Member Author

Both CodeRabbit nitpicks addressed in 2391dd2 (and the v4.1-dev merge conflict with #4109's PersistentTransaction helpers is resolved in cd0e46d — both sides kept):

  • Transaction ID / Block Hash blocks in TransactionDetailView now reuse copyableHashRow (~50 lines of duplicated markup removed, byte-identical rendering).
  • Added provider_update_service_payload_fields_extracted using rust-dashcore's ProUpServTx test vector — asserts the reconstructed 52.36.64.148:19999 service address (covering the u128→IPv4-mapped path the ProRegTx fixture can't), the wire-order pro_tx_hash, and that collateral/key-hash fields stay None.

Verified: cargo test -p platform-wallet-ffi (3 provider tests) green, full build_ios.sh --target sim green post-merge.

🤖 Addressed by Claude Code

@codecov

codecov Bot commented Jul 13, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 87.42%. Comparing base (0c5eaa3) to head (2391dd2).
⚠️ Report is 3 commits behind head on v4.1-dev.

Additional details and impacted files
@@            Coverage Diff             @@
##           v4.1-dev    #4112    +/-   ##
==========================================
  Coverage     87.42%   87.42%            
==========================================
  Files          2640     2643     +3     
  Lines        333446   333632   +186     
==========================================
+ Hits         291502   291684   +182     
- Misses        41944    41948     +4     
Components Coverage Δ
dpp 88.44% <ø> (ø)
drive 86.14% <ø> (ø)
drive-abci 89.51% <ø> (ø)
sdk ∅ <ø> (∅)
dapi-client ∅ <ø> (∅)
platform-version ∅ <ø> (∅)
platform-value 92.88% <ø> (ø)
platform-wallet ∅ <ø> (∅)
drive-proof-verifier 49.55% <ø> (ø)
🚀 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.

@QuantumExplorer QuantumExplorer merged commit ad657c8 into v4.1-dev Jul 13, 2026
21 checks passed
@QuantumExplorer QuantumExplorer deleted the claude/bump-rust-dashcore-876 branch July 13, 2026 14:20
bezibalazs added a commit that referenced this pull request Jul 14, 2026
…nd-example-app

Conflict: Cargo.lock (base bumped grovedb 5.0.1 + rust-dashcore for the
masternode-list work) — took base's resolution and re-resolved for the
branch-only workspace members.

Merge adaptation: WalletRestoreEntryFFI gained
provider_special_txs(+count) (#4112/#4116); the JNI load path initializes
them null/0 — the documented "wallet has no provider special txs" value —
since Android has no provider-special-tx persistence yet (masternode-list
parity tracked as a follow-up).

Also lands the Sdk teardown behavioral test the review asked for:
SdkLifecycleTest (4 tests over a native-free Sdk.forLifecycleTest seam —
handle 0 skips the Cleaner's native destroy) pins close-awaits-lease,
post-close fail-fast, cancellation-cannot-strand-cleanup, and the
AutoCloseable.close() fence.

The nested-C-export panic-containment finding is intentionally NOT
addressed here: shumkov confirmed the mechanism and scoped the fix into
follow-up #4121 (cfg-gated panic-catch inert under the iOS panic=abort
profiles + PlatformWalletError surfacing); an ABI-wide change from this
PR would cut across that.

Verified: cargo fmt, platform-wallet-ffi lib tests (155), JNI check
(shielded), workspace clippy --all-features -D warnings, gradle
:sdk+:app tests (SdkLifecycleTest 4/4).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants