Merge pull request #6055
a8cdaf5
checkpoints: move the checkpoints enable boolean into main (Cory Fields)11982d3
checkpoints: Decouple checkpoints from Params (Cory Fields)6996823
checkpoints: make checkpoints a member of CChainParams (Cory Fields)9f13a10
checkpoints: store mapCheckpoints in CCheckpointData rather than a pointer (Cory Fields)
This commit is contained in:
commit
00820f921d
@ -26,51 +26,6 @@ using namespace std;
|
|||||||
* timestamp before)
|
* timestamp before)
|
||||||
* + Contains no strange transactions
|
* + Contains no strange transactions
|
||||||
*/
|
*/
|
||||||
static Checkpoints::MapCheckpoints mapCheckpoints =
|
|
||||||
boost::assign::map_list_of
|
|
||||||
( 11111, uint256S("0x0000000069e244f73d78e8fd29ba2fd2ed618bd6fa2ee92559f542fdb26e7c1d"))
|
|
||||||
( 33333, uint256S("0x000000002dd5588a74784eaa7ab0507a18ad16a236e7b1ce69f00d7ddfb5d0a6"))
|
|
||||||
( 74000, uint256S("0x0000000000573993a3c9e41ce34471c079dcf5f52a0e824a81e7f953b8661a20"))
|
|
||||||
(105000, uint256S("0x00000000000291ce28027faea320c8d2b054b2e0fe44a773f3eefb151d6bdc97"))
|
|
||||||
(134444, uint256S("0x00000000000005b12ffd4cd315cd34ffd4a594f430ac814c91184a0d42d2b0fe"))
|
|
||||||
(168000, uint256S("0x000000000000099e61ea72015e79632f216fe6cb33d7899acb35b75c8303b763"))
|
|
||||||
(193000, uint256S("0x000000000000059f452a5f7340de6682a977387c17010ff6e6c3bd83ca8b1317"))
|
|
||||||
(210000, uint256S("0x000000000000048b95347e83192f69cf0366076336c639f9b7228e9ba171342e"))
|
|
||||||
(216116, uint256S("0x00000000000001b4f4b433e81ee46494af945cf96014816a4e2370f11b23df4e"))
|
|
||||||
(225430, uint256S("0x00000000000001c108384350f74090433e7fcf79a606b8e797f065b130575932"))
|
|
||||||
(250000, uint256S("0x000000000000003887df1f29024b06fc2200b55f8af8f35453d7be294df2d214"))
|
|
||||||
(279000, uint256S("0x0000000000000001ae8c72a0b0c301f67e3afca10e819efa9041e458e9bd7e40"))
|
|
||||||
(295000, uint256S("0x00000000000000004d9b4ef50f0f9d686fd69db2e03af35a100370c64632a983"))
|
|
||||||
;
|
|
||||||
static const Checkpoints::CCheckpointData data = {
|
|
||||||
&mapCheckpoints,
|
|
||||||
1397080064, // * UNIX timestamp of last checkpoint block
|
|
||||||
36544669, // * total number of transactions between genesis and last checkpoint
|
|
||||||
// (the tx=... number in the SetBestChain debug.log lines)
|
|
||||||
60000.0 // * estimated number of transactions per day after checkpoint
|
|
||||||
};
|
|
||||||
|
|
||||||
static Checkpoints::MapCheckpoints mapCheckpointsTestnet =
|
|
||||||
boost::assign::map_list_of
|
|
||||||
( 546, uint256S("000000002a936ca763904c3c35fce2f3556c559c0214345d31b1bcebf76acb70"))
|
|
||||||
;
|
|
||||||
static const Checkpoints::CCheckpointData dataTestnet = {
|
|
||||||
&mapCheckpointsTestnet,
|
|
||||||
1337966069,
|
|
||||||
1488,
|
|
||||||
300
|
|
||||||
};
|
|
||||||
|
|
||||||
static Checkpoints::MapCheckpoints mapCheckpointsRegtest =
|
|
||||||
boost::assign::map_list_of
|
|
||||||
( 0, uint256S("0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206"))
|
|
||||||
;
|
|
||||||
static const Checkpoints::CCheckpointData dataRegtest = {
|
|
||||||
&mapCheckpointsRegtest,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0
|
|
||||||
};
|
|
||||||
|
|
||||||
class CMainParams : public CChainParams {
|
class CMainParams : public CChainParams {
|
||||||
public:
|
public:
|
||||||
@ -149,11 +104,27 @@ public:
|
|||||||
fRequireStandard = true;
|
fRequireStandard = true;
|
||||||
fMineBlocksOnDemand = false;
|
fMineBlocksOnDemand = false;
|
||||||
fTestnetToBeDeprecatedFieldRPC = false;
|
fTestnetToBeDeprecatedFieldRPC = false;
|
||||||
}
|
|
||||||
|
|
||||||
const Checkpoints::CCheckpointData& Checkpoints() const
|
checkpointData = (Checkpoints::CCheckpointData) {
|
||||||
{
|
boost::assign::map_list_of
|
||||||
return data;
|
( 11111, uint256S("0x0000000069e244f73d78e8fd29ba2fd2ed618bd6fa2ee92559f542fdb26e7c1d"))
|
||||||
|
( 33333, uint256S("0x000000002dd5588a74784eaa7ab0507a18ad16a236e7b1ce69f00d7ddfb5d0a6"))
|
||||||
|
( 74000, uint256S("0x0000000000573993a3c9e41ce34471c079dcf5f52a0e824a81e7f953b8661a20"))
|
||||||
|
(105000, uint256S("0x00000000000291ce28027faea320c8d2b054b2e0fe44a773f3eefb151d6bdc97"))
|
||||||
|
(134444, uint256S("0x00000000000005b12ffd4cd315cd34ffd4a594f430ac814c91184a0d42d2b0fe"))
|
||||||
|
(168000, uint256S("0x000000000000099e61ea72015e79632f216fe6cb33d7899acb35b75c8303b763"))
|
||||||
|
(193000, uint256S("0x000000000000059f452a5f7340de6682a977387c17010ff6e6c3bd83ca8b1317"))
|
||||||
|
(210000, uint256S("0x000000000000048b95347e83192f69cf0366076336c639f9b7228e9ba171342e"))
|
||||||
|
(216116, uint256S("0x00000000000001b4f4b433e81ee46494af945cf96014816a4e2370f11b23df4e"))
|
||||||
|
(225430, uint256S("0x00000000000001c108384350f74090433e7fcf79a606b8e797f065b130575932"))
|
||||||
|
(250000, uint256S("0x000000000000003887df1f29024b06fc2200b55f8af8f35453d7be294df2d214"))
|
||||||
|
(279000, uint256S("0x0000000000000001ae8c72a0b0c301f67e3afca10e819efa9041e458e9bd7e40"))
|
||||||
|
(295000, uint256S("0x00000000000000004d9b4ef50f0f9d686fd69db2e03af35a100370c64632a983")),
|
||||||
|
1397080064, // * UNIX timestamp of last checkpoint block
|
||||||
|
36544669, // * total number of transactions between genesis and last checkpoint
|
||||||
|
// (the tx=... number in the SetBestChain debug.log lines)
|
||||||
|
60000.0 // * estimated number of transactions per day after checkpoint
|
||||||
|
};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
static CMainParams mainParams;
|
static CMainParams mainParams;
|
||||||
@ -205,10 +176,15 @@ public:
|
|||||||
fRequireStandard = false;
|
fRequireStandard = false;
|
||||||
fMineBlocksOnDemand = false;
|
fMineBlocksOnDemand = false;
|
||||||
fTestnetToBeDeprecatedFieldRPC = true;
|
fTestnetToBeDeprecatedFieldRPC = true;
|
||||||
}
|
|
||||||
const Checkpoints::CCheckpointData& Checkpoints() const
|
checkpointData = (Checkpoints::CCheckpointData) {
|
||||||
{
|
boost::assign::map_list_of
|
||||||
return dataTestnet;
|
( 546, uint256S("000000002a936ca763904c3c35fce2f3556c559c0214345d31b1bcebf76acb70")),
|
||||||
|
1337966069,
|
||||||
|
1488,
|
||||||
|
300
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
static CTestNetParams testNetParams;
|
static CTestNetParams testNetParams;
|
||||||
@ -247,10 +223,14 @@ public:
|
|||||||
fRequireStandard = false;
|
fRequireStandard = false;
|
||||||
fMineBlocksOnDemand = true;
|
fMineBlocksOnDemand = true;
|
||||||
fTestnetToBeDeprecatedFieldRPC = false;
|
fTestnetToBeDeprecatedFieldRPC = false;
|
||||||
}
|
|
||||||
const Checkpoints::CCheckpointData& Checkpoints() const
|
checkpointData = (Checkpoints::CCheckpointData){
|
||||||
{
|
boost::assign::map_list_of
|
||||||
return dataRegtest;
|
( 0, uint256S("0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206")),
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
static CRegTestParams regTestParams;
|
static CRegTestParams regTestParams;
|
||||||
|
@ -74,7 +74,7 @@ public:
|
|||||||
const std::vector<CDNSSeedData>& DNSSeeds() const { return vSeeds; }
|
const std::vector<CDNSSeedData>& DNSSeeds() const { return vSeeds; }
|
||||||
const std::vector<unsigned char>& Base58Prefix(Base58Type type) const { return base58Prefixes[type]; }
|
const std::vector<unsigned char>& Base58Prefix(Base58Type type) const { return base58Prefixes[type]; }
|
||||||
const std::vector<SeedSpec6>& FixedSeeds() const { return vFixedSeeds; }
|
const std::vector<SeedSpec6>& FixedSeeds() const { return vFixedSeeds; }
|
||||||
virtual const Checkpoints::CCheckpointData& Checkpoints() const = 0;
|
const Checkpoints::CCheckpointData& Checkpoints() const { return checkpointData; }
|
||||||
protected:
|
protected:
|
||||||
CChainParams() {}
|
CChainParams() {}
|
||||||
|
|
||||||
@ -96,6 +96,7 @@ protected:
|
|||||||
bool fRequireStandard;
|
bool fRequireStandard;
|
||||||
bool fMineBlocksOnDemand;
|
bool fMineBlocksOnDemand;
|
||||||
bool fTestnetToBeDeprecatedFieldRPC;
|
bool fTestnetToBeDeprecatedFieldRPC;
|
||||||
|
Checkpoints::CCheckpointData checkpointData;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -24,14 +24,9 @@ namespace Checkpoints {
|
|||||||
*/
|
*/
|
||||||
static const double SIGCHECK_VERIFICATION_FACTOR = 5.0;
|
static const double SIGCHECK_VERIFICATION_FACTOR = 5.0;
|
||||||
|
|
||||||
bool fEnabled = true;
|
bool CheckBlock(const CCheckpointData& data, int nHeight, const uint256& hash)
|
||||||
|
|
||||||
bool CheckBlock(int nHeight, const uint256& hash)
|
|
||||||
{
|
{
|
||||||
if (!fEnabled)
|
const MapCheckpoints& checkpoints = data.mapCheckpoints;
|
||||||
return true;
|
|
||||||
|
|
||||||
const MapCheckpoints& checkpoints = *Params().Checkpoints().mapCheckpoints;
|
|
||||||
|
|
||||||
MapCheckpoints::const_iterator i = checkpoints.find(nHeight);
|
MapCheckpoints::const_iterator i = checkpoints.find(nHeight);
|
||||||
if (i == checkpoints.end()) return true;
|
if (i == checkpoints.end()) return true;
|
||||||
@ -39,7 +34,7 @@ namespace Checkpoints {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//! Guess how far we are in the verification process at the given block index
|
//! Guess how far we are in the verification process at the given block index
|
||||||
double GuessVerificationProgress(CBlockIndex *pindex, bool fSigchecks) {
|
double GuessVerificationProgress(const CCheckpointData& data, CBlockIndex *pindex, bool fSigchecks) {
|
||||||
if (pindex==NULL)
|
if (pindex==NULL)
|
||||||
return 0.0;
|
return 0.0;
|
||||||
|
|
||||||
@ -51,8 +46,6 @@ namespace Checkpoints {
|
|||||||
// Work is defined as: 1.0 per transaction before the last checkpoint, and
|
// Work is defined as: 1.0 per transaction before the last checkpoint, and
|
||||||
// fSigcheckVerificationFactor per transaction after.
|
// fSigcheckVerificationFactor per transaction after.
|
||||||
|
|
||||||
const CCheckpointData &data = Params().Checkpoints();
|
|
||||||
|
|
||||||
if (pindex->nChainTx <= data.nTransactionsLastCheckpoint) {
|
if (pindex->nChainTx <= data.nTransactionsLastCheckpoint) {
|
||||||
double nCheapBefore = pindex->nChainTx;
|
double nCheapBefore = pindex->nChainTx;
|
||||||
double nCheapAfter = data.nTransactionsLastCheckpoint - pindex->nChainTx;
|
double nCheapAfter = data.nTransactionsLastCheckpoint - pindex->nChainTx;
|
||||||
@ -70,22 +63,19 @@ namespace Checkpoints {
|
|||||||
return fWorkBefore / (fWorkBefore + fWorkAfter);
|
return fWorkBefore / (fWorkBefore + fWorkAfter);
|
||||||
}
|
}
|
||||||
|
|
||||||
int GetTotalBlocksEstimate()
|
int GetTotalBlocksEstimate(const CCheckpointData& data)
|
||||||
{
|
{
|
||||||
if (!fEnabled)
|
const MapCheckpoints& checkpoints = data.mapCheckpoints;
|
||||||
return 0;
|
|
||||||
|
|
||||||
const MapCheckpoints& checkpoints = *Params().Checkpoints().mapCheckpoints;
|
if (checkpoints.empty())
|
||||||
|
return 0;
|
||||||
|
|
||||||
return checkpoints.rbegin()->first;
|
return checkpoints.rbegin()->first;
|
||||||
}
|
}
|
||||||
|
|
||||||
CBlockIndex* GetLastCheckpoint()
|
CBlockIndex* GetLastCheckpoint(const CCheckpointData& data)
|
||||||
{
|
{
|
||||||
if (!fEnabled)
|
const MapCheckpoints& checkpoints = data.mapCheckpoints;
|
||||||
return NULL;
|
|
||||||
|
|
||||||
const MapCheckpoints& checkpoints = *Params().Checkpoints().mapCheckpoints;
|
|
||||||
|
|
||||||
BOOST_REVERSE_FOREACH(const MapCheckpoints::value_type& i, checkpoints)
|
BOOST_REVERSE_FOREACH(const MapCheckpoints::value_type& i, checkpoints)
|
||||||
{
|
{
|
||||||
|
@ -20,24 +20,22 @@ namespace Checkpoints
|
|||||||
typedef std::map<int, uint256> MapCheckpoints;
|
typedef std::map<int, uint256> MapCheckpoints;
|
||||||
|
|
||||||
struct CCheckpointData {
|
struct CCheckpointData {
|
||||||
const MapCheckpoints *mapCheckpoints;
|
MapCheckpoints mapCheckpoints;
|
||||||
int64_t nTimeLastCheckpoint;
|
int64_t nTimeLastCheckpoint;
|
||||||
int64_t nTransactionsLastCheckpoint;
|
int64_t nTransactionsLastCheckpoint;
|
||||||
double fTransactionsPerDay;
|
double fTransactionsPerDay;
|
||||||
};
|
};
|
||||||
|
|
||||||
//! Returns true if block passes checkpoint checks
|
//! Returns true if block passes checkpoint checks
|
||||||
bool CheckBlock(int nHeight, const uint256& hash);
|
bool CheckBlock(const CCheckpointData& data, int nHeight, const uint256& hash);
|
||||||
|
|
||||||
//! Return conservative estimate of total number of blocks, 0 if unknown
|
//! Return conservative estimate of total number of blocks, 0 if unknown
|
||||||
int GetTotalBlocksEstimate();
|
int GetTotalBlocksEstimate(const CCheckpointData& data);
|
||||||
|
|
||||||
//! Returns last CBlockIndex* in mapBlockIndex that is a checkpoint
|
//! Returns last CBlockIndex* in mapBlockIndex that is a checkpoint
|
||||||
CBlockIndex* GetLastCheckpoint();
|
CBlockIndex* GetLastCheckpoint(const CCheckpointData& data);
|
||||||
|
|
||||||
double GuessVerificationProgress(CBlockIndex* pindex, bool fSigchecks = true);
|
double GuessVerificationProgress(const CCheckpointData& data, CBlockIndex* pindex, bool fSigchecks = true);
|
||||||
|
|
||||||
extern bool fEnabled;
|
|
||||||
|
|
||||||
} //namespace Checkpoints
|
} //namespace Checkpoints
|
||||||
|
|
||||||
|
@ -739,7 +739,7 @@ bool AppInit2(boost::thread_group& threadGroup)
|
|||||||
// Checkmempool and checkblockindex default to true in regtest mode
|
// Checkmempool and checkblockindex default to true in regtest mode
|
||||||
mempool.setSanityCheck(GetBoolArg("-checkmempool", chainparams.DefaultConsistencyChecks()));
|
mempool.setSanityCheck(GetBoolArg("-checkmempool", chainparams.DefaultConsistencyChecks()));
|
||||||
fCheckBlockIndex = GetBoolArg("-checkblockindex", chainparams.DefaultConsistencyChecks());
|
fCheckBlockIndex = GetBoolArg("-checkblockindex", chainparams.DefaultConsistencyChecks());
|
||||||
Checkpoints::fEnabled = GetBoolArg("-checkpoints", true);
|
fCheckpointsEnabled = GetBoolArg("-checkpoints", true);
|
||||||
|
|
||||||
// -par=0 means autodetect, but nScriptCheckThreads==0 means no concurrency
|
// -par=0 means autodetect, but nScriptCheckThreads==0 means no concurrency
|
||||||
nScriptCheckThreads = GetArg("-par", DEFAULT_SCRIPTCHECK_THREADS);
|
nScriptCheckThreads = GetArg("-par", DEFAULT_SCRIPTCHECK_THREADS);
|
||||||
|
35
src/main.cpp
35
src/main.cpp
@ -56,6 +56,7 @@ bool fHavePruned = false;
|
|||||||
bool fPruneMode = false;
|
bool fPruneMode = false;
|
||||||
bool fIsBareMultisigStd = true;
|
bool fIsBareMultisigStd = true;
|
||||||
bool fCheckBlockIndex = false;
|
bool fCheckBlockIndex = false;
|
||||||
|
bool fCheckpointsEnabled = true;
|
||||||
unsigned int nCoinCacheSize = 5000;
|
unsigned int nCoinCacheSize = 5000;
|
||||||
uint64_t nPruneTarget = 0;
|
uint64_t nPruneTarget = 0;
|
||||||
|
|
||||||
@ -1205,8 +1206,11 @@ CAmount GetBlockValue(int nHeight, const CAmount& nFees)
|
|||||||
|
|
||||||
bool IsInitialBlockDownload()
|
bool IsInitialBlockDownload()
|
||||||
{
|
{
|
||||||
|
const CChainParams& chainParams = Params();
|
||||||
LOCK(cs_main);
|
LOCK(cs_main);
|
||||||
if (fImporting || fReindex || chainActive.Height() < Checkpoints::GetTotalBlocksEstimate())
|
if (fImporting || fReindex)
|
||||||
|
return true;
|
||||||
|
if (fCheckpointsEnabled && chainActive.Height() < Checkpoints::GetTotalBlocksEstimate(chainParams.Checkpoints()))
|
||||||
return true;
|
return true;
|
||||||
static bool lockIBDState = false;
|
static bool lockIBDState = false;
|
||||||
if (lockIBDState)
|
if (lockIBDState)
|
||||||
@ -1710,7 +1714,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool fScriptChecks = pindex->nHeight >= Checkpoints::GetTotalBlocksEstimate();
|
bool fScriptChecks = (!fCheckpointsEnabled || pindex->nHeight >= Checkpoints::GetTotalBlocksEstimate(chainparams.Checkpoints()));
|
||||||
|
|
||||||
// Do not allow blocks that contain transactions which 'overwrite' older transactions,
|
// Do not allow blocks that contain transactions which 'overwrite' older transactions,
|
||||||
// unless those are already completely spent.
|
// unless those are already completely spent.
|
||||||
@ -1955,6 +1959,7 @@ void PruneAndFlush() {
|
|||||||
|
|
||||||
/** Update chainActive and related internal data structures. */
|
/** Update chainActive and related internal data structures. */
|
||||||
void static UpdateTip(CBlockIndex *pindexNew) {
|
void static UpdateTip(CBlockIndex *pindexNew) {
|
||||||
|
const CChainParams& chainParams = Params();
|
||||||
chainActive.SetTip(pindexNew);
|
chainActive.SetTip(pindexNew);
|
||||||
|
|
||||||
// New best block
|
// New best block
|
||||||
@ -1964,7 +1969,7 @@ void static UpdateTip(CBlockIndex *pindexNew) {
|
|||||||
LogPrintf("%s: new best=%s height=%d log2_work=%.8g tx=%lu date=%s progress=%f cache=%u\n", __func__,
|
LogPrintf("%s: new best=%s height=%d log2_work=%.8g tx=%lu date=%s progress=%f cache=%u\n", __func__,
|
||||||
chainActive.Tip()->GetBlockHash().ToString(), chainActive.Height(), log(chainActive.Tip()->nChainWork.getdouble())/log(2.0), (unsigned long)chainActive.Tip()->nChainTx,
|
chainActive.Tip()->GetBlockHash().ToString(), chainActive.Height(), log(chainActive.Tip()->nChainWork.getdouble())/log(2.0), (unsigned long)chainActive.Tip()->nChainTx,
|
||||||
DateTimeStrFormat("%Y-%m-%d %H:%M:%S", chainActive.Tip()->GetBlockTime()),
|
DateTimeStrFormat("%Y-%m-%d %H:%M:%S", chainActive.Tip()->GetBlockTime()),
|
||||||
Checkpoints::GuessVerificationProgress(chainActive.Tip()), (unsigned int)pcoinsTip->GetCacheSize());
|
Checkpoints::GuessVerificationProgress(chainParams.Checkpoints(), chainActive.Tip()), (unsigned int)pcoinsTip->GetCacheSize());
|
||||||
|
|
||||||
cvBlockChange.notify_all();
|
cvBlockChange.notify_all();
|
||||||
|
|
||||||
@ -2248,6 +2253,7 @@ static bool ActivateBestChainStep(CValidationState &state, CBlockIndex *pindexMo
|
|||||||
bool ActivateBestChain(CValidationState &state, CBlock *pblock) {
|
bool ActivateBestChain(CValidationState &state, CBlock *pblock) {
|
||||||
CBlockIndex *pindexNewTip = NULL;
|
CBlockIndex *pindexNewTip = NULL;
|
||||||
CBlockIndex *pindexMostWork = NULL;
|
CBlockIndex *pindexMostWork = NULL;
|
||||||
|
const CChainParams& chainParams = Params();
|
||||||
do {
|
do {
|
||||||
boost::this_thread::interruption_point();
|
boost::this_thread::interruption_point();
|
||||||
|
|
||||||
@ -2272,7 +2278,9 @@ bool ActivateBestChain(CValidationState &state, CBlock *pblock) {
|
|||||||
if (!fInitialDownload) {
|
if (!fInitialDownload) {
|
||||||
uint256 hashNewTip = pindexNewTip->GetBlockHash();
|
uint256 hashNewTip = pindexNewTip->GetBlockHash();
|
||||||
// Relay inventory, but don't relay old inventory during initial block download.
|
// Relay inventory, but don't relay old inventory during initial block download.
|
||||||
int nBlockEstimate = Checkpoints::GetTotalBlocksEstimate();
|
int nBlockEstimate = 0;
|
||||||
|
if (fCheckpointsEnabled)
|
||||||
|
nBlockEstimate = Checkpoints::GetTotalBlocksEstimate(chainParams.Checkpoints());
|
||||||
// Don't relay blocks if pruning -- could cause a peer to try to download, resulting
|
// Don't relay blocks if pruning -- could cause a peer to try to download, resulting
|
||||||
// in a stalled download if the block file is pruned before the request.
|
// in a stalled download if the block file is pruned before the request.
|
||||||
if (nLocalServices & NODE_NETWORK) {
|
if (nLocalServices & NODE_NETWORK) {
|
||||||
@ -2602,7 +2610,8 @@ bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bo
|
|||||||
|
|
||||||
bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& state, CBlockIndex * const pindexPrev)
|
bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& state, CBlockIndex * const pindexPrev)
|
||||||
{
|
{
|
||||||
const Consensus::Params& consensusParams = Params().GetConsensus();
|
const CChainParams& chainParams = Params();
|
||||||
|
const Consensus::Params& consensusParams = chainParams.GetConsensus();
|
||||||
uint256 hash = block.GetHash();
|
uint256 hash = block.GetHash();
|
||||||
if (hash == consensusParams.hashGenesisBlock)
|
if (hash == consensusParams.hashGenesisBlock)
|
||||||
return true;
|
return true;
|
||||||
@ -2612,7 +2621,7 @@ bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& sta
|
|||||||
int nHeight = pindexPrev->nHeight+1;
|
int nHeight = pindexPrev->nHeight+1;
|
||||||
|
|
||||||
// Check proof of work
|
// Check proof of work
|
||||||
if (block.nBits != GetNextWorkRequired(pindexPrev, &block, Params().GetConsensus()))
|
if (block.nBits != GetNextWorkRequired(pindexPrev, &block, consensusParams))
|
||||||
return state.DoS(100, error("%s: incorrect proof of work", __func__),
|
return state.DoS(100, error("%s: incorrect proof of work", __func__),
|
||||||
REJECT_INVALID, "bad-diffbits");
|
REJECT_INVALID, "bad-diffbits");
|
||||||
|
|
||||||
@ -2621,25 +2630,28 @@ bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& sta
|
|||||||
return state.Invalid(error("%s: block's timestamp is too early", __func__),
|
return state.Invalid(error("%s: block's timestamp is too early", __func__),
|
||||||
REJECT_INVALID, "time-too-old");
|
REJECT_INVALID, "time-too-old");
|
||||||
|
|
||||||
|
if(fCheckpointsEnabled)
|
||||||
|
{
|
||||||
// Check that the block chain matches the known block chain up to a checkpoint
|
// Check that the block chain matches the known block chain up to a checkpoint
|
||||||
if (!Checkpoints::CheckBlock(nHeight, hash))
|
if (!Checkpoints::CheckBlock(chainParams.Checkpoints(), nHeight, hash))
|
||||||
return state.DoS(100, error("%s: rejected by checkpoint lock-in at %d", __func__, nHeight),
|
return state.DoS(100, error("%s: rejected by checkpoint lock-in at %d", __func__, nHeight),
|
||||||
REJECT_CHECKPOINT, "checkpoint mismatch");
|
REJECT_CHECKPOINT, "checkpoint mismatch");
|
||||||
|
|
||||||
// Don't accept any forks from the main chain prior to last checkpoint
|
// Don't accept any forks from the main chain prior to last checkpoint
|
||||||
CBlockIndex* pcheckpoint = Checkpoints::GetLastCheckpoint();
|
CBlockIndex* pcheckpoint = Checkpoints::GetLastCheckpoint(chainParams.Checkpoints());
|
||||||
if (pcheckpoint && nHeight < pcheckpoint->nHeight)
|
if (pcheckpoint && nHeight < pcheckpoint->nHeight)
|
||||||
return state.DoS(100, error("%s: forked chain older than last checkpoint (height %d)", __func__, nHeight));
|
return state.DoS(100, error("%s: forked chain older than last checkpoint (height %d)", __func__, nHeight));
|
||||||
|
}
|
||||||
|
|
||||||
// Reject block.nVersion=1 blocks when 95% (75% on testnet) of the network has upgraded:
|
// Reject block.nVersion=1 blocks when 95% (75% on testnet) of the network has upgraded:
|
||||||
if (block.nVersion < 2 && IsSuperMajority(2, pindexPrev, Params().RejectBlockOutdatedMajority()))
|
if (block.nVersion < 2 && IsSuperMajority(2, pindexPrev, consensusParams.nMajorityRejectBlockOutdated))
|
||||||
{
|
{
|
||||||
return state.Invalid(error("%s: rejected nVersion=1 block", __func__),
|
return state.Invalid(error("%s: rejected nVersion=1 block", __func__),
|
||||||
REJECT_OBSOLETE, "bad-version");
|
REJECT_OBSOLETE, "bad-version");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reject block.nVersion=2 blocks when 95% (75% on testnet) of the network has upgraded:
|
// Reject block.nVersion=2 blocks when 95% (75% on testnet) of the network has upgraded:
|
||||||
if (block.nVersion < 3 && IsSuperMajority(3, pindexPrev, Params().RejectBlockOutdatedMajority()))
|
if (block.nVersion < 3 && IsSuperMajority(3, pindexPrev, consensusParams.nMajorityRejectBlockOutdated))
|
||||||
{
|
{
|
||||||
return state.Invalid(error("%s : rejected nVersion=2 block", __func__),
|
return state.Invalid(error("%s : rejected nVersion=2 block", __func__),
|
||||||
REJECT_OBSOLETE, "bad-version");
|
REJECT_OBSOLETE, "bad-version");
|
||||||
@ -3026,6 +3038,7 @@ CBlockIndex * InsertBlockIndex(uint256 hash)
|
|||||||
|
|
||||||
bool static LoadBlockIndexDB()
|
bool static LoadBlockIndexDB()
|
||||||
{
|
{
|
||||||
|
const CChainParams& chainparams = Params();
|
||||||
if (!pblocktree->LoadBlockIndexGuts())
|
if (!pblocktree->LoadBlockIndexGuts())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -3128,7 +3141,7 @@ bool static LoadBlockIndexDB()
|
|||||||
LogPrintf("%s: hashBestChain=%s height=%d date=%s progress=%f\n", __func__,
|
LogPrintf("%s: hashBestChain=%s height=%d date=%s progress=%f\n", __func__,
|
||||||
chainActive.Tip()->GetBlockHash().ToString(), chainActive.Height(),
|
chainActive.Tip()->GetBlockHash().ToString(), chainActive.Height(),
|
||||||
DateTimeStrFormat("%Y-%m-%d %H:%M:%S", chainActive.Tip()->GetBlockTime()),
|
DateTimeStrFormat("%Y-%m-%d %H:%M:%S", chainActive.Tip()->GetBlockTime()),
|
||||||
Checkpoints::GuessVerificationProgress(chainActive.Tip()));
|
Checkpoints::GuessVerificationProgress(chainparams.Checkpoints(), chainActive.Tip()));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -118,6 +118,7 @@ extern int nScriptCheckThreads;
|
|||||||
extern bool fTxIndex;
|
extern bool fTxIndex;
|
||||||
extern bool fIsBareMultisigStd;
|
extern bool fIsBareMultisigStd;
|
||||||
extern bool fCheckBlockIndex;
|
extern bool fCheckBlockIndex;
|
||||||
|
extern bool fCheckpointsEnabled;
|
||||||
extern unsigned int nCoinCacheSize;
|
extern unsigned int nCoinCacheSize;
|
||||||
extern CFeeRate minRelayTxFee;
|
extern CFeeRate minRelayTxFee;
|
||||||
|
|
||||||
|
@ -89,7 +89,7 @@ QDateTime ClientModel::getLastBlockDate() const
|
|||||||
double ClientModel::getVerificationProgress() const
|
double ClientModel::getVerificationProgress() const
|
||||||
{
|
{
|
||||||
LOCK(cs_main);
|
LOCK(cs_main);
|
||||||
return Checkpoints::GuessVerificationProgress(chainActive.Tip());
|
return Checkpoints::GuessVerificationProgress(Params().Checkpoints(), chainActive.Tip());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClientModel::updateTimer()
|
void ClientModel::updateTimer()
|
||||||
|
@ -490,7 +490,7 @@ Value getblockchaininfo(const Array& params, bool fHelp)
|
|||||||
obj.push_back(Pair("headers", pindexBestHeader ? pindexBestHeader->nHeight : -1));
|
obj.push_back(Pair("headers", pindexBestHeader ? pindexBestHeader->nHeight : -1));
|
||||||
obj.push_back(Pair("bestblockhash", chainActive.Tip()->GetBlockHash().GetHex()));
|
obj.push_back(Pair("bestblockhash", chainActive.Tip()->GetBlockHash().GetHex()));
|
||||||
obj.push_back(Pair("difficulty", (double)GetDifficulty()));
|
obj.push_back(Pair("difficulty", (double)GetDifficulty()));
|
||||||
obj.push_back(Pair("verificationprogress", Checkpoints::GuessVerificationProgress(chainActive.Tip())));
|
obj.push_back(Pair("verificationprogress", Checkpoints::GuessVerificationProgress(Params().Checkpoints(), chainActive.Tip())));
|
||||||
obj.push_back(Pair("chainwork", chainActive.Tip()->nChainWork.GetHex()));
|
obj.push_back(Pair("chainwork", chainActive.Tip()->nChainWork.GetHex()));
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
#include "uint256.h"
|
#include "uint256.h"
|
||||||
#include "test/test_bitcoin.h"
|
#include "test/test_bitcoin.h"
|
||||||
|
#include "chainparams.h"
|
||||||
|
|
||||||
#include <boost/test/unit_test.hpp>
|
#include <boost/test/unit_test.hpp>
|
||||||
|
|
||||||
@ -19,21 +20,22 @@ BOOST_FIXTURE_TEST_SUITE(Checkpoints_tests, BasicTestingSetup)
|
|||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(sanity)
|
BOOST_AUTO_TEST_CASE(sanity)
|
||||||
{
|
{
|
||||||
|
const Checkpoints::CCheckpointData& checkpoints = Params(CBaseChainParams::MAIN).Checkpoints();
|
||||||
uint256 p11111 = uint256S("0x0000000069e244f73d78e8fd29ba2fd2ed618bd6fa2ee92559f542fdb26e7c1d");
|
uint256 p11111 = uint256S("0x0000000069e244f73d78e8fd29ba2fd2ed618bd6fa2ee92559f542fdb26e7c1d");
|
||||||
uint256 p134444 = uint256S("0x00000000000005b12ffd4cd315cd34ffd4a594f430ac814c91184a0d42d2b0fe");
|
uint256 p134444 = uint256S("0x00000000000005b12ffd4cd315cd34ffd4a594f430ac814c91184a0d42d2b0fe");
|
||||||
BOOST_CHECK(Checkpoints::CheckBlock(11111, p11111));
|
BOOST_CHECK(Checkpoints::CheckBlock(checkpoints, 11111, p11111));
|
||||||
BOOST_CHECK(Checkpoints::CheckBlock(134444, p134444));
|
BOOST_CHECK(Checkpoints::CheckBlock(checkpoints, 134444, p134444));
|
||||||
|
|
||||||
|
|
||||||
// Wrong hashes at checkpoints should fail:
|
// Wrong hashes at checkpoints should fail:
|
||||||
BOOST_CHECK(!Checkpoints::CheckBlock(11111, p134444));
|
BOOST_CHECK(!Checkpoints::CheckBlock(checkpoints, 11111, p134444));
|
||||||
BOOST_CHECK(!Checkpoints::CheckBlock(134444, p11111));
|
BOOST_CHECK(!Checkpoints::CheckBlock(checkpoints, 134444, p11111));
|
||||||
|
|
||||||
// ... but any hash not at a checkpoint should succeed:
|
// ... but any hash not at a checkpoint should succeed:
|
||||||
BOOST_CHECK(Checkpoints::CheckBlock(11111+1, p134444));
|
BOOST_CHECK(Checkpoints::CheckBlock(checkpoints, 11111+1, p134444));
|
||||||
BOOST_CHECK(Checkpoints::CheckBlock(134444+1, p11111));
|
BOOST_CHECK(Checkpoints::CheckBlock(checkpoints, 134444+1, p11111));
|
||||||
|
|
||||||
BOOST_CHECK(Checkpoints::GetTotalBlocksEstimate() >= 134444);
|
BOOST_CHECK(Checkpoints::GetTotalBlocksEstimate(checkpoints) >= 134444);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_SUITE_END()
|
BOOST_AUTO_TEST_SUITE_END()
|
||||||
|
@ -59,7 +59,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
|
|||||||
uint256 hash;
|
uint256 hash;
|
||||||
|
|
||||||
LOCK(cs_main);
|
LOCK(cs_main);
|
||||||
Checkpoints::fEnabled = false;
|
fCheckpointsEnabled = false;
|
||||||
|
|
||||||
// Simple block creation, nothing special yet:
|
// Simple block creation, nothing special yet:
|
||||||
BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey));
|
BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey));
|
||||||
@ -262,7 +262,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
|
|||||||
BOOST_FOREACH(CTransaction *tx, txFirst)
|
BOOST_FOREACH(CTransaction *tx, txFirst)
|
||||||
delete tx;
|
delete tx;
|
||||||
|
|
||||||
Checkpoints::fEnabled = true;
|
fCheckpointsEnabled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_SUITE_END()
|
BOOST_AUTO_TEST_SUITE_END()
|
||||||
|
@ -1059,6 +1059,7 @@ int CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate)
|
|||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
int64_t nNow = GetTime();
|
int64_t nNow = GetTime();
|
||||||
|
const CChainParams& chainParams = Params();
|
||||||
|
|
||||||
CBlockIndex* pindex = pindexStart;
|
CBlockIndex* pindex = pindexStart;
|
||||||
{
|
{
|
||||||
@ -1070,12 +1071,12 @@ int CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate)
|
|||||||
pindex = chainActive.Next(pindex);
|
pindex = chainActive.Next(pindex);
|
||||||
|
|
||||||
ShowProgress(_("Rescanning..."), 0); // show rescan progress in GUI as dialog or on splashscreen, if -rescan on startup
|
ShowProgress(_("Rescanning..."), 0); // show rescan progress in GUI as dialog or on splashscreen, if -rescan on startup
|
||||||
double dProgressStart = Checkpoints::GuessVerificationProgress(pindex, false);
|
double dProgressStart = Checkpoints::GuessVerificationProgress(chainParams.Checkpoints(), pindex, false);
|
||||||
double dProgressTip = Checkpoints::GuessVerificationProgress(chainActive.Tip(), false);
|
double dProgressTip = Checkpoints::GuessVerificationProgress(chainParams.Checkpoints(), chainActive.Tip(), false);
|
||||||
while (pindex)
|
while (pindex)
|
||||||
{
|
{
|
||||||
if (pindex->nHeight % 100 == 0 && dProgressTip - dProgressStart > 0.0)
|
if (pindex->nHeight % 100 == 0 && dProgressTip - dProgressStart > 0.0)
|
||||||
ShowProgress(_("Rescanning..."), std::max(1, std::min(99, (int)((Checkpoints::GuessVerificationProgress(pindex, false) - dProgressStart) / (dProgressTip - dProgressStart) * 100))));
|
ShowProgress(_("Rescanning..."), std::max(1, std::min(99, (int)((Checkpoints::GuessVerificationProgress(chainParams.Checkpoints(), pindex, false) - dProgressStart) / (dProgressTip - dProgressStart) * 100))));
|
||||||
|
|
||||||
CBlock block;
|
CBlock block;
|
||||||
ReadBlockFromDisk(block, pindex);
|
ReadBlockFromDisk(block, pindex);
|
||||||
@ -1087,7 +1088,7 @@ int CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate)
|
|||||||
pindex = chainActive.Next(pindex);
|
pindex = chainActive.Next(pindex);
|
||||||
if (GetTime() >= nNow + 60) {
|
if (GetTime() >= nNow + 60) {
|
||||||
nNow = GetTime();
|
nNow = GetTime();
|
||||||
LogPrintf("Still rescanning. At block %d. Progress=%f\n", pindex->nHeight, Checkpoints::GuessVerificationProgress(pindex));
|
LogPrintf("Still rescanning. At block %d. Progress=%f\n", pindex->nHeight, Checkpoints::GuessVerificationProgress(chainParams.Checkpoints(), pindex));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ShowProgress(_("Rescanning..."), 100); // hide progress dialog in GUI
|
ShowProgress(_("Rescanning..."), 100); // hide progress dialog in GUI
|
||||||
|
Loading…
Reference in New Issue
Block a user