aboutsummaryrefslogtreecommitdiff
path: root/src/dogecoin.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/dogecoin.cpp')
-rw-r--r--src/dogecoin.cpp120
1 files changed, 119 insertions, 1 deletions
diff --git a/src/dogecoin.cpp b/src/dogecoin.cpp
index 77a8a0093..396c4cbc4 100644
--- a/src/dogecoin.cpp
+++ b/src/dogecoin.cpp
@@ -5,7 +5,10 @@
#include <boost/random/uniform_int.hpp>
#include <boost/random/mersenne_twister.hpp>
-#include "dogecoin.h"
+#include <arith_uint256.h>
+#include <dogecoin.h>
+#include <pow.h>
+#include <util.h>
int static generateMTRandom(unsigned int s, int range)
{
@@ -14,6 +17,121 @@ 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;
+ bool fNewDifficultyProtocol = (nHeight >= 145000);
+ // bool fNewDifficultyProtocol = (nHeight >= params.GetDigiShieldForkBlock());
+ const int64_t retargetTimespan = fNewDifficultyProtocol ? 60 // params.DigiShieldTargetTimespan()
+ :
+ params.nPowTargetTimespan;
+
+ const int64_t nActualTimespan = pindexLast->GetBlockTime() - nFirstBlockTime;
+ int64_t nModulatedTimespan = nActualTimespan;
+ int64_t nMaxTimespan;
+ int64_t nMinTimespan;
+
+ if (fNewDifficultyProtocol) //DigiShield implementation - thanks to RealSolid & WDC for this code
+ {
+ // amplitude filter - thanks to daft27 for this code
+ nModulatedTimespan = retargetTimespan + (nModulatedTimespan - retargetTimespan) / 8;
+
+ nMinTimespan = retargetTimespan - (retargetTimespan / 4);
+ nMaxTimespan = retargetTimespan + (retargetTimespan / 2);
+ } else if (nHeight > 10000) {
+ nMinTimespan = retargetTimespan / 4;
+ nMaxTimespan = retargetTimespan * 4;
+ } else if (nHeight > 5000) {
+ nMinTimespan = retargetTimespan / 8;
+ nMaxTimespan = retargetTimespan * 4;
+ } else {
+ nMinTimespan = retargetTimespan / 16;
+ nMaxTimespan = retargetTimespan * 4;
+ }
+
+ // Limit adjustment step
+ if (nModulatedTimespan < nMinTimespan)
+ nModulatedTimespan = nMinTimespan;
+ else if (nModulatedTimespan > nMaxTimespan)
+ nModulatedTimespan = nMaxTimespan;
+
+ // Retarget
+ const arith_uint256 bnPowLimit = UintToArith256(params.powLimit);
+ arith_uint256 bnNew;
+ arith_uint256 bnOld;
+ bnNew.SetCompact(pindexLast->nBits);
+ bnOld = bnNew;
+ bnNew *= nModulatedTimespan;
+ bnNew /= retargetTimespan;
+
+ if (bnNew > bnPowLimit)
+ bnNew = bnPowLimit;
+
+ /// debug print
+ LogPrintf("GetNextWorkRequired RETARGET\n");
+ LogPrintf("params.nPowTargetTimespan = %d nActualTimespan = %d\n", params.nPowTargetTimespan, nActualTimespan);
+ LogPrintf("Before: %08x %s\n", pindexLast->nBits, bnOld.ToString());
+ LogPrintf("After: %08x %s\n", bnNew.GetCompact(), bnNew.ToString());
+
+ return bnNew.GetCompact();
+}
+
+bool CheckAuxPowProofOfWork(const CBlockHeader& block, const Consensus::Params& params)
+{
+ /* Except for legacy blocks with full version 1, ensure that
+ the chain ID is correct. Legacy blocks are not allowed since
+ the merge-mining start, which is checked in AcceptBlockHeader
+ where the height is known. */
+ if (!block.IsLegacy() && params.fStrictChainId
+ && block.GetChainId() != params.nAuxpowChainId)
+ return error("%s : block does not have our chain ID"
+ " (got %d, expected %d, full nVersion %d)",
+ __func__, block.GetChainId(),
+ params.nAuxpowChainId, block.nVersion);
+
+ /* If there is no auxpow, just check the block hash. */
+ if (!block.auxpow) {
+ if (block.IsAuxpow())
+ return error("%s : no auxpow on block with auxpow version",
+ __func__);
+
+ if (!CheckProofOfWork(block.GetPoWHash(), block.nBits, params))
+ return error("%s : non-AUX proof of work failed", __func__);
+
+ return true;
+ }
+
+ /* We have auxpow. Check it. */
+
+ if (!block.IsAuxpow())
+ return error("%s : auxpow on block with non-auxpow version", __func__);
+
+ if (!block.auxpow->check(block.GetHash(), block.GetChainId(), params))
+ return error("%s : AUX POW is not valid", __func__);
+ if (!CheckProofOfWork(block.auxpow->getParentBlockPoWHash(), block.nBits, params))
+ return error("%s : AUX proof of work failed", __func__);
+
+ return true;
+}
+
CAmount GetDogecoinBlockSubsidy(int nHeight, const Consensus::Params& consensusParams, uint256 prevHash)
{
int halvings = nHeight / consensusParams.nSubsidyHalvingInterval;