Skip to content

feat(key-wallet-ffi): typed special-transaction payload on FFITransactionRecord (expose ProRegTx service IP)#876

Merged
QuantumExplorer merged 2 commits into
devfrom
claude/proreg-tx-service-ip-ffi-3615c6
Jul 13, 2026
Merged

feat(key-wallet-ffi): typed special-transaction payload on FFITransactionRecord (expose ProRegTx service IP)#876
QuantumExplorer merged 2 commits into
devfrom
claude/proreg-tx-service-ip-ffi-3615c6

Conversation

@QuantumExplorer

@QuantumExplorer QuantumExplorer commented Jul 13, 2026

Copy link
Copy Markdown
Member

Closes #875.

When a wallet's provider owner/voting key matches a ProRegTx during compact-filter sync (#863/#864), consumers need the transaction's special payload — the masternode's service IP:port, proTxHash linkage, collateral outpoint, and key hashes — without reimplementing DIP-2/DIP-3 payload parsing in every binding.

What's here

1. Typed payload types (key-wallet-ffi/src/special_payload.rs, new)

FFISpecialTransactionPayload is tagged by payload_type (the on-wire DIP-2 tx type, 1 = ProRegTx … 9 = AssetUnlockTx) with one non-null typed pointer for the four provider payload kinds:

  • FFIProviderRegistrationPayload — version, masternode type/mode, collateral outpoint, service address (display string + raw 16-byte IP + port), owner/voting key hash160s, operator BLS key, operator reward, payout script, platform node id/ports
  • FFIProviderUpdateServicePayload — proTxHash, new service address (string + raw), operator payout script, platform fields
  • FFIProviderUpdateRegistrarPayload — proTxHash, voting key hash, operator pubkey, payout script
  • FFIProviderUpdateRevocationPayload — proTxHash, reason

Other payload kinds (coinbase, asset lock/unlock, …) surface the discriminant only and can grow typed structs later without a layout break.

2. FFITransactionRecord.special_transaction_payload

Populated from the stored TransactionRecord's transaction, owned by the record, freed by its Drop. This also flows through dash-spv-ffi's transaction callbacks unchanged.

Of the three special_transaction_payload: None sites listed in the issue, two are test fixtures building payload-less transactions and the third is transaction_create() (a new empty transaction) — none has a source payload to forward, so they are compliant as-is; the record-conversion path was the real gap and now forwards the payload.

3. Retention past chainlock finalization (key-wallet)

With keep-finalized-transactions OFF (the mobile default), ManagedCoreKeysAccount::drop_finalized_transaction now keeps records that carry a DIP-3 provider payload on provider-key accounts (owner/voting/operator/platform), instead of dropping them the moment their block is chainlocked — including the chainlocked-at-first-sight historical-rescan path. These records are rare (one per masternode lifecycle event matching our keys), so memory stays bounded. finalized_txids still gets the txid, so has_transaction / transaction_is_finalized semantics are unchanged.

4. Ungated query: managed_core_account_get_special_transactions

managed_core_account_get_transactions only exists with keep-finalized-transactions ON, so retained provider records needed an always-available query. The new function returns payload-carrying records in every feature configuration (paired with the now-ungated managed_core_account_free_transactions).

Acceptance criteria from #875

  • FFITransactionRecord for a stored ProRegTx exposes a typed payload including service_address without decoding tx_data (test_transaction_record_exposes_typed_proreg_payload)
  • ✅ Conversion paths populate the payload when the source has one (the three listed sites have no source payload — see above)
  • ✅ Round-trip test with mainnet-shape values: owner/voting hash160 70993555a01f7e8d6179d6135b5c56809d2d1d36, service 54.148.58.128:9999

Testing

  • cargo test -p key-wallet -p key-wallet-ffi in both feature configurations (default and keep-finalized-transactions) — all green
  • New key-wallet tests: retention on provider account (first-sight chainlocked and apply_chain_lock promotion paths), plus controls proving payload-less records and non-provider accounts still drop
  • New FFI tests: per-payload-kind conversion (incl. v4-mapped IP handling for ProUpServTx's u128 wire form), record round-trip, and the ungated query filtering a provider account
  • cargo clippy --all-targets -- -D warnings clean in both configs, cargo fmt --check clean
  • dashd integration: cargo test -p dash-spv-ffi --test dashd_sync — 7/7 pass
  • FFI_API.md regenerated (261 functions)

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added access to special provider transactions, including registration, service update, registrar update, and revocation details.
    • Special transaction records now expose structured payload information such as service endpoints and key data.
    • Provider-related transaction records remain available after finalization when needed, even without finalized-transaction retention enabled.
  • Documentation

    • Updated API documentation with the new special-transaction retrieval endpoint and transaction cleanup guidance.

…tionRecord

Expose DIP-2/DIP-3 special payload data — most importantly a ProRegTx's
masternode service IP:port — as a typed, FFI-safe struct instead of
forcing every binding to consensus-decode the raw tx_data bytes.

- New `special_payload` module: `FFISpecialTransactionPayload` tagged by
  the on-wire DIP-2 tx type, with typed structs for ProviderRegistration
  (service address string + raw ip/port, collateral outpoint, owner/
  voting key hashes, operator BLS key, payout script, platform fields),
  ProviderUpdateService, ProviderUpdateRegistrar and
  ProviderUpdateRevocation. Other payload kinds surface the discriminant
  only, extensible later.
- `FFITransactionRecord` gains an owned `special_transaction_payload`
  pointer, populated from the stored record's transaction and freed by
  the record's Drop impl.
- `ManagedCoreKeysAccount::drop_finalized_transaction` (feature
  `keep-finalized-transactions` OFF) now retains provider-payload
  records on provider-key accounts, so a chainlocked-at-first-sight
  historical ProRegTx stays queryable.
- New ungated `managed_core_account_get_special_transactions` FFI query
  (paired with the now-ungated `managed_core_account_free_transactions`)
  returns the payload-carrying records in every feature configuration.

Closes #875

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

coderabbitai Bot commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 2b0e10ad-0dce-4d36-a0fa-dc483f0ae2d6

📥 Commits

Reviewing files that changed from the base of the PR and between b536179 and c8f6bf3.

📒 Files selected for processing (6)
  • key-wallet-ffi/FFI_API.md
  • key-wallet-ffi/src/lib.rs
  • key-wallet-ffi/src/managed_account.rs
  • key-wallet-ffi/src/special_payload.rs
  • key-wallet/src/managed_account/managed_core_keys_account.rs
  • key-wallet/src/tests/keep_finalized_transactions_tests.rs

📝 Walkthrough

Walkthrough

Adds typed DIP-2 provider payloads to FFI transaction records, exposes payload-bearing transactions through a new managed-account API, and retains provider payload records during finalization pruning for provider-key accounts when finalized-transaction retention is disabled.

Changes

Special transaction payload support

Layer / File(s) Summary
FFI payload structures and conversion
key-wallet-ffi/src/special_payload.rs, key-wallet-ffi/src/managed_account.rs, key-wallet-ffi/src/lib.rs
Adds typed #[repr(C)] provider payload structures, conversion and cleanup logic, and the special_transaction_payload field on FFITransactionRecord.
Special transaction query API
key-wallet-ffi/src/managed_account.rs, key-wallet-ffi/FFI_API.md
Adds managed_core_account_get_special_transactions, updates transaction-array cleanup documentation, and updates API counts and listings.
Provider payload finalization retention
key-wallet/src/managed_account/managed_core_keys_account.rs, key-wallet/src/tests/keep_finalized_transactions_tests.rs
Retains finalized provider-payload records for provider-key accounts while continuing to prune payload-less or non-provider-account records, including chainlock promotion coverage.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant ManagedCoreAccount
  participant TransactionRecord
  participant FFITransactionRecord
  participant FFIConsumer
  ManagedCoreAccount->>TransactionRecord: select records with special payloads
  TransactionRecord->>FFITransactionRecord: convert typed payload
  FFITransactionRecord-->>FFIConsumer: return transaction array
  FFIConsumer->>ManagedCoreAccount: free transactions array
Loading

Suggested labels: ready-for-review

Suggested reviewers: xdustinface, zocolini

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning The new ungated special-transactions query goes beyond the linked issue's FFI record-shape scope and reads like an extra feature. Remove or separate the new query if it is not part of the issue, or add it to the linked scope with explicit justification.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: adding typed special-payload support to FFITransactionRecord for ProRegTx service IP exposure.
Linked Issues check ✅ Passed The PR implements typed special payloads on FFITransactionRecord, preserves provider records, and adds tests/docs covering ProRegTx service data.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/proreg-tx-service-ip-ffi-3615c6

Warning

Tools execution failed with the following error:

Failed to run tools: Ping-pong health check failed


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.

@codecov

codecov Bot commented Jul 13, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 89.59276% with 46 lines in your changes missing coverage. Please review.
✅ Project coverage is 74.38%. Comparing base (b536179) to head (c8f6bf3).

Files with missing lines Patch % Lines
key-wallet-ffi/src/managed_account.rs 85.27% 24 Missing ⚠️
key-wallet-ffi/src/special_payload.rs 92.11% 22 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##              dev     #876      +/-   ##
==========================================
+ Coverage   74.29%   74.38%   +0.09%     
==========================================
  Files         325      326       +1     
  Lines       73910    74352     +442     
==========================================
+ Hits        54911    55308     +397     
- Misses      18999    19044      +45     
Flag Coverage Δ
core 77.08% <ø> (ø)
ffi 52.91% <89.59%> (+1.77%) ⬆️
rpc 20.00% <ø> (ø)
spv 91.03% <ø> (-0.07%) ⬇️
wallet 73.47% <ø> (ø)
Files with missing lines Coverage Δ
key-wallet-ffi/src/lib.rs 0.00% <ø> (-50.00%) ⬇️
...t/src/managed_account/managed_core_keys_account.rs 57.71% <ø> (ø)
key-wallet-ffi/src/special_payload.rs 92.11% <92.11%> (ø)
key-wallet-ffi/src/managed_account.rs 63.31% <85.27%> (+3.15%) ⬆️

... and 5 files with indirect coverage changes

xdustinface
xdustinface previously approved these changes Jul 13, 2026
…dule docs

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

Labels

ready-for-review CodeRabbit has approved this PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(key-wallet-ffi): typed special-transaction payload on FFITransactionRecord (expose ProRegTx service IP)

2 participants