From a89d54c4b228c02a62e21039f318f5225aad2cf9 Mon Sep 17 00:00:00 2001 From: Ross Nicoll Date: Wed, 27 Dec 2017 21:11:14 +0000 Subject: Change BIP65/66 enforcement to match Dogecoin (#1403) * Introduce first estimates at BIP lock-in blocks * Introduce Dogecoin BIP parameters * Re-introduce supermajority rules for BIP65 * Add BIP65 supermajority rules * Tighten v3 block constraints * Don't enforce coinbase in v2 blocks * Correct testnet majority params * Change to using base version when checking supermajority --- src/validation.cpp | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) (limited to 'src/validation.cpp') diff --git a/src/validation.cpp b/src/validation.cpp index eb02a1dd2..b233e1044 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -84,6 +84,11 @@ CAmount maxTxFee = DEFAULT_TRANSACTION_MAXFEE; CTxMemPool mempool(::minRelayTxFee); +/** + * Returns true if there are nRequired or more blocks of minVersion or above + * in the last Consensus::Params::nMajorityWindow blocks, starting at pstart and going backwards. + */ +static bool IsSuperMajority(int minVersion, const CBlockIndex* pstart, unsigned nRequired, const Consensus::Params& consensusParams); static void CheckBlockIndex(const Consensus::Params& consensusParams); /** Constant stuff for coinbase transactions we create: */ @@ -1858,8 +1863,9 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin flags |= SCRIPT_VERIFY_DERSIG; } - // Start enforcing CHECKLOCKTIMEVERIFY (BIP65) rule - if (pindex->nHeight >= chainparams.GetConsensus().BIP65Height) { + // Start enforcing CHECKLOCKTIMEVERIFY, (BIP65) for block.nVersion=4 + // blocks, when 75% of the network has upgraded: + if (block.GetBaseVersion() >= 4 && IsSuperMajority(4, pindex->pprev, chainparams.GetConsensus().nMajorityEnforceBlockUpgrade, chainparams.GetConsensus())) { flags |= SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY; } @@ -3025,11 +3031,15 @@ bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& sta // Reject outdated version blocks when 95% (75% on testnet) of the network has upgraded: // check for version 2, 3 and 4 upgrades // Dogecoin: Version 2 enforcement was never used - if((block.GetBaseVersion() < 3 && nHeight >= consensusParams.BIP66Height) || - (block.GetBaseVersion() < 4 && nHeight >= consensusParams.BIP65Height)) + if((block.GetBaseVersion() < 3 && nHeight >= consensusParams.BIP66Height)) return state.Invalid(false, REJECT_OBSOLETE, strprintf("bad-version(0x%08x)", block.GetBaseVersion()), strprintf("rejected nVersion=0x%08x block", block.GetBaseVersion())); + // Dogecoin: Introduce supermajority rules for v4 blocks + if (block.GetBaseVersion() < 4 && IsSuperMajority(4, pindexPrev, consensusParams.nMajorityRejectBlockOutdated, consensusParams)) + return state.Invalid(error("%s : rejected nVersion=3 block", __func__), + REJECT_OBSOLETE, "bad-version"); + return true; } @@ -3262,6 +3272,18 @@ static bool AcceptBlock(const std::shared_ptr& pblock, CValidation return true; } +static bool IsSuperMajority(int minVersion, const CBlockIndex* pstart, unsigned nRequired, const Consensus::Params& consensusParams) +{ + unsigned int nFound = 0; + for (int i = 0; i < consensusParams.nMajorityWindow && nFound < nRequired && pstart != NULL; i++) + { + if (pstart->nVersion >= minVersion) + ++nFound; + pstart = pstart->pprev; + } + return (nFound >= nRequired); +} + bool ProcessNewBlock(const CChainParams& chainparams, const std::shared_ptr pblock, bool fForceProcessing, bool *fNewBlock) { { -- cgit v1.2.3