Changeset View
Changeset View
Standalone View
Standalone View
src/validation.cpp
Show First 20 Lines • Show All 57 Lines • ▼ Show 20 Lines | |||||
#define MICRO 0.000001 | #define MICRO 0.000001 | ||||
#define MILLI 0.001 | #define MILLI 0.001 | ||||
namespace { | namespace { | ||||
BlockManager g_blockman; | BlockManager g_blockman; | ||||
} // namespace | } // namespace | ||||
static CChainState g_chainstate(g_blockman); | std::unique_ptr<CChainState> g_chainstate; | ||||
CChainState &ChainstateActive() { | CChainState &ChainstateActive() { | ||||
return g_chainstate; | assert(g_chainstate); | ||||
return *g_chainstate; | |||||
} | } | ||||
CChain &ChainActive() { | CChain &ChainActive() { | ||||
return g_chainstate.m_chain; | assert(g_chainstate); | ||||
return g_chainstate->m_chain; | |||||
} | } | ||||
/** | /** | ||||
* Global state | * Global state | ||||
* | * | ||||
* Mutex to guard access to validation specific variables, such as reading | * Mutex to guard access to validation specific variables, such as reading | ||||
* or changing the chainstate. | * or changing the chainstate. | ||||
* | * | ||||
▲ Show 20 Lines • Show All 77 Lines • ▼ Show 20 Lines | for (const BlockHash &hash : locator.vHave) { | ||||
if (pindex->GetAncestor(chain.Height()) == chain.Tip()) { | if (pindex->GetAncestor(chain.Height()) == chain.Tip()) { | ||||
return chain.Tip(); | return chain.Tip(); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
return chain.Genesis(); | return chain.Genesis(); | ||||
} | } | ||||
std::unique_ptr<CCoinsViewDB> pcoinsdbview; | |||||
std::unique_ptr<CCoinsViewCache> pcoinsTip; | |||||
std::unique_ptr<CBlockTreeDB> pblocktree; | std::unique_ptr<CBlockTreeDB> pblocktree; | ||||
// See definition for documentation | // See definition for documentation | ||||
static void FindFilesToPruneManual(std::set<int> &setFilesToPrune, | static void FindFilesToPruneManual(std::set<int> &setFilesToPrune, | ||||
int nManualPruneHeight); | int nManualPruneHeight); | ||||
static void FindFilesToPrune(std::set<int> &setFilesToPrune, | static void FindFilesToPrune(std::set<int> &setFilesToPrune, | ||||
uint64_t nPruneAfterHeight); | uint64_t nPruneAfterHeight); | ||||
static uint32_t GetNextBlockScriptFlags(const Consensus::Params ¶ms, | static uint32_t GetNextBlockScriptFlags(const Consensus::Params ¶ms, | ||||
▲ Show 20 Lines • Show All 228 Lines • ▼ Show 20 Lines | for (const CTxIn &txin : tx.vin) { | ||||
// Do all inputs exist? | // Do all inputs exist? | ||||
for (const CTxIn &txin : tx.vin) { | for (const CTxIn &txin : tx.vin) { | ||||
if (!coins_cache.HaveCoinInCache(txin.prevout)) { | if (!coins_cache.HaveCoinInCache(txin.prevout)) { | ||||
coins_to_uncache.push_back(txin.prevout); | coins_to_uncache.push_back(txin.prevout); | ||||
} | } | ||||
// Note: this call may add txin.prevout to the coins cache | // Note: this call may add txin.prevout to the coins cache | ||||
// (pcoinsTip.cacheCoins) by way of FetchCoin(). It should be | // (CoinsTip().cacheCoins) by way of FetchCoin(). It should be | ||||
// removed later (via coins_to_uncache) if this tx turns out to be | // removed later (via coins_to_uncache) if this tx turns out to be | ||||
// invalid. | // invalid. | ||||
if (!view.HaveCoin(txin.prevout)) { | if (!view.HaveCoin(txin.prevout)) { | ||||
// Are inputs missing because we already have the tx? | // Are inputs missing because we already have the tx? | ||||
for (size_t out = 0; out < tx.vout.size(); out++) { | for (size_t out = 0; out < tx.vout.size(); out++) { | ||||
// Optimistically just do efficient check of cache for | // Optimistically just do efficient check of cache for | ||||
// outputs. | // outputs. | ||||
if (coins_cache.HaveCoinInCache(COutPoint(txid, out))) { | if (coins_cache.HaveCoinInCache(COutPoint(txid, out))) { | ||||
▲ Show 20 Lines • Show All 310 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; | ||||
} | } | ||||
CoinsViews::CoinsViews(std::string ldb_name, size_t cache_size_bytes, | |||||
bool in_memory, bool should_wipe) | |||||
: m_dbview(GetDataDir() / ldb_name, cache_size_bytes, in_memory, | |||||
should_wipe), | |||||
m_catcherview(&m_dbview) {} | |||||
void CoinsViews::InitCache() { | |||||
m_cacheview = std::make_unique<CCoinsViewCache>(&m_catcherview); | |||||
} | |||||
// NOTE: for now m_blockman is set to a global, but this will be changed | |||||
// in a future commit. | |||||
CChainState::CChainState() : m_blockman(g_blockman) {} | |||||
void CChainState::InitCoinsDB(size_t cache_size_bytes, bool in_memory, | |||||
bool should_wipe, std::string leveldb_name) { | |||||
m_coins_views = std::make_unique<CoinsViews>(leveldb_name, cache_size_bytes, | |||||
in_memory, should_wipe); | |||||
} | |||||
void CChainState::InitCoinsCache() { | |||||
assert(m_coins_views != nullptr); | |||||
m_coins_views->InitCache(); | |||||
} | |||||
// Note that though this is marked const, we may end up modifying | // Note that though this is marked const, we may end up modifying | ||||
// `m_cached_finished_ibd`, which is a performance-related implementation | // `m_cached_finished_ibd`, which is a performance-related implementation | ||||
// detail. This function must be marked `const` so that `CValidationInterface` | // detail. This function must be marked `const` so that `CValidationInterface` | ||||
// clients (which are given a `const CChainState*`) can call it. | // clients (which are given a `const CChainState*`) can call it. | ||||
// | // | ||||
bool CChainState::IsInitialBlockDownload() const { | bool CChainState::IsInitialBlockDownload() const { | ||||
// Optimization: pre-test latch before taking the lock. | // Optimization: pre-test latch before taking the lock. | ||||
if (m_cached_finished_ibd.load(std::memory_order_relaxed)) { | if (m_cached_finished_ibd.load(std::memory_order_relaxed)) { | ||||
▲ Show 20 Lines • Show All 1,094 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
bool CChainState::FlushStateToDisk(const CChainParams &chainparams, | bool CChainState::FlushStateToDisk(const CChainParams &chainparams, | ||||
BlockValidationState &state, | BlockValidationState &state, | ||||
FlushStateMode mode, | FlushStateMode mode, | ||||
int nManualPruneHeight) { | int nManualPruneHeight) { | ||||
int64_t nMempoolUsage = g_mempool.DynamicMemoryUsage(); | int64_t nMempoolUsage = g_mempool.DynamicMemoryUsage(); | ||||
LOCK(cs_main); | LOCK(cs_main); | ||||
assert(this->CanFlushToDisk()); | |||||
static int64_t nLastWrite = 0; | static int64_t nLastWrite = 0; | ||||
static int64_t nLastFlush = 0; | static int64_t nLastFlush = 0; | ||||
std::set<int> setFilesToPrune; | std::set<int> setFilesToPrune; | ||||
bool full_flush_completed = false; | bool full_flush_completed = false; | ||||
try { | try { | ||||
{ | { | ||||
bool fFlushForPrune = false; | bool fFlushForPrune = false; | ||||
bool fDoFullFlush = false; | bool fDoFullFlush = false; | ||||
▲ Show 20 Lines • Show All 3,882 Lines • Show Last 20 Lines |