diff options
| author | Max K <[email protected]> | 2019-07-14 19:35:30 +0200 |
|---|---|---|
| committer | GitHub <[email protected]> | 2019-07-14 19:35:30 +0200 |
| commit | cee13699a5676355487f8eb2d91985f63438eae4 (patch) | |
| tree | cf12be6180f950a25ee2ee7f3f2126542835d6e3 /src/dogecoin.cpp | |
| parent | Correct build and test net seed (diff) | |
| parent | Handle legacy v2 block at #66064 (diff) | |
| download | discoin-1.17-dev.tar.xz discoin-1.17-dev.zip | |
Merge pull request #1546 from rnicoll/1.17-auxpow1.17-dev
1.17 AuxPoW support
Diffstat (limited to 'src/dogecoin.cpp')
| -rw-r--r-- | src/dogecoin.cpp | 120 |
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; |