diff options
author | James O'Beirne <james.obeirne@pm.me> | 2022-04-20 17:40:01 -0400 |
---|---|---|
committer | James O'Beirne <james.obeirne@pm.me> | 2022-09-13 13:30:14 -0400 |
commit | 252abd1e8bc5cdf4368ad55e827a873240535b28 (patch) | |
tree | 2a1c9aa9ab01a4bb5951140d52b5c5720fce5ec9 /src/node | |
parent | f9f1735f139b6a1f1c7fea50717ff90dc4ba2bce (diff) | |
download | bitcoin-252abd1e8bc5cdf4368ad55e827a873240535b28.tar.xz |
init: add utxo snapshot detection
Add functionality for activating a snapshot-based chainstate if one is
detected on-disk.
Also cautiously initialize chainstate cache usages so that we don't
somehow blow past our cache allowances during initialization, then
rebalance at the end of init.
Co-authored-by: Russell Yanofsky <russ@yanofsky.org>
Diffstat (limited to 'src/node')
-rw-r--r-- | src/node/chainstate.cpp | 24 | ||||
-rw-r--r-- | src/node/utxo_snapshot.cpp | 12 | ||||
-rw-r--r-- | src/node/utxo_snapshot.h | 6 |
3 files changed, 39 insertions, 3 deletions
diff --git a/src/node/chainstate.cpp b/src/node/chainstate.cpp index 3f1d6dd743..26af523491 100644 --- a/src/node/chainstate.cpp +++ b/src/node/chainstate.cpp @@ -48,10 +48,15 @@ ChainstateLoadResult LoadChainstate(ChainstateManager& chainman, const CacheSize } LOCK(cs_main); - chainman.InitializeChainstate(options.mempool); chainman.m_total_coinstip_cache = cache_sizes.coins; chainman.m_total_coinsdb_cache = cache_sizes.coins_db; + // Load the fully validated chainstate. + chainman.InitializeChainstate(options.mempool); + + // Load a chain created from a UTXO snapshot, if any exist. + chainman.DetectSnapshotChainstate(options.mempool); + auto& pblocktree{chainman.m_blockman.m_block_tree_db}; // new CBlockTreeDB tries to delete the existing file, which // fails if it's still open from the previous loop. Close it first: @@ -98,12 +103,20 @@ ChainstateLoadResult LoadChainstate(ChainstateManager& chainman, const CacheSize return {ChainstateLoadStatus::FAILURE, _("Error initializing block database")}; } + // Conservative value which is arbitrarily chosen, as it will ultimately be changed + // by a call to `chainman.MaybeRebalanceCaches()`. We just need to make sure + // that the sum of the two caches (40%) does not exceed the allowable amount + // during this temporary initialization state. + double init_cache_fraction = 0.2; + // At this point we're either in reindex or we've loaded a useful // block tree into BlockIndex()! for (Chainstate* chainstate : chainman.GetAll()) { + LogPrintf("Initializing chainstate %s\n", chainstate->ToString()); + chainstate->InitCoinsDB( - /*cache_size_bytes=*/cache_sizes.coins_db, + /*cache_size_bytes=*/chainman.m_total_coinsdb_cache * init_cache_fraction, /*in_memory=*/options.coins_db_in_memory, /*should_wipe=*/options.reindex || options.reindex_chainstate); @@ -125,7 +138,7 @@ ChainstateLoadResult LoadChainstate(ChainstateManager& chainman, const CacheSize } // The on-disk coinsdb is now in a good state, create the cache - chainstate->InitCoinsCache(cache_sizes.coins); + chainstate->InitCoinsCache(chainman.m_total_coinstip_cache * init_cache_fraction); assert(chainstate->CanFlushToDisk()); if (!is_coinsview_empty(chainstate)) { @@ -146,6 +159,11 @@ ChainstateLoadResult LoadChainstate(ChainstateManager& chainman, const CacheSize }; } + // Now that chainstates are loaded and we're able to flush to + // disk, rebalance the coins caches to desired levels based + // on the condition of each chainstate. + chainman.MaybeRebalanceCaches(); + return {ChainstateLoadStatus::SUCCESS, {}}; } diff --git a/src/node/utxo_snapshot.cpp b/src/node/utxo_snapshot.cpp index 29ff83a03b..bab1b75211 100644 --- a/src/node/utxo_snapshot.cpp +++ b/src/node/utxo_snapshot.cpp @@ -8,6 +8,7 @@ #include <logging.h> #include <streams.h> #include <uint256.h> +#include <util/system.h> #include <validation.h> #include <cstdio> @@ -76,4 +77,15 @@ std::optional<uint256> ReadSnapshotBaseBlockhash(fs::path chaindir) return base_blockhash; } +std::optional<fs::path> FindSnapshotChainstateDir() +{ + fs::path possible_dir = + gArgs.GetDataDirNet() / fs::u8path(strprintf("chainstate%s", SNAPSHOT_CHAINSTATE_SUFFIX)); + + if (fs::exists(possible_dir)) { + return possible_dir; + } + return std::nullopt; +} + } // namespace node diff --git a/src/node/utxo_snapshot.h b/src/node/utxo_snapshot.h index b82a791092..c94521792f 100644 --- a/src/node/utxo_snapshot.h +++ b/src/node/utxo_snapshot.h @@ -58,8 +58,14 @@ bool WriteSnapshotBaseBlockhash(Chainstate& snapshot_chainstate) std::optional<uint256> ReadSnapshotBaseBlockhash(fs::path chaindir) EXCLUSIVE_LOCKS_REQUIRED(::cs_main); +//! Suffix appended to the chainstate (leveldb) dir when created based upon +//! a snapshot. constexpr std::string_view SNAPSHOT_CHAINSTATE_SUFFIX = "_snapshot"; + +//! Return a path to the snapshot-based chainstate dir, if one exists. +std::optional<fs::path> FindSnapshotChainstateDir(); + } // namespace node #endif // BITCOIN_NODE_UTXO_SNAPSHOT_H |