feat(key-wallet-ffi): typed special-transaction payload on FFITransactionRecord (expose ProRegTx service IP)#876
Conversation
…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>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (6)
📝 WalkthroughWalkthroughAdds 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. ChangesSpecial transaction payload support
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
Suggested labels: Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
Codecov Report❌ Patch coverage is
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
|
…dule docs Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Closes #875.
When a wallet's provider owner/voting key matches a
ProRegTxduring compact-filter sync (#863/#864), consumers need the transaction's special payload — the masternode's service IP:port,proTxHashlinkage, 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)FFISpecialTransactionPayloadis tagged bypayload_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/portsFFIProviderUpdateServicePayload— proTxHash, new service address (string + raw), operator payout script, platform fieldsFFIProviderUpdateRegistrarPayload— proTxHash, voting key hash, operator pubkey, payout scriptFFIProviderUpdateRevocationPayload— proTxHash, reasonOther payload kinds (coinbase, asset lock/unlock, …) surface the discriminant only and can grow typed structs later without a layout break.
2.
FFITransactionRecord.special_transaction_payloadPopulated from the stored
TransactionRecord's transaction, owned by the record, freed by itsDrop. This also flows throughdash-spv-ffi's transaction callbacks unchanged.Of the three
special_transaction_payload: Nonesites listed in the issue, two are test fixtures building payload-less transactions and the third istransaction_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-transactionsOFF (the mobile default),ManagedCoreKeysAccount::drop_finalized_transactionnow 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_txidsstill gets the txid, sohas_transaction/transaction_is_finalizedsemantics are unchanged.4. Ungated query:
managed_core_account_get_special_transactionsmanaged_core_account_get_transactionsonly exists withkeep-finalized-transactionsON, so retained provider records needed an always-available query. The new function returns payload-carrying records in every feature configuration (paired with the now-ungatedmanaged_core_account_free_transactions).Acceptance criteria from #875
FFITransactionRecordfor a storedProRegTxexposes a typed payload includingservice_addresswithout decodingtx_data(test_transaction_record_exposes_typed_proreg_payload)70993555a01f7e8d6179d6135b5c56809d2d1d36, service54.148.58.128:9999Testing
cargo test -p key-wallet -p key-wallet-ffiin both feature configurations (default andkeep-finalized-transactions) — all greenapply_chain_lockpromotion paths), plus controls proving payload-less records and non-provider accounts still dropProUpServTx'su128wire form), record round-trip, and the ungated query filtering a provider accountcargo clippy --all-targets -- -D warningsclean in both configs,cargo fmt --checkcleandashdintegration:cargo test -p dash-spv-ffi --test dashd_sync— 7/7 passFFI_API.mdregenerated (261 functions)🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Documentation