fix(wallet): use deterministic HD key for generic asset lock transactions#790
fix(wallet): use deterministic HD key for generic asset lock transactions#790
Conversation
…ions Replace randomly generated OsRng key in generic_asset_lock_transaction() with a deterministic HD-derived key at m/9'/coin_type'/15'/index'. This ensures asset lock keys are always recoverable from the wallet seed, preventing permanent fund loss when Platform rejects a state transition after Core has already broadcast the asset lock transaction. Co-Authored-By: Claude Opus 4.6 <[email protected]>
|
Important Review skippedDraft detected. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
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 |
Replace incorrect feature 15' with DIP-9-compliant Feature 5' sub-feature paths for asset lock key derivation. Introduce AssetLockUsage enum that maps each usage to its DIP-9 sub-feature index (1'=Registration, 2'=TopUp, 3'=Invitation, 4'=PlatformAddressFunding, 5'=ShieldedTopUp). Path structure changes from m/9'/ct'/15'/index' (4 components) to m/9'/ct'/5'/sub_feature'/index' (5 components). Bootstrap now pre-derives addresses for both PlatformAddressFunding and ShieldedTopUp usages. Add TODOs for pre-existing registration/top-up path mismatches that would require a migration strategy to fix. Co-Authored-By: Claude Opus 4.6 <[email protected]>
Note: Shield-from-asset-lock DB persistence gapThis PR improves key recovery for asset locks (preventing fund loss from lost private keys), but it doesn't address a separate issue flagged in PR #786 review: the The existing identity-funding flow uses For parity, consider also:
🤖 Co-authored by Claudius the Magnificent AI Agent |
Replace direct broadcast_raw_transaction() calls in create_registration_asset_lock and create_top_up_asset_lock with broadcast_and_commit_asset_lock() to ensure DB persistence before broadcast and UTXO cleanup after. Prevents recovery gaps if app crashes after Core broadcast but before state transition completes. All asset lock broadcast paths now go through the single centralized broadcast_and_commit_asset_lock() function. Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Summary
Replaces the randomly generated private key in
generic_asset_lock_transaction()with a deterministic HD-derived key, preventing permanent fund loss when Platform rejects a state transition after Core has already broadcast the asset lock transaction.User Story
Imagine you are mining on a local network and accumulate 500 tDASH across many small coinbase UTXOs. You try to fund a Platform address with 400 tDASH. The Core transaction broadcasts successfully (your balance drops), but Platform rejects the state transition with "Tx too large". With the old code, the private key for the asset lock was randomly generated and held only in memory — once the error propagated, the key was lost and your funds were unrecoverable. With this fix, the key is derived from your wallet seed and can always be re-derived for retry or recovery.
Changes
m/9'/coin_type'/15'/index'for generic asset lock funding (sub-feature 15 avoids collision with 5=identity, 17=platform payment)generic_asset_lock_ecdsa_private_key()derives the key from the wallet seed and registers the address inknown_addresses(same pattern asidentity_top_up_ecdsa_private_key)next_generic_funding_index()scans known addresses for the next unused indexOsRngremoved fromgeneric_asset_lock_transaction()— no more random keysRelated
Test plan
m/9'/coin_type'/15'/*')🤖 Co-authored by Claudius the Magnificent AI Agent