|
|
@ -2139,6 +2139,7 @@ enum FlushStateMode { |
|
|
|
* or always and in all cases if we're in prune mode and are deleting files. |
|
|
|
* or always and in all cases if we're in prune mode and are deleting files. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
bool static FlushStateToDisk(CValidationState &state, FlushStateMode mode) { |
|
|
|
bool static FlushStateToDisk(CValidationState &state, FlushStateMode mode) { |
|
|
|
|
|
|
|
const CChainParams& chainparams = Params(); |
|
|
|
LOCK2(cs_main, cs_LastBlockFile); |
|
|
|
LOCK2(cs_main, cs_LastBlockFile); |
|
|
|
static int64_t nLastWrite = 0; |
|
|
|
static int64_t nLastWrite = 0; |
|
|
|
static int64_t nLastFlush = 0; |
|
|
|
static int64_t nLastFlush = 0; |
|
|
@ -2147,7 +2148,7 @@ bool static FlushStateToDisk(CValidationState &state, FlushStateMode mode) { |
|
|
|
bool fFlushForPrune = false; |
|
|
|
bool fFlushForPrune = false; |
|
|
|
try { |
|
|
|
try { |
|
|
|
if (fPruneMode && fCheckForPruning && !fReindex) { |
|
|
|
if (fPruneMode && fCheckForPruning && !fReindex) { |
|
|
|
FindFilesToPrune(setFilesToPrune); |
|
|
|
FindFilesToPrune(setFilesToPrune, chainparams.PruneAfterHeight()); |
|
|
|
fCheckForPruning = false; |
|
|
|
fCheckForPruning = false; |
|
|
|
if (!setFilesToPrune.empty()) { |
|
|
|
if (!setFilesToPrune.empty()) { |
|
|
|
fFlushForPrune = true; |
|
|
|
fFlushForPrune = true; |
|
|
@ -2347,8 +2348,8 @@ static int64_t nTimePostConnect = 0; |
|
|
|
* Connect a new block to chainActive. pblock is either NULL or a pointer to a CBlock |
|
|
|
* Connect a new block to chainActive. pblock is either NULL or a pointer to a CBlock |
|
|
|
* corresponding to pindexNew, to bypass loading it again from disk. |
|
|
|
* corresponding to pindexNew, to bypass loading it again from disk. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, const CBlock *pblock) { |
|
|
|
bool static ConnectTip(CValidationState& state, const CChainParams& chainparams, CBlockIndex* pindexNew, const CBlock* pblock) |
|
|
|
const CChainParams& chainparams = Params(); |
|
|
|
{ |
|
|
|
assert(pindexNew->pprev == chainActive.Tip()); |
|
|
|
assert(pindexNew->pprev == chainActive.Tip()); |
|
|
|
mempool.check(pcoinsTip); |
|
|
|
mempool.check(pcoinsTip); |
|
|
|
// Read block from disk.
|
|
|
|
// Read block from disk.
|
|
|
@ -2480,8 +2481,8 @@ static void PruneBlockIndexCandidates() { |
|
|
|
* Try to make some progress towards making pindexMostWork the active block. |
|
|
|
* Try to make some progress towards making pindexMostWork the active block. |
|
|
|
* pblock is either NULL or a pointer to a CBlock corresponding to pindexMostWork. |
|
|
|
* pblock is either NULL or a pointer to a CBlock corresponding to pindexMostWork. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
static bool ActivateBestChainStep(CValidationState &state, CBlockIndex *pindexMostWork, const CBlock *pblock) { |
|
|
|
static bool ActivateBestChainStep(CValidationState& state, const CChainParams& chainparams, CBlockIndex* pindexMostWork, const CBlock* pblock) |
|
|
|
const CChainParams& chainparams = Params(); |
|
|
|
{ |
|
|
|
AssertLockHeld(cs_main); |
|
|
|
AssertLockHeld(cs_main); |
|
|
|
bool fInvalidFound = false; |
|
|
|
bool fInvalidFound = false; |
|
|
|
const CBlockIndex *pindexOldTip = chainActive.Tip(); |
|
|
|
const CBlockIndex *pindexOldTip = chainActive.Tip(); |
|
|
@ -2514,7 +2515,7 @@ static bool ActivateBestChainStep(CValidationState &state, CBlockIndex *pindexMo |
|
|
|
|
|
|
|
|
|
|
|
// Connect new blocks.
|
|
|
|
// Connect new blocks.
|
|
|
|
BOOST_REVERSE_FOREACH(CBlockIndex *pindexConnect, vpindexToConnect) { |
|
|
|
BOOST_REVERSE_FOREACH(CBlockIndex *pindexConnect, vpindexToConnect) { |
|
|
|
if (!ConnectTip(state, pindexConnect, pindexConnect == pindexMostWork ? pblock : NULL)) { |
|
|
|
if (!ConnectTip(state, chainparams, pindexConnect, pindexConnect == pindexMostWork ? pblock : NULL)) { |
|
|
|
if (state.IsInvalid()) { |
|
|
|
if (state.IsInvalid()) { |
|
|
|
// The block violates a consensus rule.
|
|
|
|
// The block violates a consensus rule.
|
|
|
|
if (!state.CorruptionPossible()) |
|
|
|
if (!state.CorruptionPossible()) |
|
|
@ -2555,10 +2556,10 @@ static bool ActivateBestChainStep(CValidationState &state, CBlockIndex *pindexMo |
|
|
|
* or an activated best chain. pblock is either NULL or a pointer to a block |
|
|
|
* or an activated best chain. pblock is either NULL or a pointer to a block |
|
|
|
* that is already loaded (to avoid loading it again from disk). |
|
|
|
* that is already loaded (to avoid loading it again from disk). |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
bool ActivateBestChain(CValidationState &state, const CBlock *pblock) { |
|
|
|
bool ActivateBestChain(CValidationState& state, const CChainParams& chainparams, const 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(); |
|
|
|
|
|
|
|
|
|
|
@ -2571,7 +2572,7 @@ bool ActivateBestChain(CValidationState &state, const CBlock *pblock) { |
|
|
|
if (pindexMostWork == NULL || pindexMostWork == chainActive.Tip()) |
|
|
|
if (pindexMostWork == NULL || pindexMostWork == chainActive.Tip()) |
|
|
|
return true; |
|
|
|
return true; |
|
|
|
|
|
|
|
|
|
|
|
if (!ActivateBestChainStep(state, pindexMostWork, pblock && pblock->GetHash() == pindexMostWork->GetBlockHash() ? pblock : NULL)) |
|
|
|
if (!ActivateBestChainStep(state, chainparams, pindexMostWork, pblock && pblock->GetHash() == pindexMostWork->GetBlockHash() ? pblock : NULL)) |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
|
|
|
|
|
|
|
|
pindexNewTip = chainActive.Tip(); |
|
|
|
pindexNewTip = chainActive.Tip(); |
|
|
@ -3050,9 +3051,9 @@ static bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state |
|
|
|
return true; |
|
|
|
return true; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
bool AcceptBlock(const CBlock& block, CValidationState& state, CBlockIndex** ppindex, bool fRequested, CDiskBlockPos* dbp) |
|
|
|
/** Store block on disk. If dbp is non-NULL, the file is known to already reside on disk */ |
|
|
|
|
|
|
|
static bool AcceptBlock(const CBlock& block, CValidationState& state, const CChainParams& chainparams, CBlockIndex** ppindex, bool fRequested, CDiskBlockPos* dbp) |
|
|
|
{ |
|
|
|
{ |
|
|
|
const CChainParams& chainparams = Params(); |
|
|
|
|
|
|
|
AssertLockHeld(cs_main); |
|
|
|
AssertLockHeld(cs_main); |
|
|
|
|
|
|
|
|
|
|
|
CBlockIndex *&pindex = *ppindex; |
|
|
|
CBlockIndex *&pindex = *ppindex; |
|
|
@ -3142,7 +3143,7 @@ bool ProcessNewBlock(CValidationState& state, const CChainParams& chainparams, c |
|
|
|
|
|
|
|
|
|
|
|
// Store to disk
|
|
|
|
// Store to disk
|
|
|
|
CBlockIndex *pindex = NULL; |
|
|
|
CBlockIndex *pindex = NULL; |
|
|
|
bool ret = AcceptBlock(*pblock, state, &pindex, fRequested, dbp); |
|
|
|
bool ret = AcceptBlock(*pblock, state, chainparams, &pindex, fRequested, dbp); |
|
|
|
if (pindex && pfrom) { |
|
|
|
if (pindex && pfrom) { |
|
|
|
mapBlockSource[pindex->GetBlockHash()] = pfrom->GetId(); |
|
|
|
mapBlockSource[pindex->GetBlockHash()] = pfrom->GetId(); |
|
|
|
} |
|
|
|
} |
|
|
@ -3151,7 +3152,7 @@ bool ProcessNewBlock(CValidationState& state, const CChainParams& chainparams, c |
|
|
|
return error("%s: AcceptBlock FAILED", __func__); |
|
|
|
return error("%s: AcceptBlock FAILED", __func__); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (!ActivateBestChain(state, pblock)) |
|
|
|
if (!ActivateBestChain(state, chainparams, pblock)) |
|
|
|
return error("%s: ActivateBestChain failed", __func__); |
|
|
|
return error("%s: ActivateBestChain failed", __func__); |
|
|
|
|
|
|
|
|
|
|
|
return true; |
|
|
|
return true; |
|
|
@ -3241,13 +3242,13 @@ void UnlinkPrunedFiles(std::set<int>& setFilesToPrune) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* Calculate the block/rev files that should be deleted to remain under target*/ |
|
|
|
/* Calculate the block/rev files that should be deleted to remain under target*/ |
|
|
|
void FindFilesToPrune(std::set<int>& setFilesToPrune) |
|
|
|
void FindFilesToPrune(std::set<int>& setFilesToPrune, uint64_t nPruneAfterHeight) |
|
|
|
{ |
|
|
|
{ |
|
|
|
LOCK2(cs_main, cs_LastBlockFile); |
|
|
|
LOCK2(cs_main, cs_LastBlockFile); |
|
|
|
if (chainActive.Tip() == NULL || nPruneTarget == 0) { |
|
|
|
if (chainActive.Tip() == NULL || nPruneTarget == 0) { |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
if (chainActive.Tip()->nHeight <= Params().PruneAfterHeight()) { |
|
|
|
if (chainActive.Tip()->nHeight <= nPruneAfterHeight) { |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -3475,9 +3476,8 @@ CVerifyDB::~CVerifyDB() |
|
|
|
uiInterface.ShowProgress("", 100); |
|
|
|
uiInterface.ShowProgress("", 100); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
bool CVerifyDB::VerifyDB(CCoinsView *coinsview, int nCheckLevel, int nCheckDepth) |
|
|
|
bool CVerifyDB::VerifyDB(const CChainParams& chainparams, CCoinsView *coinsview, int nCheckLevel, int nCheckDepth) |
|
|
|
{ |
|
|
|
{ |
|
|
|
const CChainParams& chainparams = Params(); |
|
|
|
|
|
|
|
LOCK(cs_main); |
|
|
|
LOCK(cs_main); |
|
|
|
if (chainActive.Tip() == NULL || chainActive.Tip()->pprev == NULL) |
|
|
|
if (chainActive.Tip() == NULL || chainActive.Tip()->pprev == NULL) |
|
|
|
return true; |
|
|
|
return true; |
|
|
@ -3593,9 +3593,8 @@ bool LoadBlockIndex() |
|
|
|
return true; |
|
|
|
return true; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool InitBlockIndex(const CChainParams& chainparams) |
|
|
|
bool InitBlockIndex() { |
|
|
|
{ |
|
|
|
const CChainParams& chainparams = Params(); |
|
|
|
|
|
|
|
LOCK(cs_main); |
|
|
|
LOCK(cs_main); |
|
|
|
|
|
|
|
|
|
|
|
// Initialize global variables that cannot be constructed at startup.
|
|
|
|
// Initialize global variables that cannot be constructed at startup.
|
|
|
@ -3613,7 +3612,7 @@ bool InitBlockIndex() { |
|
|
|
// Only add the genesis block if not reindexing (in which case we reuse the one already on disk)
|
|
|
|
// Only add the genesis block if not reindexing (in which case we reuse the one already on disk)
|
|
|
|
if (!fReindex) { |
|
|
|
if (!fReindex) { |
|
|
|
try { |
|
|
|
try { |
|
|
|
CBlock &block = const_cast<CBlock&>(Params().GenesisBlock()); |
|
|
|
CBlock &block = const_cast<CBlock&>(chainparams.GenesisBlock()); |
|
|
|
// Start new block file
|
|
|
|
// Start new block file
|
|
|
|
unsigned int nBlockSize = ::GetSerializeSize(block, SER_DISK, CLIENT_VERSION); |
|
|
|
unsigned int nBlockSize = ::GetSerializeSize(block, SER_DISK, CLIENT_VERSION); |
|
|
|
CDiskBlockPos blockPos; |
|
|
|
CDiskBlockPos blockPos; |
|
|
@ -3625,7 +3624,7 @@ bool InitBlockIndex() { |
|
|
|
CBlockIndex *pindex = AddToBlockIndex(block); |
|
|
|
CBlockIndex *pindex = AddToBlockIndex(block); |
|
|
|
if (!ReceivedBlockTransactions(block, state, pindex, blockPos)) |
|
|
|
if (!ReceivedBlockTransactions(block, state, pindex, blockPos)) |
|
|
|
return error("LoadBlockIndex(): genesis block not accepted"); |
|
|
|
return error("LoadBlockIndex(): genesis block not accepted"); |
|
|
|
if (!ActivateBestChain(state, &block)) |
|
|
|
if (!ActivateBestChain(state, chainparams, &block)) |
|
|
|
return error("LoadBlockIndex(): genesis block cannot be activated"); |
|
|
|
return error("LoadBlockIndex(): genesis block cannot be activated"); |
|
|
|
// Force a chainstate write so that when we VerifyDB in a moment, it doesn't check stale data
|
|
|
|
// Force a chainstate write so that when we VerifyDB in a moment, it doesn't check stale data
|
|
|
|
return FlushStateToDisk(state, FLUSH_STATE_ALWAYS); |
|
|
|
return FlushStateToDisk(state, FLUSH_STATE_ALWAYS); |
|
|
@ -3637,11 +3636,8 @@ bool InitBlockIndex() { |
|
|
|
return true; |
|
|
|
return true; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool LoadExternalBlockFile(const CChainParams& chainparams, FILE* fileIn, CDiskBlockPos *dbp) |
|
|
|
|
|
|
|
|
|
|
|
bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp) |
|
|
|
|
|
|
|
{ |
|
|
|
{ |
|
|
|
const CChainParams& chainparams = Params(); |
|
|
|
|
|
|
|
// Map of disk positions for blocks with unknown parent (only used for reindex)
|
|
|
|
// Map of disk positions for blocks with unknown parent (only used for reindex)
|
|
|
|
static std::multimap<uint256, CDiskBlockPos> mapBlocksUnknownParent; |
|
|
|
static std::multimap<uint256, CDiskBlockPos> mapBlocksUnknownParent; |
|
|
|
int64_t nStart = GetTimeMillis(); |
|
|
|
int64_t nStart = GetTimeMillis(); |
|
|
@ -3661,10 +3657,10 @@ bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp) |
|
|
|
try { |
|
|
|
try { |
|
|
|
// locate a header
|
|
|
|
// locate a header
|
|
|
|
unsigned char buf[MESSAGE_START_SIZE]; |
|
|
|
unsigned char buf[MESSAGE_START_SIZE]; |
|
|
|
blkdat.FindByte(Params().MessageStart()[0]); |
|
|
|
blkdat.FindByte(chainparams.MessageStart()[0]); |
|
|
|
nRewind = blkdat.GetPos()+1; |
|
|
|
nRewind = blkdat.GetPos()+1; |
|
|
|
blkdat >> FLATDATA(buf); |
|
|
|
blkdat >> FLATDATA(buf); |
|
|
|
if (memcmp(buf, Params().MessageStart(), MESSAGE_START_SIZE)) |
|
|
|
if (memcmp(buf, chainparams.MessageStart(), MESSAGE_START_SIZE)) |
|
|
|
continue; |
|
|
|
continue; |
|
|
|
// read size
|
|
|
|
// read size
|
|
|
|
blkdat >> nSize; |
|
|
|
blkdat >> nSize; |
|
|
@ -4058,7 +4054,7 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam |
|
|
|
// best equivalent proof of work) than the best header chain we know about.
|
|
|
|
// best equivalent proof of work) than the best header chain we know about.
|
|
|
|
send = mi->second->IsValid(BLOCK_VALID_SCRIPTS) && (pindexBestHeader != NULL) && |
|
|
|
send = mi->second->IsValid(BLOCK_VALID_SCRIPTS) && (pindexBestHeader != NULL) && |
|
|
|
(pindexBestHeader->GetBlockTime() - mi->second->GetBlockTime() < nOneMonth) && |
|
|
|
(pindexBestHeader->GetBlockTime() - mi->second->GetBlockTime() < nOneMonth) && |
|
|
|
(GetBlockProofEquivalentTime(*pindexBestHeader, *mi->second, *pindexBestHeader, Params().GetConsensus()) < nOneMonth); |
|
|
|
(GetBlockProofEquivalentTime(*pindexBestHeader, *mi->second, *pindexBestHeader, consensusParams) < nOneMonth); |
|
|
|
if (!send) { |
|
|
|
if (!send) { |
|
|
|
LogPrintf("%s: ignoring request from peer=%i for old block that isn't in the main chain\n", __func__, pfrom->GetId()); |
|
|
|
LogPrintf("%s: ignoring request from peer=%i for old block that isn't in the main chain\n", __func__, pfrom->GetId()); |
|
|
|
} |
|
|
|
} |
|
|
@ -4932,7 +4928,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, |
|
|
|
uint256 alertHash = alert.GetHash(); |
|
|
|
uint256 alertHash = alert.GetHash(); |
|
|
|
if (pfrom->setKnown.count(alertHash) == 0) |
|
|
|
if (pfrom->setKnown.count(alertHash) == 0) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (alert.ProcessAlert(Params().AlertKey())) |
|
|
|
if (alert.ProcessAlert(chainparams.AlertKey())) |
|
|
|
{ |
|
|
|
{ |
|
|
|
// Relay
|
|
|
|
// Relay
|
|
|
|
pfrom->setKnown.insert(alertHash); |
|
|
|
pfrom->setKnown.insert(alertHash); |
|
|
|