@@ -1863,95 +1863,100 @@ static bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockInd
1863
1863
*/
1864
1864
bool static FlushStateToDisk (const CChainParams& chainparams, CValidationState &state, FlushStateMode mode, int nManualPruneHeight) {
1865
1865
int64_t nMempoolUsage = mempool.DynamicMemoryUsage ();
1866
- LOCK2 (cs_main, cs_LastBlockFile );
1866
+ LOCK (cs_main);
1867
1867
static int64_t nLastWrite = 0 ;
1868
1868
static int64_t nLastFlush = 0 ;
1869
1869
static int64_t nLastSetChain = 0 ;
1870
1870
std::set<int > setFilesToPrune;
1871
1871
bool fFlushForPrune = false ;
1872
+ bool fDoFullFlush = false ;
1873
+ int64_t nNow = 0 ;
1872
1874
try {
1873
- if (fPruneMode && (fCheckForPruning || nManualPruneHeight > 0 ) && !fReindex ) {
1874
- if (nManualPruneHeight > 0 ) {
1875
- FindFilesToPruneManual (setFilesToPrune, nManualPruneHeight);
1876
- } else {
1877
- FindFilesToPrune (setFilesToPrune, chainparams.PruneAfterHeight ());
1878
- fCheckForPruning = false ;
1879
- }
1880
- if (!setFilesToPrune.empty ()) {
1881
- fFlushForPrune = true ;
1882
- if (!fHavePruned ) {
1883
- pblocktree->WriteFlag (" prunedblockfiles" , true );
1884
- fHavePruned = true ;
1885
- }
1886
- }
1887
- }
1888
- int64_t nNow = GetTimeMicros ();
1889
- // Avoid writing/flushing immediately after startup.
1890
- if (nLastWrite == 0 ) {
1891
- nLastWrite = nNow;
1892
- }
1893
- if (nLastFlush == 0 ) {
1894
- nLastFlush = nNow;
1895
- }
1896
- if (nLastSetChain == 0 ) {
1897
- nLastSetChain = nNow;
1898
- }
1899
- int64_t nMempoolSizeMax = GetArg (" -maxmempool" , DEFAULT_MAX_MEMPOOL_SIZE) * 1000000 ;
1900
- int64_t cacheSize = pcoinsTip->DynamicMemoryUsage ();
1901
- int64_t nTotalSpace = nCoinCacheUsage + std::max<int64_t >(nMempoolSizeMax - nMempoolUsage, 0 );
1902
- // The cache is large and we're within 10% and 10 MiB of the limit, but we have time now (not in the middle of a block processing).
1903
- bool fCacheLarge = mode == FLUSH_STATE_PERIODIC && cacheSize > std::max ((9 * nTotalSpace) / 10 , nTotalSpace - MAX_BLOCK_COINSDB_USAGE * 1024 * 1024 );
1904
- // The cache is over the limit, we have to write now.
1905
- bool fCacheCritical = mode == FLUSH_STATE_IF_NEEDED && cacheSize > nTotalSpace;
1906
- // It's been a while since we wrote the block index to disk. Do this frequently, so we don't need to redownload after a crash.
1907
- bool fPeriodicWrite = mode == FLUSH_STATE_PERIODIC && nNow > nLastWrite + (int64_t )DATABASE_WRITE_INTERVAL * 1000000 ;
1908
- // It's been very long since we flushed the cache. Do this infrequently, to optimize cache usage.
1909
- bool fPeriodicFlush = mode == FLUSH_STATE_PERIODIC && nNow > nLastFlush + (int64_t )DATABASE_FLUSH_INTERVAL * 1000000 ;
1910
- // Combine all conditions that result in a full cache flush.
1911
- bool fDoFullFlush = (mode == FLUSH_STATE_ALWAYS) || fCacheLarge || fCacheCritical || fPeriodicFlush || fFlushForPrune ;
1912
- // Write blocks and block index to disk.
1913
- if (fDoFullFlush || fPeriodicWrite ) {
1914
- // Depend on nMinDiskSpace to ensure we can write block index
1915
- if (!CheckDiskSpace (0 ))
1916
- return state.Error (" out of disk space" );
1917
- // First make sure all block and undo data is flushed to disk.
1918
- FlushBlockFile ();
1919
- // Then update all block file information (which may refer to block and undo files).
1920
- {
1921
- std::vector<std::pair<int , const CBlockFileInfo*> > vFiles;
1922
- vFiles.reserve (setDirtyFileInfo.size ());
1923
- for (std::set<int >::iterator it = setDirtyFileInfo.begin (); it != setDirtyFileInfo.end (); ) {
1924
- vFiles.push_back (std::make_pair (*it, &vinfoBlockFile[*it]));
1925
- setDirtyFileInfo.erase (it++);
1875
+ {
1876
+ LOCK (cs_LastBlockFile);
1877
+ if (fPruneMode && (fCheckForPruning || nManualPruneHeight > 0 ) && !fReindex ) {
1878
+ if (nManualPruneHeight > 0 ) {
1879
+ FindFilesToPruneManual (setFilesToPrune, nManualPruneHeight);
1880
+ } else {
1881
+ FindFilesToPrune (setFilesToPrune, chainparams.PruneAfterHeight ());
1882
+ fCheckForPruning = false ;
1926
1883
}
1927
- std::vector<const CBlockIndex*> vBlocks;
1928
- vBlocks.reserve (setDirtyBlockIndex.size ());
1929
- for (std::set<CBlockIndex*>::iterator it = setDirtyBlockIndex.begin (); it != setDirtyBlockIndex.end (); ) {
1930
- vBlocks.push_back (*it);
1931
- setDirtyBlockIndex.erase (it++);
1884
+ if (!setFilesToPrune.empty ()) {
1885
+ fFlushForPrune = true ;
1886
+ if (!fHavePruned ) {
1887
+ pblocktree->WriteFlag (" prunedblockfiles" , true );
1888
+ fHavePruned = true ;
1889
+ }
1932
1890
}
1933
- if (!pblocktree->WriteBatchSync (vFiles, nLastBlockFile, vBlocks)) {
1934
- return AbortNode (state, " Failed to write to block index database" );
1891
+ }
1892
+ nNow = GetTimeMicros ();
1893
+ // Avoid writing/flushing immediately after startup.
1894
+ if (nLastWrite == 0 ) {
1895
+ nLastWrite = nNow;
1896
+ }
1897
+ if (nLastFlush == 0 ) {
1898
+ nLastFlush = nNow;
1899
+ }
1900
+ if (nLastSetChain == 0 ) {
1901
+ nLastSetChain = nNow;
1902
+ }
1903
+ int64_t nMempoolSizeMax = GetArg (" -maxmempool" , DEFAULT_MAX_MEMPOOL_SIZE) * 1000000 ;
1904
+ int64_t cacheSize = pcoinsTip->DynamicMemoryUsage ();
1905
+ int64_t nTotalSpace = nCoinCacheUsage + std::max<int64_t >(nMempoolSizeMax - nMempoolUsage, 0 );
1906
+ // The cache is large and we're within 10% and 10 MiB of the limit, but we have time now (not in the middle of a block processing).
1907
+ bool fCacheLarge = mode == FLUSH_STATE_PERIODIC && cacheSize > std::max ((9 * nTotalSpace) / 10 , nTotalSpace - MAX_BLOCK_COINSDB_USAGE * 1024 * 1024 );
1908
+ // The cache is over the limit, we have to write now.
1909
+ bool fCacheCritical = mode == FLUSH_STATE_IF_NEEDED && cacheSize > nTotalSpace;
1910
+ // It's been a while since we wrote the block index to disk. Do this frequently, so we don't need to redownload after a crash.
1911
+ bool fPeriodicWrite = mode == FLUSH_STATE_PERIODIC && nNow > nLastWrite + (int64_t )DATABASE_WRITE_INTERVAL * 1000000 ;
1912
+ // It's been very long since we flushed the cache. Do this infrequently, to optimize cache usage.
1913
+ bool fPeriodicFlush = mode == FLUSH_STATE_PERIODIC && nNow > nLastFlush + (int64_t )DATABASE_FLUSH_INTERVAL * 1000000 ;
1914
+ // Combine all conditions that result in a full cache flush.
1915
+ fDoFullFlush = (mode == FLUSH_STATE_ALWAYS) || fCacheLarge || fCacheCritical || fPeriodicFlush || fFlushForPrune ;
1916
+ // Write blocks and block index to disk.
1917
+ if (fDoFullFlush || fPeriodicWrite ) {
1918
+ // Depend on nMinDiskSpace to ensure we can write block index
1919
+ if (!CheckDiskSpace (0 ))
1920
+ return state.Error (" out of disk space" );
1921
+ // First make sure all block and undo data is flushed to disk.
1922
+ FlushBlockFile ();
1923
+ // Then update all block file information (which may refer to block and undo files).
1924
+ {
1925
+ std::vector<std::pair<int , const CBlockFileInfo*> > vFiles;
1926
+ vFiles.reserve (setDirtyFileInfo.size ());
1927
+ for (std::set<int >::iterator it = setDirtyFileInfo.begin (); it != setDirtyFileInfo.end (); ) {
1928
+ vFiles.push_back (std::make_pair (*it, &vinfoBlockFile[*it]));
1929
+ setDirtyFileInfo.erase (it++);
1930
+ }
1931
+ std::vector<const CBlockIndex*> vBlocks;
1932
+ vBlocks.reserve (setDirtyBlockIndex.size ());
1933
+ for (std::set<CBlockIndex*>::iterator it = setDirtyBlockIndex.begin (); it != setDirtyBlockIndex.end (); ) {
1934
+ vBlocks.push_back (*it);
1935
+ setDirtyBlockIndex.erase (it++);
1936
+ }
1937
+ if (!pblocktree->WriteBatchSync (vFiles, nLastBlockFile, vBlocks)) {
1938
+ return AbortNode (state, " Failed to write to block index database" );
1939
+ }
1935
1940
}
1941
+ // Finally remove any pruned files
1942
+ if (fFlushForPrune )
1943
+ UnlinkPrunedFiles (setFilesToPrune);
1944
+ nLastWrite = nNow;
1945
+ }
1946
+ // Flush best chain related state. This can only be done if the blocks / block index write was also done.
1947
+ if (fDoFullFlush ) {
1948
+ // Typical Coin structures on disk are around 48 bytes in size.
1949
+ // Pushing a new one to the database can cause it to be written
1950
+ // twice (once in the log, and once in the tables). This is already
1951
+ // an overestimation, as most will delete an existing entry or
1952
+ // overwrite one. Still, use a conservative safety factor of 2.
1953
+ if (!CheckDiskSpace (48 * 2 * 2 * pcoinsTip->GetCacheSize ()))
1954
+ return state.Error (" out of disk space" );
1955
+ // Flush the chainstate (which may refer to block index entries).
1956
+ if (!pcoinsTip->Flush ())
1957
+ return AbortNode (state, " Failed to write to coin database" );
1958
+ nLastFlush = nNow;
1936
1959
}
1937
- // Finally remove any pruned files
1938
- if (fFlushForPrune )
1939
- UnlinkPrunedFiles (setFilesToPrune);
1940
- nLastWrite = nNow;
1941
- }
1942
- // Flush best chain related state. This can only be done if the blocks / block index write was also done.
1943
- if (fDoFullFlush ) {
1944
- // Typical Coin structures on disk are around 48 bytes in size.
1945
- // Pushing a new one to the database can cause it to be written
1946
- // twice (once in the log, and once in the tables). This is already
1947
- // an overestimation, as most will delete an existing entry or
1948
- // overwrite one. Still, use a conservative safety factor of 2.
1949
- if (!CheckDiskSpace (48 * 2 * 2 * pcoinsTip->GetCacheSize ()))
1950
- return state.Error (" out of disk space" );
1951
- // Flush the chainstate (which may refer to block index entries).
1952
- if (!pcoinsTip->Flush ())
1953
- return AbortNode (state, " Failed to write to coin database" );
1954
- nLastFlush = nNow;
1955
1960
}
1956
1961
if (fDoFullFlush || ((mode == FLUSH_STATE_ALWAYS || mode == FLUSH_STATE_PERIODIC) && nNow > nLastSetChain + (int64_t )DATABASE_WRITE_INTERVAL * 1000000 )) {
1957
1962
// Update best block in wallet (so we can detect restored wallets).
0 commit comments