forked from bitcoin/bitcoin
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
feat!: implement Decentralized Masternode Shares DIP #7437
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
PastaPastaPasta
wants to merge
27
commits into
dashpay:develop
Choose a base branch
from
PastaPastaPasta:claude/masternode-shares-dip-c40ac2
base: develop
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+5,047
−73
Open
Changes from all commits
Commits
Show all changes
27 commits
Select commit
Hold shift + click to select a range
9d7436b
consensus: add shared collateral template script and new special tx t…
PastaPastaPasta 9dc4b76
evo: extend extended-address ProRegTx payload with collateral shares
PastaPastaPasta 5597ef1
evo: shared masternode consensus rules, state, and special transactions
PastaPastaPasta e45437d
masternode: split shared masternode rewards by share amounts
PastaPastaPasta 44f4b81
mempool: conflict tracking and eviction for shared masternode transac…
PastaPastaPasta 79ad37c
policy: relay carve-outs for the shared collateral template
PastaPastaPasta d8ab525
filters: match shared masternode fields in bloom and compact filters
PastaPastaPasta 2ed8a6f
rpc: shared masternode registration, dissolution and update commands
PastaPastaPasta da887ff
test: unit and functional coverage for decentralized masternode shares
PastaPastaPasta de1b4e9
doc: release notes for decentralized masternode shares
PastaPastaPasta 8e7c463
rpc: preflight shared registration terms and document standby dissolu…
PastaPastaPasta 3fd25d0
evo: disallow same-block registration and dissolution of a shared mas…
PastaPastaPasta a08f9b9
rpc: fail clearly when special transaction inputs cannot be signed at…
PastaPastaPasta a816174
test: filter matching and reorg coverage for shared masternodes
PastaPastaPasta 14309f8
test: cover shared masternode revival and pre-activation rejection
PastaPastaPasta 6b01878
rpc, gui: surface shared masternodes in payee displays and wallet fil…
PastaPastaPasta f67b521
evo: cap dissolution fees and unilateral penalty overpayment
PastaPastaPasta fcd1dc7
evo: enforce the ProUpShareTx signature size statelessly
PastaPastaPasta 16af0ff
miner: recheck the shared-collateral covenant for every packaged tran…
PastaPastaPasta 4d91abe
rpc: guard shared_sign against unnoticed dissolution time locks
PastaPastaPasta 0066781
test: backfill DIP test-list coverage for shared masternodes
PastaPastaPasta 0fe0dde
fix: adapt shared masternode code after rebase
PastaPastaPasta 4d7882c
fix: close shared masternode ownership and mempool gaps
PastaPastaPasta d7a5fd9
refactor: simplify shared masternode payout helpers
PastaPastaPasta f977eea
style: normalize shared transaction bloom checks
PastaPastaPasta 865e72d
test: cover shared masternodes across participant wallets
PastaPastaPasta 5e58f10
test: reject adversarial shared masternode transactions
PastaPastaPasta File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,75 @@ | ||
| # Decentralized Masternode Shares | ||
|
|
||
| This release implements the Decentralized Masternode Shares DIP, activating | ||
| together with DIP-0026 multi-party payouts as part of the v24 hard fork | ||
| (`DEPLOYMENT_V24`). Before activation there is no behavior change. | ||
|
|
||
| ## Consensus changes (active with v24) | ||
|
|
||
| - A version 3 (extended addresses) ProRegTx may carry a collateral share table: 2 to 8 participants | ||
| fund the masternode collateral atomically in one registration, each recording | ||
| an immutable amount, refund script and share owner key, plus an updatable | ||
| reward script. Every participant consents by signing a digest that binds the | ||
| exact funding inputs, all outputs, the share table, the penalty terms and the | ||
| registrar configuration. | ||
| - The shared collateral is paid to the 7-byte template script | ||
| `04445348437551` (`0x04 "DSHC" OP_DROP OP_TRUE`). From activation, an output | ||
| paying this exact script is valid only as the collateral of a valid shared | ||
| registration, and spending such an output is valid only via a ProDisTx. | ||
| Template outputs mined before activation become permanently unspendable. | ||
| - Three new special transaction types: | ||
| - **ProDisTx (type 10)** dissolves a shared masternode, refunding every | ||
| participant's principal to its immutable refund script. Exactly one | ||
| signature (unilateral, penalized during the configured early period) or one | ||
| per share (unanimous, penalty-free). Validity is monotone: a ProDisTx that | ||
| is valid at some height is valid at every later height, which makes offline | ||
| "standby dissolutions" safe. The transaction fee is capped at 1000000 duffs | ||
| and a unilateral dissolution may not pay bonuses beyond the configured | ||
| early penalty, bounding what a stolen share owner key can drain from its | ||
| own share. | ||
| - **ProUpShareTx (type 11)** lets one share owner update their reward script. | ||
| - **ProUpSharedRegTx (type 12)** updates the operator key and/or voting key | ||
| with a signature from every share owner. A plain ProUpRegTx is invalid for | ||
| shared masternodes. | ||
| - The owner reward of a shared masternode is split across the share table | ||
| proportionally to the recorded contributions (sequential floor, remainder to | ||
| the last entry), paying each share's reward script (or its refund script when | ||
| none is set). Operator rewards are unchanged. | ||
| - Withdrawal (asset unlock) transactions may not pay the template script. | ||
|
|
||
| ## Relay policy changes | ||
|
|
||
| - The template output relays only as the declared collateral output of a shared | ||
| registration, and a template prevout is accepted only inside a ProDisTx; both | ||
| remain nonstandard everywhere else. | ||
|
|
||
| ## New RPCs | ||
|
|
||
| - `protx register_shared_prepare` builds an unsigned shared registration from a | ||
| caller-supplied funding transaction. | ||
| - `protx shared_sign` signs a shared registration, dissolution or shared | ||
| registrar update with every share owner key the wallet holds. It refuses a | ||
| dissolution carrying a lock time or non-final sequence unless | ||
| `allowTimeLocks` is set. | ||
| - `protx shared_combine` combines collected signatures and optionally submits. | ||
| - `protx dissolve` creates, signs and submits a unilateral ProDisTx (or, with | ||
| `submit=false`, returns hex suitable for offline standby storage). | ||
| - `protx dissolve_prepare` builds an unsigned unanimous ProDisTx. | ||
| - `protx update_share` updates one share's reward address. | ||
| - `protx update_shared_registrar_prepare` builds an unsigned ProUpSharedRegTx. | ||
|
|
||
| Updated RPCs | ||
| ------------ | ||
|
|
||
| - `masternodelist` and `masternode list` report comma-separated share owner | ||
| addresses in `owneraddress` for shared masternodes. The `json` and `recent` | ||
| modes can be filtered by any share owner address. Shared registrations and | ||
| masternode state omit the singular `ownerAddress` field in `protx` and decoded | ||
| transaction output; each participant's owner address is in `shares`. (#7437) | ||
|
|
||
| GUI changes | ||
| ----------- | ||
|
|
||
| - The owned-masternode filter includes shared masternodes when the wallet holds | ||
| a participant's refund destination, including when rewards go to a different | ||
| wallet. (#7437) | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -46,7 +46,7 @@ CSimplifiedMNListEntry CDeterministicMN::to_sml_entry() const | |
| const CDeterministicMNState& state{*pdmnState}; | ||
| return CSimplifiedMNListEntry(proTxHash, state.confirmedHash, state.netInfo, state.pubKeyOperator, | ||
| state.keyIDVoting, !state.IsBanned(), state.platformHTTPPort, state.platformNodeID, | ||
| state.scriptPayout, GetOwnerPayouts(state), | ||
| state.scriptPayout, GetOwnerPayouts(state), state.shares, | ||
| state.scriptOperatorPayout, state.nVersion, nType); | ||
| } | ||
|
|
||
|
|
@@ -432,7 +432,19 @@ void CDeterministicMNList::AddMN(const CDeterministicMNCPtr& dmn, bool fBumpTota | |
| strprintf("%s: Can't add a masternode %s with invalid address", __func__, dmn->proTxHash.ToString())); | ||
| } | ||
| } | ||
| if (!AddUniqueProperty(*dmn, dmn->pdmnState->keyIDOwner)) { | ||
| if (dmn->pdmnState->IsShared()) { | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can shares be changed? If so, |
||
| // A shared masternode has a null keyIDOwner; each share owner key takes its place. Share | ||
| // owner keys deliberately land in the same uniqueness namespace as keyIDOwner | ||
| // (GetUniquePropertyHash is an untagged SerializeHash of the value), which is what makes | ||
| // owner-key reuse between shared and non-shared masternodes impossible in both directions. | ||
| for (const auto& share : dmn->pdmnState->shares) { | ||
| if (!AddUniqueProperty(*dmn, share.keyIDOwner)) { | ||
| mnUniquePropertyMap = mnUniquePropertyMapSaved; | ||
| throw(std::runtime_error(strprintf("%s: Can't add a masternode %s with a duplicate share ownerKeyID=%s", __func__, | ||
| dmn->proTxHash.ToString(), EncodeDestination(PKHash(share.keyIDOwner))))); | ||
| } | ||
| } | ||
| } else if (!AddUniqueProperty(*dmn, dmn->pdmnState->keyIDOwner)) { | ||
| mnUniquePropertyMap = mnUniquePropertyMapSaved; | ||
| throw(std::runtime_error(strprintf("%s: Can't add a masternode %s with a duplicate keyIDOwner=%s", __func__, | ||
| dmn->proTxHash.ToString(), EncodeDestination(PKHash(dmn->pdmnState->keyIDOwner))))); | ||
|
|
@@ -589,7 +601,16 @@ void CDeterministicMNList::RemoveMN(const uint256& proTxHash) | |
| dmn->proTxHash.ToString())); | ||
| } | ||
| } | ||
| if (!DeleteUniqueProperty(*dmn, dmn->pdmnState->keyIDOwner)) { | ||
| if (dmn->pdmnState->IsShared()) { | ||
| // Shared masternodes have a null keyIDOwner; the share owner keys were registered instead | ||
| for (const auto& share : dmn->pdmnState->shares) { | ||
| if (!DeleteUniqueProperty(*dmn, share.keyIDOwner)) { | ||
| mnUniquePropertyMap = mnUniquePropertyMapSaved; | ||
| throw(std::runtime_error(strprintf("%s: Can't delete a masternode %s with a share ownerKeyID=%s", __func__, | ||
| proTxHash.ToString(), EncodeDestination(PKHash(share.keyIDOwner))))); | ||
| } | ||
| } | ||
| } else if (!DeleteUniqueProperty(*dmn, dmn->pdmnState->keyIDOwner)) { | ||
| mnUniquePropertyMap = mnUniquePropertyMapSaved; | ||
| throw(std::runtime_error(strprintf("%s: Can't delete a masternode %s with a keyIDOwner=%s", __func__, | ||
| proTxHash.ToString(), EncodeDestination(PKHash(dmn->pdmnState->keyIDOwner))))); | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
rpc names are inconsistent.
register_shared_prepare - in the middle
shared_sign, shared_combine - at the beginning
update_share, update_shared_registrar_prepare - end
dissolve / dissove_prepare <- not even in the middle.
Consider unifying it to:
Or something similar