Skip to content

Commit be7afa7

Browse files
PastaPastaPastathepastaclaw
authored andcommitted
Merge bitcoin#25308: refactor: Reduce number of LoadChainstate parameters and return values
Upstream commits: - 3b91d4b refactor: Reduce number of LoadChainstate parameters - b3e7de7 refactor: Reduce number of LoadChainstate return values - 6db6552 refactor: Reduce number of SanityChecks return values - 1e761a0 ci: Enable IWYU in src/kernel directory
1 parent 36589d4 commit be7afa7

10 files changed

Lines changed: 225 additions & 332 deletions

File tree

ci/dash/lint-tidy.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ iwyu_tool.py \
8787
"src/compat" \
8888
"src/dbwrapper.cpp" \
8989
"src/init" \
90-
"src/kernel/mempool_persist.cpp" \
90+
"src/kernel" \
9191
"src/node/chainstate.cpp" \
9292
"src/node/minisketchwrapper.cpp" \
9393
"src/policy/feerate.cpp" \

src/bitcoin-chainstate.cpp

Lines changed: 16 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include <masternode/meta.h>
2727
#include <masternode/sync.h>
2828
#include <node/blockstorage.h>
29+
#include <node/caches.h>
2930
#include <node/chainstate.h>
3031
#include <scheduler.h>
3132
#include <script/sigcache.h>
@@ -101,8 +102,16 @@ int main(int argc, char* argv[])
101102

102103
std::unique_ptr<LLMQContext> llmq_ctx;
103104
std::unique_ptr<CChainstateHelper> chain_helper;
104-
auto rv = node::LoadChainstate(/*fReset=*/false,
105-
std::ref(chainman),
105+
node::CacheSizes cache_sizes;
106+
cache_sizes.block_tree_db = 2 << 20;
107+
cache_sizes.coins_db = 2 << 22;
108+
cache_sizes.coins = (450 << 20) - (2 << 20) - (2 << 22);
109+
node::ChainstateLoadOptions options;
110+
options.bls_threads = 1;
111+
options.worker_count = 1;
112+
options.max_recsigs_age = 1;
113+
options.check_interrupt = [] { return false; };
114+
auto [status, error] = node::LoadChainstate(chainman,
106115
metaman,
107116
sporkman,
108117
chainlocks,
@@ -111,32 +120,15 @@ int main(int argc, char* argv[])
111120
dmnman,
112121
evodb,
113122
llmq_ctx,
114-
/*mempool=*/nullptr,
115123
gArgs.GetDataDirNet(),
116-
/*fPruneMode=*/false,
117-
/*fReindexChainState=*/false,
118-
2 << 20,
119-
2 << 22,
120-
(450 << 20) - (2 << 20) - (2 << 22),
121-
/*block_tree_db_in_memory=*/false,
122-
/*coins_db_in_memory=*/false,
123-
/*dash_dbs_in_memory=*/false,
124-
/*bls_threads=*/1,
125-
/*worker_count=*/1,
126-
/*max_recsigs_age=*/1,
127-
/*shutdown_requested=*/[]() { return false; },
128-
/*coins_error_cb=*/[]() {});
129-
if (rv.has_value()) {
124+
cache_sizes,
125+
options);
126+
if (status != node::ChainstateLoadStatus::SUCCESS) {
130127
std::cerr << "Failed to load Chain state from your datadir." << std::endl;
131128
goto epilogue;
132129
} else {
133-
auto maybe_verify_error = node::VerifyLoadedChainstate(std::ref(chainman),
134-
*evodb,
135-
false,
136-
false,
137-
DEFAULT_CHECKBLOCKS,
138-
DEFAULT_CHECKLEVEL);
139-
if (maybe_verify_error.has_value()) {
130+
std::tie(status, error) = node::VerifyLoadedChainstate(std::ref(chainman), *evodb, options);
131+
if (status != node::ChainstateLoadStatus::SUCCESS) {
140132
std::cerr << "Failed to verify loaded Chain state from your datadir." << std::endl;
141133
goto epilogue;
142134
}

src/init.cpp

Lines changed: 67 additions & 145 deletions
Original file line numberDiff line numberDiff line change
@@ -157,8 +157,6 @@ using kernel::DumpMempool;
157157

158158
using node::CacheSizes;
159159
using node::CalculateCacheSizes;
160-
using node::ChainstateLoadingError;
161-
using node::ChainstateLoadVerifyError;
162160
using node::DashChainstateSetupClose;
163161
using node::DEFAULT_PERSIST_MEMPOOL;
164162
using node::DEFAULT_PRINTPRIORITY;
@@ -1474,21 +1472,8 @@ static bool LockDataDirectory(bool probeOnly)
14741472
bool AppInitSanityChecks(const kernel::Context& kernel)
14751473
{
14761474
// ********************************************************* Step 4: sanity checks
1477-
auto maybe_error = kernel::SanityChecks(kernel);
1478-
1479-
if (maybe_error.has_value()) {
1480-
switch (maybe_error.value()) {
1481-
case kernel::SanityCheckError::ERROR_ECC:
1482-
InitError(Untranslated("Elliptic curve cryptography sanity check failure. Aborting."));
1483-
break;
1484-
case kernel::SanityCheckError::ERROR_BLS:
1485-
InitError(Untranslated("BLS cryptographic sanity check failure. Aborting."));
1486-
break;
1487-
case kernel::SanityCheckError::ERROR_RANDOM:
1488-
InitError(Untranslated("OS cryptographic RNG sanity check failure. Aborting."));
1489-
break;
1490-
} // no default case, so the compiler can warn about missing cases
1491-
1475+
if (auto error = kernel::SanityChecks(kernel)) {
1476+
InitError(*error);
14921477
return InitError(strprintf(_("Initialization sanity check failed. %s is shutting down."), PACKAGE_NAME));
14931478
}
14941479

@@ -2036,147 +2021,84 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
20362021
*/
20372022
node.mn_sync = std::make_unique<CMasternodeSync>(std::make_unique<NodeSyncNotifierImpl>(*node.connman, *node.netfulfilledman));
20382023

2039-
const bool fReset = fReindex;
20402024
bilingual_str strLoadError;
20412025

2026+
node::ChainstateLoadOptions options;
2027+
options.mempool = Assert(node.mempool.get());
2028+
options.reindex = node::fReindex;
2029+
options.reindex_chainstate = fReindexChainState;
2030+
options.prune = node::fPruneMode;
2031+
options.bls_threads = [&args]() -> int8_t {
2032+
int64_t threads = args.GetIntArg("-parbls", llmq::DEFAULT_BLSCHECK_THREADS);
2033+
if (threads <= 0) {
2034+
// -parbls=0 means autodetect (number of cores - 1 validator threads)
2035+
// -parbls=-n means "leave n cores free" (number of cores - n - 1 validator threads)
2036+
threads += GetNumCores();
2037+
}
2038+
// Subtract 1 because the main thread counts towards the par threads
2039+
const int64_t adjusted_threads = std::clamp<int64_t>(threads, 1, int64_t{llmq::MAX_BLSCHECK_THREADS} + 1) - 1;
2040+
return static_cast<int8_t>(adjusted_threads);
2041+
}();
2042+
options.worker_count = llmq::DEFAULT_WORKER_COUNT;
2043+
options.max_recsigs_age = args.GetIntArg("-maxrecsigsage", llmq::DEFAULT_MAX_RECOVERED_SIGS_AGE);
2044+
options.check_blocks = args.GetIntArg("-checkblocks", DEFAULT_CHECKBLOCKS);
2045+
options.check_level = args.GetIntArg("-checklevel", DEFAULT_CHECKLEVEL);
2046+
options.check_interrupt = ShutdownRequested;
2047+
options.coins_error_cb = [] {
2048+
uiInterface.ThreadSafeMessageBox(
2049+
_("Error reading from database, shutting down."),
2050+
"", CClientUIInterface::MSG_ERROR);
2051+
};
2052+
options.notify_bls_state = [](bool bls_state) {
2053+
LogPrintf("%s: bls_legacy_scheme=%d\n", __func__, bls_state);
2054+
};
2055+
20422056
uiInterface.InitMessage(_("Loading block index…").translated);
20432057
const auto load_block_index_start_time{SteadyClock::now()};
2044-
std::optional<ChainstateLoadingError> maybe_load_error;
2045-
try {
2046-
maybe_load_error = LoadChainstate(fReset,
2047-
chainman,
2048-
*node.mn_metaman,
2049-
*node.sporkman,
2050-
*node.chainlocks,
2051-
*node.mn_sync,
2052-
node.chain_helper,
2053-
node.dmnman,
2054-
node.evodb,
2055-
node.llmq_ctx,
2056-
Assert(node.mempool.get()),
2057-
args.GetDataDirNet(),
2058-
fPruneMode,
2059-
fReindexChainState,
2060-
cache_sizes.block_tree_db,
2061-
cache_sizes.coins_db,
2062-
cache_sizes.coins,
2063-
/*block_tree_db_in_memory=*/false,
2064-
/*coins_db_in_memory=*/false,
2065-
/*dash_dbs_in_memory=*/false,
2066-
/*bls_threads=*/[&args]() -> int8_t {
2067-
int64_t threads = args.GetIntArg("-parbls", llmq::DEFAULT_BLSCHECK_THREADS);
2068-
if (threads <= 0) {
2069-
// -parbls=0 means autodetect (number of cores - 1 validator threads)
2070-
// -parbls=-n means "leave n cores free" (number of cores - n - 1 validator threads)
2071-
threads += GetNumCores();
2072-
}
2073-
// Subtract 1 because the main thread counts towards the par threads
2074-
const int64_t adjusted_threads = std::clamp<int64_t>(
2075-
threads, 1, int64_t{llmq::MAX_BLSCHECK_THREADS} + 1) - 1;
2076-
return static_cast<int8_t>(adjusted_threads);
2077-
}(),
2078-
llmq::DEFAULT_WORKER_COUNT,
2079-
args.GetIntArg("-maxrecsigsage", llmq::DEFAULT_MAX_RECOVERED_SIGS_AGE),
2080-
/*shutdown_requested=*/ShutdownRequested,
2081-
/*coins_error_cb=*/[]() {
2082-
uiInterface.ThreadSafeMessageBox(
2083-
_("Error reading from database, shutting down."),
2084-
"", CClientUIInterface::MSG_ERROR);
2085-
});
2086-
} catch (const std::exception& e) {
2087-
LogPrintf("%s\n", e.what());
2088-
maybe_load_error = ChainstateLoadingError::ERROR_GENERIC_BLOCKDB_OPEN_FAILED;
2089-
}
2090-
if (maybe_load_error.has_value()) {
2091-
switch (maybe_load_error.value()) {
2092-
case ChainstateLoadingError::ERROR_LOADING_BLOCK_DB:
2093-
strLoadError = _("Error loading block database");
2094-
break;
2095-
case ChainstateLoadingError::ERROR_BAD_GENESIS_BLOCK:
2096-
// If the loaded chain has a wrong genesis, bail out immediately
2097-
// (we're likely using a testnet datadir, or the other way around).
2098-
return InitError(_("Incorrect or no genesis block found. Wrong datadir for network?"));
2099-
case ChainstateLoadingError::ERROR_BAD_DEVNET_GENESIS_BLOCK:
2100-
return InitError(_("Incorrect or no devnet genesis block found. Wrong datadir for devnet specified?"));
2101-
case ChainstateLoadingError::ERROR_PRUNED_NEEDS_REINDEX:
2102-
strLoadError = _("You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain");
2103-
break;
2104-
case ChainstateLoadingError::ERROR_LOAD_GENESIS_BLOCK_FAILED:
2105-
strLoadError = _("Error initializing block database");
2106-
break;
2107-
case ChainstateLoadingError::ERROR_CHAINSTATE_UPGRADE_FAILED:
2108-
return InitError(_("Unsupported chainstate database format found. "
2109-
"Please restart with -reindex-chainstate. This will "
2110-
"rebuild the chainstate database."));
2111-
case ChainstateLoadingError::ERROR_REPLAYBLOCKS_FAILED:
2112-
strLoadError = _("Unable to replay blocks. You will need to rebuild the database using -reindex-chainstate.");
2113-
break;
2114-
case ChainstateLoadingError::ERROR_LOADCHAINTIP_FAILED:
2115-
strLoadError = _("Error initializing block database");
2116-
break;
2117-
case ChainstateLoadingError::ERROR_GENERIC_BLOCKDB_OPEN_FAILED:
2118-
strLoadError = _("Error opening block database");
2119-
break;
2120-
case ChainstateLoadingError::ERROR_COMMITING_EVO_DB:
2121-
strLoadError = _("Failed to commit Evo database");
2122-
break;
2123-
case ChainstateLoadingError::ERROR_UPGRADING_EVO_DB:
2124-
strLoadError = _("Failed to upgrade Evo database");
2125-
break;
2126-
case ChainstateLoadingError::ERROR_UPGRADING_SIGNALS_DB:
2127-
strLoadError = _("Error upgrading evo database for EHF");
2128-
break;
2129-
case ChainstateLoadingError::SHUTDOWN_PROBED:
2130-
break;
2131-
}
2132-
} else {
2133-
std::optional<ChainstateLoadVerifyError> maybe_verify_error;
2058+
auto catch_exceptions = [](auto&& fn) -> node::ChainstateLoadResult {
21342059
try {
2135-
uiInterface.InitMessage(_("Verifying blocks…").translated);
2136-
auto check_blocks = args.GetIntArg("-checkblocks", DEFAULT_CHECKBLOCKS);
2137-
if (chainman.m_blockman.m_have_pruned && check_blocks > MIN_BLOCKS_TO_KEEP) {
2138-
LogWarning("pruned datadir may not have more than %d blocks; only checking available blocks\n",
2139-
MIN_BLOCKS_TO_KEEP);
2140-
}
2141-
maybe_verify_error = VerifyLoadedChainstate(chainman,
2142-
*Assert(node.evodb.get()),
2143-
fReset,
2144-
fReindexChainState,
2145-
check_blocks,
2146-
args.GetIntArg("-checklevel", DEFAULT_CHECKLEVEL),
2147-
[](bool bls_state) {
2148-
LogPrintf("%s: bls_legacy_scheme=%d\n", __func__, bls_state);
2149-
});
2060+
return fn();
21502061
} catch (const std::exception& e) {
21512062
LogPrintf("%s\n", e.what());
2152-
maybe_verify_error = ChainstateLoadVerifyError::ERROR_GENERIC_FAILURE;
2063+
return {node::ChainstateLoadStatus::FAILURE, _("Error opening block database")};
21532064
}
2154-
if (maybe_verify_error.has_value()) {
2155-
switch (maybe_verify_error.value()) {
2156-
case ChainstateLoadVerifyError::ERROR_BLOCK_FROM_FUTURE:
2157-
strLoadError = _("The block database contains a block which appears to be from the future. "
2158-
"This may be due to your computer's date and time being set incorrectly. "
2159-
"Only rebuild the block database if you are sure that your computer's date and time are correct");
2160-
break;
2161-
case ChainstateLoadVerifyError::ERROR_CORRUPTED_BLOCK_DB:
2162-
strLoadError = _("Corrupted block database detected");
2163-
break;
2164-
case ChainstateLoadVerifyError::ERROR_EVO_DB_SANITY_FAILED:
2165-
strLoadError = _("Error initializing block database");
2166-
break;
2167-
case ChainstateLoadVerifyError::ERROR_GENERIC_FAILURE:
2168-
strLoadError = _("Error opening block database");
2169-
break;
2170-
}
2171-
} else {
2172-
fLoaded = true;
2173-
LogPrintf(" block index %15dms\n", Ticks<std::chrono::milliseconds>(SteadyClock::now() - load_block_index_start_time));
2065+
};
2066+
auto [status, error] = catch_exceptions([&] {
2067+
return LoadChainstate(chainman,
2068+
*node.mn_metaman,
2069+
*node.sporkman,
2070+
*node.chainlocks,
2071+
*node.mn_sync,
2072+
node.chain_helper,
2073+
node.dmnman,
2074+
node.evodb,
2075+
node.llmq_ctx,
2076+
args.GetDataDirNet(),
2077+
cache_sizes,
2078+
options);
2079+
});
2080+
if (status == node::ChainstateLoadStatus::SUCCESS) {
2081+
uiInterface.InitMessage(_("Verifying blocks…").translated);
2082+
if (chainman.m_blockman.m_have_pruned && options.check_blocks > MIN_BLOCKS_TO_KEEP) {
2083+
LogWarning("pruned datadir may not have more than %d blocks; only checking available blocks\n",
2084+
MIN_BLOCKS_TO_KEEP);
21742085
}
2086+
std::tie(status, error) = catch_exceptions([&] {
2087+
return VerifyLoadedChainstate(chainman, *Assert(node.evodb), options);
2088+
});
2089+
}
2090+
if (status == node::ChainstateLoadStatus::SUCCESS) {
2091+
fLoaded = true;
2092+
LogPrintf(" block index %15dms\n", Ticks<std::chrono::milliseconds>(SteadyClock::now() - load_block_index_start_time));
2093+
} else if (status == node::ChainstateLoadStatus::FAILURE_INCOMPATIBLE_DB) {
2094+
return InitError(error);
2095+
} else {
2096+
strLoadError = error;
21752097
}
21762098

21772099
if (!fLoaded && !ShutdownRequested()) {
21782100
// first suggest a reindex
2179-
if (!fReset) {
2101+
if (!options.reindex) {
21802102
bool fRet = uiInterface.ThreadSafeQuestion(
21812103
strLoadError + Untranslated(".\n\n") + _("Do you want to rebuild the block database now?"),
21822104
strLoadError.original + ".\nPlease restart with -reindex or -reindex-chainstate to recover.",

src/kernel/checks.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,21 +7,24 @@
77
#include <bls/bls.h>
88
#include <key.h>
99
#include <random.h>
10+
#include <util/translation.h>
11+
12+
#include <memory>
1013

1114
namespace kernel {
1215

13-
std::optional<SanityCheckError> SanityChecks(const Context&)
16+
std::optional<bilingual_str> SanityChecks(const Context&)
1417
{
1518
if (!ECC_InitSanityCheck()) {
16-
return SanityCheckError::ERROR_ECC;
19+
return Untranslated("Elliptic curve cryptography sanity check failure. Aborting.");
1720
}
1821

1922
if (!BLSInit()) {
20-
return SanityCheckError::ERROR_BLS;
23+
return Untranslated("BLS cryptographic sanity check failure. Aborting.");
2124
}
2225

2326
if (!Random_SanityCheck()) {
24-
return SanityCheckError::ERROR_RANDOM;
27+
return Untranslated("OS cryptographic RNG sanity check failure. Aborting.");
2528
}
2629

2730
return std::nullopt;

src/kernel/checks.h

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,20 +7,16 @@
77

88
#include <optional>
99

10+
struct bilingual_str;
11+
1012
namespace kernel {
1113

1214
struct Context;
1315

14-
enum class SanityCheckError {
15-
ERROR_ECC,
16-
ERROR_BLS,
17-
ERROR_RANDOM,
18-
};
19-
2016
/**
2117
* Ensure a usable environment with all necessary library support.
2218
*/
23-
std::optional<SanityCheckError> SanityChecks(const Context&);
19+
std::optional<bilingual_str> SanityChecks(const Context&);
2420

2521
}
2622

0 commit comments

Comments
 (0)