Skip to content

Commit

Permalink
Merge #6304: backport: merge bitcoin#23280 (coalesce chainstate loadi…
Browse files Browse the repository at this point in the history
…ng sequence between {,non-}unittest codepaths)

1974651 refactor: move remaining `LogPrintf` usage outside (Kittywhiskers Van Gogh)
04dbaa8 style-only: Remove redundant scope in *Chainstate (Kittywhiskers Van Gogh)
872158d Remove all #include // for * comments (Kittywhiskers Van Gogh)
09ab629 test/setup: Use LoadChainstate (Kittywhiskers Van Gogh)
459f339 node/chainstate: extract Dash post-`InitializeChainstate` logic (Kittywhiskers Van Gogh)
c06e074 node/chainstate: Add options for in-memory DBs (Kittywhiskers Van Gogh)
52bb35d node/caches: Remove intermediate variables (Kittywhiskers Van Gogh)
4ab1827 node/caches: Extract cache calculation logic (Kittywhiskers Van Gogh)
d7f1e23 validation: VerifyDB only needs Consensus::Params (Kittywhiskers Van Gogh)
c405492 node/chainstate: Decouple from ShutdownRequested (Kittywhiskers Van Gogh)
fdf803d node/chainstate: Decouple from GetTime (Kittywhiskers Van Gogh)
f7aef8d init: Delay RPC block notif until warmup finished (Kittywhiskers Van Gogh)
94c0ceb Move -checkblocks LogPrintf to AppInitMain (Kittywhiskers Van Gogh)
d3345ee node/chainstate: Reduce coupling of LogPrintf (Kittywhiskers Van Gogh)
a141f5d node/chainstate: Decouple from concept of uiInterface (Kittywhiskers Van Gogh)
913411e Split off VerifyLoadedChainstate (Kittywhiskers Van Gogh)
53231ca node/chainstate: Remove do/while loop (Kittywhiskers Van Gogh)
2ea1bbc Move init logistics message for BAD_GENESIS_BLOCK to init.cpp (Kittywhiskers Van Gogh)
29c7362 Move mempool nullptr Assert out of LoadChainstate (Kittywhiskers Van Gogh)
7071282 node/chainstate: Decouple from concept of NodeContext (Kittywhiskers Van Gogh)
ee9d3dd node/chainstate: Decouple from ArgsManager (Kittywhiskers Van Gogh)
d7419e4 node/chainstate: Decouple from stringy errors (Kittywhiskers Van Gogh)
9ab08c4 node/chainstate: Decouple from GetTimeMillis (Kittywhiskers Van Gogh)
2455c06 node: Extract chainstate loading sequence (Kittywhiskers Van Gogh)
620146b chore: sync chainstate loading logic with upstream (Kittywhiskers Van Gogh)

Pull request description:

  ## Additional Information

  * Dependent on #6296

  * Dependent on #6443

  * As one of the backport's intentions were to unify code between `init.cpp` and `setup_common.cpp`, Dash-specific initialization code (to the extent that it can be moved out non-disruptively) has been spun out into `DashChainstateSetup{,Close}()` so it can also be used in `setup_common.cpp` and `validation_chainstatemanager_tests.cpp`.

    This is also why `DashTestSetup{,Close}()` (now `DashPostChainstateSetup{,Close}()`) was introduced in [dash#5531](#5531).
    * `DashChainstateSetup{,Close}()` (as defined in `node/chainstate.cpp`) cannot take `NodeContext` in because  `node/chainstate.cpp` is used in `bitcoin-chainstate`, which doesn't include `NodeContext` ([source](https://github.com/bitcoin/bitcoin/pull/24304/files#diff-4cb884d03ebb901069e4ee5de5d02538c40dd9b39919c615d8eaa9d364bbbd77R795-R798)), this is reflected by neither `LoadChainstate` nor `VerifyLoadedChainstate` taking in `NodeContext`.

    * To make it less onerous to use in unit tests, `DashChainstateSetup{,Close}()` has been overloaded with a variant that accepts `NodeContext`.

  * To remove `LogPrintf` usage in `node/chainstate.cpp`, index enablement reporting has been pulled out of chainstate loading and BLS scheme reporting has been abstracted out using `notify_bls_state`.

  ## Breaking Changes

  None expected.

  ## Checklist

  - [x] I have performed a self-review of my own code
  - [x] I have commented my code, particularly in hard-to-understand areas **(note: N/A)**
  - [x] I have added or updated relevant unit/integration/functional/e2e tests
  - [x] I have made corresponding changes to the documentation **(note: N/A)**
  - [x] I have assigned this pull request to a milestone _(for repository code-owners and collaborators only)_

ACKs for top commit:
  UdjinM6:
    utACK 1974651
  PastaPastaPasta:
    utACK 1974651

Tree-SHA512: 8ebfce48dccc6a867339aff9374a4cb8dc7b02b0c17432db2b97c982523d0d9589a87e6527a103f314bf32be176486311ef6dcde1c4d5cdccc1eeb1f80bbb040
  • Loading branch information
PastaPastaPasta committed Dec 17, 2024
2 parents 7530f3d + 1974651 commit a5d5400
Show file tree
Hide file tree
Showing 13 changed files with 821 additions and 343 deletions.
4 changes: 4 additions & 0 deletions src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,8 @@ BITCOIN_CORE_H = \
netgroup.h \
netmessagemaker.h \
node/blockstorage.h \
node/caches.h \
node/chainstate.h \
node/coin.h \
node/coinstats.h \
node/connection_types.h \
Expand Down Expand Up @@ -502,6 +504,8 @@ libbitcoin_server_a_SOURCES = \
netgroup.cpp \
net_processing.cpp \
node/blockstorage.cpp \
node/caches.cpp \
node/chainstate.cpp \
node/coin.cpp \
node/coinstats.cpp \
node/connection_types.cpp \
Expand Down
450 changes: 157 additions & 293 deletions src/init.cpp

Large diffs are not rendered by default.

32 changes: 32 additions & 0 deletions src/node/caches.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Copyright (c) 2021 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <node/caches.h>

#include <txdb.h>
#include <util/system.h>
#include <validation.h>

CacheSizes CalculateCacheSizes(const ArgsManager& args, size_t n_indexes)
{
int64_t nTotalCache = (args.GetArg("-dbcache", nDefaultDbCache) << 20);
nTotalCache = std::max(nTotalCache, nMinDbCache << 20); // total cache cannot be less than nMinDbCache
nTotalCache = std::min(nTotalCache, nMaxDbCache << 20); // total cache cannot be greater than nMaxDbcache
CacheSizes sizes;
sizes.block_tree_db = std::min(nTotalCache / 8, nMaxBlockDBCache << 20);
nTotalCache -= sizes.block_tree_db;
sizes.tx_index = std::min(nTotalCache / 8, args.GetBoolArg("-txindex", DEFAULT_TXINDEX) ? nMaxTxIndexCache << 20 : 0);
nTotalCache -= sizes.tx_index;
sizes.filter_index = 0;
if (n_indexes > 0) {
int64_t max_cache = std::min(nTotalCache / 8, max_filter_index_cache << 20);
sizes.filter_index = max_cache / n_indexes;
nTotalCache -= sizes.filter_index * n_indexes;
}
sizes.coins_db = std::min(nTotalCache / 2, (nTotalCache / 4) + (1 << 23)); // use 25%-50% of the remainder for disk cache
sizes.coins_db = std::min(sizes.coins_db, nMaxCoinsDBCache << 20); // cap total coins db cache
nTotalCache -= sizes.coins_db;
sizes.coins = nTotalCache; // the rest goes to in-memory cache
return sizes;
}
22 changes: 22 additions & 0 deletions src/node/caches.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Copyright (c) 2021 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#ifndef BITCOIN_NODE_CACHES_H
#define BITCOIN_NODE_CACHES_H

#include <cstddef>
#include <cstdint>

class ArgsManager;

struct CacheSizes {
int64_t block_tree_db;
int64_t coins_db;
int64_t coins;
int64_t tx_index;
int64_t filter_index;
};
CacheSizes CalculateCacheSizes(const ArgsManager& args, size_t n_indexes = 0);

#endif // BITCOIN_NODE_CACHES_H
328 changes: 328 additions & 0 deletions src/node/chainstate.cpp

Large diffs are not rendered by default.

162 changes: 162 additions & 0 deletions src/node/chainstate.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
// Copyright (c) 2021 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#ifndef BITCOIN_NODE_CHAINSTATE_H
#define BITCOIN_NODE_CHAINSTATE_H

#include <cstdint>
#include <functional>
#include <memory>
#include <optional>
#include <string>

class CActiveMasternodeManager;
class CChainstateHelper;
class CCreditPoolManager;
class CDeterministicMNManager;
class CEvoDB;
class CGovernanceManager;
class ChainstateManager;
class CMasternodeMetaMan;
class CMasternodeSync;
class CMNHFManager;
class CSporkManager;
class CTxMemPool;
struct LLMQContext;

namespace llmq {
class CChainLocksHandler;
class CInstantSendManager;
class CQuorumSnapshotManager;
}

namespace Consensus {
struct Params;
}

enum class ChainstateLoadingError {
ERROR_LOADING_BLOCK_DB,
ERROR_BAD_GENESIS_BLOCK,
ERROR_BAD_DEVNET_GENESIS_BLOCK,
ERROR_TXINDEX_DISABLED_WHEN_GOV_ENABLED,
ERROR_ADDRIDX_NEEDS_REINDEX,
ERROR_SPENTIDX_NEEDS_REINDEX,
ERROR_TIMEIDX_NEEDS_REINDEX,
ERROR_PRUNED_NEEDS_REINDEX,
ERROR_LOAD_GENESIS_BLOCK_FAILED,
ERROR_CHAINSTATE_UPGRADE_FAILED,
ERROR_REPLAYBLOCKS_FAILED,
ERROR_LOADCHAINTIP_FAILED,
ERROR_GENERIC_BLOCKDB_OPEN_FAILED,
ERROR_COMMITING_EVO_DB,
ERROR_UPGRADING_EVO_DB,
ERROR_UPGRADING_SIGNALS_DB,
SHUTDOWN_PROBED,
};

/** This sequence can have 4 types of outcomes:
*
* 1. Success
* 2. Shutdown requested
* - nothing failed but a shutdown was triggered in the middle of the
* sequence
* 3. Soft failure
* - a failure that might be recovered from with a reindex
* 4. Hard failure
* - a failure that definitively cannot be recovered from with a reindex
*
* Currently, LoadChainstate returns a std::optional<ChainstateLoadingError>
* which:
*
* - if has_value()
* - Either "Soft failure", "Hard failure", or "Shutdown requested",
* differentiable by the specific enumerator.
*
* Note that a return value of SHUTDOWN_PROBED means ONLY that "during
* this sequence, when we explicitly checked shutdown_requested() at
* arbitrary points, one of those calls returned true". Therefore, a
* return value other than SHUTDOWN_PROBED does not guarantee that
* shutdown_requested() hasn't been called indirectly.
* - else
* - Success!
*/
std::optional<ChainstateLoadingError> LoadChainstate(bool fReset,
ChainstateManager& chainman,
CGovernanceManager& govman,
CMasternodeMetaMan& mn_metaman,
CMasternodeSync& mn_sync,
CSporkManager& sporkman,
std::unique_ptr<CActiveMasternodeManager>& mn_activeman,
std::unique_ptr<CChainstateHelper>& chain_helper,
std::unique_ptr<CCreditPoolManager>& cpoolman,
std::unique_ptr<CDeterministicMNManager>& dmnman,
std::unique_ptr<CEvoDB>& evodb,
std::unique_ptr<CMNHFManager>& mnhf_manager,
std::unique_ptr<llmq::CChainLocksHandler>& clhandler,
std::unique_ptr<llmq::CInstantSendManager>& isman,
std::unique_ptr<llmq::CQuorumSnapshotManager>& qsnapman,
std::unique_ptr<LLMQContext>& llmq_ctx,
CTxMemPool* mempool,
bool fPruneMode,
bool is_addrindex_enabled,
bool is_governance_enabled,
bool is_spentindex_enabled,
bool is_timeindex_enabled,
bool is_txindex_enabled,
const Consensus::Params& consensus_params,
const std::string& network_id,
bool fReindexChainState,
int64_t nBlockTreeDBCache,
int64_t nCoinDBCache,
int64_t nCoinCacheUsage,
bool block_tree_db_in_memory,
bool coins_db_in_memory,
std::function<bool()> shutdown_requested = nullptr,
std::function<void()> coins_error_cb = nullptr);

/** Initialize Dash-specific components during chainstate initialization */
void DashChainstateSetup(ChainstateManager& chainman,
CGovernanceManager& govman,
CMasternodeMetaMan& mn_metaman,
CMasternodeSync& mn_sync,
CSporkManager& sporkman,
std::unique_ptr<CActiveMasternodeManager>& mn_activeman,
std::unique_ptr<CChainstateHelper>& chain_helper,
std::unique_ptr<CCreditPoolManager>& cpoolman,
std::unique_ptr<CDeterministicMNManager>& dmnman,
std::unique_ptr<CEvoDB>& evodb,
std::unique_ptr<CMNHFManager>& mnhf_manager,
std::unique_ptr<llmq::CQuorumSnapshotManager>& qsnapman,
std::unique_ptr<LLMQContext>& llmq_ctx,
CTxMemPool* mempool,
bool fReset,
bool fReindexChainState,
const Consensus::Params& consensus_params);

void DashChainstateSetupClose(std::unique_ptr<CChainstateHelper>& chain_helper,
std::unique_ptr<CCreditPoolManager>& cpoolman,
std::unique_ptr<CDeterministicMNManager>& dmnman,
std::unique_ptr<CMNHFManager>& mnhf_manager,
std::unique_ptr<llmq::CQuorumSnapshotManager>& qsnapman,
std::unique_ptr<LLMQContext>& llmq_ctx,
CTxMemPool* mempool);

enum class ChainstateLoadVerifyError {
ERROR_BLOCK_FROM_FUTURE,
ERROR_CORRUPTED_BLOCK_DB,
ERROR_EVO_DB_SANITY_FAILED,
ERROR_GENERIC_FAILURE,
};

std::optional<ChainstateLoadVerifyError> VerifyLoadedChainstate(ChainstateManager& chainman,
CEvoDB& evodb,
bool fReset,
bool fReindexChainState,
const Consensus::Params& consensus_params,
unsigned int check_blocks,
unsigned int check_level,
std::function<int64_t()> get_unix_time_seconds,
std::function<void(bool)> notify_bls_state = nullptr);

#endif // BITCOIN_NODE_CHAINSTATE_H
2 changes: 1 addition & 1 deletion src/rpc/blockchain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1642,7 +1642,7 @@ static RPCHelpMan verifychain()

CChainState& active_chainstate = chainman.ActiveChainstate();
return CVerifyDB().VerifyDB(
active_chainstate, Params(), active_chainstate.CoinsTip(), *CHECK_NONFATAL(node.evodb), check_level, check_depth);
active_chainstate, Params().GetConsensus(), active_chainstate.CoinsTip(), *CHECK_NONFATAL(node.evodb), check_level, check_depth);
},
};
}
Expand Down
4 changes: 2 additions & 2 deletions src/test/evo_deterministicmns_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -816,8 +816,8 @@ void FuncVerifyDB(TestChainSetup& setup)

// Verify db consistency
LOCK(cs_main);
BOOST_REQUIRE(CVerifyDB().VerifyDB(chainman.ActiveChainstate(), Params(), chainman.ActiveChainstate().CoinsTip(),
*(setup.m_node.evodb), 4, 2));
BOOST_REQUIRE(CVerifyDB().VerifyDB(chainman.ActiveChainstate(), Params().GetConsensus(),
chainman.ActiveChainstate().CoinsTip(), *(setup.m_node.evodb), 4, 2));
}

BOOST_AUTO_TEST_SUITE(evo_dip3_activation_tests)
Expand Down
Loading

0 comments on commit a5d5400

Please sign in to comment.