src/main.cpp
bool static FlushStateToDisk(CValidationState &state, FlushStateMode mode) {
    LOCK(cs_main);
    static int64_t nLastWrite = 0;
    if ((mode == FLUSH_STATE_ALWAYS) ||
        ((mode == FLUSH_STATE_PERIODIC || mode == FLUSH_STATE_IF_NEEDED) && pcoinsTip->GetCacheSize() > nCoinCacheSize) ||
        (mode == FLUSH_STATE_PERIODIC && GetTimeMicros() > nLastWrite + DATABASE_WRITE_INTERVAL * 1000000)) {
        // Typical CCoins structures on disk are around 100 bytes in size.
        // Pushing a new one to the database can cause it to be written
        // twice (once in the log, and once in the tables). This is already
        // an overestimation, as most will delete an existing entry or
        // overwrite one. Still, use a conservative safety factor of 2.
        if (!CheckDiskSpace(100 * 2 * 2 * pcoinsTip->GetCacheSize()))
            return state.Error("out of disk space");
        // First make sure all block and undo data is flushed to disk.
        FlushBlockFile();
        // Then update all block file information (which may refer to block and undo files).
        bool fileschanged = false;
        for (set<int>::iterator it = setDirtyFileInfo.begin(); it != setDirtyFileInfo.end(); ) {
            if (!pblocktree->WriteBlockFileInfo(*it, vinfoBlockFile[*it])) {
                return state.Abort("Failed to write to block index");
            }
            fileschanged = true;
            setDirtyFileInfo.erase(it++);
        }
        if (fileschanged && !pblocktree->WriteLastBlockFile(nLastBlockFile)) {
            return state.Abort("Failed to write to block index");
        }
        for (set<CBlockIndex*>::iterator it = setDirtyBlockIndex.begin(); it != setDirtyBlockIndex.end(); ) {
             if (!pblocktree->WriteBlockIndex(CDiskBlockIndex(*it))) {
                 return state.Abort("Failed to write to block index");
             }
             setDirtyBlockIndex.erase(it++);
        }
        pblocktree->Sync();
        // Finally flush the chainstate (which may refer to block index entries).
        if (!pcoinsTip->Flush())
            return state.Abort("Failed to write to coin database");
        // Update best block in wallet (so we can detect restored wallets).
        if (mode != FLUSH_STATE_IF_NEEDED) {
            g_signals.SetBestChain(chainActive.GetLocator());
        }
        nLastWrite = GetTimeMicros();
    }
    return true;
}
/**
 * Update the on-disk chain state.
 * The caches and indexes are flushed if either they're too large, forceWrite is set, or
 * fast is not set and it's been a while since the last write.
 */
Update the on-disk chain state.
The caches and indexes are flushed if either they're too large, forceWrite is set, or
fast is not set and it's been a while since the last write.
Update the on - disk chain state . The caches and indexes are flushed if either they ' re too large forceWrite is set or fast is not set and it ' s been a while since the last write .
bool static FlushStateToDisk(CValidationState &state, FlushStateMode mode) {
    LOCK(cs_main);
    static int64_t nLastWrite = 0;
    if ((mode == FLUSH_STATE_ALWAYS) ||
        ((mode == FLUSH_STATE_PERIODIC || mode == FLUSH_STATE_IF_NEEDED) && pcoinsTip->GetCacheSize() > nCoinCacheSize) ||
        (mode == FLUSH_STATE_PERIODIC && GetTimeMicros() > nLastWrite + DATABASE_WRITE_INTERVAL * 1000000)) {
        if (!CheckDiskSpace(100 * 2 * 2 * pcoinsTip->GetCacheSize()))
            return state.Error("out of disk space");
        FlushBlockFile();
        bool fileschanged = false;
        for (set<int>::iterator it = setDirtyFileInfo.begin(); it != setDirtyFileInfo.end(); ) {
            if (!pblocktree->WriteBlockFileInfo(*it, vinfoBlockFile[*it])) {
                return state.Abort("Failed to write to block index");
            }
            fileschanged = true;
            setDirtyFileInfo.erase(it++);
        }
        if (fileschanged && !pblocktree->WriteLastBlockFile(nLastBlockFile)) {
            return state.Abort("Failed to write to block index");
        }
        for (set<CBlockIndex*>::iterator it = setDirtyBlockIndex.begin(); it != setDirtyBlockIndex.end(); ) {
             if (!pblocktree->WriteBlockIndex(CDiskBlockIndex(*it))) {
                 return state.Abort("Failed to write to block index");
             }
             setDirtyBlockIndex.erase(it++);
        }
        pblocktree->Sync();
        if (!pcoinsTip->Flush())
            return state.Abort("Failed to write to coin database");
        if (mode != FLUSH_STATE_IF_NEEDED) {
            g_signals.SetBestChain(chainActive.GetLocator());
        }
        nLastWrite = GetTimeMicros();
    }
    return true;
}
bool static FlushStateToDisk ( CValidationState & state , FlushStateMode mode ) { LOCK ( cs_main ) ; static int64_t nLastWrite = 0 ; if ( ( mode == FLUSH_STATE_ALWAYS ) || ( ( mode == FLUSH_STATE_PERIODIC || mode == FLUSH_STATE_IF_NEEDED ) && pcoinsTip -> GetCacheSize ( ) > nCoinCacheSize ) || ( mode == FLUSH_STATE_PERIODIC && GetTimeMicros ( ) > nLastWrite + DATABASE_WRITE_INTERVAL * 1000000 ) ) { if ( ! CheckDiskSpace ( 100 * 2 * 2 * pcoinsTip -> GetCacheSize ( ) ) ) return state . Error ( " " ) ; FlushBlockFile ( ) ; bool fileschanged = false ; for ( set < int > :: iterator it = setDirtyFileInfo . begin ( ) ; it != setDirtyFileInfo . end ( ) ; ) { if ( ! pblocktree -> WriteBlockFileInfo ( * it , vinfoBlockFile [ * it ] ) ) { return state . Abort ( " " ) ; } fileschanged = true ; setDirtyFileInfo . erase ( it ++ ) ; } if ( fileschanged && ! pblocktree -> WriteLastBlockFile ( nLastBlockFile ) ) { return state . Abort ( " " ) ; } for ( set < CBlockIndex * > :: iterator it = setDirtyBlockIndex . begin ( ) ; it != setDirtyBlockIndex . end ( ) ; ) { if ( ! pblocktree -> WriteBlockIndex ( CDiskBlockIndex ( * it ) ) ) { return state . Abort ( " " ) ; } setDirtyBlockIndex . erase ( it ++ ) ; } pblocktree -> Sync ( ) ; if ( ! pcoinsTip -> Flush ( ) ) return state . Abort ( " " ) ; if ( mode != FLUSH_STATE_IF_NEEDED ) { g_signals . SetBestChain ( chainActive . GetLocator ( ) ) ; } nLastWrite = GetTimeMicros ( ) ; } return true ; }
Update the on-disk chain state.
Update the on - disk chain state .
// Typical CCoins structures on disk are around 100 bytes in size. // Pushing a new one to the database can cause it to be written // twice (once in the log, and once in the tables). This is already // an overestimation, as most will delete an existing entry or // overwrite one. Still, use a conservative safety factor of 2. // First make sure all block and undo data is flushed to disk. // Then update all block file information (which may refer to block and undo files). // Finally flush the chainstate (which may refer to block index entries). // Update best block in wallet (so we can detect restored wallets).