mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-03-13 19:37:04 +01:00
Merge 1ede4803f1
into a50af6e4c4
This commit is contained in:
commit
d15aa49c94
8 changed files with 26 additions and 24 deletions
|
@ -265,7 +265,7 @@ epilogue:
|
||||||
LOCK(cs_main);
|
LOCK(cs_main);
|
||||||
for (Chainstate* chainstate : chainman.GetAll()) {
|
for (Chainstate* chainstate : chainman.GetAll()) {
|
||||||
if (chainstate->CanFlushToDisk()) {
|
if (chainstate->CanFlushToDisk()) {
|
||||||
chainstate->ForceFlushStateToDisk();
|
chainstate->ForceFlushStateToDisk(/*wipe_cache=*/true);
|
||||||
chainstate->ResetCoinsViews();
|
chainstate->ResetCoinsViews();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -342,7 +342,7 @@ void Shutdown(NodeContext& node)
|
||||||
LOCK(cs_main);
|
LOCK(cs_main);
|
||||||
for (Chainstate* chainstate : node.chainman->GetAll()) {
|
for (Chainstate* chainstate : node.chainman->GetAll()) {
|
||||||
if (chainstate->CanFlushToDisk()) {
|
if (chainstate->CanFlushToDisk()) {
|
||||||
chainstate->ForceFlushStateToDisk();
|
chainstate->ForceFlushStateToDisk(/*wipe_cache=*/true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -368,7 +368,7 @@ void Shutdown(NodeContext& node)
|
||||||
LOCK(cs_main);
|
LOCK(cs_main);
|
||||||
for (Chainstate* chainstate : node.chainman->GetAll()) {
|
for (Chainstate* chainstate : node.chainman->GetAll()) {
|
||||||
if (chainstate->CanFlushToDisk()) {
|
if (chainstate->CanFlushToDisk()) {
|
||||||
chainstate->ForceFlushStateToDisk();
|
chainstate->ForceFlushStateToDisk(/*wipe_cache=*/true);
|
||||||
chainstate->ResetCoinsViews();
|
chainstate->ResetCoinsViews();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1000,7 +1000,7 @@ static RPCHelpMan gettxoutsetinfo()
|
||||||
NodeContext& node = EnsureAnyNodeContext(request.context);
|
NodeContext& node = EnsureAnyNodeContext(request.context);
|
||||||
ChainstateManager& chainman = EnsureChainman(node);
|
ChainstateManager& chainman = EnsureChainman(node);
|
||||||
Chainstate& active_chainstate = chainman.ActiveChainstate();
|
Chainstate& active_chainstate = chainman.ActiveChainstate();
|
||||||
active_chainstate.ForceFlushStateToDisk();
|
active_chainstate.ForceFlushStateToDisk(/*wipe_cache=*/false);
|
||||||
|
|
||||||
CCoinsView* coins_view;
|
CCoinsView* coins_view;
|
||||||
BlockManager* blockman;
|
BlockManager* blockman;
|
||||||
|
@ -2319,7 +2319,7 @@ static RPCHelpMan scantxoutset()
|
||||||
ChainstateManager& chainman = EnsureChainman(node);
|
ChainstateManager& chainman = EnsureChainman(node);
|
||||||
LOCK(cs_main);
|
LOCK(cs_main);
|
||||||
Chainstate& active_chainstate = chainman.ActiveChainstate();
|
Chainstate& active_chainstate = chainman.ActiveChainstate();
|
||||||
active_chainstate.ForceFlushStateToDisk();
|
active_chainstate.ForceFlushStateToDisk(/*wipe_cache=*/false);
|
||||||
pcursor = CHECK_NONFATAL(active_chainstate.CoinsDB().Cursor());
|
pcursor = CHECK_NONFATAL(active_chainstate.CoinsDB().Cursor());
|
||||||
tip = CHECK_NONFATAL(active_chainstate.m_chain.Tip());
|
tip = CHECK_NONFATAL(active_chainstate.m_chain.Tip());
|
||||||
}
|
}
|
||||||
|
@ -3123,7 +3123,7 @@ PrepareUTXOSnapshot(
|
||||||
//
|
//
|
||||||
AssertLockHeld(::cs_main);
|
AssertLockHeld(::cs_main);
|
||||||
|
|
||||||
chainstate.ForceFlushStateToDisk();
|
chainstate.ForceFlushStateToDisk(/*wipe_cache=*/false);
|
||||||
|
|
||||||
maybe_stats = GetUTXOStats(&chainstate.CoinsDB(), chainstate.m_blockman, CoinStatsHashType::HASH_SERIALIZED, interruption_point);
|
maybe_stats = GetUTXOStats(&chainstate.CoinsDB(), chainstate.m_blockman, CoinStatsHashType::HASH_SERIALIZED, interruption_point);
|
||||||
if (!maybe_stats) {
|
if (!maybe_stats) {
|
||||||
|
|
|
@ -87,9 +87,9 @@ FUZZ_TARGET(utxo_total_supply)
|
||||||
tx.vin.emplace_back(txo.first);
|
tx.vin.emplace_back(txo.first);
|
||||||
tx.vout.emplace_back(txo.second.nValue, txo.second.scriptPubKey); // "Forward" coin with no fee
|
tx.vout.emplace_back(txo.second.nValue, txo.second.scriptPubKey); // "Forward" coin with no fee
|
||||||
};
|
};
|
||||||
const auto UpdateUtxoStats = [&]() {
|
const auto UpdateUtxoStats = [&](bool wipe_cache) {
|
||||||
LOCK(chainman.GetMutex());
|
LOCK(chainman.GetMutex());
|
||||||
chainman.ActiveChainstate().ForceFlushStateToDisk();
|
chainman.ActiveChainstate().ForceFlushStateToDisk(/*wipe_cache=*/wipe_cache);
|
||||||
utxo_stats = std::move(
|
utxo_stats = std::move(
|
||||||
*Assert(kernel::ComputeUTXOStats(kernel::CoinStatsHashType::NONE, &chainman.ActiveChainstate().CoinsDB(), chainman.m_blockman, {})));
|
*Assert(kernel::ComputeUTXOStats(kernel::CoinStatsHashType::NONE, &chainman.ActiveChainstate().CoinsDB(), chainman.m_blockman, {})));
|
||||||
// Check that miner can't print more money than they are allowed to
|
// Check that miner can't print more money than they are allowed to
|
||||||
|
@ -99,7 +99,7 @@ FUZZ_TARGET(utxo_total_supply)
|
||||||
|
|
||||||
// Update internal state to chain tip
|
// Update internal state to chain tip
|
||||||
StoreLastTxo();
|
StoreLastTxo();
|
||||||
UpdateUtxoStats();
|
UpdateUtxoStats(/*wipe_cache=*/fuzzed_data_provider.ConsumeBool());
|
||||||
assert(ActiveHeight() == 0);
|
assert(ActiveHeight() == 0);
|
||||||
// Get at which height we duplicate the coinbase
|
// Get at which height we duplicate the coinbase
|
||||||
// Assuming that the fuzzer will mine relatively short chains (less than 200 blocks), we want the duplicate coinbase to be not too high.
|
// Assuming that the fuzzer will mine relatively short chains (less than 200 blocks), we want the duplicate coinbase to be not too high.
|
||||||
|
@ -124,7 +124,7 @@ FUZZ_TARGET(utxo_total_supply)
|
||||||
circulation += GetBlockSubsidy(ActiveHeight(), Params().GetConsensus());
|
circulation += GetBlockSubsidy(ActiveHeight(), Params().GetConsensus());
|
||||||
|
|
||||||
assert(ActiveHeight() == 1);
|
assert(ActiveHeight() == 1);
|
||||||
UpdateUtxoStats();
|
UpdateUtxoStats(/*wipe_cache=*/fuzzed_data_provider.ConsumeBool());
|
||||||
current_block = PrepareNextBlock();
|
current_block = PrepareNextBlock();
|
||||||
StoreLastTxo();
|
StoreLastTxo();
|
||||||
|
|
||||||
|
@ -163,7 +163,7 @@ FUZZ_TARGET(utxo_total_supply)
|
||||||
circulation += GetBlockSubsidy(ActiveHeight(), Params().GetConsensus());
|
circulation += GetBlockSubsidy(ActiveHeight(), Params().GetConsensus());
|
||||||
}
|
}
|
||||||
|
|
||||||
UpdateUtxoStats();
|
UpdateUtxoStats(/*wipe_cache=*/fuzzed_data_provider.ConsumeBool());
|
||||||
|
|
||||||
if (!was_valid) {
|
if (!was_valid) {
|
||||||
// utxo stats must not change
|
// utxo stats must not change
|
||||||
|
|
|
@ -375,7 +375,7 @@ struct SnapshotTestSetup : TestChain100Setup {
|
||||||
{
|
{
|
||||||
for (Chainstate* cs : chainman.GetAll()) {
|
for (Chainstate* cs : chainman.GetAll()) {
|
||||||
LOCK(::cs_main);
|
LOCK(::cs_main);
|
||||||
cs->ForceFlushStateToDisk();
|
cs->ForceFlushStateToDisk(/*wipe_cache=*/true);
|
||||||
}
|
}
|
||||||
// Process all callbacks referring to the old manager before wiping it.
|
// Process all callbacks referring to the old manager before wiping it.
|
||||||
m_node.validation_signals->SyncWithValidationInterfaceQueue();
|
m_node.validation_signals->SyncWithValidationInterfaceQueue();
|
||||||
|
|
|
@ -2895,7 +2895,7 @@ bool Chainstate::FlushStateToDisk(
|
||||||
// It's been very long since we flushed the cache. Do this infrequently, to optimize cache usage.
|
// It's been very long since we flushed the cache. Do this infrequently, to optimize cache usage.
|
||||||
bool fPeriodicFlush = mode == FlushStateMode::PERIODIC && nNow > m_last_flush + DATABASE_FLUSH_INTERVAL;
|
bool fPeriodicFlush = mode == FlushStateMode::PERIODIC && nNow > m_last_flush + DATABASE_FLUSH_INTERVAL;
|
||||||
// Combine all conditions that result in a full cache flush.
|
// Combine all conditions that result in a full cache flush.
|
||||||
fDoFullFlush = (mode == FlushStateMode::ALWAYS) || fCacheLarge || fCacheCritical || fPeriodicFlush || fFlushForPrune;
|
fDoFullFlush = (mode == FlushStateMode::FORCE_FLUSH) || (mode == FlushStateMode::FORCE_SYNC) || fCacheLarge || fCacheCritical || fPeriodicFlush || fFlushForPrune;
|
||||||
// Write blocks and block index to disk.
|
// Write blocks and block index to disk.
|
||||||
if (fDoFullFlush || fPeriodicWrite) {
|
if (fDoFullFlush || fPeriodicWrite) {
|
||||||
// Ensure we can write block index
|
// Ensure we can write block index
|
||||||
|
@ -2944,7 +2944,7 @@ bool Chainstate::FlushStateToDisk(
|
||||||
return FatalError(m_chainman.GetNotifications(), state, _("Disk space is too low!"));
|
return FatalError(m_chainman.GetNotifications(), state, _("Disk space is too low!"));
|
||||||
}
|
}
|
||||||
// Flush the chainstate (which may refer to block index entries).
|
// Flush the chainstate (which may refer to block index entries).
|
||||||
const auto empty_cache{(mode == FlushStateMode::ALWAYS) || fCacheLarge || fCacheCritical};
|
const auto empty_cache{(mode == FlushStateMode::FORCE_FLUSH) || fCacheLarge || fCacheCritical};
|
||||||
if (empty_cache ? !CoinsTip().Flush() : !CoinsTip().Sync()) {
|
if (empty_cache ? !CoinsTip().Flush() : !CoinsTip().Sync()) {
|
||||||
return FatalError(m_chainman.GetNotifications(), state, _("Failed to write to coin database."));
|
return FatalError(m_chainman.GetNotifications(), state, _("Failed to write to coin database."));
|
||||||
}
|
}
|
||||||
|
@ -2968,10 +2968,10 @@ bool Chainstate::FlushStateToDisk(
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Chainstate::ForceFlushStateToDisk()
|
void Chainstate::ForceFlushStateToDisk(bool wipe_cache)
|
||||||
{
|
{
|
||||||
BlockValidationState state;
|
BlockValidationState state;
|
||||||
if (!this->FlushStateToDisk(state, FlushStateMode::ALWAYS)) {
|
if (!this->FlushStateToDisk(state, wipe_cache ? FlushStateMode::FORCE_FLUSH : FlushStateMode::FORCE_SYNC)) {
|
||||||
LogPrintf("%s: failed to flush state (%s)\n", __func__, state.ToString());
|
LogPrintf("%s: failed to flush state (%s)\n", __func__, state.ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5608,7 +5608,7 @@ bool Chainstate::ResizeCoinsCaches(size_t coinstip_size, size_t coinsdb_size)
|
||||||
ret = FlushStateToDisk(state, FlushStateMode::IF_NEEDED);
|
ret = FlushStateToDisk(state, FlushStateMode::IF_NEEDED);
|
||||||
} else {
|
} else {
|
||||||
// Otherwise, flush state to disk and deallocate the in-memory coins map.
|
// Otherwise, flush state to disk and deallocate the in-memory coins map.
|
||||||
ret = FlushStateToDisk(state, FlushStateMode::ALWAYS);
|
ret = FlushStateToDisk(state, FlushStateMode::FORCE_FLUSH);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -6079,7 +6079,7 @@ util::Result<void> ChainstateManager::PopulateAndValidateSnapshot(
|
||||||
// returns in `ActivateSnapshot()`, when `MaybeRebalanceCaches()` is
|
// returns in `ActivateSnapshot()`, when `MaybeRebalanceCaches()` is
|
||||||
// called, since we've added a snapshot chainstate and therefore will
|
// called, since we've added a snapshot chainstate and therefore will
|
||||||
// have to downsize the IBD chainstate, which will result in a call to
|
// have to downsize the IBD chainstate, which will result in a call to
|
||||||
// `FlushStateToDisk(ALWAYS)`.
|
// `FlushStateToDisk(FORCE_FLUSH)`.
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(index);
|
assert(index);
|
||||||
|
@ -6179,7 +6179,7 @@ SnapshotCompletionResult ChainstateManager::MaybeCompleteSnapshotValidation()
|
||||||
assert(this->GetAll().size() == 2);
|
assert(this->GetAll().size() == 2);
|
||||||
|
|
||||||
CCoinsViewDB& ibd_coins_db = m_ibd_chainstate->CoinsDB();
|
CCoinsViewDB& ibd_coins_db = m_ibd_chainstate->CoinsDB();
|
||||||
m_ibd_chainstate->ForceFlushStateToDisk();
|
m_ibd_chainstate->ForceFlushStateToDisk(/*wipe_cache=*/true);
|
||||||
|
|
||||||
const auto& maybe_au_data = m_options.chainparams.AssumeutxoForHeight(curr_height);
|
const auto& maybe_au_data = m_options.chainparams.AssumeutxoForHeight(curr_height);
|
||||||
if (!maybe_au_data) {
|
if (!maybe_au_data) {
|
||||||
|
|
|
@ -440,7 +440,8 @@ enum class FlushStateMode {
|
||||||
NONE,
|
NONE,
|
||||||
IF_NEEDED,
|
IF_NEEDED,
|
||||||
PERIODIC,
|
PERIODIC,
|
||||||
ALWAYS
|
FORCE_SYNC,
|
||||||
|
FORCE_FLUSH,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -670,7 +671,7 @@ public:
|
||||||
int nManualPruneHeight = 0);
|
int nManualPruneHeight = 0);
|
||||||
|
|
||||||
//! Unconditionally flush all changes to disk.
|
//! Unconditionally flush all changes to disk.
|
||||||
void ForceFlushStateToDisk();
|
void ForceFlushStateToDisk(bool wipe_cache);
|
||||||
|
|
||||||
//! Prune blockfiles from the disk if necessary and then flush chainstate changes
|
//! Prune blockfiles from the disk if necessary and then flush chainstate changes
|
||||||
//! if we pruned.
|
//! if we pruned.
|
||||||
|
|
|
@ -106,7 +106,8 @@ FLUSHMODE_NAME = {
|
||||||
0: "NONE",
|
0: "NONE",
|
||||||
1: "IF_NEEDED",
|
1: "IF_NEEDED",
|
||||||
2: "PERIODIC",
|
2: "PERIODIC",
|
||||||
3: "ALWAYS",
|
3: "FORCE_SYNC",
|
||||||
|
4: "FORCE_FLUSH",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -374,8 +375,8 @@ class UTXOCacheTracepointTest(BitcoinTestFramework):
|
||||||
# A node shutdown causes two flushes. One that flushes UTXOS_IN_CACHE
|
# A node shutdown causes two flushes. One that flushes UTXOS_IN_CACHE
|
||||||
# UTXOs and one that flushes 0 UTXOs. Normally the 0-UTXO-flush is the
|
# UTXOs and one that flushes 0 UTXOs. Normally the 0-UTXO-flush is the
|
||||||
# second flush, however it can happen that the order changes.
|
# second flush, however it can happen that the order changes.
|
||||||
expected_flushes.append({"mode": "ALWAYS", "for_prune": False, "size": UTXOS_IN_CACHE})
|
expected_flushes.append({"mode": "FORCE_FLUSH", "for_prune": False, "size": UTXOS_IN_CACHE})
|
||||||
expected_flushes.append({"mode": "ALWAYS", "for_prune": False, "size": 0})
|
expected_flushes.append({"mode": "FORCE_FLUSH", "for_prune": False, "size": 0})
|
||||||
self.stop_node(0)
|
self.stop_node(0)
|
||||||
|
|
||||||
bpf.perf_buffer_poll(timeout=200)
|
bpf.perf_buffer_poll(timeout=200)
|
||||||
|
|
Loading…
Add table
Reference in a new issue