Skip to content

feat(dash): dedicated PlatformNodeId newtype for platform_node_id fields#885

Merged
QuantumExplorer merged 4 commits into
devfrom
claude/awesome-moser-a4d663
Jul 14, 2026
Merged

feat(dash): dedicated PlatformNodeId newtype for platform_node_id fields#885
QuantumExplorer merged 4 commits into
devfrom
claude/awesome-moser-a4d663

Conversation

@QuantumExplorer

@QuantumExplorer QuantumExplorer commented Jul 14, 2026

Copy link
Copy Markdown
Member

What

Follow-up to #883 (fixed in #884). Introduces a dedicated dashcore::PlatformNodeId newtype (20 bytes) and uses it for platform_node_id everywhere the value appears:

  • ProviderRegistrationPayload.platform_node_id: Option<PubkeyHash>Option<PlatformNodeId>
  • ProviderUpdateServicePayload.platform_node_id: Option<[u8; 20]>Option<PlatformNodeId>
  • EntryMasternodeType::HighPerformance.platform_node_id (SML masternode list entry): PubkeyHashPlatformNodeId

Why

The field is semantically a Tenderdash/CometBFT node ID — SHA256(ed25519_pubkey)[0..20] — not a hash160 public key hash; only the wire width (20 bytes) is the same. Typing it as PubkeyHash is what allowed the hash160 vs SHA256-truncated conventions to be conflated in #883. With a dedicated type, the compiler now rejects that mix-up.

The type carries from_ed25519_public_key, encoding the canonical CometBFT derivation (with a test asserting it equals truncated SHA256), plus hex Display/FromStr, serde, bincode, and consensus encoding.

Compatibility

  • Consensus serialization is byte-identical (raw 20 bytes). Existing test vectors pass unchanged; the v2 ProRegTx round-trip test now additionally asserts the decoded platform_node_id value and platform ports.
  • Bincode layout is unchanged — important because dash-spv persists masternode-list snapshots containing EntryMasternodeType. A regression test (bincode_layout_matches_pubkey_hash) locks the new type's layout to the old PubkeyHash layout.
  • Serde: unchanged for ProRegTx/SML (forward hex string, same as hash160). The one representation change is ProviderUpdateServicePayload, where the previous raw [u8; 20] serialized as a number array in JSON and now serializes as a hex string, consistent with the other payloads.
  • key-wallet-ffi C ABI is untouched (structs keep [u8; 20]; conversion goes through to_byte_array()).
  • rpc-json needs no changes — it parses its own [u8; 20] from JSON strings and never touches the dash consensus types.

Reviewer notes

Testing

  • cargo test -p dashcore --all-features, -p key-wallet --all-features, -p key-wallet-ffi, rpc crates — all pass
  • dashd-backed integration suites: cargo test -p dash-spv and cargo test -p dash-spv-ffi --test dashd_sync (exercises persisted masternode-list decode paths) — all pass
  • cargo clippy --all-features --all-targets and cargo fmt --check clean

🤖 Generated with Claude Code

The platform_node_id on ProRegTx was typed Option<PubkeyHash> (and raw
Option<[u8; 20]> on ProUpServTx), but the value is a Tenderdash/CometBFT
node ID — SHA256(ed25519_pubkey) truncated to 20 bytes — not a hash160
public key hash. Sharing the PubkeyHash type is what let the two
conventions get conflated in the first place (#883, fixed in #884).

Introduce dashcore::PlatformNodeId, a 20-byte newtype with hex
Display/FromStr, serde, bincode, and consensus encoding, plus
from_ed25519_public_key encoding the canonical CometBFT derivation.
Use it for platform_node_id on ProviderRegistrationPayload,
ProviderUpdateServicePayload, and EntryMasternodeType::HighPerformance.

All wire/persisted encodings stay byte-identical: consensus encoding is
the same raw 20 bytes (existing test vectors still pass, and the v2
ProRegTx round-trip test now also asserts the decoded node-ID value),
and a regression test locks the bincode layout to the old PubkeyHash
layout so persisted dash-spv masternode-list snapshots keep decoding.
key-wallet's platform-key matchers now compare raw bytes explicitly,
making the hash160-vs-node-ID distinction visible at the comparison
site; behavior is unchanged. The key-wallet-ffi C ABI is untouched.

Follow-up to #883.

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

coderabbitai Bot commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

@QuantumExplorer, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 6 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: c825a0cd-e8c0-4746-8a96-d5cc649df1ca

📥 Commits

Reviewing files that changed from the base of the PR and between a959459 and 7fc2321.

📒 Files selected for processing (11)
  • dash/src/blockdata/transaction/special_transaction/provider_registration.rs
  • dash/src/blockdata/transaction/special_transaction/provider_update_service.rs
  • dash/src/lib.rs
  • dash/src/platform_node_id.rs
  • dash/src/sml/masternode_list_entry/mod.rs
  • key-wallet-ffi/src/special_payload.rs
  • key-wallet/src/derivation_slip10.rs
  • key-wallet/src/tests/special_transaction_matching_tests.rs
  • key-wallet/src/tests/special_transaction_tests.rs
  • key-wallet/src/transaction_checking/account_checker.rs
  • key-wallet/src/transaction_checking/transaction_router/tests/provider.rs
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/awesome-moser-a4d663

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 14, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 94.73684% with 7 lines in your changes missing coverage. Please review.
✅ Project coverage is 74.36%. Comparing base (a959459) to head (7fc2321).

Files with missing lines Patch % Lines
dash/src/platform_node_id.rs 93.44% 4 Missing ⚠️
...ction/special_transaction/provider_registration.rs 97.61% 1 Missing ⚠️
...ion/special_transaction/provider_update_service.rs 96.15% 1 Missing ⚠️
...wallet/src/transaction_checking/account_checker.rs 50.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##              dev     #885      +/-   ##
==========================================
+ Coverage   74.30%   74.36%   +0.05%     
==========================================
  Files         326      327       +1     
  Lines       74636    74747     +111     
==========================================
+ Hits        55462    55586     +124     
+ Misses      19174    19161      -13     
Flag Coverage Δ
core 77.26% <95.34%> (+0.17%) ⬆️
ffi 50.31% <100.00%> (+<0.01%) ⬆️
rpc 20.00% <ø> (ø)
spv 91.09% <ø> (-0.03%) ⬇️
wallet 74.40% <66.66%> (-0.01%) ⬇️
Files with missing lines Coverage Δ
dash/src/sml/masternode_list_entry/mod.rs 62.31% <ø> (ø)
key-wallet-ffi/src/special_payload.rs 92.05% <100.00%> (-0.06%) ⬇️
key-wallet/src/derivation_slip10.rs 51.41% <100.00%> (-0.35%) ⬇️
...ction/special_transaction/provider_registration.rs 65.65% <97.61%> (+2.89%) ⬆️
...ion/special_transaction/provider_update_service.rs 82.69% <96.15%> (+0.87%) ⬆️
...wallet/src/transaction_checking/account_checker.rs 53.98% <50.00%> (ø)
dash/src/platform_node_id.rs 93.44% <93.44%> (ø)

... and 9 files with indirect coverage changes

QuantumExplorer and others added 2 commits July 14, 2026 12:03
PR #884 added derivation_slip10::tenderdash_node_id and this branch
added PlatformNodeId::from_ed25519_public_key — two copies of the same
SHA256(pubkey)[0..20] derivation. Keep the dash-crate newtype as the
single audited implementation and delegate the key-wallet helper to it;
the #884 golden-vector tests pin the output unchanged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Close the patch-coverage gaps codecov flagged: hex Display/FromStr
round-trip (including wrong-length and non-hex failures), serde JSON
round-trip as a hex string, and the zero-filled wire encoding of v2
high-performance ProRegTx / ProUpServTx payloads whose platform fields
are None.

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

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant