Skip to content

Latest commit

 

History

History
482 lines (384 loc) · 18.6 KB

dcp-0010.mediawiki

File metadata and controls

482 lines (384 loc) · 18.6 KB

DCP: 0010
Title: Change PoW/PoS Subsidy Split To 10/80
Author: Dave Collins <davec@decred.org>
        Jake Yocom-Piatt
Status: Active
Created: 2021-12-16
License: CC0-1.0
License-Code: ISC
Requires: DCP0006
Superseded-By: DCP0012

Table of Contents

Abstract

This specifies modifications to the block reward subsidy split such that 10% goes to Proof-of-Work (PoW) and 80% goes to Proof-of-Stake (PoS). The Treasury subsidy remains at 10%.

Motivation

This proposal is motivated by an extensive analysis that shows the majority of the PoW hash power is highly centralized and being used to maliciously manipulate Decred markets.

The proposed modification to the subsidy split is intended to substantially diminish the ability to attack Decred's markets with mined coins and improve decentralization of the issuance process.

See the Politeia proposal for further details.

Specification

Integer Math

In order to facilitate better compatibility across implementations and languages, the formulas defined by the specification make use of integer math instead of floating point math as denoted by the use of the floor function. This is highly desirable for consensus code since floating point math can be problematic across languages due to issues such as rounding errors and uncertainty in their respective libraries.

Full Block Subsidy Formula

The calculated full subsidy for each block MUST remain the same as it is prior to this specification. Since calculation of the modified subsidy proportions for PoW and PoS relies on first calculating the full subsidy, the details of the existing calculation are also provided in this specification.

Explanation of terms:

Sfull = The full block subsidy at a given height
h = The height for which the full subsidy is to be calculated
P = The coins generated by the first block (1,680,000 X 108 on mainnet)
I = The number of blocks in the subsidy reduction interval (6144 on mainnet)
c0 = The base coin subsidy before any reductions (3,119,582,664 on mainnet)
Rm = The coin subsidy reduction multiplier (100 on mainnet)
Rd = The coin subsidy reduction divisor (101 on mainnet)

Modified Subsidy Split

The subsidy split for the full block subsidy MUST be split between Proof-of-Work (PoW), Proof-of-Stake (PoS), and the decentralized Treasury as follows:

  • PoW - 10%
  • PoS - 80%
  • Treasury - 10% (no change from existing)
Additionally, the resulting PoS subsidy MUST be split evenly between the maximum number of votes per block, which, as of this specification, is 5 on all networks.

The Treasury subsidy proportion MUST remain the same and otherwise retain all existing semantics it has prior to this specification.

The following formulas precisely specify the calculations for the modified subsidy splits for arbitrary heights. This ensures the semantics are fully specified for all heights; however, it is important to note that they MUST only be applied to mainnet, and current testnet, for heights where the new rules are active per the associated on-chain vote.

Explanation of terms:

Sfull = The full block subsidy at a given height
Spow = The subsidy for proof of work at a given height for a given number of votes
Svote = The subsidy for a single vote at a given height
h = The height for which the subsidy is to be calculated
v = The number of votes included in the block
Hsv = The height at which stake validation begins (4096 on mainnet)
vb = The number of votes per block (5 on all networks)
vm = The minimum number of required votes (3 on all networks)

Subsidy Enforcement

IMPORTANT: The PoS subsidy, and hence each individual vote subsidy, is based on the block PRIOR to the one that contains the vote since that prior block is the one being voted on. In practice, this means the formula to calculate the vote subsidy MUST be called with a height of one less than the PoW subsidy formula once the height that voting begins at is reached.

The following modified rules MUST be enforced:

  • The input value of the one and only input of the coinbase transaction MUST commit to the modified PoW subsidy proportion
  • The total of the output values of the coinbase transaction MUST NOT exceed the modified PoW subsidy proportion plus the total fees from all transactions contained in the block
  • The input value of the stakebase of vote transactions MUST commit to the modified single vote subsidy proportion
  • The proportional payouts of vote transactions MUST be calculated based on the modified single vote subsidy proportion
  • The total of the output values of vote transactions MUST NOT exceed modified single vote subsidy proportion

Coinbase Rules and DCP0006 Requirement

The rule regarding the total of the output values of the coinbase transaction takes into account that DCP0006[1] is already active.

Rationale

Proof of Work is intended to provide several key properties to Decred, some of which are:

  • Unambiguous determination of the exact contents of a block
  • Unforgeable historical timestamps
  • A source of entropy
  • Significantly increased cost to conduct a wide variety of attacks
  • Protection against data manipulation and double spends
  • Fair coin distribution
While PoW has worked well for almost all of these properties, unfortunately extensive analysis has shown that the expected results of a fair coin distribution has not been achieved.

A commonly overlooked aspect of PoW mining is that it has to behave similarly to gold mining in order for it to achieve the expected results of a fair coin distribution. That is the reason the process is referred to as mining.

More concretely, the price is expected to track the cost of production such that, as the profitability goes up, the incentives for competition also go up which leads to more participants (hash power) and thus profitability reduces accordingly.

That expected result has not happened in Decred, which has led to Decred significantly overpaying for what PoW provides, as evidenced by the relative stability in overall network hashrate throughout long periods of large (e.g. 10-20x) changes in the exchange rate. The consequence of that has been a high degree of centralization of the coins.

The most expedient approach to deal with Decred overpaying for PoW is to simply reduce the PoW subsidy from 60% to 10% of the block subsidy.

This way, Decred retains the positive parts of PoW, like it being an entropy source and providing unforgeable costliness and irreversibility, without requiring substantial consensus work.

Alternative Approaches

Some other approaches that were considered and deemed unsuitable at the current time are:

Change the PoW algorithm

  • It does not solve the underlying issue of Decred overpaying for PoW
  • It would require 6-12 months of research and debate to do properly
  • The same issue is likely to emerge with any new algorithm due to the first point
Switch to pure PoS

  • This would require deep consensus changes and take 12+ months to execute
  • There are several attack vectors present with pure PoS that are difficult to solve
Compete on ASICs

  • High risk, high cost, and high lead time
  • Competing with existing manufacturers requires substantial capital expenditures in the 10s of millions of USD
  • Existing manufacturers have a massive advantage due to industry expertise, existing infrastructure, and backroom deals

Deployment

Voting Agenda Parameters

This proposal will be deployed to mainnet using the standard Decred on-chain voting infrastructure as follows:

Name Setting
Deployment Version 9
Agenda ID changesubsidysplit
Agenda Description Change block reward subsidy split to 10/80/10 as defined in DCP0010
Start Time 1631750400 (Sep 16th, 2021 00:00:00 +0000 UTC)
Expire Time 1694822400 (Sep 16th, 2023 00:00:00 +0000 UTC)
Mask 0x0180 (Bits 7 and 8)
Choices
Choice English Description Bits
abstain abstain voting for change 0x00
no keep the existing consensus rules 0x0080 (Bit 7)
yes change to the new consensus rules 0x0100 (Bit 8)

Voting Results

This proposal was approved by the stakeholder voting process and is now active.

Implementations MAY optimize their enforcement activation logic to apply the new rules specified by this proposal to the Active block and all of its descendants as opposed to tallying historical votes.

Status Block Hash Block Height
Voting Started 0000000000000000199b4ae1b9fe1649ce0a357e728ca12ad46d453c6e8f4ee5 641152
Locked In 0000000000000000320d41ff60cf34d15ae836a7298c94c0e690f18ff1cfbdfa 649216
Active 00000000000000002f4c6aaf0e9cb4d5a74c238d9bf8b8909e2372776c7c214c 657280

Compatibility

This is a hard-forking change to the Decred consensus. This means that once the agenda is voted in and becomes locked in, anybody running code that fully validates blocks must upgrade before the activation time or they will reject all blocks containing transactions with payouts that conform to the new subsidy split since they are invalid under the old rules.

Other software that performs full validation will need to modify their consensus enforcement rules accordingly and any software that creates coinbases or votes will need to be updated to handle the changes specified herein.

Reference Implementation

The following implementations are simplified versions intended to clearly illustrate the exact semantics of this specification with self-contained functions. See the linked pull request for the full implementations that include optimizations and the ability to selectively calculate both the legacy subsidy proportions as well as the new ones defined herein.

Full Block Subsidy Calculation

// calcBlockSubsidy returns the max potential subsidy for a block at the
// provided height.  This value is reduced over time based on the height and
// then split proportionally between PoW, PoS, and the Treasury.
func calcBlockSubsidy(height int64) int64 {
	// These parameters are ordinarily unique per chain and thus should be
	// passed into the function via a chain parameters structure, however,
	// they are defined as constants with the mainnet parameters here for the
	// purposes of providing a self-contained function for the DCP.
	const (
		mainnetBlockOneSubsidy            = 1680000 * 100000000
		mainnetSubsidyReductionInterval   = 6144
		mainnetBaseSubsidy                = 3119582664
		mainnetSubsidyReductionMultiplier = 100
		mainnetSubsidyReductionDivisor    = 101
	)

	// Negative block heights are invalid and produce no subsidy.
	// Block 0 is the genesis block and produces no subsidy.
	// Block 1 subsidy is special as it is used for initial token distribution.
	switch {
	case height <= 0:
		return 0
	case height == 1:
		return mainnetBlockOneSubsidy
	}

	// Calculate the subsidy by applying the appropriate number of reductions
	// per the requested height.
	reductions := height / mainnetSubsidyReductionInterval
	subsidy := int64(mainnetBaseSubsidy)
	for i := int64(0); i < reductions; i++ {
		subsidy *= mainnetSubsidyReductionMultiplier
		subsidy /= mainnetSubsidyReductionDivisor

		// Stop once no further reduction is possible.  This ensures a bounded
		// computation for large requested intervals and that all future
		// requests for intervals at or after the final reduction interval
		// return 0 without recalculating.
		if subsidy == 0 {
			break
		}
	}
	return subsidy
}

Work (PoW) Proportion Subsidy Calculation

// calcWorkSubsidyDCP0010 returns the proof of work subsidy for a block at the
// provided height and given number of votes using the modified subsidy split.
func calcWorkSubsidyDCP0010(height int64, voters uint16) int64 {
	// These parameters are ordinarily unique per chain and thus should be
	// passed into the function via a chain parameters structure, however,
	// they are defined as constants with the mainnet parameters here for the
	// purposes of providing a self-contained function for the DCP.
	const (
		mainnetStakeValidationHeight = 4096
		votesPerBlock                = 5
		minVotesRequired             = (votesPerBlock / 2) + 1
	)

	// The first block has special subsidy rules.
	if height == 1 {
		return calcBlockSubsidy(height)
	}

	// The subsidy is zero if there are not enough voters once voting begins.  A
	// block without enough voters will fail to validate anyway.
	if height >= mainnetStakeValidationHeight && voters < minVotesRequired {
		return 0
	}

	// Calculate the full block subsidy and reduce it according to the PoW
	// proportion.
	const proportion = 1
	const totalProportions = 10
	subsidy := calcBlockSubsidy(height)
	subsidy *= proportion
	subsidy /= totalProportions

	// Ignore any potential subsidy reductions due to the number of votes prior
	// to the point voting begins.
	if height < mainnetStakeValidationHeight {
		return subsidy
	}

	// Adjust for the number of voters.
	return (int64(voters) * subsidy) / votesPerBlock
}

Stake Vote (PoS) Proportion Subsidy Calculation

// calcStakeVoteSubsidyDCP0010 returns the subsidy for a single stake vote for a
// block at the provided height using the modified subsidy split.
func calcStakeVoteSubsidyDCP0010(height int64) int64 {
	// These parameters are ordinarily unique per chain and thus should be
	// passed into the function via a chain parameters structure, however,
	// they are defined as constants with the mainnet parameters here for the
	// purposes of providing a self-contained function for the DCP.
	const (
		mainnetStakeValidationHeight = 4096
		votesPerBlock                = 5
		minVotesRequired             = (votesPerBlock / 2) + 1
	)

	// Votes have no subsidy prior to the point voting begins.  The minus one
	// accounts for the fact that vote subsidy are, based on the height that is
	// being voted on as opposed to the block in which they are included.
	if height < mainnetStakeValidationHeight-1 {
		return 0
	}

	// Calculate the full block subsidy and reduce it according to the stake
	// proportion.  Then divide it by the number of votes per block to arrive
	// at the amount per vote.
	const proportion = 8
	const totalProportions = 10
	subsidy := calcBlockSubsidy(height)
	subsidy *= proportion
	subsidy /= (totalProportions * votesPerBlock)

	return subsidy
}

Pull Requests

Subsidy Enforcement

A reference implementation of the required consensus changes to enforce the new subsidy split is provided by pull request #2848.

Deployment

A reference implementation of the required agenda definition is implemented by pull request #2847.

Test Vectors

The following test vectors are provided in order to facilitate testing across implementations. These are the expected values for mainnet.

Subsidy Calculations

All subsidy values are in atoms.

Height Num Votes Full Subsidy Work Subsidy Vote Subsidy Notes
-1 0 0 0 0 negative height, invalid
0 0 0 0 0 genesis block
1 0 168000000000000 168000000000000 0 initial payouts
2 0 3119582664 311958266 0 first non-special block prior voting start
4094 0 3119582664 311958266 0 two blocks prior to voting start
4095 0 3119582664 311958266 499133226 final block prior to voting start
4096 5 3119582664 311958266 499133226 voting start, 5 votes
4096 4 3119582664 249566612 499133226 voting start, 4 votes
4096 3 3119582664 187174959 499133226 voting start, 3 votes
4096 2 3119582664 0 499133226 only 2 votes, invalid block
6143 5 3119582664 311958266 499133226 final block prior to 1st reduction
6144 5 3088695706 308869570 494191312 1st block in 1st reduction, 5 votes
6144 4 3088695706 247095656 494191312 1st block in 1st reduction, 4 votes
12287 5 3088695706 308869570 494191312 last block in 1st reduction
12288 5 3058114560 305811456 489298329 1st block in 2nd reduction
307200 5 1896827356 189682735 303492376 1st block in 50th reduction, 5 votes
307200 3 1896827356 189682735 303492376 1st block in 50th reduction, 3 votes
10954752 5 9 0 1 first zero work subsidy 1783rd reduction
10973184 5 6 0 0 first zero vote subsidy 1786th reduction
11010048 5 0 0 0 first zero full subsidy 1792nd reduction

Acknowledgements

Collaborators

Thanks to the following individuals who provided valuable feedback during the review process of this proposal (alphabetical order):

References

Inline References

  1. ^ DCP0006

Additional References

  1. Politeia Proposal - Change PoW/PoS Subsidy Split From 60/30 to 10/80
  2. The Suppressor Part 1: War of Attrition
  3. The Suppressor Part 2: On-Chain Analysis

Copyright

This document is licensed under the CC0-1.0: Creative Commons CC0 1.0 Universal license.

The code is licensed under the ISC License.