aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main.cpp35
-rw-r--r--src/main.h15
-rw-r--r--src/miner.cpp4
-rw-r--r--src/pow.cpp48
-rw-r--r--src/pow.h8
-rw-r--r--src/rpcmining.cpp2
-rw-r--r--src/test/DoS_tests.cpp6
7 files changed, 53 insertions, 65 deletions
diff --git a/src/main.cpp b/src/main.cpp
index c7ba15ef13..ddc37ea534 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1420,25 +1420,6 @@ void static InvalidBlockFound(CBlockIndex *pindex, const CValidationState &state
}
}
-void UpdateTime(CBlockHeader& block, const CBlockIndex* pindexPrev)
-{
- block.nTime = max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime());
-
- // Updating time can change work required on testnet:
- if (Params().AllowMinDifficultyBlocks())
- block.nBits = GetNextWorkRequired(pindexPrev, &block);
-}
-
-
-
-
-
-
-
-
-
-
-
void UpdateCoins(const CTransaction& tx, CValidationState &state, CCoinsViewCache &inputs, CTxUndo &txundo, int nHeight)
{
bool ret;
@@ -2435,12 +2416,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");
@@ -3297,15 +3273,6 @@ bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp)
return nLoaded > 0;
}
-
-
-
-
-
-
-
-
-
//////////////////////////////////////////////////////////////////////////////
//
// CAlert
diff --git a/src/main.h b/src/main.h
index 142c41444e..0a1ff45460 100644
--- a/src/main.h
+++ b/src/main.h
@@ -14,6 +14,7 @@
#include "coins.h"
#include "core.h"
#include "net.h"
+#include "pow.h"
#include "script.h"
#include "sync.h"
#include "txmempool.h"
@@ -163,8 +164,6 @@ bool GetTransaction(const uint256 &hash, CTransaction &tx, uint256 &hashBlock, b
bool ActivateBestChain(CValidationState &state, CBlock *pblock = NULL);
int64_t GetBlockValue(int nHeight, int64_t nFees);
-void UpdateTime(CBlockHeader& block, const CBlockIndex* pindexPrev);
-
/** Create a new block index entry for a given block hash */
CBlockIndex * InsertBlockIndex(uint256 hash);
/** Verify a signature */
@@ -736,17 +735,7 @@ public:
uint256 GetBlockWork() const
{
- 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;
+ return GetProofIncrement(nBits);
}
enum { nMedianTimeSpan=11 };
diff --git a/src/miner.cpp b/src/miner.cpp
index 8696edcf6e..96dc80a26d 100644
--- a/src/miner.cpp
+++ b/src/miner.cpp
@@ -307,7 +307,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn)
// Fill in header
pblock->hashPrevBlock = pindexPrev->GetBlockHash();
- UpdateTime(*pblock, pindexPrev);
+ UpdateTime(pblock, pindexPrev);
pblock->nBits = GetNextWorkRequired(pindexPrev, pblock);
pblock->nNonce = 0;
pblocktemplate->vTxSigOps[0] = GetLegacySigOpCount(pblock->vtx[0]);
@@ -540,7 +540,7 @@ void static BitcoinMiner(CWallet *pwallet)
break;
// Update nTime every few seconds
- UpdateTime(*pblock, pindexPrev);
+ UpdateTime(pblock, pindexPrev);
if (Params().AllowMinDifficultyBlocks())
{
// Changing pblock->nTime can change work required on testnet:
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;
}
diff --git a/src/pow.h b/src/pow.h
index 0ce5b48766..f350d763f4 100644
--- a/src/pow.h
+++ b/src/pow.h
@@ -17,7 +17,11 @@ 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);
+
+uint256 GetProofIncrement(unsigned int nBits);
#endif
diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp
index 6e508abcda..e4a5bc4162 100644
--- a/src/rpcmining.cpp
+++ b/src/rpcmining.cpp
@@ -458,7 +458,7 @@ Value getblocktemplate(const Array& params, bool fHelp)
CBlock* pblock = &pblocktemplate->block; // pointer for convenience
// Update nTime
- UpdateTime(*pblock, pindexPrev);
+ UpdateTime(pblock, pindexPrev);
pblock->nNonce = 0;
Array transactions;
diff --git a/src/test/DoS_tests.cpp b/src/test/DoS_tests.cpp
index 4ecf6e2535..8fa38c3605 100644
--- a/src/test/DoS_tests.cpp
+++ b/src/test/DoS_tests.cpp
@@ -107,11 +107,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)