Merge pull request #3703 from PastaPastaPasta/backport-v16-realloc

[v0.16.x] Backport v16 realloc
This commit is contained in:
UdjinM6 2020-09-14 01:33:02 +03:00 committed by GitHub
commit 5c2861538c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 442 additions and 53 deletions

View File

@ -82,15 +82,21 @@ static CBlock CreateGenesisBlock(uint32_t nTime, uint32_t nNonce, uint32_t nBits
} }
void CChainParams::UpdateVersionBitsParameters(Consensus::DeploymentPos d, int64_t nStartTime, int64_t nTimeout, int64_t nWindowSize, int64_t nThreshold) void CChainParams::UpdateVersionBitsParameters(Consensus::DeploymentPos d, int64_t nStartTime, int64_t nTimeout, int64_t nWindowSize, int64_t nThresholdStart, int64_t nThresholdMin, int64_t nFalloffCoeff)
{ {
consensus.vDeployments[d].nStartTime = nStartTime; consensus.vDeployments[d].nStartTime = nStartTime;
consensus.vDeployments[d].nTimeout = nTimeout; consensus.vDeployments[d].nTimeout = nTimeout;
if (nWindowSize != -1) { if (nWindowSize != -1) {
consensus.vDeployments[d].nWindowSize = nWindowSize; consensus.vDeployments[d].nWindowSize = nWindowSize;
} }
if (nThreshold != -1) { if (nThresholdStart != -1) {
consensus.vDeployments[d].nThreshold = nThreshold; consensus.vDeployments[d].nThresholdStart = nThresholdStart;
}
if (nThresholdMin != -1) {
consensus.vDeployments[d].nThresholdMin = nThresholdMin;
}
if (nFalloffCoeff != -1) {
consensus.vDeployments[d].nFalloffCoeff = nFalloffCoeff;
} }
} }
@ -320,28 +326,37 @@ public:
consensus.vDeployments[Consensus::DEPLOYMENT_DIP0001].nStartTime = 1508025600; // Oct 15th, 2017 consensus.vDeployments[Consensus::DEPLOYMENT_DIP0001].nStartTime = 1508025600; // Oct 15th, 2017
consensus.vDeployments[Consensus::DEPLOYMENT_DIP0001].nTimeout = 1539561600; // Oct 15th, 2018 consensus.vDeployments[Consensus::DEPLOYMENT_DIP0001].nTimeout = 1539561600; // Oct 15th, 2018
consensus.vDeployments[Consensus::DEPLOYMENT_DIP0001].nWindowSize = 4032; consensus.vDeployments[Consensus::DEPLOYMENT_DIP0001].nWindowSize = 4032;
consensus.vDeployments[Consensus::DEPLOYMENT_DIP0001].nThreshold = 3226; // 80% of 4032 consensus.vDeployments[Consensus::DEPLOYMENT_DIP0001].nThresholdStart = 3226; // 80% of 4032
// Deployment of BIP147 // Deployment of BIP147
consensus.vDeployments[Consensus::DEPLOYMENT_BIP147].bit = 2; consensus.vDeployments[Consensus::DEPLOYMENT_BIP147].bit = 2;
consensus.vDeployments[Consensus::DEPLOYMENT_BIP147].nStartTime = 1524477600; // Apr 23th, 2018 consensus.vDeployments[Consensus::DEPLOYMENT_BIP147].nStartTime = 1524477600; // Apr 23th, 2018
consensus.vDeployments[Consensus::DEPLOYMENT_BIP147].nTimeout = 1556013600; // Apr 23th, 2019 consensus.vDeployments[Consensus::DEPLOYMENT_BIP147].nTimeout = 1556013600; // Apr 23th, 2019
consensus.vDeployments[Consensus::DEPLOYMENT_BIP147].nWindowSize = 4032; consensus.vDeployments[Consensus::DEPLOYMENT_BIP147].nWindowSize = 4032;
consensus.vDeployments[Consensus::DEPLOYMENT_BIP147].nThreshold = 3226; // 80% of 4032 consensus.vDeployments[Consensus::DEPLOYMENT_BIP147].nThresholdStart = 3226; // 80% of 4032
// Deployment of DIP0003 // Deployment of DIP0003
consensus.vDeployments[Consensus::DEPLOYMENT_DIP0003].bit = 3; consensus.vDeployments[Consensus::DEPLOYMENT_DIP0003].bit = 3;
consensus.vDeployments[Consensus::DEPLOYMENT_DIP0003].nStartTime = 1546300800; // Jan 1st, 2019 consensus.vDeployments[Consensus::DEPLOYMENT_DIP0003].nStartTime = 1546300800; // Jan 1st, 2019
consensus.vDeployments[Consensus::DEPLOYMENT_DIP0003].nTimeout = 1577836800; // Jan 1st, 2020 consensus.vDeployments[Consensus::DEPLOYMENT_DIP0003].nTimeout = 1577836800; // Jan 1st, 2020
consensus.vDeployments[Consensus::DEPLOYMENT_DIP0003].nWindowSize = 4032; consensus.vDeployments[Consensus::DEPLOYMENT_DIP0003].nWindowSize = 4032;
consensus.vDeployments[Consensus::DEPLOYMENT_DIP0003].nThreshold = 3226; // 80% of 4032 consensus.vDeployments[Consensus::DEPLOYMENT_DIP0003].nThresholdStart = 3226; // 80% of 4032
// Deployment of DIP0008 // Deployment of DIP0008
consensus.vDeployments[Consensus::DEPLOYMENT_DIP0008].bit = 4; consensus.vDeployments[Consensus::DEPLOYMENT_DIP0008].bit = 4;
consensus.vDeployments[Consensus::DEPLOYMENT_DIP0008].nStartTime = 1557878400; // May 15th, 2019 consensus.vDeployments[Consensus::DEPLOYMENT_DIP0008].nStartTime = 1557878400; // May 15th, 2019
consensus.vDeployments[Consensus::DEPLOYMENT_DIP0008].nTimeout = 1589500800; // May 15th, 2020 consensus.vDeployments[Consensus::DEPLOYMENT_DIP0008].nTimeout = 1589500800; // May 15th, 2020
consensus.vDeployments[Consensus::DEPLOYMENT_DIP0008].nWindowSize = 4032; consensus.vDeployments[Consensus::DEPLOYMENT_DIP0008].nWindowSize = 4032;
consensus.vDeployments[Consensus::DEPLOYMENT_DIP0008].nThreshold = 3226; // 80% of 4032 consensus.vDeployments[Consensus::DEPLOYMENT_DIP0008].nThresholdStart = 3226; // 80% of 4032
// Deployment of Block Reward Reallocation
consensus.vDeployments[Consensus::DEPLOYMENT_REALLOC].bit = 5;
consensus.vDeployments[Consensus::DEPLOYMENT_REALLOC].nStartTime = 1601510400; // Oct 1st, 2020
consensus.vDeployments[Consensus::DEPLOYMENT_REALLOC].nTimeout = 1633046400; // Oct 1st, 2021
consensus.vDeployments[Consensus::DEPLOYMENT_REALLOC].nWindowSize = 4032;
consensus.vDeployments[Consensus::DEPLOYMENT_REALLOC].nThresholdStart = 3226; // 80% of 4032
consensus.vDeployments[Consensus::DEPLOYMENT_REALLOC].nThresholdMin = 2420; // 60% of 4032
consensus.vDeployments[Consensus::DEPLOYMENT_REALLOC].nFalloffCoeff = 5; // this corresponds to 10 periods
// The best chain should have at least this much work. // The best chain should have at least this much work.
consensus.nMinimumChainWork = uint256S("0x0000000000000000000000000000000000000000000027b81f49774e9f7fc93f"); // 1215000 consensus.nMinimumChainWork = uint256S("0x0000000000000000000000000000000000000000000027b81f49774e9f7fc93f"); // 1215000
@ -507,28 +522,37 @@ public:
consensus.vDeployments[Consensus::DEPLOYMENT_DIP0001].nStartTime = 1544655600; // Dec 13th, 2018 consensus.vDeployments[Consensus::DEPLOYMENT_DIP0001].nStartTime = 1544655600; // Dec 13th, 2018
consensus.vDeployments[Consensus::DEPLOYMENT_DIP0001].nTimeout = 1576191600; // Dec 13th, 2019 consensus.vDeployments[Consensus::DEPLOYMENT_DIP0001].nTimeout = 1576191600; // Dec 13th, 2019
consensus.vDeployments[Consensus::DEPLOYMENT_DIP0001].nWindowSize = 100; consensus.vDeployments[Consensus::DEPLOYMENT_DIP0001].nWindowSize = 100;
consensus.vDeployments[Consensus::DEPLOYMENT_DIP0001].nThreshold = 50; // 50% of 100 consensus.vDeployments[Consensus::DEPLOYMENT_DIP0001].nThresholdStart = 50; // 50% of 100
// Deployment of BIP147 // Deployment of BIP147
consensus.vDeployments[Consensus::DEPLOYMENT_BIP147].bit = 2; consensus.vDeployments[Consensus::DEPLOYMENT_BIP147].bit = 2;
consensus.vDeployments[Consensus::DEPLOYMENT_BIP147].nStartTime = 1544655600; // Dec 13th, 2018 consensus.vDeployments[Consensus::DEPLOYMENT_BIP147].nStartTime = 1544655600; // Dec 13th, 2018
consensus.vDeployments[Consensus::DEPLOYMENT_BIP147].nTimeout = 1576191600; // Dec 13th, 2019 consensus.vDeployments[Consensus::DEPLOYMENT_BIP147].nTimeout = 1576191600; // Dec 13th, 2019
consensus.vDeployments[Consensus::DEPLOYMENT_BIP147].nWindowSize = 100; consensus.vDeployments[Consensus::DEPLOYMENT_BIP147].nWindowSize = 100;
consensus.vDeployments[Consensus::DEPLOYMENT_BIP147].nThreshold = 50; // 50% of 100 consensus.vDeployments[Consensus::DEPLOYMENT_BIP147].nThresholdStart = 50; // 50% of 100
// Deployment of DIP0003 // Deployment of DIP0003
consensus.vDeployments[Consensus::DEPLOYMENT_DIP0003].bit = 3; consensus.vDeployments[Consensus::DEPLOYMENT_DIP0003].bit = 3;
consensus.vDeployments[Consensus::DEPLOYMENT_DIP0003].nStartTime = 1544655600; // Dec 13th, 2018 consensus.vDeployments[Consensus::DEPLOYMENT_DIP0003].nStartTime = 1544655600; // Dec 13th, 2018
consensus.vDeployments[Consensus::DEPLOYMENT_DIP0003].nTimeout = 1576191600; // Dec 13th, 2019 consensus.vDeployments[Consensus::DEPLOYMENT_DIP0003].nTimeout = 1576191600; // Dec 13th, 2019
consensus.vDeployments[Consensus::DEPLOYMENT_DIP0003].nWindowSize = 100; consensus.vDeployments[Consensus::DEPLOYMENT_DIP0003].nWindowSize = 100;
consensus.vDeployments[Consensus::DEPLOYMENT_DIP0003].nThreshold = 50; // 50% of 100 consensus.vDeployments[Consensus::DEPLOYMENT_DIP0003].nThresholdStart = 50; // 50% of 100
// Deployment of DIP0008 // Deployment of DIP0008
consensus.vDeployments[Consensus::DEPLOYMENT_DIP0008].bit = 4; consensus.vDeployments[Consensus::DEPLOYMENT_DIP0008].bit = 4;
consensus.vDeployments[Consensus::DEPLOYMENT_DIP0008].nStartTime = 1553126400; // Mar 21st, 2019 consensus.vDeployments[Consensus::DEPLOYMENT_DIP0008].nStartTime = 1553126400; // Mar 21st, 2019
consensus.vDeployments[Consensus::DEPLOYMENT_DIP0008].nTimeout = 1584748800; // Mar 21st, 2020 consensus.vDeployments[Consensus::DEPLOYMENT_DIP0008].nTimeout = 1584748800; // Mar 21st, 2020
consensus.vDeployments[Consensus::DEPLOYMENT_DIP0008].nWindowSize = 100; consensus.vDeployments[Consensus::DEPLOYMENT_DIP0008].nWindowSize = 100;
consensus.vDeployments[Consensus::DEPLOYMENT_DIP0008].nThreshold = 50; // 50% of 100 consensus.vDeployments[Consensus::DEPLOYMENT_DIP0008].nThresholdStart = 50; // 50% of 100
// Deployment of Block Reward Reallocation
consensus.vDeployments[Consensus::DEPLOYMENT_REALLOC].bit = 5;
consensus.vDeployments[Consensus::DEPLOYMENT_REALLOC].nStartTime = 1598918400; // Sep 1st, 2020
consensus.vDeployments[Consensus::DEPLOYMENT_REALLOC].nTimeout = 1630454400; // Sep 1st, 2021
consensus.vDeployments[Consensus::DEPLOYMENT_REALLOC].nWindowSize = 100;
consensus.vDeployments[Consensus::DEPLOYMENT_REALLOC].nThresholdStart = 80; // 80% of 100
consensus.vDeployments[Consensus::DEPLOYMENT_REALLOC].nThresholdMin = 60; // 60% of 100
consensus.vDeployments[Consensus::DEPLOYMENT_REALLOC].nFalloffCoeff = 5; // this corresponds to 10 periods
// The best chain should have at least this much work. // The best chain should have at least this much work.
consensus.nMinimumChainWork = uint256S("0x00000000000000000000000000000000000000000000000000ac720e0b2ed13d"); // 260000 consensus.nMinimumChainWork = uint256S("0x00000000000000000000000000000000000000000000000000ac720e0b2ed13d"); // 260000
@ -666,28 +690,37 @@ public:
consensus.vDeployments[Consensus::DEPLOYMENT_DIP0001].nStartTime = 1505692800; // Sep 18th, 2017 consensus.vDeployments[Consensus::DEPLOYMENT_DIP0001].nStartTime = 1505692800; // Sep 18th, 2017
consensus.vDeployments[Consensus::DEPLOYMENT_DIP0001].nTimeout = 1537228800; // Sep 18th, 2018 consensus.vDeployments[Consensus::DEPLOYMENT_DIP0001].nTimeout = 1537228800; // Sep 18th, 2018
consensus.vDeployments[Consensus::DEPLOYMENT_DIP0001].nWindowSize = 100; consensus.vDeployments[Consensus::DEPLOYMENT_DIP0001].nWindowSize = 100;
consensus.vDeployments[Consensus::DEPLOYMENT_DIP0001].nThreshold = 50; // 50% of 100 consensus.vDeployments[Consensus::DEPLOYMENT_DIP0001].nThresholdStart = 50; // 50% of 100
// Deployment of BIP147 // Deployment of BIP147
consensus.vDeployments[Consensus::DEPLOYMENT_BIP147].bit = 2; consensus.vDeployments[Consensus::DEPLOYMENT_BIP147].bit = 2;
consensus.vDeployments[Consensus::DEPLOYMENT_BIP147].nStartTime = 1517792400; // Feb 5th, 2018 consensus.vDeployments[Consensus::DEPLOYMENT_BIP147].nStartTime = 1517792400; // Feb 5th, 2018
consensus.vDeployments[Consensus::DEPLOYMENT_BIP147].nTimeout = 1549328400; // Feb 5th, 2019 consensus.vDeployments[Consensus::DEPLOYMENT_BIP147].nTimeout = 1549328400; // Feb 5th, 2019
consensus.vDeployments[Consensus::DEPLOYMENT_BIP147].nWindowSize = 100; consensus.vDeployments[Consensus::DEPLOYMENT_BIP147].nWindowSize = 100;
consensus.vDeployments[Consensus::DEPLOYMENT_BIP147].nThreshold = 50; // 50% of 100 consensus.vDeployments[Consensus::DEPLOYMENT_BIP147].nThresholdStart = 50; // 50% of 100
// Deployment of DIP0003 // Deployment of DIP0003
consensus.vDeployments[Consensus::DEPLOYMENT_DIP0003].bit = 3; consensus.vDeployments[Consensus::DEPLOYMENT_DIP0003].bit = 3;
consensus.vDeployments[Consensus::DEPLOYMENT_DIP0003].nStartTime = 1535752800; // Sep 1st, 2018 consensus.vDeployments[Consensus::DEPLOYMENT_DIP0003].nStartTime = 1535752800; // Sep 1st, 2018
consensus.vDeployments[Consensus::DEPLOYMENT_DIP0003].nTimeout = 1567288800; // Sep 1st, 2019 consensus.vDeployments[Consensus::DEPLOYMENT_DIP0003].nTimeout = 1567288800; // Sep 1st, 2019
consensus.vDeployments[Consensus::DEPLOYMENT_DIP0003].nWindowSize = 100; consensus.vDeployments[Consensus::DEPLOYMENT_DIP0003].nWindowSize = 100;
consensus.vDeployments[Consensus::DEPLOYMENT_DIP0003].nThreshold = 50; // 50% of 100 consensus.vDeployments[Consensus::DEPLOYMENT_DIP0003].nThresholdStart = 50; // 50% of 100
// Deployment of DIP0008 // Deployment of DIP0008
consensus.vDeployments[Consensus::DEPLOYMENT_DIP0008].bit = 4; consensus.vDeployments[Consensus::DEPLOYMENT_DIP0008].bit = 4;
consensus.vDeployments[Consensus::DEPLOYMENT_DIP0008].nStartTime = 1553126400; // Mar 21st, 2019 consensus.vDeployments[Consensus::DEPLOYMENT_DIP0008].nStartTime = 1553126400; // Mar 21st, 2019
consensus.vDeployments[Consensus::DEPLOYMENT_DIP0008].nTimeout = 1900281600; // Mar 21st, 2030 consensus.vDeployments[Consensus::DEPLOYMENT_DIP0008].nTimeout = 1900281600; // Mar 21st, 2030
consensus.vDeployments[Consensus::DEPLOYMENT_DIP0008].nWindowSize = 100; consensus.vDeployments[Consensus::DEPLOYMENT_DIP0008].nWindowSize = 100;
consensus.vDeployments[Consensus::DEPLOYMENT_DIP0008].nThreshold = 50; // 50% of 100 consensus.vDeployments[Consensus::DEPLOYMENT_DIP0008].nThresholdStart = 50; // 50% of 100
// Deployment of Block Reward Reallocation
consensus.vDeployments[Consensus::DEPLOYMENT_REALLOC].bit = 5;
consensus.vDeployments[Consensus::DEPLOYMENT_REALLOC].nStartTime = 1598918400; // Sep 1st, 2020
consensus.vDeployments[Consensus::DEPLOYMENT_REALLOC].nTimeout = 1900281600; // Mar 21st, 2030
consensus.vDeployments[Consensus::DEPLOYMENT_REALLOC].nWindowSize = 100;
consensus.vDeployments[Consensus::DEPLOYMENT_REALLOC].nThresholdStart = 80; // 80% of 100
consensus.vDeployments[Consensus::DEPLOYMENT_REALLOC].nThresholdMin = 60; // 60% of 100
consensus.vDeployments[Consensus::DEPLOYMENT_REALLOC].nFalloffCoeff = 5; // this corresponds to 10 periods
// The best chain should have at least this much work. // The best chain should have at least this much work.
consensus.nMinimumChainWork = uint256S("0x000000000000000000000000000000000000000000000000000000000000000"); consensus.nMinimumChainWork = uint256S("0x000000000000000000000000000000000000000000000000000000000000000");
@ -827,6 +860,13 @@ public:
consensus.vDeployments[Consensus::DEPLOYMENT_DIP0008].bit = 4; consensus.vDeployments[Consensus::DEPLOYMENT_DIP0008].bit = 4;
consensus.vDeployments[Consensus::DEPLOYMENT_DIP0008].nStartTime = 0; consensus.vDeployments[Consensus::DEPLOYMENT_DIP0008].nStartTime = 0;
consensus.vDeployments[Consensus::DEPLOYMENT_DIP0008].nTimeout = 999999999999ULL; consensus.vDeployments[Consensus::DEPLOYMENT_DIP0008].nTimeout = 999999999999ULL;
consensus.vDeployments[Consensus::DEPLOYMENT_REALLOC].bit = 5;
consensus.vDeployments[Consensus::DEPLOYMENT_REALLOC].nStartTime = 0;
consensus.vDeployments[Consensus::DEPLOYMENT_REALLOC].nTimeout = 999999999999ULL;
consensus.vDeployments[Consensus::DEPLOYMENT_REALLOC].nWindowSize = 500;
consensus.vDeployments[Consensus::DEPLOYMENT_REALLOC].nThresholdStart = 400; // 80%
consensus.vDeployments[Consensus::DEPLOYMENT_REALLOC].nThresholdMin = 300; // 60%
consensus.vDeployments[Consensus::DEPLOYMENT_REALLOC].nFalloffCoeff = 5;
// The best chain should have at least this much work. // The best chain should have at least this much work.
consensus.nMinimumChainWork = uint256S("0x00"); consensus.nMinimumChainWork = uint256S("0x00");
@ -928,9 +968,9 @@ void SelectParams(const std::string& network)
globalChainParams = CreateChainParams(network); globalChainParams = CreateChainParams(network);
} }
void UpdateVersionBitsParameters(Consensus::DeploymentPos d, int64_t nStartTime, int64_t nTimeout, int64_t nWindowSize, int64_t nThreshold) void UpdateVersionBitsParameters(Consensus::DeploymentPos d, int64_t nStartTime, int64_t nTimeout, int64_t nWindowSize, int64_t nThresholdStart, int64_t nThresholdMin, int64_t nFalloffCoeff)
{ {
globalChainParams->UpdateVersionBitsParameters(d, nStartTime, nTimeout, nWindowSize, nThreshold); globalChainParams->UpdateVersionBitsParameters(d, nStartTime, nTimeout, nWindowSize, nThresholdStart, nThresholdMin, nFalloffCoeff);
} }
void UpdateDIP3Parameters(int nActivationHeight, int nEnforcementHeight) void UpdateDIP3Parameters(int nActivationHeight, int nEnforcementHeight)

View File

@ -81,7 +81,7 @@ public:
const std::vector<SeedSpec6>& FixedSeeds() const { return vFixedSeeds; } const std::vector<SeedSpec6>& FixedSeeds() const { return vFixedSeeds; }
const CCheckpointData& Checkpoints() const { return checkpointData; } const CCheckpointData& Checkpoints() const { return checkpointData; }
const ChainTxData& TxData() const { return chainTxData; } const ChainTxData& TxData() const { return chainTxData; }
void UpdateVersionBitsParameters(Consensus::DeploymentPos d, int64_t nStartTime, int64_t nTimeout, int64_t nWindowSize, int64_t nThreshold); void UpdateVersionBitsParameters(Consensus::DeploymentPos d, int64_t nStartTime, int64_t nTimeout, int64_t nWindowSize, int64_t nThresholdStart, int64_t nThresholdMin, int64_t nFalloffCoeff);
void UpdateDIP3Parameters(int nActivationHeight, int nEnforcementHeight); void UpdateDIP3Parameters(int nActivationHeight, int nEnforcementHeight);
void UpdateBudgetParameters(int nMasternodePaymentsStartBlock, int nBudgetPaymentsStartBlock, int nSuperblockStartBlock); void UpdateBudgetParameters(int nMasternodePaymentsStartBlock, int nBudgetPaymentsStartBlock, int nSuperblockStartBlock);
void UpdateSubsidyAndDiffParams(int nMinimumDifficultyBlocks, int nHighSubsidyBlocks, int nHighSubsidyFactor); void UpdateSubsidyAndDiffParams(int nMinimumDifficultyBlocks, int nHighSubsidyBlocks, int nHighSubsidyFactor);
@ -151,7 +151,7 @@ void SelectParams(const std::string& chain);
/** /**
* Allows modifying the Version Bits regtest parameters. * Allows modifying the Version Bits regtest parameters.
*/ */
void UpdateVersionBitsParameters(Consensus::DeploymentPos d, int64_t nStartTime, int64_t nTimeout, int64_t nWindowSize, int64_t nThreshold); void UpdateVersionBitsParameters(Consensus::DeploymentPos d, int64_t nStartTime, int64_t nTimeout, int64_t nWindowSize, int64_t nThresholdStart, int64_t nThresholdMin, int64_t nFalloffCoeff);
/** /**
* Allows modifying the DIP3 activation and enforcement height * Allows modifying the DIP3 activation and enforcement height

View File

@ -20,6 +20,7 @@ enum DeploymentPos
DEPLOYMENT_BIP147, // Deployment of BIP147 (NULLDUMMY) DEPLOYMENT_BIP147, // Deployment of BIP147 (NULLDUMMY)
DEPLOYMENT_DIP0003, // Deployment of DIP0002 and DIP0003 (txv3 and deterministic MN lists) DEPLOYMENT_DIP0003, // Deployment of DIP0002 and DIP0003 (txv3 and deterministic MN lists)
DEPLOYMENT_DIP0008, // Deployment of ChainLock enforcement DEPLOYMENT_DIP0008, // Deployment of ChainLock enforcement
DEPLOYMENT_REALLOC, // Deployment of Block Reward Reallocation
// NOTE: Also add new deployments to VersionBitsDeploymentInfo in versionbits.cpp // NOTE: Also add new deployments to VersionBitsDeploymentInfo in versionbits.cpp
MAX_VERSION_BITS_DEPLOYMENTS MAX_VERSION_BITS_DEPLOYMENTS
}; };
@ -36,8 +37,12 @@ struct BIP9Deployment {
int64_t nTimeout; int64_t nTimeout;
/** The number of past blocks (including the block under consideration) to be taken into account for locking in a fork. */ /** The number of past blocks (including the block under consideration) to be taken into account for locking in a fork. */
int64_t nWindowSize{0}; int64_t nWindowSize{0};
/** A number of blocks, in the range of 1..nWindowSize, which must signal for a fork in order to lock it in. */ /** A starting number of blocks, in the range of 1..nWindowSize, which must signal for a fork in order to lock it in. */
int64_t nThreshold{0}; int64_t nThresholdStart{0};
/** A minimum number of blocks, in the range of 1..nWindowSize, which must signal for a fork in order to lock it in. */
int64_t nThresholdMin{0};
/** A coefficient which adjusts the speed a required number of signaling blocks is decreasing from nThresholdStart to nThresholdMin at with each period. */
int64_t nFalloffCoeff{0};
}; };
enum LLMQType : uint8_t enum LLMQType : uint8_t
@ -157,7 +162,7 @@ struct Params {
/** /**
* Minimum blocks including miner confirmation of the total of nMinerConfirmationWindow blocks in a retargeting period, * Minimum blocks including miner confirmation of the total of nMinerConfirmationWindow blocks in a retargeting period,
* (nPowTargetTimespan / nPowTargetSpacing) which is also used for BIP9 deployments. * (nPowTargetTimespan / nPowTargetSpacing) which is also used for BIP9 deployments.
* Default BIP9Deployment::nThreshold value for deployments where it's not specified and for unknown deployments. * Default BIP9Deployment::nThresholdStart value for deployments where it's not specified and for unknown deployments.
* Examples: 1916 for 95%, 1512 for testchains. * Examples: 1916 for 95%, 1512 for testchains.
*/ */
uint32_t nRuleChangeActivationThreshold; uint32_t nRuleChangeActivationThreshold;

View File

@ -1351,10 +1351,10 @@ bool AppInitParameterInteraction()
for (const std::string& strDeployment : gArgs.GetArgs("-vbparams")) { for (const std::string& strDeployment : gArgs.GetArgs("-vbparams")) {
std::vector<std::string> vDeploymentParams; std::vector<std::string> vDeploymentParams;
boost::split(vDeploymentParams, strDeployment, boost::is_any_of(":")); boost::split(vDeploymentParams, strDeployment, boost::is_any_of(":"));
if (vDeploymentParams.size() != 3 && vDeploymentParams.size() != 5) { if (vDeploymentParams.size() != 3 && vDeploymentParams.size() != 5 && vDeploymentParams.size() != 7) {
return InitError("Version bits parameters malformed, expecting deployment:start:end or deployment:start:end:window:threshold"); return InitError("Version bits parameters malformed, expecting deployment:start:end or deployment:start:end:window:threshold or deployment:start:end:window:thresholdstart:thresholdmin:falloffcoeff");
} }
int64_t nStartTime, nTimeout, nWindowSize = -1, nThreshold = -1; int64_t nStartTime, nTimeout, nWindowSize = -1, nThresholdStart = -1, nThresholdMin = -1, nFalloffCoeff = -1;
if (!ParseInt64(vDeploymentParams[1], &nStartTime)) { if (!ParseInt64(vDeploymentParams[1], &nStartTime)) {
return InitError(strprintf("Invalid nStartTime (%s)", vDeploymentParams[1])); return InitError(strprintf("Invalid nStartTime (%s)", vDeploymentParams[1]));
} }
@ -1365,17 +1365,26 @@ bool AppInitParameterInteraction()
if (!ParseInt64(vDeploymentParams[3], &nWindowSize)) { if (!ParseInt64(vDeploymentParams[3], &nWindowSize)) {
return InitError(strprintf("Invalid nWindowSize (%s)", vDeploymentParams[3])); return InitError(strprintf("Invalid nWindowSize (%s)", vDeploymentParams[3]));
} }
if (!ParseInt64(vDeploymentParams[4], &nThreshold)) { if (!ParseInt64(vDeploymentParams[4], &nThresholdStart)) {
return InitError(strprintf("Invalid nThreshold (%s)", vDeploymentParams[4])); return InitError(strprintf("Invalid nThresholdStart (%s)", vDeploymentParams[4]));
}
}
if (vDeploymentParams.size() == 7) {
if (!ParseInt64(vDeploymentParams[5], &nThresholdMin)) {
return InitError(strprintf("Invalid nThresholdMin (%s)", vDeploymentParams[5]));
}
if (!ParseInt64(vDeploymentParams[6], &nFalloffCoeff)) {
return InitError(strprintf("Invalid nFalloffCoeff (%s)", vDeploymentParams[6]));
} }
} }
bool found = false; bool found = false;
for (int j=0; j<(int)Consensus::MAX_VERSION_BITS_DEPLOYMENTS; ++j) for (int j=0; j<(int)Consensus::MAX_VERSION_BITS_DEPLOYMENTS; ++j)
{ {
if (vDeploymentParams[0].compare(VersionBitsDeploymentInfo[j].name) == 0) { if (vDeploymentParams[0].compare(VersionBitsDeploymentInfo[j].name) == 0) {
UpdateVersionBitsParameters(Consensus::DeploymentPos(j), nStartTime, nTimeout, nWindowSize, nThreshold); UpdateVersionBitsParameters(Consensus::DeploymentPos(j), nStartTime, nTimeout, nWindowSize, nThresholdStart, nThresholdMin, nFalloffCoeff);
found = true; found = true;
LogPrintf("Setting version bits activation parameters for %s to start=%ld, timeout=%ld, window=%ld, threshold=%ld\n", vDeploymentParams[0], nStartTime, nTimeout, nWindowSize, nThreshold); LogPrintf("Setting version bits activation parameters for %s to start=%ld, timeout=%ld, window=%ld, thresholdstart=%ld, thresholdmin=%ld, falloffcoeff=%ld\n",
vDeploymentParams[0], nStartTime, nTimeout, nWindowSize, nThresholdStart, nThresholdMin, nFalloffCoeff);
break; break;
} }
} }

View File

@ -319,14 +319,22 @@ bool CMasternodePayments::GetBlockTxOuts(int nBlockHeight, CAmount blockReward,
{ {
voutMasternodePaymentsRet.clear(); voutMasternodePaymentsRet.clear();
CAmount masternodeReward = GetMasternodePayment(nBlockHeight, blockReward);
const CBlockIndex* pindex; const CBlockIndex* pindex;
int nReallocActivationHeight{std::numeric_limits<int>::max()};
{ {
LOCK(cs_main); LOCK(cs_main);
pindex = chainActive[nBlockHeight - 1]; pindex = chainActive[nBlockHeight - 1];
const Consensus::Params& consensusParams = Params().GetConsensus();
if (VersionBitsState(pindex, consensusParams, Consensus::DEPLOYMENT_REALLOC, versionbitscache) == THRESHOLD_ACTIVE) {
nReallocActivationHeight = VersionBitsStateSinceHeight(pindex, consensusParams, Consensus::DEPLOYMENT_REALLOC, versionbitscache);
}
} }
uint256 proTxHash; uint256 proTxHash;
CAmount masternodeReward = GetMasternodePayment(nBlockHeight, blockReward, nReallocActivationHeight);
auto dmnPayee = deterministicMNManager->GetListForBlock(pindex).GetMNPayee(); auto dmnPayee = deterministicMNManager->GetListForBlock(pindex).GetMNPayee();
if (!dmnPayee) { if (!dmnPayee) {
return false; return false;

View File

@ -25,7 +25,7 @@ public:
int64_t BeginTime(const Consensus::Params& params) const override { return TestTime(10000); } int64_t BeginTime(const Consensus::Params& params) const override { return TestTime(10000); }
int64_t EndTime(const Consensus::Params& params) const override { return TestTime(20000); } int64_t EndTime(const Consensus::Params& params) const override { return TestTime(20000); }
int Period(const Consensus::Params& params) const override { return 1000; } int Period(const Consensus::Params& params) const override { return 1000; }
int Threshold(const Consensus::Params& params) const override { return 900; } int Threshold(const Consensus::Params& params, int nAttempt) const override { return 900; }
bool Condition(const CBlockIndex* pindex, const Consensus::Params& params) const override { return (pindex->nVersion & 0x100); } bool Condition(const CBlockIndex* pindex, const Consensus::Params& params) const override { return (pindex->nVersion & 0x100); }
ThresholdState GetStateFor(const CBlockIndex* pindexPrev) const { return AbstractThresholdConditionChecker::GetStateFor(pindexPrev, paramsDummy, cache); } ThresholdState GetStateFor(const CBlockIndex* pindexPrev) const { return AbstractThresholdConditionChecker::GetStateFor(pindexPrev, paramsDummy, cache); }

View File

@ -1155,7 +1155,7 @@ CAmount GetBlockSubsidy(int nPrevBits, int nPrevHeight, const Consensus::Params&
return fSuperblockPartOnly ? nSuperblockPart : nSubsidy - nSuperblockPart; return fSuperblockPartOnly ? nSuperblockPart : nSubsidy - nSuperblockPart;
} }
CAmount GetMasternodePayment(int nHeight, CAmount blockValue) CAmount GetMasternodePayment(int nHeight, CAmount blockValue, int nReallocActivationHeight)
{ {
CAmount ret = blockValue/5; // start at 20% CAmount ret = blockValue/5; // start at 20%
@ -1173,7 +1173,47 @@ CAmount GetMasternodePayment(int nHeight, CAmount blockValue)
if(nHeight > nMNPIBlock+(nMNPIPeriod* 7)) ret += blockValue / 40; // 278960 - 47.5% - 2015-06-01 if(nHeight > nMNPIBlock+(nMNPIPeriod* 7)) ret += blockValue / 40; // 278960 - 47.5% - 2015-06-01
if(nHeight > nMNPIBlock+(nMNPIPeriod* 9)) ret += blockValue / 40; // 313520 - 50.0% - 2015-08-03 if(nHeight > nMNPIBlock+(nMNPIPeriod* 9)) ret += blockValue / 40; // 313520 - 50.0% - 2015-08-03
if (nHeight < nReallocActivationHeight) {
// Block Reward Realocation is not activated yet, nothing to do
return ret; return ret;
}
int nSuperblockCycle = Params().GetConsensus().nSuperblockCycle;
// Actual realocation starts in the cycle next to one activation happens in
int nReallocStart = nReallocActivationHeight - nReallocActivationHeight % nSuperblockCycle + nSuperblockCycle;
if (nHeight < nReallocStart) {
// Activated but we have to wait for the next cycle to start realocation, nothing to do
return ret;
}
// Periods used to reallocate the masternode reward from 50% to 60%
static std::vector<int> vecPeriods{
513, // Period 1: 51.3%
526, // Period 2: 52.6%
533, // Period 3: 53.3%
540, // Period 4: 54%
546, // Period 5: 54.6%
552, // Period 6: 55.2%
557, // Period 7: 55.7%
562, // Period 8: 56.2%
567, // Period 9: 56.7%
572, // Period 10: 57.2%
577, // Period 11: 57.7%
582, // Period 12: 58.2%
585, // Period 13: 58.5%
588, // Period 14: 58.8%
591, // Period 15: 59.1%
594, // Period 16: 59.4%
597, // Period 17: 59.7%
599, // Period 18: 59.9%
600 // Period 19: 60%
};
int nReallocCycle = nSuperblockCycle * 3;
int nCurrentPeriod = std::min<int>((nHeight - nReallocStart) / nReallocCycle, vecPeriods.size() - 1);
return static_cast<CAmount>(blockValue * vecPeriods[nCurrentPeriod] / 1000);
} }
bool IsInitialBlockDownload() bool IsInitialBlockDownload()
@ -1875,7 +1915,7 @@ public:
int64_t BeginTime(const Consensus::Params& params) const override { return 0; } int64_t BeginTime(const Consensus::Params& params) const override { return 0; }
int64_t EndTime(const Consensus::Params& params) const override { return std::numeric_limits<int64_t>::max(); } int64_t EndTime(const Consensus::Params& params) const override { return std::numeric_limits<int64_t>::max(); }
int Period(const Consensus::Params& params) const override { return params.nMinerConfirmationWindow; } int Period(const Consensus::Params& params) const override { return params.nMinerConfirmationWindow; }
int Threshold(const Consensus::Params& params) const override { return params.nRuleChangeActivationThreshold; } int Threshold(const Consensus::Params& params, int nAttempt) const override { return params.nRuleChangeActivationThreshold; }
bool Condition(const CBlockIndex* pindex, const Consensus::Params& params) const override bool Condition(const CBlockIndex* pindex, const Consensus::Params& params) const override
{ {
@ -4855,7 +4895,7 @@ ThresholdState VersionBitsTipState(const Consensus::Params& params, Consensus::D
BIP9Stats VersionBitsTipStatistics(const Consensus::Params& params, Consensus::DeploymentPos pos) BIP9Stats VersionBitsTipStatistics(const Consensus::Params& params, Consensus::DeploymentPos pos)
{ {
LOCK(cs_main); LOCK(cs_main);
return VersionBitsStatistics(chainActive.Tip(), params, pos); return VersionBitsStatistics(chainActive.Tip(), params, pos, versionbitscache);
} }
int VersionBitsTipStateSinceHeight(const Consensus::Params& params, Consensus::DeploymentPos pos) int VersionBitsTipStateSinceHeight(const Consensus::Params& params, Consensus::DeploymentPos pos)

View File

@ -283,7 +283,7 @@ bool ActivateBestChain(CValidationState& state, const CChainParams& chainparams,
double ConvertBitsToDouble(unsigned int nBits); double ConvertBitsToDouble(unsigned int nBits);
CAmount GetBlockSubsidy(int nBits, int nHeight, const Consensus::Params& consensusParams, bool fSuperblockPartOnly = false); CAmount GetBlockSubsidy(int nBits, int nHeight, const Consensus::Params& consensusParams, bool fSuperblockPartOnly = false);
CAmount GetMasternodePayment(int nHeight, CAmount blockValue); CAmount GetMasternodePayment(int nHeight, CAmount blockValue, int nReallocActivationHeight = std::numeric_limits<int>::max() /* not activated */);
/** Guess verification progress (as a fraction between 0.0=genesis and 1.0=current tip). */ /** Guess verification progress (as a fraction between 0.0=genesis and 1.0=current tip). */
double GuessVerificationProgress(const ChainTxData& data, const CBlockIndex* pindex); double GuessVerificationProgress(const ChainTxData& data, const CBlockIndex* pindex);

View File

@ -35,13 +35,17 @@ const struct VBDeploymentInfo VersionBitsDeploymentInfo[Consensus::MAX_VERSION_B
/*.name =*/ "dip0008", /*.name =*/ "dip0008",
/*.gbt_force =*/ true, /*.gbt_force =*/ true,
/*.check_mn_protocol =*/ false, /*.check_mn_protocol =*/ false,
} },
{
/*.name =*/ "realloc",
/*.gbt_force =*/ true,
/*.check_mn_protocol =*/ false,
},
}; };
ThresholdState AbstractThresholdConditionChecker::GetStateFor(const CBlockIndex* pindexPrev, const Consensus::Params& params, ThresholdConditionCache& cache) const ThresholdState AbstractThresholdConditionChecker::GetStateFor(const CBlockIndex* pindexPrev, const Consensus::Params& params, ThresholdConditionCache& cache) const
{ {
int nPeriod = Period(params); int nPeriod = Period(params);
int nThreshold = Threshold(params);
int64_t nTimeStart = BeginTime(params); int64_t nTimeStart = BeginTime(params);
int64_t nTimeTimeout = EndTime(params); int64_t nTimeTimeout = EndTime(params);
@ -71,6 +75,13 @@ ThresholdState AbstractThresholdConditionChecker::GetStateFor(const CBlockIndex*
assert(cache.count(pindexPrev)); assert(cache.count(pindexPrev));
ThresholdState state = cache[pindexPrev]; ThresholdState state = cache[pindexPrev];
int nStartHeight{std::numeric_limits<int>::max()};
for (const auto& pair : cache) {
if (pair.second == THRESHOLD_STARTED && nStartHeight > pair.first->nHeight + 1) {
nStartHeight = pair.first->nHeight + 1;
}
}
// Now walk forward and compute the state of descendants of pindexPrev // Now walk forward and compute the state of descendants of pindexPrev
while (!vToCompute.empty()) { while (!vToCompute.empty()) {
ThresholdState stateNext = state; ThresholdState stateNext = state;
@ -83,6 +94,7 @@ ThresholdState AbstractThresholdConditionChecker::GetStateFor(const CBlockIndex*
stateNext = THRESHOLD_FAILED; stateNext = THRESHOLD_FAILED;
} else if (pindexPrev->GetMedianTimePast() >= nTimeStart) { } else if (pindexPrev->GetMedianTimePast() >= nTimeStart) {
stateNext = THRESHOLD_STARTED; stateNext = THRESHOLD_STARTED;
nStartHeight = pindexPrev->nHeight + 1;
} }
break; break;
} }
@ -100,7 +112,9 @@ ThresholdState AbstractThresholdConditionChecker::GetStateFor(const CBlockIndex*
} }
pindexCount = pindexCount->pprev; pindexCount = pindexCount->pprev;
} }
if (count >= nThreshold) { assert(nStartHeight > 0 && nStartHeight < std::numeric_limits<int>::max());
int nAttempt = (pindexCount->nHeight + 1 - nStartHeight) / nPeriod;
if (count >= Threshold(params, nAttempt)) {
stateNext = THRESHOLD_LOCKED_IN; stateNext = THRESHOLD_LOCKED_IN;
} }
break; break;
@ -123,12 +137,12 @@ ThresholdState AbstractThresholdConditionChecker::GetStateFor(const CBlockIndex*
} }
// return the numerical statistics of blocks signalling the specified BIP9 condition in this current period // return the numerical statistics of blocks signalling the specified BIP9 condition in this current period
BIP9Stats AbstractThresholdConditionChecker::GetStateStatisticsFor(const CBlockIndex* pindex, const Consensus::Params& params) const BIP9Stats AbstractThresholdConditionChecker::GetStateStatisticsFor(const CBlockIndex* pindex, const Consensus::Params& params, ThresholdConditionCache& cache) const
{ {
BIP9Stats stats = {}; BIP9Stats stats = {};
stats.period = Period(params); stats.period = Period(params);
stats.threshold = Threshold(params); stats.threshold = Threshold(params, 0);
if (pindex == nullptr) if (pindex == nullptr)
return stats; return stats;
@ -137,6 +151,15 @@ BIP9Stats AbstractThresholdConditionChecker::GetStateStatisticsFor(const CBlockI
const CBlockIndex* pindexEndOfPrevPeriod = pindex->GetAncestor(pindex->nHeight - ((pindex->nHeight + 1) % stats.period)); const CBlockIndex* pindexEndOfPrevPeriod = pindex->GetAncestor(pindex->nHeight - ((pindex->nHeight + 1) % stats.period));
stats.elapsed = pindex->nHeight - pindexEndOfPrevPeriod->nHeight; stats.elapsed = pindex->nHeight - pindexEndOfPrevPeriod->nHeight;
// Re-calculate current threshold
int nAttempt{0};
const ThresholdState state = GetStateFor(pindexEndOfPrevPeriod, params, cache);
if (state == THRESHOLD_STARTED) {
int nStartHeight = GetStateSinceHeightFor(pindexEndOfPrevPeriod, params, cache);
nAttempt = (pindexEndOfPrevPeriod->nHeight + 1 - nStartHeight)/stats.period;
}
stats.threshold = Threshold(params, nAttempt);
// Count from current block to beginning of period // Count from current block to beginning of period
int count = 0; int count = 0;
const CBlockIndex* currentIndex = pindex; const CBlockIndex* currentIndex = pindex;
@ -195,7 +218,17 @@ protected:
int64_t BeginTime(const Consensus::Params& params) const override { return params.vDeployments[id].nStartTime; } int64_t BeginTime(const Consensus::Params& params) const override { return params.vDeployments[id].nStartTime; }
int64_t EndTime(const Consensus::Params& params) const override { return params.vDeployments[id].nTimeout; } int64_t EndTime(const Consensus::Params& params) const override { return params.vDeployments[id].nTimeout; }
int Period(const Consensus::Params& params) const override { return params.vDeployments[id].nWindowSize ? params.vDeployments[id].nWindowSize : params.nMinerConfirmationWindow; } int Period(const Consensus::Params& params) const override { return params.vDeployments[id].nWindowSize ? params.vDeployments[id].nWindowSize : params.nMinerConfirmationWindow; }
int Threshold(const Consensus::Params& params) const override { return params.vDeployments[id].nThreshold ? params.vDeployments[id].nThreshold : params.nRuleChangeActivationThreshold; } int Threshold(const Consensus::Params& params, int nAttempt) const override
{
if (params.vDeployments[id].nThresholdStart == 0) {
return params.nRuleChangeActivationThreshold;
}
if (params.vDeployments[id].nThresholdMin == 0 || params.vDeployments[id].nFalloffCoeff == 0) {
return params.vDeployments[id].nThresholdStart;
}
int64_t nThresholdCalc = params.vDeployments[id].nThresholdStart - nAttempt * nAttempt * Period(params) / 100 / params.vDeployments[id].nFalloffCoeff;
return std::max(params.vDeployments[id].nThresholdMin, nThresholdCalc);
}
bool Condition(const CBlockIndex* pindex, const Consensus::Params& params) const override bool Condition(const CBlockIndex* pindex, const Consensus::Params& params) const override
{ {
@ -214,9 +247,9 @@ ThresholdState VersionBitsState(const CBlockIndex* pindexPrev, const Consensus::
return VersionBitsConditionChecker(pos).GetStateFor(pindexPrev, params, cache.caches[pos]); return VersionBitsConditionChecker(pos).GetStateFor(pindexPrev, params, cache.caches[pos]);
} }
BIP9Stats VersionBitsStatistics(const CBlockIndex* pindexPrev, const Consensus::Params& params, Consensus::DeploymentPos pos) BIP9Stats VersionBitsStatistics(const CBlockIndex* pindexPrev, const Consensus::Params& params, Consensus::DeploymentPos pos, VersionBitsCache& cache)
{ {
return VersionBitsConditionChecker(pos).GetStateStatisticsFor(pindexPrev, params); return VersionBitsConditionChecker(pos).GetStateStatisticsFor(pindexPrev, params, cache.caches[pos]);
} }
int VersionBitsStateSinceHeight(const CBlockIndex* pindexPrev, const Consensus::Params& params, Consensus::DeploymentPos pos, VersionBitsCache& cache) int VersionBitsStateSinceHeight(const CBlockIndex* pindexPrev, const Consensus::Params& params, Consensus::DeploymentPos pos, VersionBitsCache& cache)

View File

@ -58,10 +58,10 @@ protected:
virtual int64_t BeginTime(const Consensus::Params& params) const =0; virtual int64_t BeginTime(const Consensus::Params& params) const =0;
virtual int64_t EndTime(const Consensus::Params& params) const =0; virtual int64_t EndTime(const Consensus::Params& params) const =0;
virtual int Period(const Consensus::Params& params) const =0; virtual int Period(const Consensus::Params& params) const =0;
virtual int Threshold(const Consensus::Params& params) const =0; virtual int Threshold(const Consensus::Params& params, int nAttempt) const =0;
public: public:
BIP9Stats GetStateStatisticsFor(const CBlockIndex* pindex, const Consensus::Params& params) const; BIP9Stats GetStateStatisticsFor(const CBlockIndex* pindex, const Consensus::Params& params, ThresholdConditionCache& cache) const;
// Note that the functions below take a pindexPrev as input: they compute information for block B based on its parent. // Note that the functions below take a pindexPrev as input: they compute information for block B based on its parent.
ThresholdState GetStateFor(const CBlockIndex* pindexPrev, const Consensus::Params& params, ThresholdConditionCache& cache) const; ThresholdState GetStateFor(const CBlockIndex* pindexPrev, const Consensus::Params& params, ThresholdConditionCache& cache) const;
int GetStateSinceHeightFor(const CBlockIndex* pindexPrev, const Consensus::Params& params, ThresholdConditionCache& cache) const; int GetStateSinceHeightFor(const CBlockIndex* pindexPrev, const Consensus::Params& params, ThresholdConditionCache& cache) const;
@ -75,7 +75,7 @@ struct VersionBitsCache
}; };
ThresholdState VersionBitsState(const CBlockIndex* pindexPrev, const Consensus::Params& params, Consensus::DeploymentPos pos, VersionBitsCache& cache); ThresholdState VersionBitsState(const CBlockIndex* pindexPrev, const Consensus::Params& params, Consensus::DeploymentPos pos, VersionBitsCache& cache);
BIP9Stats VersionBitsStatistics(const CBlockIndex* pindexPrev, const Consensus::Params& params, Consensus::DeploymentPos pos); BIP9Stats VersionBitsStatistics(const CBlockIndex* pindexPrev, const Consensus::Params& params, Consensus::DeploymentPos pos, VersionBitsCache& cache);
int VersionBitsStateSinceHeight(const CBlockIndex* pindexPrev, const Consensus::Params& params, Consensus::DeploymentPos pos, VersionBitsCache& cache); int VersionBitsStateSinceHeight(const CBlockIndex* pindexPrev, const Consensus::Params& params, Consensus::DeploymentPos pos, VersionBitsCache& cache);
uint32_t VersionBitsMask(const Consensus::Params& params, Consensus::DeploymentPos pos); uint32_t VersionBitsMask(const Consensus::Params& params, Consensus::DeploymentPos pos);

View File

@ -392,7 +392,11 @@ class DIP3Test(BitcoinTestFramework):
coinbasevalue += new_fees coinbasevalue += new_fees
if mn_amount is None: if mn_amount is None:
mn_amount = get_masternode_payment(height, coinbasevalue) realloc_info = get_bip9_status(self.nodes[0], 'realloc')
realloc_height = 99999999
if realloc_info['status'] == 'active':
realloc_height = realloc_info['since']
mn_amount = get_masternode_payment(height, coinbasevalue, realloc_height)
miner_amount = coinbasevalue - mn_amount miner_amount = coinbasevalue - mn_amount
outputs = {miner_address: str(Decimal(miner_amount) / COIN)} outputs = {miner_address: str(Decimal(miner_amount) / COIN)}

View File

@ -0,0 +1,207 @@
#!/usr/bin/env python3
# Copyright (c) 2015-2020 The Dash Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
from test_framework.blocktools import create_block, create_coinbase, get_masternode_payment
from test_framework.mininode import *
from test_framework.script import CScript
from test_framework.test_framework import DashTestFramework
from test_framework.util import assert_equal, get_bip9_status, hex_str_to_bytes
'''
feature_block_reward_reallocation.py
Checks block reward reallocation correctness
'''
class BlockRewardReallocationTest(DashTestFramework):
def set_test_params(self):
self.set_dash_test_params(4, 3, fast_dip3_enforcement=True)
self.set_dash_dip8_activation(450)
# 536870912 == 0x20000000, i.e. not signalling for anything
def create_test_block(self, version=536870912):
self.bump_mocktime(150)
bt = self.nodes[0].getblocktemplate()
tip = int(bt['previousblockhash'], 16)
nextheight = bt['height']
coinbase = create_coinbase(nextheight)
coinbase.nVersion = 3
coinbase.nType = 5 # CbTx
coinbase.vout[0].nValue = bt['coinbasevalue']
for mn in bt['masternode']:
coinbase.vout.append(CTxOut(mn['amount'], CScript(hex_str_to_bytes(mn['script']))))
coinbase.vout[0].nValue -= mn['amount']
cbtx = FromHex(CCbTx(), bt['coinbase_payload'])
coinbase.vExtraPayload = cbtx.serialize()
coinbase.rehash()
coinbase.calc_sha256()
block = create_block(tip, coinbase, self.mocktime)
block.nVersion = version
# Add quorum commitments from template
for tx in bt['transactions']:
tx2 = FromHex(CTransaction(), tx['data'])
if tx2.nType == 6:
block.vtx.append(tx2)
block.hashMerkleRoot = block.calc_merkle_root()
block.rehash()
block.solve()
return block
def signal(self, num_blocks, expected_lockin):
self.log.info("Signal with %d/500 blocks" % (num_blocks))
# create and send non-signalling blocks
for i in range(500 - num_blocks):
test_block = self.create_test_block()
self.nodes[0].p2p.send_blocks_and_test([test_block], self.nodes[0], timeout=5)
# generate at most 10 signaling blocks at a time
if num_blocks > 0:
for i in range((num_blocks - 1) // 10):
self.bump_mocktime(10)
self.nodes[0].generate(10)
self.sync_blocks()
self.nodes[0].generate((num_blocks - 1) % 10)
self.sync_blocks()
assert_equal(get_bip9_status(self.nodes[0], 'realloc')['status'], 'started')
self.nodes[0].generate(1)
self.sync_blocks()
if expected_lockin:
assert_equal(get_bip9_status(self.nodes[0], 'realloc')['status'], 'locked_in')
else:
assert_equal(get_bip9_status(self.nodes[0], 'realloc')['status'], 'started')
def threshold(self, attempt):
threshold_calc = 400 - attempt * attempt
if threshold_calc < 300:
return 300
return threshold_calc
def run_test(self):
self.log.info("Wait for DIP3 to activate")
while get_bip9_status(self.nodes[0], 'dip0003')['status'] != 'active':
self.bump_mocktime(10)
self.nodes[0].generate(10)
self.sync_blocks()
self.nodes[0].add_p2p_connection(P2PDataStore())
network_thread_start()
self.nodes[0].p2p.wait_for_verack()
self.log.info("Mine all but one remaining block in the window")
bi = self.nodes[0].getblockchaininfo()
for i in range(498 - bi['blocks']):
self.bump_mocktime(1)
self.nodes[0].generate(1)
self.sync_blocks()
self.log.info("Initial state is DEFINED")
bi = self.nodes[0].getblockchaininfo()
assert_equal(bi['blocks'], 498)
assert_equal(bi['bip9_softforks']['realloc']['status'], 'defined')
self.log.info("Advance from DEFINED to STARTED at height = 499")
self.nodes[0].generate(1)
bi = self.nodes[0].getblockchaininfo()
assert_equal(bi['blocks'], 499)
assert_equal(bi['bip9_softforks']['realloc']['status'], 'started')
assert_equal(bi['bip9_softforks']['realloc']['statistics']['threshold'], self.threshold(0))
self.signal(399, False) # 1 block short
self.log.info("Still STARTED but new threshold should be lower at height = 999")
bi = self.nodes[0].getblockchaininfo()
assert_equal(bi['blocks'], 999)
assert_equal(bi['bip9_softforks']['realloc']['statistics']['threshold'], self.threshold(1))
self.signal(398, False) # 1 block short again
self.log.info("Still STARTED but new threshold should be even lower at height = 1499")
bi = self.nodes[0].getblockchaininfo()
assert_equal(bi['blocks'], 1499)
assert_equal(bi['bip9_softforks']['realloc']['statistics']['threshold'], self.threshold(2))
pre_locked_in_blockhash = bi['bestblockhash']
self.signal(396, True) # just enough to lock in
self.log.info("Advanced to LOCKED_IN at height = 1999")
for i in range(49):
self.bump_mocktime(10)
self.nodes[0].generate(10)
self.sync_blocks()
self.nodes[0].generate(9)
self.sync_blocks()
self.log.info("Still LOCKED_IN at height = 2498")
bi = self.nodes[0].getblockchaininfo()
assert_equal(bi['blocks'], 2498)
assert_equal(bi['bip9_softforks']['realloc']['status'], 'locked_in')
self.log.info("Advance from LOCKED_IN to ACTIVE at height = 2499")
self.nodes[0].generate(1) # activation
bi = self.nodes[0].getblockchaininfo()
assert_equal(bi['blocks'], 2499)
assert_equal(bi['bip9_softforks']['realloc']['status'], 'active')
assert_equal(bi['bip9_softforks']['realloc']['since'], 2500)
self.log.info("Reward split should stay ~50/50 before the first superblock after activation")
# This applies even if reallocation was activated right at superblock height like it does here
bt = self.nodes[0].getblocktemplate()
assert_equal(bt['height'], 2500)
assert_equal(bt['masternode'][0]['amount'], get_masternode_payment(bt['height'], bt['coinbasevalue'], 2500))
self.nodes[0].generate(9)
self.sync_blocks()
bt = self.nodes[0].getblocktemplate()
assert_equal(bt['masternode'][0]['amount'], get_masternode_payment(bt['height'], bt['coinbasevalue'], 2500))
assert_equal(bt['coinbasevalue'], 13748571607)
assert_equal(bt['masternode'][0]['amount'], 6874285801) # 0.4999999998
self.log.info("Reallocation should kick-in with the superblock mined at height = 2010")
for period in range(19): # there will be 19 adjustments, 3 superblocks long each
for i in range(3):
self.bump_mocktime(10)
self.nodes[0].generate(10)
self.sync_blocks()
bt = self.nodes[0].getblocktemplate()
assert_equal(bt['masternode'][0]['amount'], get_masternode_payment(bt['height'], bt['coinbasevalue'], 2500))
self.log.info("Reward split should reach ~60/40 after reallocation is done")
assert_equal(bt['coinbasevalue'], 10221599170)
assert_equal(bt['masternode'][0]['amount'], 6132959502) # 0.6
self.log.info("Reward split should stay ~60/40 after reallocation is done")
for period in range(10): # check 10 next superblocks
self.bump_mocktime(10)
self.nodes[0].generate(10)
self.sync_blocks()
bt = self.nodes[0].getblocktemplate()
assert_equal(bt['masternode'][0]['amount'], get_masternode_payment(bt['height'], bt['coinbasevalue'], 2500))
assert_equal(bt['coinbasevalue'], 9491484944)
assert_equal(bt['masternode'][0]['amount'], 5694890966) # 0.6
self.log.info("Rollback the chain back to the STARTED state")
self.mocktime = self.nodes[0].getblock(pre_locked_in_blockhash, 1)['time']
for node in self.nodes:
node.invalidateblock(pre_locked_in_blockhash)
self.sync_all()
# create and send non-signalling block
test_block = self.create_test_block()
self.nodes[0].p2p.send_blocks_and_test([test_block], self.nodes[0], timeout=5)
bi = self.nodes[0].getblockchaininfo()
assert_equal(bi['blocks'], 1499)
assert_equal(bi['bip9_softforks']['realloc']['status'], 'started')
assert_equal(bi['bip9_softforks']['realloc']['statistics']['threshold'], self.threshold(2))
self.log.info("Check thresholds reach min level and stay there")
for i in range(8): # 7 to reach min level and 1 more to check it doesn't go lower than that
self.signal(0, False) # no need to signal
bi = self.nodes[0].getblockchaininfo()
assert_equal(bi['blocks'], 1999 + i * 500)
assert_equal(bi['bip9_softforks']['realloc']['status'], 'started')
assert_equal(bi['bip9_softforks']['realloc']['statistics']['threshold'], self.threshold(i + 3))
assert_equal(bi['bip9_softforks']['realloc']['statistics']['threshold'], 300)
if __name__ == '__main__':
BlockRewardReallocationTest().main()

View File

@ -9,7 +9,7 @@ from test_framework import mininode
from test_framework.blocktools import get_masternode_payment, create_coinbase, create_block from test_framework.blocktools import get_masternode_payment, create_coinbase, create_block
from test_framework.mininode import * from test_framework.mininode import *
from test_framework.test_framework import DashTestFramework from test_framework.test_framework import DashTestFramework
from test_framework.util import sync_blocks, sync_mempools, p2p_port, assert_raises_rpc_error from test_framework.util import sync_blocks, sync_mempools, p2p_port, assert_raises_rpc_error, get_bip9_status
''' '''
llmq-is-cl-conflicts.py llmq-is-cl-conflicts.py
@ -241,7 +241,11 @@ class LLMQ_IS_CL_Conflicts(DashTestFramework):
coinbasevalue -= bt_fees coinbasevalue -= bt_fees
coinbasevalue += new_fees coinbasevalue += new_fees
mn_amount = get_masternode_payment(height, coinbasevalue) realloc_info = get_bip9_status(self.nodes[0], 'realloc')
realloc_height = 99999999
if realloc_info['status'] == 'active':
realloc_height = realloc_info['since']
mn_amount = get_masternode_payment(height, coinbasevalue, realloc_height)
miner_amount = coinbasevalue - mn_amount miner_amount = coinbasevalue - mn_amount
outputs = {miner_address: str(Decimal(miner_amount) / COIN)} outputs = {miner_address: str(Decimal(miner_amount) / COIN)}

View File

@ -87,7 +87,7 @@ def get_legacy_sigopcount_tx(tx, fAccurate=True):
return count return count
# Identical to GetMasternodePayment in C++ code # Identical to GetMasternodePayment in C++ code
def get_masternode_payment(nHeight, blockValue): def get_masternode_payment(nHeight, blockValue, nReallocActivationHeight):
ret = int(blockValue / 5) ret = int(blockValue / 5)
nMNPIBlock = 350 nMNPIBlock = 350
@ -112,4 +112,42 @@ def get_masternode_payment(nHeight, blockValue):
if nHeight > nMNPIBlock+(nMNPIPeriod* 9): if nHeight > nMNPIBlock+(nMNPIPeriod* 9):
ret += int(blockValue / 40) ret += int(blockValue / 40)
if nHeight < nReallocActivationHeight:
# Block Reward Realocation is not activated yet, nothing to do
return ret return ret
nSuperblockCycle = 10
# Actual realocation starts in the cycle next to one activation happens in
nReallocStart = nReallocActivationHeight - nReallocActivationHeight % nSuperblockCycle + nSuperblockCycle
if nHeight < nReallocStart:
# Activated but we have to wait for the next cycle to start realocation, nothing to do
return ret
# Periods used to reallocate the masternode reward from 50% to 60%
vecPeriods = [
513, # Period 1: 51.3%
526, # Period 2: 52.6%
533, # Period 3: 53.3%
540, # Period 4: 54%
546, # Period 5: 54.6%
552, # Period 6: 55.2%
557, # Period 7: 55.7%
562, # Period 8: 56.2%
567, # Period 9: 56.7%
572, # Period 10: 57.2%
577, # Period 11: 57.7%
582, # Period 12: 58.2%
585, # Period 13: 58.5%
588, # Period 14: 58.8%
591, # Period 15: 59.1%
594, # Period 16: 59.4%
597, # Period 17: 59.7%
599, # Period 18: 59.9%
600 # Period 19: 60%
]
nReallocCycle = nSuperblockCycle * 3
nCurrentPeriod = min(int((nHeight - nReallocStart) / nReallocCycle), len(vecPeriods) - 1)
return int(blockValue * vecPeriods[nCurrentPeriod] / 1000)

View File

@ -55,6 +55,7 @@ BASE_SCRIPTS= [
# Scripts that are run by the travis build process. # Scripts that are run by the travis build process.
# Longest test should go first, to favor running tests in parallel # Longest test should go first, to favor running tests in parallel
'dip3-deterministicmns.py', # NOTE: needs dash_hash to pass 'dip3-deterministicmns.py', # NOTE: needs dash_hash to pass
'feature_block_reward_reallocation.py',
'wallet-hd.py', 'wallet-hd.py',
'walletbackup.py', 'walletbackup.py',
# vv Tests less than 5m vv # vv Tests less than 5m vv