diff --git a/src/main.cpp b/src/main.cpp index fab5af73b..9e07f43c4 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2410,12 +2410,7 @@ bool AcceptBlockHeader(CBlockHeader& block, CValidationState& state, CBlockIndex return state.DoS(100, error("CheckBlockHeader() : block with timestamp before last checkpoint"), REJECT_CHECKPOINT, "time-too-old"); } - bool fOverflow = false; - uint256 bnNewBlock; - bnNewBlock.SetCompact(block.nBits, NULL, &fOverflow); - uint256 bnRequired; - bnRequired.SetCompact(ComputeMinWork(pcheckpoint->nBits, deltaTime)); - if (fOverflow || bnNewBlock > bnRequired) + if (!CheckMinWork(block.nBits, pcheckpoint->nBits, deltaTime)) { return state.DoS(100, error("CheckBlockHeader() : block with too little proof-of-work"), REJECT_INVALID, "bad-diffbits"); diff --git a/src/pow.cpp b/src/pow.cpp index d76928bda..1d2b743b4 100644 --- a/src/pow.cpp +++ b/src/pow.cpp @@ -94,29 +94,36 @@ bool CheckProofOfWork(uint256 hash, unsigned int nBits) } // -// minimum amount of work that could possibly be required nTime after -// minimum work required was nBase +// true if nBits is greater than the minimum amount of work that could +// possibly be required deltaTime after minimum work required was nBase // -unsigned int ComputeMinWork(unsigned int nBase, int64_t nTime) +bool CheckMinWork(unsigned int nBits, unsigned int nBase, int64_t deltaTime) { + bool fOverflow = false; + uint256 bnNewBlock; + bnNewBlock.SetCompact(nBits, NULL, &fOverflow); + if (fOverflow) + return false; + const uint256 &bnLimit = Params().ProofOfWorkLimit(); // Testnet has min-difficulty blocks // after Params().TargetSpacing()*2 time between blocks: - if (Params().AllowMinDifficultyBlocks() && nTime > Params().TargetSpacing()*2) - return bnLimit.GetCompact(); + if (Params().AllowMinDifficultyBlocks() && deltaTime > Params().TargetSpacing()*2) + return bnNewBlock <= bnLimit; uint256 bnResult; bnResult.SetCompact(nBase); - while (nTime > 0 && bnResult < bnLimit) + while (deltaTime > 0 && bnResult < bnLimit) { // Maximum 400% adjustment... bnResult *= 4; // ... in best-case exactly 4-times-normal target time - nTime -= Params().TargetTimespan()*4; + deltaTime -= Params().TargetTimespan()*4; } if (bnResult > bnLimit) bnResult = bnLimit; - return bnResult.GetCompact(); + + return bnNewBlock <= bnResult; } void UpdateTime(CBlockHeader* pblock, const CBlockIndex* pindexPrev) diff --git a/src/pow.h b/src/pow.h index 6aea713fc..f350d763f 100644 --- a/src/pow.h +++ b/src/pow.h @@ -17,8 +17,8 @@ unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHead /** Check whether a block hash satisfies the proof-of-work requirement specified by nBits */ bool CheckProofOfWork(uint256 hash, unsigned int nBits); -/** Calculate the minimum amount of work a received block needs, without knowing its direct parent */ -unsigned int ComputeMinWork(unsigned int nBase, int64_t nTime); +/** Check the work is more than the minimum a received block needs, without knowing its direct parent */ +bool CheckMinWork(unsigned int nBits, unsigned int nBase, int64_t deltaTime); void UpdateTime(CBlockHeader* block, const CBlockIndex* pindexPrev); diff --git a/src/test/DoS_tests.cpp b/src/test/DoS_tests.cpp index 5e17555e7..bb15db43b 100644 --- a/src/test/DoS_tests.cpp +++ b/src/test/DoS_tests.cpp @@ -106,11 +106,7 @@ static bool CheckNBits(unsigned int nbits1, int64_t time1, unsigned int nbits2, return CheckNBits(nbits2, time2, nbits1, time1); int64_t deltaTime = time2-time1; - uint256 required; - required.SetCompact(ComputeMinWork(nbits1, deltaTime)); - uint256 have; - have.SetCompact(nbits2); - return (have <= required); + return CheckMinWork(nbits2, nbits1, deltaTime); } BOOST_AUTO_TEST_CASE(DoS_checknbits)