Skip to content

feat(dash)!: decode unknown special transaction types as raw payloads - #1136

Merged
ZocoLini merged 3 commits into
devfrom
feat/unknown-special-tx-payload
Oct 10, 2026
Merged

ZocoLini merged 3 commits into
devfrom
feat/unknown-special-tx-payload

Conversation

@ZocoLini

@ZocoLini ZocoLini commented Oct 7, 2026 •

Copy link
Copy Markdown
Collaborator

Closes #1130. Part of #1047.

A transaction with a special type we don't know failed to decode (UnknownSpecialTransactionType), and with it the whole block, so a new Core tx type would stall SPV sync and get_block consumers.

Changes

  • TransactionType::Unknown(u16) and TransactionPayload::UnknownPayloadType(u16, Vec<u8>): the payload is read through its length prefix and written back verbatim, so the tx re-encodes to the same bytes and txid.
  • Unknown types are non-segwit, like the other special types (an input-less one would otherwise be read as BIP144).
  • key-wallet router: matches on tx.tx_type() instead of the payload variant (same result). Unknown types are classified by shape like classic txs, so every fund-bearing account is checked.

Breaking: new enum variants on public, exhaustive enums.

Out of scope

Testing

  • Unit: round trip (bytes, txid, size), stream alignment across two txs, input-less unknown type, router classification.
  • cargo test -p dashcore -p key-wallet, cargo test -p dash-spv with dashd integration tests, clippy -D warnings.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Unknown transaction types can now be encoded and decoded, including transactions with no inputs.
    • Unknown transaction types and their payloads are preserved when processing transactions.
    • Transactions that follow an unknown transaction are decoded correctly.
    • Unknown transactions are classified as standard unless their contents indicate a coinbase or CoinJoin transaction.

PR Hygiene · 249ef12

  • Bots — coderabbitai ✓
  • Self-review — post /self-reviewed
  • Build green
  • Approvals
    • files with no dedicated owner (dash/src/blockdata/transaction/mod.rs, dash/src/blockdata/transaction/special_transaction/mod.rs, dash/src/test_utils/mod.rs and 1 more) — QuantumExplorer or xdustinface
    • key-wallet (key-wallet/src/transaction_checking/transaction_router/mod.rs, key-wallet/src/transaction_checking/transaction_router/tests/classification.rs) — QuantumExplorer or xdustinface

When every merge requirement is met, the PR Hygiene check passes. Reviewer limits do not block merging; other required GitHub checks and protections still apply.

A transaction whose special type this crate does not know failed to
decode with `UnknownSpecialTransactionType`, which failed the whole
block. Such transactions now decode as `TransactionType::Unknown` with a
raw `TransactionPayload::UnknownPayloadType`, read through the payload
length prefix and written back verbatim, so they re-encode to the same
bytes and txid.

Unknown types are treated as non-segwit like the other special types,
and the key-wallet router classifies them by shape like a classic
transaction, so they are checked across every fund-bearing account.

The router now matches on `tx.tx_type()` instead of the payload variant.

Closes #1130

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Oct 7, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository: dashpay/rust-dashcore/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: d5173613-c377-4abd-9747-59a907636bce
📥 Commits

Reviewing files that changed from the base of the PR and between 6d48530 and 249ef12.

📒 Files selected for processing (4)
  • dash/src/blockdata/transaction/mod.rs
  • dash/src/test_utils/mod.rs
  • dash/src/test_utils/transaction.rs
  • key-wallet/src/transaction_checking/transaction_router/tests/classification.rs

Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

Unknown special transaction types now retain their raw type and payload through encoding and decoding. Transactions with unknown types use non-SegWit framing. The wallet transaction router classifies unknown types by transaction shape.

Changes

Unknown transaction support

Layer / File(s) Summary
Unknown payload representation and codec
dash/src/blockdata/transaction/special_transaction/mod.rs
TransactionPayload and TransactionType now represent unknown special transaction types. Encoding and decoding preserve the raw type and payload bytes, including the length prefix.
Transaction wire handling
dash/src/blockdata/transaction/mod.rs, dash/src/test_utils/transaction.rs, dash/src/test_utils/mod.rs
Transaction encoding and decoding use non-SegWit framing for unknown types. Tests cover round trips, txid preservation, stream alignment, and transactions with no inputs. Test utilities expose the unassigned type constant.
Wallet transaction classification
key-wallet/src/transaction_checking/transaction_router/mod.rs, key-wallet/src/transaction_checking/transaction_router/tests/classification.rs
The router classifies transactions by type. Unknown types fall back to coinbase, CoinJoin, or Standard based on transaction shape. A test checks that an unknown special payload is classified as Standard.

Priority: ➖ Normal

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

Change: Bug fix · Severity of issue fixed: Medium

Merge Risk: ⚪ Minimal · up to 249ef

No actionable issue was established in the reviewed unknown-transaction codec, wire framing, or wallet classification changes; no identified risk blocks merging.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 71.43% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 21 functions across 6 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ 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: decoding unknown special transaction types as raw payloads.
Linked Issues check ✅ Passed Issue [#1130] requires unknown special transaction types to decode without failing block decoding and to retain the length-prefixed payload as raw bytes. The PR adds TransactionType::Unknown(u16) an…
Out of Scope Changes check ✅ Passed The transaction changes implement [#1130]. The key-wallet router change handles the new public transaction variant, and its classification test verifies unknown transaction handling. The shared test c…
  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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.

@ZocoLini
ZocoLini requested a review from xdustinface October 7, 2026 19:35
coderabbitai[bot]
coderabbitai Bot previously approved these changes Oct 7, 2026
@github-actions

github-actions Bot commented Oct 7, 2026 •

Copy link
Copy Markdown
Contributor

Bots are done — your move: post /self-reviewed.
Full checklist in the description.

@github-actions github-actions Bot added the waiting-self-review Waiting for the author to post /self-reviewed label Oct 7, 2026
@codecov

codecov Bot commented Oct 7, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 96.34146% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 78.09%. Comparing base (67b307c) to head (249ef12).
⚠️ Report is 3 commits behind head on dev.

Files with missing lines Patch % Lines
...c/blockdata/transaction/special_transaction/mod.rs 80.00% 2 Missing ⚠️
...src/transaction_checking/transaction_router/mod.rs 92.85% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##              dev    #1136      +/-   ##
==========================================
+ Coverage   77.92%   78.09%   +0.16%     
==========================================
  Files         302      302              
  Lines       79108    79315     +207     
==========================================
+ Hits        61644    61938     +294     
+ Misses      17464    17377      -87     
Flag Coverage Δ
core 75.23% <97.05%> (+0.26%) ⬆️
ffi 51.84% <ø> (+0.68%) ⬆️
rpc 49.21% <ø> (+0.25%) ⬆️
spv 92.43% <ø> (+0.03%) ⬆️
wallet 81.99% <92.85%> (+<0.01%) ⬆️
Files with missing lines Coverage Δ
dash/src/blockdata/transaction/mod.rs 88.16% <100.00%> (+1.25%) ⬆️
...src/transaction_checking/transaction_router/mod.rs 91.45% <92.85%> (+1.20%) ⬆️
...c/blockdata/transaction/special_transaction/mod.rs 40.27% <80.00%> (+2.11%) ⬆️

... and 29 files with indirect coverage changes

@xdustinface

Copy link
Copy Markdown
Collaborator

Two test issues before this can merge:

  1. unknown_special_transaction_type_without_inputs_is_not_segwit passes even without the fix. It only checks encode → decode → encode. If you revert both Unknown(_) segwit lines, the encoder writes the BIP144 marker 00 01 and the decoder reads it straight back, so the round trip still passes. Please assert the wire bytes instead. Either assert_eq!(bytes.len(), tx.size()) works, or check that bytes[4..6] == [0x00, 0x01] is followed directly by the output value.

  2. The tests use type 10, which Core develop already assigns to TRANSACTION_PROVIDER_DISSOLVE. Once dash: add payloads for special tx types 10-12 (ProDisTx, ProUpShareTx, ProUpSharedRegTx) #1131 adds parsing for types 10 to 12, Unknown(10) stops being unknown and all four new tests fail. That includes the router test in classification.rs. The TODO has the same problem: a real ProDisTx vector would no longer exercise the unknown-type path at all. Please switch to a type nobody has assigned (e.g. 0xffff, ideally behind a shared const), and drop or reword the TODO.

ZocoLini and others added 2 commits October 8, 2026 06:42
The test only round-tripped the transaction, which also passes with the
BIP144 marker the encoder and decoder agree on. Assert that the output
value follows the counts directly and that the length matches `size()`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Type 10 is ProDisTx in Core develop, so the tests would stop exercising
the unknown-type path once types 10-12 are parsed. Use `0xffff` through
a shared `UNASSIGNED_SPECIAL_TX_TYPE` test constant and drop the TODO
about a real ProDisTx vector.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@ZocoLini

ZocoLini commented Oct 8, 2026

Copy link
Copy Markdown
Collaborator Author

Done

@github-actions

github-actions Bot commented Oct 8, 2026 •

Copy link
Copy Markdown
Contributor

Waiting for bot review — coderabbitai not yet. Wait for the missing reviews, or a writer can post /skip-bots to proceed without them; blocking findings still need addressing.
Full checklist in the description.

@github-actions github-actions Bot added waiting-bots Waiting for the review bots to report on this head and removed waiting-self-review Waiting for the author to post /self-reviewed labels Oct 8, 2026
@github-actions

github-actions Bot commented Oct 8, 2026

Copy link
Copy Markdown
Contributor

Bots are done — your move: post /self-reviewed.
Full checklist in the description.

@github-actions github-actions Bot added waiting-self-review Waiting for the author to post /self-reviewed and removed waiting-bots Waiting for the review bots to report on this head labels Oct 8, 2026
@ZocoLini
ZocoLini merged commit 3ae5b48 into dev Oct 10, 2026
42 of 43 checks passed
@ZocoLini
ZocoLini deleted the feat/unknown-special-tx-payload branch October 10, 2026 12:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

waiting-self-review Waiting for the author to post /self-reviewed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

dash: don't fail on unknown special transaction types

2 participants