Skip to content

Commit 208bf5b

Browse files
committed
Merge pull request #3839
fd704c7 move pow constants to chainparams (jtimon) df852d2 Refactor proof of work related functions out of main (jtimon)
2 parents 27383b9 + fd704c7 commit 208bf5b

File tree

11 files changed

+163
-124
lines changed

11 files changed

+163
-124
lines changed

src/Makefile.am

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ BITCOIN_CORE_H = \
7171
netbase.h \
7272
net.h \
7373
noui.h \
74+
pow.h \
7475
protocol.h \
7576
rpcclient.h \
7677
rpcprotocol.h \
@@ -121,6 +122,7 @@ libbitcoin_server_a_SOURCES = \
121122
miner.cpp \
122123
net.cpp \
123124
noui.cpp \
125+
pow.cpp \
124126
rpcblockchain.cpp \
125127
rpcmining.cpp \
126128
rpcmisc.cpp \

src/chainparams.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,8 @@ class CMainParams : public CChainParams {
117117
nRejectBlockOutdatedMajority = 950;
118118
nToCheckBlockUpgradeMajority = 1000;
119119
nMinerThreads = 0;
120+
nTargetTimespan = 14 * 24 * 60 * 60; // two weeks
121+
nTargetSpacing = 10 * 60;
120122

121123
// Build the genesis block. Note that the output of the genesis coinbase cannot
122124
// be spent as it did not originally exist in the database.
@@ -204,6 +206,9 @@ class CTestNetParams : public CMainParams {
204206
nEnforceBlockUpgradeMajority = 51;
205207
nRejectBlockOutdatedMajority = 75;
206208
nToCheckBlockUpgradeMajority = 100;
209+
nMinerThreads = 0;
210+
nTargetTimespan = 14 * 24 * 60 * 60; // two weeks
211+
nTargetSpacing = 10 * 60;
207212
strDataDir = "testnet3";
208213

209214
// Modify the testnet genesis block so the timestamp is valid for a later start.
@@ -251,6 +256,8 @@ class CRegTestParams : public CTestNetParams {
251256
nRejectBlockOutdatedMajority = 950;
252257
nToCheckBlockUpgradeMajority = 1000;
253258
nMinerThreads = 1;
259+
nTargetTimespan = 14 * 24 * 60 * 60; // two weeks
260+
nTargetSpacing = 10 * 60;
254261
bnProofOfWorkLimit = ~uint256(0) >> 1;
255262
genesis.nTime = 1296688602;
256263
genesis.nBits = 0x207fffff;

src/chainparams.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,9 @@ class CChainParams
7070
bool AllowMinDifficultyBlocks() const { return fAllowMinDifficultyBlocks; }
7171
/* Make standard checks */
7272
bool RequireStandard() const { return fRequireStandard; }
73+
int64_t TargetTimespan() const { return nTargetTimespan; }
74+
int64_t TargetSpacing() const { return nTargetSpacing; }
75+
int64_t Interval() const { return nTargetTimespan / nTargetSpacing; }
7376
const std::string& DataDir() const { return strDataDir; }
7477
/* Make miner stop after a block is found. In RPC, don't return
7578
* until nGenProcLimit blocks are generated */
@@ -95,6 +98,8 @@ class CChainParams
9598
int nEnforceBlockUpgradeMajority;
9699
int nRejectBlockOutdatedMajority;
97100
int nToCheckBlockUpgradeMajority;
101+
int64_t nTargetTimespan;
102+
int64_t nTargetSpacing;
98103
std::string strDataDir;
99104
int nMinerThreads;
100105
std::vector<CDNSSeedData> vSeeds;

src/main.cpp

Lines changed: 1 addition & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include "checkqueue.h"
1313
#include "init.h"
1414
#include "net.h"
15+
#include "pow.h"
1516
#include "txdb.h"
1617
#include "txmempool.h"
1718
#include "ui_interface.h"
@@ -1194,118 +1195,6 @@ int64_t GetBlockValue(int nHeight, int64_t nFees)
11941195
return nSubsidy + nFees;
11951196
}
11961197

1197-
static const int64_t nTargetTimespan = 14 * 24 * 60 * 60; // two weeks
1198-
static const int64_t nTargetSpacing = 10 * 60;
1199-
static const int64_t nInterval = nTargetTimespan / nTargetSpacing;
1200-
1201-
//
1202-
// minimum amount of work that could possibly be required nTime after
1203-
// minimum work required was nBase
1204-
//
1205-
unsigned int ComputeMinWork(unsigned int nBase, int64_t nTime)
1206-
{
1207-
const uint256 &bnLimit = Params().ProofOfWorkLimit();
1208-
// Testnet has min-difficulty blocks
1209-
// after nTargetSpacing*2 time between blocks:
1210-
if (Params().AllowMinDifficultyBlocks() && nTime > nTargetSpacing*2)
1211-
return bnLimit.GetCompact();
1212-
1213-
uint256 bnResult;
1214-
bnResult.SetCompact(nBase);
1215-
while (nTime > 0 && bnResult < bnLimit)
1216-
{
1217-
// Maximum 400% adjustment...
1218-
bnResult *= 4;
1219-
// ... in best-case exactly 4-times-normal target time
1220-
nTime -= nTargetTimespan*4;
1221-
}
1222-
if (bnResult > bnLimit)
1223-
bnResult = bnLimit;
1224-
return bnResult.GetCompact();
1225-
}
1226-
1227-
unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock)
1228-
{
1229-
unsigned int nProofOfWorkLimit = Params().ProofOfWorkLimit().GetCompact();
1230-
1231-
// Genesis block
1232-
if (pindexLast == NULL)
1233-
return nProofOfWorkLimit;
1234-
1235-
// Only change once per interval
1236-
if ((pindexLast->nHeight+1) % nInterval != 0)
1237-
{
1238-
if (Params().AllowMinDifficultyBlocks())
1239-
{
1240-
// Special difficulty rule for testnet:
1241-
// If the new block's timestamp is more than 2* 10 minutes
1242-
// then allow mining of a min-difficulty block.
1243-
if (pblock->nTime > pindexLast->nTime + nTargetSpacing*2)
1244-
return nProofOfWorkLimit;
1245-
else
1246-
{
1247-
// Return the last non-special-min-difficulty-rules-block
1248-
const CBlockIndex* pindex = pindexLast;
1249-
while (pindex->pprev && pindex->nHeight % nInterval != 0 && pindex->nBits == nProofOfWorkLimit)
1250-
pindex = pindex->pprev;
1251-
return pindex->nBits;
1252-
}
1253-
}
1254-
return pindexLast->nBits;
1255-
}
1256-
1257-
// Go back by what we want to be 14 days worth of blocks
1258-
const CBlockIndex* pindexFirst = pindexLast;
1259-
for (int i = 0; pindexFirst && i < nInterval-1; i++)
1260-
pindexFirst = pindexFirst->pprev;
1261-
assert(pindexFirst);
1262-
1263-
// Limit adjustment step
1264-
int64_t nActualTimespan = pindexLast->GetBlockTime() - pindexFirst->GetBlockTime();
1265-
LogPrintf(" nActualTimespan = %d before bounds\n", nActualTimespan);
1266-
if (nActualTimespan < nTargetTimespan/4)
1267-
nActualTimespan = nTargetTimespan/4;
1268-
if (nActualTimespan > nTargetTimespan*4)
1269-
nActualTimespan = nTargetTimespan*4;
1270-
1271-
// Retarget
1272-
uint256 bnNew;
1273-
uint256 bnOld;
1274-
bnNew.SetCompact(pindexLast->nBits);
1275-
bnOld = bnNew;
1276-
bnNew *= nActualTimespan;
1277-
bnNew /= nTargetTimespan;
1278-
1279-
if (bnNew > Params().ProofOfWorkLimit())
1280-
bnNew = Params().ProofOfWorkLimit();
1281-
1282-
/// debug print
1283-
LogPrintf("GetNextWorkRequired RETARGET\n");
1284-
LogPrintf("nTargetTimespan = %d nActualTimespan = %d\n", nTargetTimespan, nActualTimespan);
1285-
LogPrintf("Before: %08x %s\n", pindexLast->nBits, bnOld.ToString());
1286-
LogPrintf("After: %08x %s\n", bnNew.GetCompact(), bnNew.ToString());
1287-
1288-
return bnNew.GetCompact();
1289-
}
1290-
1291-
bool CheckProofOfWork(uint256 hash, unsigned int nBits)
1292-
{
1293-
bool fNegative;
1294-
bool fOverflow;
1295-
uint256 bnTarget;
1296-
bnTarget.SetCompact(nBits, &fNegative, &fOverflow);
1297-
1298-
// Check range
1299-
if (fNegative || bnTarget == 0 || fOverflow || bnTarget > Params().ProofOfWorkLimit())
1300-
return error("CheckProofOfWork() : nBits below minimum work");
1301-
1302-
// Check proof of work matches claimed amount
1303-
if (hash > bnTarget)
1304-
return error("CheckProofOfWork() : hash doesn't match nBits");
1305-
1306-
return true;
1307-
}
1308-
13091198
bool IsInitialBlockDownload()
13101199
{
13111200
LOCK(cs_main);

src/main.h

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -146,10 +146,6 @@ bool ProcessMessages(CNode* pfrom);
146146
bool SendMessages(CNode* pto, bool fSendTrickle);
147147
/** Run an instance of the script checking thread */
148148
void ThreadScriptCheck();
149-
/** Check whether a block hash satisfies the proof-of-work requirement specified by nBits */
150-
bool CheckProofOfWork(uint256 hash, unsigned int nBits);
151-
/** Calculate the minimum amount of work a received block needs, without knowing its direct parent */
152-
unsigned int ComputeMinWork(unsigned int nBase, int64_t nTime);
153149
/** Check whether we are doing an initial block download (synchronizing from disk or network) */
154150
bool IsInitialBlockDownload();
155151
/** Format a string that describes several potential problems detected by the core */
@@ -159,7 +155,6 @@ bool GetTransaction(const uint256 &hash, CTransaction &tx, uint256 &hashBlock, b
159155
/** Find the best known block, and make it the tip of the block chain */
160156
bool ActivateBestChain(CValidationState &state);
161157
int64_t GetBlockValue(int nHeight, int64_t nFees);
162-
unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock);
163158

164159
void UpdateTime(CBlockHeader& block, const CBlockIndex* pindexPrev);
165160

@@ -812,11 +807,6 @@ class CBlockIndex
812807
return (~bnTarget / (bnTarget + 1)) + 1;
813808
}
814809

815-
bool CheckIndex() const
816-
{
817-
return CheckProofOfWork(GetBlockHash(), nBits);
818-
}
819-
820810
enum { nMedianTimeSpan=11 };
821811

822812
int64_t GetMedianTimePast() const

src/miner.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "hash.h"
1010
#include "main.h"
1111
#include "net.h"
12+
#include "pow.h"
1213
#ifdef ENABLE_WALLET
1314
#include "wallet.h"
1415
#endif

src/pow.cpp

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
// Copyright (c) 2009-2010 Satoshi Nakamoto
2+
// Copyright (c) 2009-2014 The Bitcoin developers
3+
// Distributed under the MIT/X11 software license, see the accompanying
4+
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
5+
6+
#include "pow.h"
7+
8+
#include "chainparams.h"
9+
#include "core.h"
10+
#include "main.h"
11+
#include "uint256.h"
12+
13+
unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock)
14+
{
15+
unsigned int nProofOfWorkLimit = Params().ProofOfWorkLimit().GetCompact();
16+
17+
// Genesis block
18+
if (pindexLast == NULL)
19+
return nProofOfWorkLimit;
20+
21+
// Only change once per interval
22+
if ((pindexLast->nHeight+1) % Params().Interval() != 0)
23+
{
24+
if (Params().AllowMinDifficultyBlocks())
25+
{
26+
// Special difficulty rule for testnet:
27+
// If the new block's timestamp is more than 2* 10 minutes
28+
// then allow mining of a min-difficulty block.
29+
if (pblock->nTime > pindexLast->nTime + Params().TargetSpacing()*2)
30+
return nProofOfWorkLimit;
31+
else
32+
{
33+
// Return the last non-special-min-difficulty-rules-block
34+
const CBlockIndex* pindex = pindexLast;
35+
while (pindex->pprev && pindex->nHeight % Params().Interval() != 0 && pindex->nBits == nProofOfWorkLimit)
36+
pindex = pindex->pprev;
37+
return pindex->nBits;
38+
}
39+
}
40+
return pindexLast->nBits;
41+
}
42+
43+
// Go back by what we want to be 14 days worth of blocks
44+
const CBlockIndex* pindexFirst = pindexLast;
45+
for (int i = 0; pindexFirst && i < Params().Interval()-1; i++)
46+
pindexFirst = pindexFirst->pprev;
47+
assert(pindexFirst);
48+
49+
// Limit adjustment step
50+
int64_t nActualTimespan = pindexLast->GetBlockTime() - pindexFirst->GetBlockTime();
51+
LogPrintf(" nActualTimespan = %d before bounds\n", nActualTimespan);
52+
if (nActualTimespan < Params().TargetTimespan()/4)
53+
nActualTimespan = Params().TargetTimespan()/4;
54+
if (nActualTimespan > Params().TargetTimespan()*4)
55+
nActualTimespan = Params().TargetTimespan()*4;
56+
57+
// Retarget
58+
uint256 bnNew;
59+
uint256 bnOld;
60+
bnNew.SetCompact(pindexLast->nBits);
61+
bnOld = bnNew;
62+
bnNew *= nActualTimespan;
63+
bnNew /= Params().TargetTimespan();
64+
65+
if (bnNew > Params().ProofOfWorkLimit())
66+
bnNew = Params().ProofOfWorkLimit();
67+
68+
/// debug print
69+
LogPrintf("GetNextWorkRequired RETARGET\n");
70+
LogPrintf("Params().TargetTimespan() = %d nActualTimespan = %d\n", Params().TargetTimespan(), nActualTimespan);
71+
LogPrintf("Before: %08x %s\n", pindexLast->nBits, bnOld.ToString());
72+
LogPrintf("After: %08x %s\n", bnNew.GetCompact(), bnNew.ToString());
73+
74+
return bnNew.GetCompact();
75+
}
76+
77+
bool CheckProofOfWork(uint256 hash, unsigned int nBits)
78+
{
79+
bool fNegative;
80+
bool fOverflow;
81+
uint256 bnTarget;
82+
bnTarget.SetCompact(nBits, &fNegative, &fOverflow);
83+
84+
// Check range
85+
if (fNegative || bnTarget == 0 || fOverflow || bnTarget > Params().ProofOfWorkLimit())
86+
return error("CheckProofOfWork() : nBits below minimum work");
87+
88+
// Check proof of work matches claimed amount
89+
if (hash > bnTarget)
90+
return error("CheckProofOfWork() : hash doesn't match nBits");
91+
92+
return true;
93+
}
94+
95+
//
96+
// minimum amount of work that could possibly be required nTime after
97+
// minimum work required was nBase
98+
//
99+
unsigned int ComputeMinWork(unsigned int nBase, int64_t nTime)
100+
{
101+
const uint256 &bnLimit = Params().ProofOfWorkLimit();
102+
// Testnet has min-difficulty blocks
103+
// after Params().TargetSpacing()*2 time between blocks:
104+
if (Params().AllowMinDifficultyBlocks() && nTime > Params().TargetSpacing()*2)
105+
return bnLimit.GetCompact();
106+
107+
uint256 bnResult;
108+
bnResult.SetCompact(nBase);
109+
while (nTime > 0 && bnResult < bnLimit)
110+
{
111+
// Maximum 400% adjustment...
112+
bnResult *= 4;
113+
// ... in best-case exactly 4-times-normal target time
114+
nTime -= Params().TargetTimespan()*4;
115+
}
116+
if (bnResult > bnLimit)
117+
bnResult = bnLimit;
118+
return bnResult.GetCompact();
119+
}

src/pow.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
2+
// Copyright (c) 2009-2010 Satoshi Nakamoto
3+
// Copyright (c) 2009-2014 The Bitcoin developers
4+
// Distributed under the MIT/X11 software license, see the accompanying
5+
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
6+
7+
#ifndef BITCOIN_POW_H
8+
#define BITCOIN_POW_H
9+
10+
#include <stdint.h>
11+
12+
class CBlockIndex;
13+
class CBlockHeader;
14+
class uint256;
15+
16+
unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock);
17+
18+
/** Check whether a block hash satisfies the proof-of-work requirement specified by nBits */
19+
bool CheckProofOfWork(uint256 hash, unsigned int nBits);
20+
/** Calculate the minimum amount of work a received block needs, without knowing its direct parent */
21+
unsigned int ComputeMinWork(unsigned int nBase, int64_t nTime);
22+
23+
#endif

src/rpcmining.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "net.h"
1010
#include "main.h"
1111
#include "miner.h"
12+
#include "pow.h"
1213
#ifdef ENABLE_WALLET
1314
#include "db.h"
1415
#include "wallet.h"

src/test/DoS_tests.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include "keystore.h"
1212
#include "main.h"
1313
#include "net.h"
14+
#include "pow.h"
1415
#include "script.h"
1516
#include "serialize.h"
1617

0 commit comments

Comments
 (0)