Repository navigation
refactor(dpp): decode instant asset lock proofs with rust-dashcore's legacy asset lock decoder - #5423
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info
📝 Walkthrough
Merge Risk: ⚪ Minimal · up to
|
|
✅ Final review complete — no blockers (commit ff15245) · triage: normal |
|
Waiting for bot review — coderabbitai ✓ · thepastaclaw not yet. Wait for the missing reviews, or a writer can post |
fff5d99 to
79b3030
Compare
|
Waiting for bot review — coderabbitai not yet · thepastaclaw not yet. Wait for the missing reviews, or a writer can post |
79b3030 to
ff15245
Compare
|
Waiting for bot review — coderabbitai not yet · thepastaclaw not yet. Wait for the missing reviews, or a writer can post |
thepastaclaw
left a comment
There was a problem hiding this comment.
Final validation — Phase 1 + Phase 2
No in-scope defects were found at ff15245. Static comparison of the removed workaround with the exact pinned rust-dashcore change supports unchanged decoding behavior, including signed-version selection, witness handling, payload reader limits, trailing-byte rejection, and error mapping; the added differential and execution tests cover the intended compatibility. No builds or tests were run in this static lane, and Rust workspace validation and JS builds remained queued in the supplied CI snapshot.
Review provenance
Source: reviewer 1: muse-spark-1.3-contributor (agent: phase1-reviewer, role: general); reviewer 2: muse-spark-1.3-contributor (agent: phase1-reviewer, role: rust-quality); reviewer 3: gpt-6.1-sol (agent: phase2-reviewer, role: general); reviewer 4: gpt-6.1-sol (agent: phase2-reviewer, role: architecture-layering); reviewer 5: gpt-6.1-sol (agent: phase2-reviewer, role: platform-versioning); reviewer 6: gpt-6.1-sol (agent: phase2-reviewer, role: rust-quality); reviewer 7: gpt-6.1-sol (agent: phase2-reviewer, role: security-auditor); final verifier: gpt-6.1-sol (agent: sol-verifier, role: final-verifier)
- Triage:
normalbygpt-6.1-sol(effort low) — The production changes replace a contained asset-lock decoder and add Core RPC compatibility handling, while most added code is tests, so the diff does not clearly meet the large-or-intricate critical-surface threshold. - Phase 1 reviewers:
muse-spark-1.3-contributor— general (completed, effort xhigh); agentphase1-reviewer,muse-spark-1.3-contributor— rust-quality (completed, effort xhigh); agentphase1-reviewer - Phase 1 model:
muse-spark-1.3-contributor— not quota-gated; passed overgemini-3.8-flash-high(antigravity below 15% reserve: weekly 14% left, 5h 100% left),glm-5.3-flash(not used above high effort; tier asks max) - Fresh verifier:
gpt-6.1-sol— final-verifier; agentsol-verifier - Phase 2 reviewers:
gpt-6.1-sol— general (completed, effort high); agentphase2-reviewer,gpt-6.1-sol— architecture-layering (completed, effort high); agentphase2-reviewer,gpt-6.1-sol— platform-versioning (completed, effort high); agentphase2-reviewer,gpt-6.1-sol— rust-quality (completed, effort high); agentphase2-reviewer,gpt-6.1-sol— security-auditor (completed, effort high); agentphase2-reviewer
|
Bots are done — your move: post |
…legacy asset lock decoder An instant asset lock proof's transaction is decoded from sender-chosen bytes, and an asset lock's payload has always been read whatever length its length prefix announces: neither the InstantSend lock nor the transition signature covers the prefix. #5403 kept that working with `decode_asset_lock_transaction`, a byte-level workaround on top of rust-dashcore's strict decoder. rust-dashcore now provides the same decoding as `Transaction::deserialize_ignoring_asset_lock_payload_length` (dashpay/rust-dashcore#1167). The rust-dashcore pin moves to a5ae6375 on integration/v5.0-core-v24, which is 379f0574 plus that commit cherry-picked, so the workaround is deleted and the proof decodes through it. Consensus is unchanged at every protocol version: the new function gives the same Ok/Err, decoded transaction and error string as the workaround for every input. A new differential test checks this against a test-only copy of the workaround over 100,000 seeded mutations of a real asset lock, its witness form and its zero-input form. A differential run in rust-dashcore covered 16M more. The #5403 tests pass unchanged, and now also cover 5- and 9-byte prefixes. The drive-abci IdentityCreate test also replaces the 1-byte prefix with a 3- and a 5-byte one, and checks the same identity, fee and balance. No red/green step applies: the change keeps the output identical. The differential test goes red when the new call is replaced with plain `deserialize`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…new name rust-dashcore renamed `Transaction::deserialize_ignoring_asset_lock_payload_length` to `Transaction::deserialize_with_legacy_asset_lock_framing` and moved it into its own module (dashpay/rust-dashcore#1167), so that it reads as what it is: a legacy decoder Platform keeps calling to agree with its older binaries. The rust-dashcore pin moves to edc4d430 on integration/v5.0-core-v24, which is a5ae6375 plus that commit cherry-picked. Instant asset lock proofs and the differential test call the new name. Consensus is unchanged: the function body is byte-for-byte the one the previous pin had. The differential test against the byte-level decoder, the test_raw_instant_lock_proof_* tests and the drive-abci IdentityCreate test with a 3- and a 5-byte payload length prefix pass. No red/green step applies: nothing behaves differently. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
734e7ea to
f9076a4
Compare
Merge origin/v5.0-dev (51ee8a7) into v5.1-dev (5b5daf6). Conflicts resolved: - Cargo.toml: GroveDB from v5.0-dev (6.1.0, fc7028d8); rust-dashcore pinned to dev afbe5515, which carries the legacy asset lock decoder (dashpay#1167) that dpp's instant asset lock proofs need (dashpay#5423), plus everything v5.0-dev's edc4d430 backported. - Cargo.lock: v5.1-dev's lockfile plus `cargo update -p dashcore -p grovedb`; no crates.io package changes. - CHANGELOG.md: kept the [Unreleased] section above the rc.1, rc.2 and rc.3 entries, and updated its rust-dashcore pin note. Semantic fixes for code v5.0-dev added against APIs that v5.1-dev changed: - drive-abci wasm vector examples and wasm-sdk cache tests: secp256k1 0.33 (from_secret_bytes, context-free from_secret_key) and dpp::bls instead of the removed dpp::bls_signatures re-export. The quorum public keys come out byte-identical. - wasm-sdk fixtures regenerated with the examples for the latest protocol version (15), as their README prescribes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PSi8cX229kW2fmLxKW6ir4
Issue being fixed or feature implemented
An instant asset lock proof carries a Core asset lock transaction as raw bytes the sender chooses. Neither the InstantSend lock nor the transition signature covers the asset lock's payload length prefix, and Platform has always read the payload whatever length that prefix announces. #5403 kept that behaviour once rust-dashcore started reading special payloads strictly through their prefix: it added
decode_asset_lock_transaction, a byte-level workaround that zeroes the type bytes of a copy, decodes it as a classic transaction up to the payload, then reads and ignores the prefix.That decoding now lives in rust-dashcore as a named, frozen legacy decoder in its own module,
Transaction::deserialize_with_legacy_asset_lock_framing(dashpay/rust-dashcore#1167, merged). It is deliberately neither#[deprecated]nor behind a cargo feature: Platform has to call it for as long as it must agree with its older binaries and replay its chain, so there is nothing to migrate to. This PR uses it and deletes the workaround.Based on #5422. This branch is built on #5422's branch (
Core-v24-getdeploymentinfo-softforks; start on Dash Core v24), because both move the rust-dashcore pin alongintegration/v5.0-core-v24. Until #5422 merges, its commits also show in this PR's diff; this PR's own changes are the last two commits. Merge #5422 first.What was done?
edc4d430onintegration/v5.0-core-v24. That is the previous head379f0574(fix(platform): start on Dash Core v24, which no longer reports softforks in getblockchaininfo #5422's pin) plus rust-dashcore#1167's two commits, cherry-picked withgit cherry-pick -x: the function (a5ae6375), then its rename and move into its own module (edc4d430).TryFrom<RawInstantLockProof> for InstantAssetLockProofcallsTransaction::deserialize_with_legacy_asset_lock_framing.decode_asset_lock_transactionand its imports are removed.test_raw_instant_lock_proof_decodes_every_transaction_as_the_byte_level_decoder_didkeeps a test-only copy of the removed workaround. It checks that both decoders agree on 100,000 seeded mutations of a real asset lock, its witness form and its zero-input form, on Ok/Err, the decodedTransactionand the error string. Half of the mutations rewrite the payload length prefix in a random width.should_create_the_same_identity_from_a_proof_with_another_payload_length_prefixalso replaces the 1-byte prefix with a 3-byte one. The IdentityCreate must still execute with the same identity, fee and balance.Out of scope: client-side code that builds a proof from Core's own bytes still uses plain
dashcore::consensus::deserialize, for example the wasm-dpp2InstantAssetLockProofconstructor and rs-sdk-ffiidentity/helpers.rs. It never sees a relayed, altered prefix. Every node decodes a proof throughTryFrom<RawInstantLockProof>, whether from bincode, serde or platform_value, so that is where the change applies.In-place changes to shipped generations
TryFrom<RawInstantLockProof>, reached by every funding transition (IdentityCreate, IdentityTopUp, AddressFundingFromAssetLock, ShieldFromAssetLock).Transactionand the same error string, which reachesProtocolError::DecodingErrorunchanged.Decodable for TransactionorAssetLockPayload::consensus_decode, so later rust-dashcore changes to those cannot change it.i16, type 8), both the old and the new code calldeserialize.7302d0a6and at rust-dashcoredev, with no Ok/Err, transaction or error mismatch;How Has This Been Tested?
All at the final pin
edc4d430:cargo test -p dpp --lib instant_asset_lock_proof: 27 passed. This includes the new differential test, which decoded about 22k of the 100k mutations from non-canonical bytes, with every prefix width succeeding at least once.cargo test -p dpp --lib asset_lock: 156 passed.cargo test -p drive-abci --lib identity_create: 243 passed, including the prefix test with 1-, 3- and 5-byte prefixes.cargo test -p drive-abci --lib asset_lock: 180 passed.cargo test -p drive-abci --lib rpc::core(fix(platform): start on Dash Core v24, which no longer reports softforks in getblockchaininfo #5422's tests): 13 passed.cargo clippy -p dpp -p drive-abci --tests -- -D warnings: clean.deserialize.rust.ymlpassed onintegration/v5.0-core-v24ata5ae6375and is running atedc4d430. Locally, the 46 decoder tests,cargo clippy -p dashcore --all-features --all-targets -- -D warningsandcargo docwith-D warningspass atedc4d430.edc4d430is the decoding ata5ae6375.Breaking Changes
None. Consensus behaviour is unchanged at every protocol version: proofs decode exactly as before.
Checklist:
structure.rs, regeneratedgrovedb-structure.json, and checked the structure viewer link posted on this pull requestFor repository code-owners and collaborators only
🤖 Generated with Claude Code
PR Hygiene ·
ff15245/self-reviewedWhen every merge requirement is met, the
PR Hygienecheck passes. Reviewer limits do not block merging; other required GitHub checks and protections still apply.