aboutsummaryrefslogtreecommitdiff
path: root/src/pow.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/pow.cpp')
-rw-r--r--src/pow.cpp48
1 files changed, 40 insertions, 8 deletions
diff --git a/src/pow.cpp b/src/pow.cpp
index b091cbec3d..893f6c18be 100644
--- a/src/pow.cpp
+++ b/src/pow.cpp
@@ -8,6 +8,7 @@
#include "chainparams.h"
#include "core.h"
#include "main.h"
+#include "timedata.h"
#include "uint256.h"
#include "util.h"
@@ -94,27 +95,58 @@ 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)
+{
+ pblock->nTime = std::max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime());
+
+ // Updating time can change work required on testnet:
+ if (Params().AllowMinDifficultyBlocks())
+ pblock->nBits = GetNextWorkRequired(pindexPrev, pblock);
+}
+
+uint256 GetProofIncrement(unsigned int nBits)
+{
+ uint256 bnTarget;
+ bool fNegative;
+ bool fOverflow;
+ bnTarget.SetCompact(nBits, &fNegative, &fOverflow);
+ if (fNegative || fOverflow || bnTarget == 0)
+ return 0;
+ // We need to compute 2**256 / (bnTarget+1), but we can't represent 2**256
+ // as it's too large for a uint256. However, as 2**256 is at least as large
+ // as bnTarget+1, it is equal to ((2**256 - bnTarget - 1) / (bnTarget+1)) + 1,
+ // or ~bnTarget / (nTarget+1) + 1.
+ return (~bnTarget / (bnTarget + 1)) + 1;
}