Changeset View
Changeset View
Standalone View
Standalone View
src/validation.cpp
Show First 20 Lines • Show All 832 Lines • ▼ Show 20 Lines | Amount GetBlockSubsidy(int nHeight, const Consensus::Params &consensusParams) { | ||||
} | } | ||||
Amount nSubsidy = 50 * COIN; | Amount nSubsidy = 50 * COIN; | ||||
// Subsidy is cut in half every 210,000 blocks which will occur | // Subsidy is cut in half every 210,000 blocks which will occur | ||||
// approximately every 4 years. | // approximately every 4 years. | ||||
return ((nSubsidy / SATOSHI) >> halvings) * SATOSHI; | return ((nSubsidy / SATOSHI) >> halvings) * SATOSHI; | ||||
} | } | ||||
bool IsInitialBlockDownload() { | // Note that though this is marked const, we may end up modifying | ||||
// Once this function has returned false, it must remain false. | // `m_cached_finished_ibd`, which is a performance-related implementation | ||||
static std::atomic<bool> latchToFalse{false}; | // detail. This function must be marked `const` so that `CValidationInterface` | ||||
// clients (which are given a `const CChainState*`) can call it. | |||||
// | |||||
bool CChainState::IsInitialBlockDownload() const { | |||||
// Optimization: pre-test latch before taking the lock. | // Optimization: pre-test latch before taking the lock. | ||||
if (latchToFalse.load(std::memory_order_relaxed)) { | if (m_cached_finished_ibd.load(std::memory_order_relaxed)) { | ||||
return false; | return false; | ||||
} | } | ||||
LOCK(cs_main); | LOCK(cs_main); | ||||
if (latchToFalse.load(std::memory_order_relaxed)) { | if (m_cached_finished_ibd.load(std::memory_order_relaxed)) { | ||||
return false; | return false; | ||||
} | } | ||||
if (fImporting || fReindex) { | if (fImporting || fReindex) { | ||||
return true; | return true; | ||||
} | } | ||||
if (::ChainActive().Tip() == nullptr) { | if (m_chain.Tip() == nullptr) { | ||||
return true; | return true; | ||||
} | } | ||||
if (::ChainActive().Tip()->nChainWork < nMinimumChainWork) { | if (m_chain.Tip()->nChainWork < nMinimumChainWork) { | ||||
return true; | return true; | ||||
} | } | ||||
if (::ChainActive().Tip()->GetBlockTime() < (GetTime() - nMaxTipAge)) { | if (m_chain.Tip()->GetBlockTime() < (GetTime() - nMaxTipAge)) { | ||||
return true; | return true; | ||||
} | } | ||||
LogPrintf("Leaving InitialBlockDownload (latching to false)\n"); | LogPrintf("Leaving InitialBlockDownload (latching to false)\n"); | ||||
latchToFalse.store(true, std::memory_order_relaxed); | m_cached_finished_ibd.store(true, std::memory_order_relaxed); | ||||
return false; | return false; | ||||
} | } | ||||
CBlockIndex const *pindexBestForkTip = nullptr; | CBlockIndex const *pindexBestForkTip = nullptr; | ||||
CBlockIndex const *pindexBestForkBase = nullptr; | CBlockIndex const *pindexBestForkBase = nullptr; | ||||
static void AlertNotify(const std::string &strMessage) { | static void AlertNotify(const std::string &strMessage) { | ||||
uiInterface.NotifyAlertChanged(); | uiInterface.NotifyAlertChanged(); | ||||
Show All 15 Lines | static void AlertNotify(const std::string &strMessage) { | ||||
t.detach(); | t.detach(); | ||||
} | } | ||||
static void CheckForkWarningConditions() EXCLUSIVE_LOCKS_REQUIRED(cs_main) { | static void CheckForkWarningConditions() EXCLUSIVE_LOCKS_REQUIRED(cs_main) { | ||||
AssertLockHeld(cs_main); | AssertLockHeld(cs_main); | ||||
// Before we get past initial download, we cannot reliably alert about forks | // Before we get past initial download, we cannot reliably alert about forks | ||||
// (we assume we don't get stuck on a fork before finishing our initial | // (we assume we don't get stuck on a fork before finishing our initial | ||||
// sync) | // sync) | ||||
if (IsInitialBlockDownload()) { | if (::ChainstateActive().IsInitialBlockDownload()) { | ||||
return; | return; | ||||
} | } | ||||
// If our best fork is no longer within 72 blocks (+/- 12 hours if no one | // If our best fork is no longer within 72 blocks (+/- 12 hours if no one | ||||
// mines it) of our head, drop it | // mines it) of our head, drop it | ||||
if (pindexBestForkTip && | if (pindexBestForkTip && | ||||
::ChainActive().Height() - pindexBestForkTip->nHeight >= 72) { | ::ChainActive().Height() - pindexBestForkTip->nHeight >= 72) { | ||||
pindexBestForkTip = nullptr; | pindexBestForkTip = nullptr; | ||||
▲ Show 20 Lines • Show All 1,886 Lines • ▼ Show 20 Lines | static void NotifyHeaderTip() LOCKS_EXCLUDED(cs_main) { | ||||
static CBlockIndex *pindexHeaderOld = nullptr; | static CBlockIndex *pindexHeaderOld = nullptr; | ||||
CBlockIndex *pindexHeader = nullptr; | CBlockIndex *pindexHeader = nullptr; | ||||
{ | { | ||||
LOCK(cs_main); | LOCK(cs_main); | ||||
pindexHeader = pindexBestHeader; | pindexHeader = pindexBestHeader; | ||||
if (pindexHeader != pindexHeaderOld) { | if (pindexHeader != pindexHeaderOld) { | ||||
fNotify = true; | fNotify = true; | ||||
fInitialBlockDownload = IsInitialBlockDownload(); | fInitialBlockDownload = | ||||
::ChainstateActive().IsInitialBlockDownload(); | |||||
pindexHeaderOld = pindexHeader; | pindexHeaderOld = pindexHeader; | ||||
} | } | ||||
} | } | ||||
// Send block tip changed notifications without cs_main | // Send block tip changed notifications without cs_main | ||||
if (fNotify) { | if (fNotify) { | ||||
uiInterface.NotifyHeaderTip(fInitialBlockDownload, pindexHeader); | uiInterface.NotifyHeaderTip(fInitialBlockDownload, pindexHeader); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 1,550 Lines • ▼ Show 20 Lines | static void FindFilesToPrune(std::set<int> &setFilesToPrune, | ||||
int count = 0; | int count = 0; | ||||
if (nCurrentUsage + nBuffer >= nPruneTarget) { | if (nCurrentUsage + nBuffer >= nPruneTarget) { | ||||
// On a prune event, the chainstate DB is flushed. | // On a prune event, the chainstate DB is flushed. | ||||
// To avoid excessive prune events negating the benefit of high dbcache | // To avoid excessive prune events negating the benefit of high dbcache | ||||
// values, we should not prune too rapidly. | // values, we should not prune too rapidly. | ||||
// So when pruning in IBD, increase the buffer a bit to avoid a re-prune | // So when pruning in IBD, increase the buffer a bit to avoid a re-prune | ||||
// too soon. | // too soon. | ||||
if (IsInitialBlockDownload()) { | if (::ChainstateActive().IsInitialBlockDownload()) { | ||||
// Since this is only relevant during IBD, we use a fixed 10% | // Since this is only relevant during IBD, we use a fixed 10% | ||||
nBuffer += nPruneTarget / 10; | nBuffer += nPruneTarget / 10; | ||||
} | } | ||||
for (int fileNumber = 0; fileNumber < nLastBlockFile; fileNumber++) { | for (int fileNumber = 0; fileNumber < nLastBlockFile; fileNumber++) { | ||||
nBytesToPrune = vinfoBlockFile[fileNumber].nSize + | nBytesToPrune = vinfoBlockFile[fileNumber].nSize + | ||||
vinfoBlockFile[fileNumber].nUndoSize; | vinfoBlockFile[fileNumber].nUndoSize; | ||||
▲ Show 20 Lines • Show All 1,359 Lines • Show Last 20 Lines |