mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-01-31 10:41:08 +00:00
Merge bitcoin/bitcoin#33680: validation: do not wipe utxo cache for stats/scans/snapshots
c6ca2b85a3e6e73674e210aee4ed69c4af2848e4 validation: do not wipe utxo cache for stats/scans/snapshots (Pieter Wuille) 7099e93d0a80c65a547131d7bab977b09573310c refactor: rename `FlushStateMode::ALWAYS` to `FORCE_FLUSH` (Lőrinc) Pull request description: Revival of https://github.com/bitcoin/bitcoin/pull/30610#issuecomment-3432564955 with the remaining comments applied on top > Since #28280, the cost of a non-wiping sync of the UTXO cache is only proportional to the number of dirty entries, rather than proportional to the size of the entire cache. Because of that, there is no reason to perform a wiping flush in case the contents of the cache is still useful. > > Split the `FlushStateMode::ALWAYS` mode into a FORCE_SYNC (non-wiping) and a FORCE_FLUSH (wiping), and then use the former in `scantxoutset`, `gettxoutsetinfo`, snapshot creation. (slightly updated after #30214) ACKs for top commit: optout21: reACK c6ca2b85a3e6e73674e210aee4ed69c4af2848e4 cedwies: reACK c6ca2b8 (trivial) achow101: ACK c6ca2b85a3e6e73674e210aee4ed69c4af2848e4 sedited: ACK c6ca2b85a3e6e73674e210aee4ed69c4af2848e4 Tree-SHA512: f3525a85dc512db4a0a9c749ad47c0d3fa44085a121aa54cd77646260a719c71f754ec6570ae77779c0ed68a24799116f79c686e7a17ce57a26f6a598f7bf926
This commit is contained in:
commit
4e4fa0199e
@ -246,10 +246,10 @@ $ python3 contrib/tracing/log_utxocache_flush.py $(pidof bitcoind)
|
|||||||
|
|
||||||
```
|
```
|
||||||
Logging utxocache flushes. Ctrl-C to end...
|
Logging utxocache flushes. Ctrl-C to end...
|
||||||
Duration (µs) Mode Coins Count Memory Usage Prune
|
Duration (µs) Mode Coins Count Memory Usage Flush for Prune
|
||||||
730451 IF_NEEDED 22990 3323.54 kB True
|
2556340 IF_NEEDED 2899141 394844.34 kB False
|
||||||
637657 ALWAYS 122320 17124.80 kB False
|
2005788 FORCE_FLUSH 2238117 310189.68 kB False
|
||||||
81349 ALWAYS 0 1383.49 kB False
|
2685 FORCE_FLUSH 0 262.24 kB False
|
||||||
```
|
```
|
||||||
|
|
||||||
### log_utxos.bt
|
### log_utxos.bt
|
||||||
|
|||||||
@ -10,7 +10,7 @@ from bcc import BPF, USDT
|
|||||||
"""Example logging Bitcoin Core utxo set cache flushes utilizing
|
"""Example logging Bitcoin Core utxo set cache flushes utilizing
|
||||||
the utxocache:flush tracepoint."""
|
the utxocache:flush tracepoint."""
|
||||||
|
|
||||||
# USAGE: ./contrib/tracing/log_utxocache_flush.py path/to/bitcoind
|
# USAGE: ./contrib/tracing/log_utxocache_flush.py <pid of bitcoind>
|
||||||
|
|
||||||
# BCC: The C program to be compiled to an eBPF program (by BCC) and loaded into
|
# BCC: The C program to be compiled to an eBPF program (by BCC) and loaded into
|
||||||
# a sandboxed Linux kernel VM.
|
# a sandboxed Linux kernel VM.
|
||||||
@ -45,7 +45,8 @@ FLUSH_MODES = [
|
|||||||
'NONE',
|
'NONE',
|
||||||
'IF_NEEDED',
|
'IF_NEEDED',
|
||||||
'PERIODIC',
|
'PERIODIC',
|
||||||
'ALWAYS'
|
'FORCE_FLUSH',
|
||||||
|
'FORCE_SYNC',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
@ -61,7 +62,7 @@ class Data(ctypes.Structure):
|
|||||||
|
|
||||||
|
|
||||||
def print_event(event):
|
def print_event(event):
|
||||||
print("%-15d %-10s %-15d %-15s %-8s" % (
|
print("%-15d %-12s %-15d %-15s %-8s" % (
|
||||||
event.duration,
|
event.duration,
|
||||||
FLUSH_MODES[event.mode],
|
FLUSH_MODES[event.mode],
|
||||||
event.coins_count,
|
event.coins_count,
|
||||||
@ -88,7 +89,7 @@ def main(pid):
|
|||||||
|
|
||||||
b["flush"].open_perf_buffer(handle_flush)
|
b["flush"].open_perf_buffer(handle_flush)
|
||||||
print("Logging utxocache flushes. Ctrl-C to end...")
|
print("Logging utxocache flushes. Ctrl-C to end...")
|
||||||
print("%-15s %-10s %-15s %-15s %-8s" % ("Duration (µs)", "Mode",
|
print("%-15s %-12s %-15s %-15s %-8s" % ("Duration (µs)", "Mode",
|
||||||
"Coins Count", "Memory Usage",
|
"Coins Count", "Memory Usage",
|
||||||
"Flush for Prune"))
|
"Flush for Prune"))
|
||||||
|
|
||||||
|
|||||||
@ -185,8 +185,8 @@ Is called *after* the in-memory UTXO cache is flushed.
|
|||||||
|
|
||||||
Arguments passed:
|
Arguments passed:
|
||||||
1. Time it took to flush the cache microseconds as `int64`
|
1. Time it took to flush the cache microseconds as `int64`
|
||||||
2. Flush state mode as `uint32`. It's an enumerator class with values `0`
|
2. Flush state mode as `uint32`. It's an enumerator class with values
|
||||||
(`NONE`), `1` (`IF_NEEDED`), `2` (`PERIODIC`), `3` (`ALWAYS`)
|
`0` (`NONE`), `1` (`IF_NEEDED`), `2` (`PERIODIC`), `3` (`FORCE_FLUSH`), `4` (`FORCE_SYNC`)
|
||||||
3. Cache size (number of coins) before the flush as `uint64`
|
3. Cache size (number of coins) before the flush as `uint64`
|
||||||
4. Cache memory usage in bytes as `uint64`
|
4. Cache memory usage in bytes as `uint64`
|
||||||
5. If pruning caused the flush as `bool`
|
5. If pruning caused the flush as `bool`
|
||||||
|
|||||||
@ -1043,7 +1043,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;
|
||||||
@ -2383,7 +2383,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());
|
||||||
}
|
}
|
||||||
@ -3200,7 +3200,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) {
|
||||||
|
|||||||
@ -82,7 +82,7 @@ BOOST_FIXTURE_TEST_CASE(write_during_multiblock_activation, TestChain100Setup)
|
|||||||
BOOST_CHECK_EQUAL(second_from_tip->pprev, chainstate.m_chain.Tip());
|
BOOST_CHECK_EQUAL(second_from_tip->pprev, chainstate.m_chain.Tip());
|
||||||
|
|
||||||
// Set m_next_write to current time
|
// Set m_next_write to current time
|
||||||
chainstate.FlushStateToDisk(state_dummy, FlushStateMode::ALWAYS);
|
chainstate.FlushStateToDisk(state_dummy, FlushStateMode::FORCE_FLUSH);
|
||||||
m_node.validation_signals->SyncWithValidationInterfaceQueue();
|
m_node.validation_signals->SyncWithValidationInterfaceQueue();
|
||||||
// The periodic flush interval is between 50 and 70 minutes (inclusive)
|
// The periodic flush interval is between 50 and 70 minutes (inclusive)
|
||||||
// The next call to a PERIODIC write will flush
|
// The next call to a PERIODIC write will flush
|
||||||
|
|||||||
@ -57,7 +57,7 @@ void sanity_check_snapshot()
|
|||||||
// Connect the chain to the tmp chainman and sanity check the chainparams snapshot values.
|
// Connect the chain to the tmp chainman and sanity check the chainparams snapshot values.
|
||||||
LOCK(cs_main);
|
LOCK(cs_main);
|
||||||
auto& cs{node.chainman->ActiveChainstate()};
|
auto& cs{node.chainman->ActiveChainstate()};
|
||||||
cs.ForceFlushStateToDisk();
|
cs.ForceFlushStateToDisk(/*wipe_cache=*/false);
|
||||||
const auto stats{*Assert(kernel::ComputeUTXOStats(kernel::CoinStatsHashType::HASH_SERIALIZED, &cs.CoinsDB(), node.chainman->m_blockman))};
|
const auto stats{*Assert(kernel::ComputeUTXOStats(kernel::CoinStatsHashType::HASH_SERIALIZED, &cs.CoinsDB(), node.chainman->m_blockman))};
|
||||||
const auto cp_au_data{*Assert(node.chainman->GetParams().AssumeutxoForHeight(2 * COINBASE_MATURITY))};
|
const auto cp_au_data{*Assert(node.chainman->GetParams().AssumeutxoForHeight(2 * COINBASE_MATURITY))};
|
||||||
Assert(stats.nHeight == cp_au_data.height);
|
Assert(stats.nHeight == cp_au_data.height);
|
||||||
|
|||||||
@ -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);
|
||||||
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
|
||||||
|
|||||||
@ -2769,8 +2769,9 @@ bool Chainstate::FlushStateToDisk(
|
|||||||
bool fCacheCritical = mode == FlushStateMode::IF_NEEDED && cache_state >= CoinsCacheSizeState::CRITICAL;
|
bool fCacheCritical = mode == FlushStateMode::IF_NEEDED && cache_state >= CoinsCacheSizeState::CRITICAL;
|
||||||
// It's been a while since we wrote the block index and chain state to disk. Do this frequently, so we don't need to redownload or reindex after a crash.
|
// It's been a while since we wrote the block index and chain state to disk. Do this frequently, so we don't need to redownload or reindex after a crash.
|
||||||
bool fPeriodicWrite = mode == FlushStateMode::PERIODIC && nNow >= m_next_write;
|
bool fPeriodicWrite = mode == FlushStateMode::PERIODIC && nNow >= m_next_write;
|
||||||
|
const auto empty_cache{(mode == FlushStateMode::FORCE_FLUSH) || fCacheLarge || fCacheCritical};
|
||||||
// Combine all conditions that result in a write to disk.
|
// Combine all conditions that result in a write to disk.
|
||||||
bool should_write = (mode == FlushStateMode::ALWAYS) || fCacheLarge || fCacheCritical || fPeriodicWrite || fFlushForPrune;
|
bool should_write = (mode == FlushStateMode::FORCE_SYNC) || empty_cache || fPeriodicWrite || fFlushForPrune;
|
||||||
// Write blocks, block index and best chain related state to disk.
|
// Write blocks, block index and best chain related state to disk.
|
||||||
if (should_write) {
|
if (should_write) {
|
||||||
LogDebug(BCLog::COINDB, "Writing chainstate to disk: flush mode=%s, prune=%d, large=%d, critical=%d, periodic=%d",
|
LogDebug(BCLog::COINDB, "Writing chainstate to disk: flush mode=%s, prune=%d, large=%d, critical=%d, periodic=%d",
|
||||||
@ -2818,7 +2819,6 @@ 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};
|
|
||||||
empty_cache ? CoinsTip().Flush() : CoinsTip().Sync();
|
empty_cache ? CoinsTip().Flush() : CoinsTip().Sync();
|
||||||
full_flush_completed = true;
|
full_flush_completed = true;
|
||||||
TRACEPOINT(utxocache, flush,
|
TRACEPOINT(utxocache, flush,
|
||||||
@ -2845,10 +2845,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)) {
|
||||||
LogWarning("Failed to force flush state (%s)", state.ToString());
|
LogWarning("Failed to force flush state (%s)", state.ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -5531,7 +5531,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;
|
||||||
}
|
}
|
||||||
@ -5977,7 +5977,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);
|
||||||
|
|||||||
@ -457,12 +457,13 @@ enum DisconnectResult
|
|||||||
class ConnectTrace;
|
class ConnectTrace;
|
||||||
|
|
||||||
/** @see Chainstate::FlushStateToDisk */
|
/** @see Chainstate::FlushStateToDisk */
|
||||||
inline constexpr std::array FlushStateModeNames{"NONE", "IF_NEEDED", "PERIODIC", "ALWAYS"};
|
inline constexpr std::array FlushStateModeNames{"NONE", "IF_NEEDED", "PERIODIC", "FORCE_FLUSH", "FORCE_SYNC"};
|
||||||
enum class FlushStateMode: uint8_t {
|
enum class FlushStateMode: uint8_t {
|
||||||
NONE,
|
NONE,
|
||||||
IF_NEEDED,
|
IF_NEEDED,
|
||||||
PERIODIC,
|
PERIODIC,
|
||||||
ALWAYS
|
FORCE_FLUSH,
|
||||||
|
FORCE_SYNC,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -735,8 +736,8 @@ public:
|
|||||||
FlushStateMode mode,
|
FlushStateMode mode,
|
||||||
int nManualPruneHeight = 0);
|
int nManualPruneHeight = 0);
|
||||||
|
|
||||||
//! Unconditionally flush all changes to disk.
|
//! Flush all changes to disk.
|
||||||
void ForceFlushStateToDisk();
|
void ForceFlushStateToDisk(bool wipe_cache = true);
|
||||||
|
|
||||||
//! 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.
|
||||||
|
|||||||
@ -109,7 +109,8 @@ FLUSHMODE_NAME = {
|
|||||||
0: "NONE",
|
0: "NONE",
|
||||||
1: "IF_NEEDED",
|
1: "IF_NEEDED",
|
||||||
2: "PERIODIC",
|
2: "PERIODIC",
|
||||||
3: "ALWAYS",
|
3: "FORCE_FLUSH",
|
||||||
|
4: "FORCE_SYNC",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -385,12 +386,12 @@ class UTXOCacheTracepointTest(BitcoinTestFramework):
|
|||||||
bpf["utxocache_flush"].open_perf_buffer(handle_utxocache_flush)
|
bpf["utxocache_flush"].open_perf_buffer(handle_utxocache_flush)
|
||||||
|
|
||||||
self.log.info("stop the node to flush the UTXO cache")
|
self.log.info("stop the node to flush the UTXO cache")
|
||||||
UTXOS_IN_CACHE = 2 # might need to be changed if the earlier tests are modified
|
UTXOS_IN_CACHE = 3 # might need to be changed if the earlier tests are modified
|
||||||
# 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)
|
||||||
@ -415,7 +416,7 @@ class UTXOCacheTracepointTest(BitcoinTestFramework):
|
|||||||
bpf["utxocache_flush"].open_perf_buffer(handle_utxocache_flush)
|
bpf["utxocache_flush"].open_perf_buffer(handle_utxocache_flush)
|
||||||
|
|
||||||
self.log.info("prune blockchain to trigger a flush for pruning")
|
self.log.info("prune blockchain to trigger a flush for pruning")
|
||||||
expected_flushes.append({"mode": "NONE", "for_prune": True, "size": 0})
|
expected_flushes.append({"mode": "NONE", "for_prune": True, "size": BLOCKS_TO_MINE})
|
||||||
self.nodes[0].pruneblockchain(315)
|
self.nodes[0].pruneblockchain(315)
|
||||||
|
|
||||||
bpf.perf_buffer_poll(timeout=500)
|
bpf.perf_buffer_poll(timeout=500)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user