diff --git a/src/dogecoin.cpp b/src/dogecoin.cpp index 8ac2782ba..76db22f94 100644 --- a/src/dogecoin.cpp +++ b/src/dogecoin.cpp @@ -16,6 +16,24 @@ int static generateMTRandom(unsigned int s, int range) return dist(gen); } +// Dogecoin: Normally minimum difficulty blocks can only occur in between +// retarget blocks. However, once we introduce Digishield every block is +// a retarget, so we need to handle minimum difficulty on all blocks. +bool AllowDigishieldMinDifficultyForBlock(const CBlockIndex* pindexLast, const CBlockHeader *pblock, const Consensus::Params& params) +{ + // check if the chain allows minimum difficulty blocks + if (!params.fPowAllowMinDifficultyBlocks) + return false; + + // check if the chain allows minimum difficulty blocks on recalc blocks + if (pindexLast->nHeight < 157500) + // if (!params.fPowAllowDigishieldMinDifficultyBlocks) + return false; + + // Allow for a minimum block time if the elapsed time > 2*nTargetSpacing + return (pblock->GetBlockTime() > pindexLast->GetBlockTime() + params.nPowTargetSpacing*2); +} + unsigned int CalculateDogecoinNextWorkRequired(const CBlockIndex* pindexLast, int64_t nFirstBlockTime, const Consensus::Params& params) { int nHeight = pindexLast->nHeight + 1; @@ -88,8 +106,7 @@ bool CheckAuxPowProofOfWork(const CBlockHeader& block, const Consensus::Params& params.nAuxpowChainId, block.nVersion); /* If there is no auxpow, just check the block hash. */ - if (!block.auxpow) - { + if (!block.auxpow) { if (block.IsAuxpow()) return error("%s : no auxpow on block with auxpow version", __func__); diff --git a/src/dogecoin.h b/src/dogecoin.h index edc07b5f5..e466d1e98 100644 --- a/src/dogecoin.h +++ b/src/dogecoin.h @@ -6,6 +6,7 @@ #include "chain.h" #include "chainparams.h" +bool AllowDigishieldMinDifficultyForBlock(const CBlockIndex* pindexLast, const CBlockHeader *pblock, const Consensus::Params& params); CAmount GetDogecoinBlockSubsidy(int nHeight, const Consensus::Params& consensusParams, uint256 prevHash); unsigned int CalculateDogecoinNextWorkRequired(const CBlockIndex* pindexLast, int64_t nLastRetargetTime, const Consensus::Params& params); diff --git a/src/pow.cpp b/src/pow.cpp index a8d0efdab..b569e709a 100644 --- a/src/pow.cpp +++ b/src/pow.cpp @@ -21,8 +21,21 @@ unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHead if (pindexLast == NULL) return nProofOfWorkLimit; + // Dogecoin: Special rules for minimum difficulty blocks with Digishield + if (AllowDigishieldMinDifficultyForBlock(pindexLast, pblock, params)) + { + // Special difficulty rule for testnet: + // If the new block's timestamp is more than 2* nTargetSpacing minutes + // then allow mining of a min-difficulty block. + return nProofOfWorkLimit; + } + // Only change once per difficulty adjustment interval - if ((pindexLast->nHeight+1) % params.DifficultyAdjustmentInterval() != 0) + bool fNewDifficultyProtocol = (pindexLast->nHeight >= 145000); + const int64_t difficultyAdjustmentInterval = fNewDifficultyProtocol + ? 1 + : params.DifficultyAdjustmentInterval(); + if ((pindexLast->nHeight+1) % difficultyAdjustmentInterval != 0) { if (params.fPowAllowMinDifficultyBlocks) { @@ -45,9 +58,9 @@ unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHead // Litecoin: This fixes an issue where a 51% attack can change difficulty at will. // Go back the full period unless it's the first retarget after genesis. Code courtesy of Art Forz - int blockstogoback = params.DifficultyAdjustmentInterval()-1; - if ((pindexLast->nHeight+1) != params.DifficultyAdjustmentInterval()) - blockstogoback = params.DifficultyAdjustmentInterval(); + int blockstogoback = difficultyAdjustmentInterval-1; + if ((pindexLast->nHeight+1) != difficultyAdjustmentInterval) + blockstogoback = difficultyAdjustmentInterval; // Go back by what we want to be 14 days worth of blocks int nHeightFirst = pindexLast->nHeight - blockstogoback; diff --git a/src/primitives/pureheader.h b/src/primitives/pureheader.h index 0443a530d..841743632 100644 --- a/src/primitives/pureheader.h +++ b/src/primitives/pureheader.h @@ -149,7 +149,9 @@ public: */ inline bool IsLegacy() const { - return nVersion == 1; + return nVersion == 1 + // Dogecoin: We have a random v2 block with no AuxPoW, treat as legacy + || (nVersion == 2 && GetChainId() == 0); } }; diff --git a/src/test/auxpow_tests.cpp b/src/test/auxpow_tests.cpp index eaad49eef..5cb2e3269 100644 --- a/src/test/auxpow_tests.cpp +++ b/src/test/auxpow_tests.cpp @@ -362,7 +362,9 @@ BOOST_AUTO_TEST_CASE(auxpow_pow) mineBlock(block, true); BOOST_CHECK(CheckAuxPowProofOfWork(block, params)); - block.nVersion = 2; + // Dogecoin block version 2 can be both AuxPoW and regular, so test 3 + + block.nVersion = 3; mineBlock(block, true); BOOST_CHECK(!CheckAuxPowProofOfWork(block, params));