refactoring: FlushStateToDisk -> CChainState

Also renames global methods for clarity:

- ::FlushStateToDisk() -> CChainState::ForceFlushStateToDisk()
  - This performs an unconditional flush.

- ::PruneAndFlush() -> CChainState::PruneAndFlush()
This commit is contained in:
James O'Beirne 2019-03-27 12:07:52 -04:00
parent 4d6688603b
commit 3ccbc376dd
4 changed files with 52 additions and 35 deletions

View file

@ -259,7 +259,7 @@ void Shutdown(InitInterfaces& interfaces)
// FlushStateToDisk generates a ChainStateFlushed callback, which we should avoid missing
if (pcoinsTip != nullptr) {
FlushStateToDisk();
::ChainstateActive().ForceFlushStateToDisk();
}
// After there are no more peers/RPC left to give us new data which may generate
@ -275,7 +275,7 @@ void Shutdown(InitInterfaces& interfaces)
{
LOCK(cs_main);
if (pcoinsTip != nullptr) {
FlushStateToDisk();
::ChainstateActive().ForceFlushStateToDisk();
}
pcoinsTip.reset();
pcoinscatcher.reset();
@ -1692,7 +1692,7 @@ bool AppInitMain(InitInterfaces& interfaces)
nLocalServices = ServiceFlags(nLocalServices & ~NODE_NETWORK);
if (!fReindex) {
uiInterface.InitMessage(_("Pruning blockstore..."));
PruneAndFlush();
::ChainstateActive().PruneAndFlush();
}
}

View file

@ -1077,7 +1077,7 @@ static UniValue gettxoutsetinfo(const JSONRPCRequest& request)
UniValue ret(UniValue::VOBJ);
CCoinsStats stats;
FlushStateToDisk();
::ChainstateActive().ForceFlushStateToDisk();
if (GetUTXOStats(pcoinsdbview.get(), stats)) {
ret.pushKV("height", (int64_t)stats.nHeight);
ret.pushKV("bestblock", stats.hashBlock.GetHex());
@ -2283,7 +2283,7 @@ UniValue scantxoutset(const JSONRPCRequest& request)
std::unique_ptr<CCoinsViewCursor> pcursor;
{
LOCK(cs_main);
FlushStateToDisk();
::ChainstateActive().ForceFlushStateToDisk();
pcursor = std::unique_ptr<CCoinsViewCursor>(pcoinsdbview->Cursor());
assert(pcursor);
}

View file

@ -173,15 +173,7 @@ std::unique_ptr<CCoinsViewDB> pcoinsdbview;
std::unique_ptr<CCoinsViewCache> pcoinsTip;
std::unique_ptr<CBlockTreeDB> pblocktree;
enum class FlushStateMode {
NONE,
IF_NEEDED,
PERIODIC,
ALWAYS
};
// See definition for documentation
static bool FlushStateToDisk(const CChainParams& chainParams, CValidationState &state, FlushStateMode mode, int nManualPruneHeight=0);
static void FindFilesToPruneManual(std::set<int>& setFilesToPrune, int nManualPruneHeight);
static void FindFilesToPrune(std::set<int>& setFilesToPrune, uint64_t nPruneAfterHeight);
bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsViewCache &inputs, bool fScriptChecks, unsigned int flags, bool cacheSigStore, bool cacheFullScriptStore, PrecomputedTransactionData& txdata, std::vector<CScriptCheck> *pvChecks = nullptr);
@ -854,7 +846,7 @@ static bool AcceptToMemoryPoolWithTime(const CChainParams& chainparams, CTxMemPo
}
// After we've (potentially) uncached entries, ensure our coins cache is still within its size limits
CValidationState stateDummy;
FlushStateToDisk(chainparams, stateDummy, FlushStateMode::PERIODIC);
::ChainstateActive().FlushStateToDisk(chainparams, stateDummy, FlushStateMode::PERIODIC);
return res;
}
@ -1951,16 +1943,12 @@ bool CChainState::ConnectBlock(const CBlock& block, CValidationState& state, CBl
return true;
}
/**
* Update the on-disk chain state.
* The caches and indexes are flushed depending on the mode we're called with
* if they're too large, if it's been a while since the last write,
* or always and in all cases if we're in prune mode and are deleting files.
*
* If FlushStateMode::NONE is used, then FlushStateToDisk(...) won't do anything
* besides checking if we need to prune.
*/
bool static FlushStateToDisk(const CChainParams& chainparams, CValidationState &state, FlushStateMode mode, int nManualPruneHeight) {
bool CChainState::FlushStateToDisk(
const CChainParams& chainparams,
CValidationState &state,
FlushStateMode mode,
int nManualPruneHeight)
{
int64_t nMempoolUsage = mempool.DynamicMemoryUsage();
LOCK(cs_main);
static int64_t nLastWrite = 0;
@ -2058,7 +2046,7 @@ bool static FlushStateToDisk(const CChainParams& chainparams, CValidationState &
}
if (full_flush_completed) {
// Update best block in wallet (so we can detect restored wallets).
GetMainSignals().ChainStateFlushed(::ChainActive().GetLocator());
GetMainSignals().ChainStateFlushed(m_chain.GetLocator());
}
} catch (const std::runtime_error& e) {
return AbortNode(state, std::string("System error while flushing: ") + e.what());
@ -2066,19 +2054,20 @@ bool static FlushStateToDisk(const CChainParams& chainparams, CValidationState &
return true;
}
void FlushStateToDisk() {
void CChainState::ForceFlushStateToDisk() {
CValidationState state;
const CChainParams& chainparams = Params();
if (!FlushStateToDisk(chainparams, state, FlushStateMode::ALWAYS)) {
if (!this->FlushStateToDisk(chainparams, state, FlushStateMode::ALWAYS)) {
LogPrintf("%s: failed to flush state (%s)\n", __func__, FormatStateMessage(state));
}
}
void PruneAndFlush() {
void CChainState::PruneAndFlush() {
CValidationState state;
fCheckForPruning = true;
const CChainParams& chainparams = Params();
if (!FlushStateToDisk(chainparams, state, FlushStateMode::NONE)) {
if (!this->FlushStateToDisk(chainparams, state, FlushStateMode::NONE)) {
LogPrintf("%s: failed to flush state (%s)\n", __func__, FormatStateMessage(state));
}
}
@ -3587,7 +3576,8 @@ void PruneBlockFilesManual(int nManualPruneHeight)
{
CValidationState state;
const CChainParams& chainparams = Params();
if (!FlushStateToDisk(chainparams, state, FlushStateMode::NONE, nManualPruneHeight)) {
if (!::ChainstateActive().FlushStateToDisk(
chainparams, state, FlushStateMode::NONE, nManualPruneHeight)) {
LogPrintf("%s: failed to flush state (%s)\n", __func__, FormatStateMessage(state));
}
}
@ -4183,7 +4173,7 @@ bool RewindBlockIndex(const CChainParams& params) {
// and skip it here, we're about to -reindex-chainstate anyway, so
// it'll get called a bunch real soon.
CValidationState state;
if (!FlushStateToDisk(params, state, FlushStateMode::ALWAYS)) {
if (!::ChainstateActive().FlushStateToDisk(params, state, FlushStateMode::ALWAYS)) {
LogPrintf("RewindBlockIndex: unable to flush state to disk (%s)\n", FormatStateMessage(state));
return false;
}

View file

@ -31,6 +31,7 @@
#include <utility>
#include <vector>
class CChainState;
class CBlockIndex;
class CBlockTreeDB;
class CBlockUndo;
@ -277,10 +278,6 @@ void PruneOneBlockFile(const int fileNumber) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
*/
void UnlinkPrunedFiles(const std::set<int>& setFilesToPrune);
/** Flush all state, indexes and buffers to disk. */
void FlushStateToDisk();
/** Prune block files and flush state to disk. */
void PruneAndFlush();
/** Prune block files up to a given height */
void PruneBlockFilesManual(int nManualPruneHeight);
@ -432,6 +429,14 @@ enum DisconnectResult
class ConnectTrace;
/** @see CChainState::FlushStateToDisk */
enum class FlushStateMode {
NONE,
IF_NEEDED,
PERIODIC,
ALWAYS
};
struct CBlockIndexWorkComparator
{
bool operator()(const CBlockIndex *pa, const CBlockIndex *pb) const;
@ -508,6 +513,28 @@ public:
bool LoadBlockIndex(const Consensus::Params& consensus_params, CBlockTreeDB& blocktree) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
/**
* Update the on-disk chain state.
* The caches and indexes are flushed depending on the mode we're called with
* if they're too large, if it's been a while since the last write,
* or always and in all cases if we're in prune mode and are deleting files.
*
* If FlushStateMode::NONE is used, then FlushStateToDisk(...) won't do anything
* besides checking if we need to prune.
*/
bool FlushStateToDisk(
const CChainParams& chainparams,
CValidationState &state,
FlushStateMode mode,
int nManualPruneHeight = 0);
//! Unconditionally flush all changes to disk.
void ForceFlushStateToDisk();
//! Prune blockfiles from the disk if necessary and then flush chainstate changes
//! if we pruned.
void PruneAndFlush();
bool ActivateBestChain(CValidationState &state, const CChainParams& chainparams, std::shared_ptr<const CBlock> pblock) LOCKS_EXCLUDED(cs_main);
/**