Skip to content

fix: proper migration for legacy bls keys to the protx v>=2#7472

Open
knst wants to merge 19 commits into
dashpay:developfrom
knst:fix-providertx-versions-2
Open

fix: proper migration for legacy bls keys to the protx v>=2#7472
knst wants to merge 19 commits into
dashpay:developfrom
knst:fix-providertx-versions-2

Conversation

@knst

@knst knst commented Jul 17, 2026

Copy link
Copy Markdown
Collaborator

depends on #7302 to prevent conflicts ;

but changes are appliable for develop, issue is reproduced on develop too.

Issue being fixed or feature implemented

Issue has been spotted during reviewing #7302, see original comment:

Blocking: Normalize and re-key the operator key during v1-to-v3 upgrades

A post-v24 ProUpServTx can upgrade a v1 state to v3 without changing pubKeyOperator, and a same-key ProUpRegTx follows the same pattern. SetStateVersion() migrates payouts and netInfo but leaves CBLSLazyPublicKey encoded as legacy; the early return preserves that mismatch. Operator-key uniqueness is indexed by the wrapper's serialized GetHash(), while UpdateUniqueProperty() skips updates when two wrappers represent the same mathematical key. A v3 registration using the basic encoding of that existing key can therefore evade bad-protx-dup-key. Snapshot serialization can later normalize the wrapper without rebuilding the index, making acceptance dependent on reconstruction history. Re-encode the key for the target version, re-key the unique-property map when its serialized hash changes, and test duplicate rejection before and after reload.

What was done?

Keep the operator key's BLS encoding a deterministic function of nVersion, matching the SML and
on-disk serialization, so the unique-property index is re-keyed to the same scheme on every node
whether the list was built online or reloaded from a snapshot. Done before the early return because
callers pre-set nVersion, which would otherwise skip a needed re-encode. Runs only under the
v24-gated version transition, so pre-v24 blocks are untouched.

How Has This Been Tested?

Firstly, added new regression tests.

Secondly, there's mockup python script that reproduces issue (first comment on PR). This script is not meant to be merged, because its functionality is covered by regression tests

Breaking Changes

Fixes Dash Core v24 introduced issue, has not been released yet.

Checklist:

Go over all the following points, and put an x in all the boxes that apply.

  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have added or updated relevant unit/integration/functional/e2e tests
  • I have made corresponding changes to the documentation
  • I have assigned this pull request to a milestone (for repository code-owners and collaborators only)

knst added 18 commits July 14, 2026 23:23
…dation

This commit replaces usage of helpers GetPayload+IsTrivialValid to GetValidatedPayload
It unifies validation between regression tests and production code and
useful for the next commits in PR
CProRegTx and CProUpServTx used to be the only type of protx that have
a different version. It is theoretically acceptable in assumption that
there is no new features or version will ever be introduced for protx
special transaction.

Though, for better compatibility for futher version, unification, simplicity
of documentation and to reduce user's confusions for after-v24 version
of CProUpRegTx and CProUpRevTx are allowed to be "ext addresses" even they
don't have any network related fields _at the moment_

So, since now:
 - version 1: legacy BLS, extended addresses disallowed (pre v19 fork)
 - version 2: basic BLS, extended addresses disallowed (since v19 fork)
 - version 3: basic BLS, extended addresses allowed, multi-payouts allowed (since v24 fork)

NOTE: there are also classes CSimplifiedMNListEntry and CDeterministicMNState
use the same enum for its version; moreover CDeterministicMNState inherits
version directly from CProRegTx. This refactoring doesn't contradict or conflict
this behavior
It helps to drop multiple circular dependencies for providertx <-> validation.h as a side effect
@knst knst added this to the 24 milestone Jul 17, 2026
@github-actions

github-actions Bot commented Jul 17, 2026

Copy link
Copy Markdown

Potential PR merge conflicts

This is advisory only. It does not block CI, but it marks PRs that will likely need a rebase depending on merge order.

If this PR merges first

These open PRs will likely need a rebase:

  • #7302: fix!: use the same version along all protx special transactions Changed files: src/common/bloom.cpp, src/evo/core_write.cpp, src/evo/deterministicmns.cpp, src/evo/dmnstate.cpp, src/evo/dmnstate.h, src/evo/netinfo.cpp, src/evo/providertx.cpp, src/evo/providertx.h, src/evo/providertx_util.cpp, src/evo/specialtx_filter.cpp, src/evo/specialtxman.cpp, src/evo/specialtxman.h, and 16 more.
  • #7437: feat!: implement Decentralized Masternode Shares DIP Changed files: src/common/bloom.cpp, src/evo/core_write.cpp, src/evo/deterministicmns.cpp, src/evo/dmnstate.cpp, src/evo/dmnstate.h, src/evo/providertx.cpp, src/evo/providertx.h, src/evo/providertx_util.cpp, src/evo/specialtx_filter.cpp, src/evo/specialtxman.cpp, src/evo/specialtxman.h, src/masternode/payments.cpp, and 3 more.

If these PRs merge first

This PR will likely need a rebase:

@thepastaclaw

thepastaclaw commented Jul 17, 2026

Copy link
Copy Markdown

🕓 Ready for review — 10 ahead in queue (commit 5f66192)
Queue position: 11/11

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 94f3129802

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/evo/specialtxman.cpp
// v24-gated version transition, so pre-v24 blocks are untouched.
if (state_mn.pubKeyOperator != CBLSLazyPublicKey()) {
const auto pubkey{state_mn.pubKeyOperator.Get()};
state_mn.pubKeyOperator.Set(pubkey, nVersion == ProTxVersion::LegacyBLS);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Force diffs to carry BLS re-encodes

When a v24 update keeps the same operator key, this line changes only the CBLSLazyPublicKey encoding; however CDeterministicMNStateDiff still decides whether to include Field_pubKeyOperator via operator!=, which treats legacy/basic encodings of the same point as equal. BuildDiff therefore omits the key, so nodes reconstructing the MN list from stored/P2P diffs set nVersion to v3 but keep the legacy-encoded key and legacy unique-property hash, reintroducing the reconstruction-dependent duplicate-key behavior this patch is trying to remove.

Useful? React with 👍 / 👎.

@coderabbitai

coderabbitai Bot commented Jul 17, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: b2ca7817-0945-4544-be93-b4942bdab0b7

📥 Commits

Reviewing files that changed from the base of the PR and between 94f3129 and 5f66192.

📒 Files selected for processing (1)
  • src/rpc/evo.cpp
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/rpc/evo.cpp

Walkthrough

The PR centralizes ProTx version selection and owner-payout extraction around ProTxVersion::ExtAddr. It updates payout serialization, JSON/RPC output, payment processing, bloom filtering, and deterministic-node interfaces to use state-based payout access. Validation separates deployment-based payload limits from trivial transaction checks. State transitions migrate legacy payouts and re-encode operator keys while preserving unique-property indexing. Tests cover v19/v24 versioning, payout encoding, collateral reuse, and key re-indexing.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant RPC
  participant GetValidatedPayload
  participant ProTxState
  participant PayoutConsumers
  RPC->>GetValidatedPayload: construct and validate ProTx payload
  GetValidatedPayload->>ProTxState: apply version and payout state
  ProTxState->>PayoutConsumers: expose state-based owner payouts
  PayoutConsumers-->>RPC: serialize or display payout destinations
Loading

Possibly related PRs

  • dashpay/dash#7340: Both update provider payout extraction in bloom-filter processing and related owner-payout handling.

Suggested reviewers: pastapastapasta

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 10.81% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title matches the main change: migrating legacy BLS keys during ProTx version upgrades.
Description check ✅ Passed The description is directly about the same migration bug, fix, and regression tests described in the changeset.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
src/validation.cpp (1)

5831-5838: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Prefer the ChainstateManager overload here. It keeps both deployment checks on the same path and avoids mixing GetConsensus() with chainman.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/validation.cpp` around lines 5831 - 5838, Update DeploymentToProtxVersion
to use the ChainstateManager overload of DeploymentActiveAfter for the
DEPLOYMENT_V19 check, passing chainman consistently as already done for
DEPLOYMENT_V24; preserve the existing is_basic_override behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/rpc/evo.cpp`:
- Line 1106: Update the ptx.nVersion assignment in the relevant RPC flow to
retain BasicBLS for legacy service updates after v24 instead of unconditionally
using DeploymentToProtxVersion(). Preserve the higher-version selection for
applicable non-legacy updates so SignAndSendSpecialTx() receives a valid
transaction version.
- Around line 1228-1239: Update the empty operator-key handling in the RPC
method using nVersion so a reused legacy operator key is decoded and re-encoded
with the target version when nVersion is ExtAddr, while preserving the same key.
Do not copy the legacy encoding unchanged; ensure the resulting key satisfies
the existing version invariant.

---

Nitpick comments:
In `@src/validation.cpp`:
- Around line 5831-5838: Update DeploymentToProtxVersion to use the
ChainstateManager overload of DeploymentActiveAfter for the DEPLOYMENT_V19
check, passing chainman consistently as already done for DEPLOYMENT_V24;
preserve the existing is_basic_override behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 150955fa-ddc8-4072-95fa-5096a05accef

📥 Commits

Reviewing files that changed from the base of the PR and between ca2912d and 94f3129.

📒 Files selected for processing (28)
  • src/common/bloom.cpp
  • src/evo/core_write.cpp
  • src/evo/deterministicmns.cpp
  • src/evo/deterministicmns.h
  • src/evo/dmnstate.cpp
  • src/evo/dmnstate.h
  • src/evo/netinfo.cpp
  • src/evo/providertx.cpp
  • src/evo/providertx.h
  • src/evo/providertx_util.cpp
  • src/evo/specialtx_filter.cpp
  • src/evo/specialtxman.cpp
  • src/evo/specialtxman.h
  • src/evo/types.h
  • src/masternode/payments.cpp
  • src/node/interfaces.cpp
  • src/rpc/evo.cpp
  • src/rpc/masternode.cpp
  • src/test/data/trivially_invalid.json
  • src/test/evo_deterministicmns_tests.cpp
  • src/test/evo_trivialvalidation.cpp
  • src/validation.cpp
  • src/validation.h
  • test/functional/feature_masternode_payout_shares.py
  • test/functional/feature_protx_version.py
  • test/functional/rpc_netinfo.py
  • test/functional/test_runner.py
  • test/lint/lint-circular-dependencies.py

Comment thread src/rpc/evo.cpp
Comment thread src/rpc/evo.cpp
@knst

knst commented Jul 17, 2026

Copy link
Copy Markdown
Collaborator Author

Extra python script to reproduce issue [it is reproducible on top of develop as well]:

repro_protx_dupkey_reload_divergence.py

not an artefact to merge so far as replaced by regression tests

@UdjinM6

UdjinM6 commented Jul 17, 2026

Copy link
Copy Markdown

I noticed this issue too while reviewing #7302 and started with the same approach initially but this can actually stall block production, pls see #7473 for an alternative solution.

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.

3 participants